/* Decompression support for libdwfl: zlib (gzip) and/or bzlib (bzip2).
   Copyright (C) 2009 Red Hat, Inc.
   This file is part of elfutils.

   This file is free software; you can redistribute it and/or modify
   it under the terms of either

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at
       your option) any later version

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at
       your option) any later version

   or both in parallel, as here.

   elfutils is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see <http://www.gnu.org/licenses/>.  */

#include "libdwflP.h"
#include "system.h"

#include <unistd.h>

#ifdef LZMA
# define USE_INFLATE	1
# include <lzma.h>
# define unzip		__libdw_unlzma
# define DWFL_E_ZLIB	DWFL_E_LZMA
# define MAGIC		"\xFD" "7zXZ\0" /* XZ file format.  */
# define MAGIC2		"\x5d\0"	/* Raw LZMA format.  */
# define Z(what)	LZMA_##what
# define LZMA_ERRNO	LZMA_PROG_ERROR
# define z_stream	lzma_stream
# define inflateInit(z)	lzma_auto_decoder (z, 1 << 30, 0)
# define do_inflate(z)	lzma_code (z, LZMA_RUN)
# define inflateEnd(z)	lzma_end (z)
#elif defined BZLIB
# define USE_INFLATE	1
# include <bzlib.h>
# define unzip		__libdw_bunzip2
# define DWFL_E_ZLIB	DWFL_E_BZLIB
# define MAGIC		"BZh"
# define Z(what)	BZ_##what
# define BZ_ERRNO	BZ_IO_ERROR
# define z_stream	bz_stream
# define inflateInit(z)	BZ2_bzDecompressInit (z, 0, 0)
# define do_inflate(z)	BZ2_bzDecompress (z)
# define inflateEnd(z)	BZ2_bzDecompressEnd (z)
#else
# define USE_INFLATE	0
# define crc32		loser_crc32
# include <zlib.h>
# define unzip		__libdw_gunzip
# define MAGIC		"\037\213"
# define Z(what)	Z_##what
#endif

#define READ_SIZE		(1 << 20)

struct unzip_state {
#if !USE_INFLATE
  gzFile zf;
#endif
  size_t mapped_size;
  void **whole;
  void *buffer;
  size_t size;
  void *input_buffer;
  off_t input_pos;
};

static inline bool
bigger_buffer (struct unzip_state *state, size_t start)
{
  size_t more = state->size ? state->size * 2 : start;
  char *b = realloc (state->buffer, more);
  while (unlikely (b == NULL) && more >= state->size + 1024)
    b = realloc (state->buffer, more -= 1024);
  if (unlikely (b == NULL))
    return false;
  state->buffer = b;
  state->size = more;
  return true;
}

static inline void
smaller_buffer (struct unzip_state *state, size_t end)
{
  state->buffer =
      realloc (state->buffer, end) ?: end == 0 ? NULL : state->buffer;
  state->size = end;
}

static inline Dwfl_Error
fail (struct unzip_state *state, Dwfl_Error failure)
{
  if (state->input_pos == (off_t) state->mapped_size)
    *state->whole = state->input_buffer;
  else
    {
      free (state->input_buffer);
      *state->whole = NULL;
    }
  free (state->buffer);
  return failure;
}

static inline Dwfl_Error
zlib_fail (struct unzip_state *state, int result)
{
  switch (result)
    {
    case Z (MEM_ERROR):
      return fail (state, DWFL_E_NOMEM);
    case Z (ERRNO):
      return fail (state, DWFL_E_ERRNO);
    default:
      return fail (state, DWFL_E_ZLIB);
    }
}

#if !USE_INFLATE
static Dwfl_Error
open_stream (int fd, off_t start_offset, struct unzip_state *state)
{
    int d = dup (fd);
    if (unlikely (d < 0))
      return DWFL_E_BADELF;
    if (start_offset != 0)
      {
	off_t off = lseek (d, start_offset, SEEK_SET);
	if (off != start_offset)
	  {
	    close (d);
	    return DWFL_E_BADELF;
	  }
      }
    state->zf = gzdopen (d, "r");
    if (unlikely (state->zf == NULL))
      {
	close (d);
	return zlib_fail (state, Z (MEM_ERROR));
      }

    /* From here on, zlib will close D.  */

    return DWFL_E_NOERROR;
}
#endif

/* If this is not a compressed image, return DWFL_E_BADELF.
   If we uncompressed it into *WHOLE, *WHOLE_SIZE, return DWFL_E_NOERROR.
   Otherwise return an error for bad compressed data or I/O failure.
   If we return an error after reading the first part of the file,
   leave that portion malloc'd in *WHOLE, *WHOLE_SIZE.  If *WHOLE
   is not null on entry, we'll use it in lieu of repeating a read.  */

