/* 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/>.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#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;
}
