/* Copyright (C) 2021-2025 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 = xstrdup (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 *) xmalloc (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 *) xmalloc (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;
}