Dwfl_Error internal_function
unzip (int fd, off_t start_offset,
       void *mapped, size_t _mapped_size,
       void **_whole, size_t *whole_size)
{
  struct unzip_state state =
    {
#if !USE_INFLATE
      .zf = NULL,
#endif
      .mapped_size = _mapped_size,
      .whole = _whole,
      .buffer = NULL,
      .size = 0,
      .input_buffer = NULL,
      .input_pos = 0
    };

  if (mapped == NULL)
    {
      if (*state.whole == NULL)
	{
	  state.input_buffer = malloc (READ_SIZE);
	  if (unlikely (state.input_buffer == NULL))
	    return DWFL_E_NOMEM;

	  ssize_t n = pread_retry (fd, state.input_buffer, READ_SIZE, start_offset);
	  if (unlikely (n < 0))
	    return zlib_fail (&state, Z (ERRNO));

	  state.input_pos = n;
	  mapped = state.input_buffer;
	  state.mapped_size = n;
	}
      else
	{
	  state.input_buffer = *state.whole;
	  state.input_pos = state.mapped_size = *whole_size;
	}
    }

#define NOMAGIC(magic) \
  (state.mapped_size <= sizeof magic || \
   memcmp (mapped, magic, sizeof magic - 1))

  /* First, look at the header.  */
  if (NOMAGIC (MAGIC)
#ifdef MAGIC2
      && NOMAGIC (MAGIC2)
#endif
      )
    /* Not a compressed file.  */
    return DWFL_E_BADELF;

#if USE_INFLATE

  /* This style actually only works with bzlib and liblzma.
     The stupid zlib interface has nothing to grok the
     gzip file headers except the slow gzFile interface.  */

  z_stream z = { .next_in = mapped, .avail_in = state.mapped_size };
  int result = inflateInit (&z);
  if (result != Z (OK))
    {
      inflateEnd (&z);
      return zlib_fail (&state, result);
    }

  do
    {
      if (z.avail_in == 0 && state.input_buffer != NULL)
	{
	  ssize_t n = pread_retry (fd, state.input_buffer, READ_SIZE,
				   start_offset + state.input_pos);
	  if (unlikely (n < 0))
	    {
	      inflateEnd (&z);
	      return zlib_fail (&state, Z (ERRNO));
	    }
	  z.next_in = state.input_buffer;
	  z.avail_in = n;
	  state.input_pos += n;
	}
      if (z.avail_out == 0)
	{
	  ptrdiff_t pos = (void *) z.next_out - state.buffer;
	  if (!bigger_buffer (&state, z.avail_in))
	    {
	      result = Z (MEM_ERROR);
	      break;
	    }
	  z.next_out = state.buffer + pos;
	  z.avail_out = state.size - pos;
	}
    }
  while ((result = do_inflate (&z)) == Z (OK));

#ifdef BZLIB
  uint64_t total_out = (((uint64_t) z.total_out_hi32 << 32)
			| z.total_out_lo32);
  smaller_buffer (&state, total_out);
#else
  smaller_buffer (&state, z.total_out);
#endif

  inflateEnd (&z);

  if (result != Z (STREAM_END))
    return zlib_fail (&state, result);

#else  /* gzip only.  */

  /* Let the decompression library read the file directly.  */

  Dwfl_Error result = open_stream (fd, start_offset, &state);

  if (result == DWFL_E_NOERROR && gzdirect (state.zf))
    {
      gzclose (state.zf);
      return fail (&state, DWFL_E_BADELF);
    }

  if (result != DWFL_E_NOERROR)
    return fail (&state, result);

  ptrdiff_t pos = 0;
  while (1)
    {
      if (!bigger_buffer (&state, 1024))
	{
	  gzclose (state.zf);
	  return zlib_fail (&state, Z (MEM_ERROR));
	}
      int n = gzread (state.zf, state.buffer + pos, state.size - pos);
      if (n < 0)
	{
	  int code;
	  gzerror (state.zf, &code);
	  gzclose (state.zf);
	  return zlib_fail (&state, code);
	}
      if (n == 0)
	break;
      pos += n;
    }

  gzclose (state.zf);
  smaller_buffer (&state, pos);
#endif

  free (state.input_buffer);

  *state.whole = state.buffer;
  *whole_size = state.size;

  return DWFL_E_NOERROR;
}
