/* Copyright (C) 2021 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program 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 a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#include "zlib.h"
#include "util.h"
#include "DbeJarFile.h"
#include "Data_window.h"
#include "vec.h"

static uint32_t
get_u1 (unsigned char *b)
{
  return (uint32_t) ((b)[0]);
}

static uint32_t
get_u2 (unsigned char *b)
{
  return (get_u1 (b + 1) << 8) | get_u1 (b);
}

static uint32_t
get_u4 (unsigned char *b)
{
  return (get_u2 (b + 2) << 16) | get_u2 (b);
}

static uint64_t
get_u8 (unsigned char *b)
{
  return (((uint64_t) get_u4 (b + 4)) << 32) | get_u4 (b);
}

enum
{
  END_CENT_DIR_SIZE     = 22,
  LOC_FILE_HEADER_SIZE  = 30,
  CENT_FILE_HEADER_SIZE = 46,
  ZIP64_LOCATOR_SIZE    = 20,
  ZIP64_CENT_DIR_SIZE   = 56,
  ZIP_BUF_SIZE          = 65536
};

struct EndCentDir
{
  uint64_t count;
  uint64_t size;
  uint64_t offset;
};

class ZipEntry
{
public:

  ZipEntry ()
  {
    name = NULL;
    data_offset = 0;
  }

  ~ZipEntry ()
  {
    free (name);
  }

  int
  compare (ZipEntry *ze)
  {
    return dbe_strcmp (name, ze->name);
  }

  char *name;       // entry name
  int time;         // modification time
  int64_t size;     // size of uncompressed data
  int64_t csize;    // size of compressed data (zero if uncompressed)
  uint32_t compressionMethod;
  int64_t offset;   // offset of LOC header
  int64_t data_offset;
};

static int
cmp_names (const void *a, const void *b)
{
  ZipEntry *e1 = *((ZipEntry **) a);
  ZipEntry *e2 = *((ZipEntry **) b);
  return e1->compare (e2);
}

template<> void Vector<ZipEntry *>::dump (const char *msg)
{
  Dprintf (1, NTXT ("Vector<ZipEntry *> %s  [%lld]\n"), msg ? msg : NTXT (""), (long long) size ());
  for (long i = 0, sz = size (); i < sz; i++)
    {
      ZipEntry *ze = get (i);
      Dprintf (1, NTXT ("  %lld offset:%lld (0x%llx) size: %lld --> %lld %s\n"),
	       (long long) i, (long long) ze->offset, (long long) ze->offset,
	       (long long) ze->csize, (long long) ze->size, STR (ze->name));
    }
}

DbeJarFile::DbeJarFile (const char *jarName)
{
  name = strdup (jarName);
  fnames = NULL;
  dwin = new Data_window (name);
  get_entries ();
}

DbeJarFile::~DbeJarFile ()
{
  free (name);
  delete fnames;
}

void
DbeJarFile::get_entries ()
{
  Dprintf (DUMP_JAR_FILE, NTXT ("\nArchive: %s\n"), STR (name));
  if (dwin->not_opened ())
    {
      append_msg (CMSG_ERROR, GTXT ("Cannot open file `%s'"), name);
      return;
    }
  struct EndCentDir endCentDir;
  if (get_EndCentDir (&endCentDir) == 0)
    return;

  if (endCentDir.count == 0)
    {
      append_msg (CMSG_WARN, GTXT ("No files in %s"), name);
      return;
    }
  unsigned char *b = (unsigned char *) dwin->bind (endCentDir.offset, endCentDir.size);
  if (b == NULL)
    {
      append_msg (CMSG_ERROR, GTXT ("%s: cannot read the central directory record"), name);
      return;
    }

  fnames = new Vector<ZipEntry*>(endCentDir.count);
  for (uint64_t i = 0, offset = endCentDir.offset, last = endCentDir.offset + endCentDir.size; i < endCentDir.count; i++)
    {
      if ((last - offset) < CENT_FILE_HEADER_SIZE)
	{
	  append_msg (CMSG_ERROR, GTXT ("%s: cannot read the central file header (%lld (from %lld), offset=0x%016llx last=0x%016llx"),
		      name, (long long) i, (long long) endCentDir.count, (long long) offset, (long long) last);
	  break;
	}
      b = (unsigned char *) dwin->bind (offset, CENT_FILE_HEADER_SIZE);
      //  Central file header
      //  Offset Bytes    Description
      //     0     4   central file header signature = 0x02014b50
      //     4     2   version made by
      //     6     2   version needed to extract
      //     8     2   general purpose bit flag
      //    10     2   compression method
      //    12     2   last mod file time
      //    14     2   last mod file date
      //    16     4   crc-32
      //    20     4   compressed size
      //    24     4   uncompressed size
      //    28     2   file name length
      //    30     2   extra field length
      //    32     2   file comment length
      //    34     2   disk number start
      //    36     2   internal file attributes
      //    38     4   external file attributes
      //    42     4   relative offset of local header
      //    46         file name (variable size)
      //               extra field (variable size)
      //               file comment (variable size)
      uint32_t signature = get_u4 (b);
      if (signature != 0x02014b50)
	{
	  append_msg (CMSG_ERROR, GTXT ("%s: wrong header signature (%lld (total %lld), offset=0x%016llx last=0x%016llx"),
		      name, (long long) i, (long long) endCentDir.count, (long long) offset, (long long) last);
	  break;
	}
      ZipEntry *ze = new ZipEntry ();
      fnames->append (ze);
      uint32_t name_len = get_u2 (b + 28);
      uint32_t extra_len = get_u2 (b + 30);
      uint32_t comment_len = get_u2 (b + 32);
      ze->compressionMethod = get_u2 (b + 10);
      ze->csize = get_u4 (b + 20);
      ze->size = get_u4 (b + 24);
      ze->offset = get_u4 (b + 42);
      char *nm = (char *) dwin->bind (offset + 46, name_len);
      if (nm)
	{
	  ze->name = (char *) malloc (name_len + 1);
	  strncpy (ze->name, nm, name_len);
	  ze->name[name_len] = 0;
	}
      offset += CENT_FILE_HEADER_SIZE + name_len + extra_len + comment_len;
    }
  fnames->sort (cmp_names);
  if (DUMP_JAR_FILE)
    fnames->dump (get_basename (name));
}

int
DbeJarFile::get_entry (const char *fname)
{
  if (fnames == NULL)
    return -1;
  ZipEntry zipEntry, *ze = &zipEntry;
  ze->name = (char *) fname;
  int ind = fnames->bisearch (0, -1, &ze, cmp_names);
  ze->name = NULL;
  return ind;
}

long long
DbeJarFile::copy (char *toFileNname, int fromEntryNum)
{
  if (fromEntryNum < 0 || fromEntryNum >= VecSize (fnames))
    return -1;
  ZipEntry *ze = fnames->get (fromEntryNum);
  if (ze->data_offset == 0)
    {
      //  Local file header
      //  Offset Bytes    Description
      //     0     4   local file header signature = 0x04034b50
      //     4     2   version needed to extract
      //     6     2   general purpose bit flag
      //     8     2   compression method
      //    10     2   last mod file time
      //    12     2   last mod file date
      //    14     4   crc-32
      //    18     4   compressed size
      //    22     4   uncompressed size
      //    26     2   file name length
      //    28     2   extra field length
      //    30     2   file name (variable size)
      //               extra field (variable size)
      unsigned char *b = (unsigned char *) dwin->bind (ze->offset, LOC_FILE_HEADER_SIZE);
      if (b == NULL)
	{
	  append_msg (CMSG_ERROR,
		 GTXT ("%s: Cannot read a local file header (%s offset=0x%lld"),
		 name, STR (ze->name), (long long) ze->offset);
	  return -1;
	}
      uint32_t signature = get_u4 (b);
      if (signature != 0x04034b50)
	{
	  append_msg (CMSG_ERROR,
		      GTXT ("%s: wrong local header signature ('%s' offset=%lld (0x%llx)"),
		      name, STR (ze->name), (long long) ze->offset,
		      (long long) ze->offset);
	  return -1;
	}
      ze->data_offset = ze->offset + LOC_FILE_HEADER_SIZE + get_u2 (b + 26) + get_u2 (b + 28);
    }

  if (ze->compressionMethod == 0)
    {
      int fd = open (toFileNname, O_CREAT | O_WRONLY | O_LARGEFILE, 0644);
      if (fd == -1)
	{
	  append_msg (CMSG_ERROR, GTXT ("Cannot create file %s (%s)"), toFileNname, STR (strerror (errno)));
	  return -1;
	}
      long long len = dwin->copy_to_file (fd, ze->data_offset, ze->size);
      close (fd);
      if (len != ze->size)
	{
	  append_msg (CMSG_ERROR, GTXT ("%s: Cannot write %lld bytes (only %lld)"),
		      toFileNname, (long long) ze->size, (long long) len);
	  unlink (toFileNname);
	  return -1;
	}
      return len;
    }

  unsigned char *b = (unsigned char *) dwin->bind (ze->data_offset, ze->csize);
  if (b == NULL)
    {
      append_msg (CMSG_ERROR,
		  GTXT ("%s: Cannot extract file %s (offset=0x%lld csize=%lld)"),
		  name, STR (ze->name), (long long) ze->offset,
		  (long long) ze->csize);
      return -1;
    }
  z_stream strm;
  strm.zalloc = Z_NULL;
  strm.zfree = Z_NULL;
  strm.opaque = Z_NULL;
  strm.next_in = Z_NULL;
  strm.avail_in = 0;
  if (inflateInit2 (&strm, -MAX_WBITS) != Z_OK)
    {
      append_msg (CMSG_ERROR, GTXT ("%s: inflateInit2 failed (%s)"), STR (ze->name), STR (strm.msg));
      return -1;
    }
  strm.avail_in = ze->csize;
  strm.next_in = b;
  int retval = ze->size;
  unsigned char *buf = (unsigned char *) malloc (ze->size);
  for (;;)
    {
      strm.next_out = buf;
      strm.avail_out = ze->size;
      int ret = inflate (&strm, Z_SYNC_FLUSH);
      if ((ret == Z_NEED_DICT) || (ret == Z_DATA_ERROR) || (ret == Z_MEM_ERROR) || (ret == Z_STREAM_ERROR))
	{
	  append_msg (CMSG_ERROR, GTXT ("%s: inflate('%s') error %d (%s)"), name, STR (ze->name), ret, STR (strm.msg));
	  retval = -1;
	  break;
	}
      if (strm.avail_out != 0)
	break;
    }
  inflateEnd (&strm);
  if (retval != -1)
    {
      int fd = open (toFileNname, O_CREAT | O_WRONLY | O_LARGEFILE, 0644);
      if (fd == -1)
	{
	  append_msg (CMSG_ERROR, GTXT ("Cannot create file %s (%s)"), toFileNname, STR (strerror (errno)));
	  retval = -1;
	}
      else
	{
	  long long len = write (fd, buf, ze->size);
	  if (len != ze->size)
	    {
	      append_msg (CMSG_ERROR, GTXT ("%s: Cannot write %lld bytes (only %lld)"),
			  toFileNname, (long long) strm.avail_out, (long long) len);
	      retval = -1;
	    }
	  close (fd);
	}
    }
  free (buf);
  return retval;
}

int
DbeJarFile::get_EndCentDir (struct EndCentDir *endCentDir)
{
  int64_t fsize = dwin->get_fsize ();
  int64_t sz = (fsize < ZIP_BUF_SIZE) ? fsize : ZIP_BUF_SIZE;

  // Find the end of central directory record:
  unsigned char *b = (unsigned char *) dwin->bind (fsize - sz, sz);
  if (b == NULL)
    {
      append_msg (CMSG_ERROR, GTXT ("%s: cannot find the central directory record (fsize=%lld)"),
		  name, (long long) fsize);
      return 0;
    }

  //  End of central directory record:
  //  Offset Bytes    Description
  //     0     4    end of central directory signature = 0x06054b50
  //     4     2    number of this disk
  //     6     2    disk where central directory starts
  //     8     2    number of central directory records on this disk
  //    10     2    total number of central directory records
  //    12     4    size of central directory(bytes)
  //    16     4    offset of start of central directory, relative to start of archive
  //    20     2    comment length(n)
  //    22     n    comment

  endCentDir->count = 0;
  endCentDir->size = 0;
  endCentDir->offset = 0;
  int64_t ecdrOffset = fsize;
  for (int64_t i = END_CENT_DIR_SIZE; i < sz; i++)
    {
      b = (unsigned char *) dwin->bind (fsize - i, END_CENT_DIR_SIZE);
      if (b == NULL)
	{
	  append_msg (CMSG_ERROR, GTXT ("%s: read failed (offset:0x%llx  bytes:%lld"),
		      name, (long long) (fsize - i), (long long) END_CENT_DIR_SIZE);
	  break;
	}
      uint32_t signature = get_u4 (b);
      if (signature == 0x06054b50)
	{
	  int64_t len_comment = get_u2 (b + 20);
	  if (i != (len_comment + END_CENT_DIR_SIZE))
	    continue;
	  ecdrOffset = fsize - i;
	  endCentDir->count = get_u2 (b + 10);
	  endCentDir->size = get_u4 (b + 12);
	  endCentDir->offset = get_u4 (b + 16);
	  Dprintf (DUMP_JAR_FILE,
		   "  Zip archive file size:              %10lld (0x%016llx)\n"
		   "  end-cent-dir record offset:         %10lld (0x%016llx)\n"
		   "  cent-dir offset:                    %10lld (0x%016llx)\n"
		   "  cent-dir size:                      %10lld (0x%016llx)\n"
		   "  cent-dir entries:                   %10lld\n",
		   (long long) fsize, (long long) fsize,
		   (long long) ecdrOffset, (long long) ecdrOffset,
		   (long long) endCentDir->offset, (long long) endCentDir->offset,
		   (long long) endCentDir->size, (long long) endCentDir->size,
		   (long long) endCentDir->count);
	  break;
	}
    }
  if (ecdrOffset == fsize)
    {
      append_msg (CMSG_ERROR,
		  GTXT ("%s: cannot find the central directory record"), name);
      return 0;
    }
  if (endCentDir->count == 0xffff || endCentDir->offset == 0xffffffff
      || endCentDir->size == 0xffffffff)
    {
      // Zip64 format:
      //      Zip64 end of central directory record
      //      Zip64 end of central directory locator  ( Can be absent )
      //      End of central directory record
      b = (unsigned char *) dwin->bind (ecdrOffset - ZIP64_LOCATOR_SIZE,
					ZIP64_LOCATOR_SIZE);
      if (b == NULL)
	{
	  append_msg (CMSG_ERROR,
	     GTXT ("%s: cannot find the Zip64 central directory record"), name);
	  return 0;
	}
      uint32_t signature = get_u4 (b);
      if (signature == 0x07064b50)
	{ // Get an offset from the Zip64 cent-dir locator
	  //  Zip64 end of central directory locator
	  //  Offset Bytes    Description
	  //     0     4    Zip64 end of central dir locator signature = 0x07064b50
	  //     4     4    number of the disk with the start of the zip64 end of central directory
	  //     8     8    relative offset of the Zip64 end of central directory record
	  //    12     4    total number of disks
	  Dprintf (DUMP_JAR_FILE, "    cent-dir locator offset           %10lld (0x%016llx)\n",
		   (long long) (ecdrOffset - ZIP64_LOCATOR_SIZE), (long long) (ecdrOffset - ZIP64_LOCATOR_SIZE));
	  ecdrOffset = get_u8 (b + 8);
	}
      else   // the Zip64 end of central directory locator is absent
	ecdrOffset -= ZIP64_CENT_DIR_SIZE;
      Dprintf (DUMP_JAR_FILE, NTXT ("  Zip64 end-cent-dir record offset:   %10lld (0x%016llx)\n"),
	       (long long) ecdrOffset, (long long) ecdrOffset);

      b = (unsigned char *) dwin->bind (ecdrOffset, ZIP64_CENT_DIR_SIZE);
      if (b == NULL)
	{
	  append_msg (CMSG_ERROR,
	     GTXT ("%s: cannot find the Zip64 central directory record"), name);
	  return 0;
	}
      //  Zip64 end of central directory record
      //  Offset Bytes    Description
      //     0     4    Zip64 end of central dir signature = 0x06064b50
      //     4     8    size of zip64 end of central directory record
      //    12     2    version made by
      //    14     2    version needed to extract
      //    16     4    number of this disk
      //    20     4    number of the disk with the start of the central directory
      //    24     8    total number of entries in the central directory on this disk
      //    32     8    total number of entries in the central directory
      //    40     8    size of the central directory
      //    48     8    offset of start of centraldirectory with respect to the starting disk number
      //    56          Zip64 extensible data sector (variable size)
      signature = get_u4 (b);
      if (signature != 0x06064b50)
	{
	  append_msg (CMSG_ERROR, GTXT ("%s: cannot find the Zip64 central directory record"), name);
	  return 0;
	}
      endCentDir->count = get_u8 (b + 32);
      endCentDir->size = get_u8 (b + 40);
      endCentDir->offset = get_u8 (b + 48);
      Dprintf (DUMP_JAR_FILE,
	       NTXT ("  cent-dir offset:                    %10lld (0x%016llx)\n"
		     "  cent-dir size:                      %10lld (0x%016llx)\n"
		     "  cent-dir entries:                   %10lld\n"),
	       (long long) endCentDir->offset, (long long) endCentDir->offset,
	       (long long) endCentDir->size, (long long) endCentDir->size,
	       (long long) endCentDir->count);
    }
  return 1;
}

