/* unzip.c -- decompress files in gzip or pkzip format.
- * Copyright (C) 1992-1993 Jean-loup Gailly
- * This is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License, see the file COPYING.
- *
+
+ Copyright (C) 1997-1999, 2009-2018 Free Software Foundation, Inc.
+ Copyright (C) 1992-1993 Jean-loup Gailly
+
+ 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,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/*
* The code in this file is derived from the file funzip.c written
* and put in the public domain by Mark Adler.
*/
either deflated or stored.
*/
-#ifdef RCSID
-static char rcsid[] = "$Id$";
-#endif
-
+#include <config.h>
#include "tailor.h"
#include "gzip.h"
-#include "crypt.h"
/* PKZIP header definitions */
#define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */
#define CRPFLG 1 /* bit for encrypted entry */
#define EXTFLG 8 /* bit for extended local header */
#define LOCHOW 8 /* offset of compression method */
-#define LOCTIM 10 /* file mod time (for decryption) */
+/* #define LOCTIM 10 UNUSED file mod time (for decryption) */
#define LOCCRC 14 /* offset of crc */
#define LOCSIZ 18 /* offset of compressed size */
#define LOCLEN 22 /* offset of uncompressed length */
#define LOCEXT 28 /* offset of extra field length */
#define LOCHDR 30 /* size of local header, including sig */
#define EXTHDR 16 /* size of extended local header, inc sig */
+#define RAND_HEAD_LEN 12 /* length of encryption random header */
/* Globals */
-int decrypt; /* flag to turn on decryption */
-char *key; /* not used--needed to link crypt.c */
-int pkzip = 0; /* set for a pkzip file */
-int ext_header = 0; /* set if extended local header */
+static int decrypt; /* flag to turn on decryption */
+static int pkzip = 0; /* set for a pkzip file */
+static int ext_header = 0; /* set if extended local header */
/* ===========================================================================
* Check zip file and advance inptr to the start of the compressed data.
inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT);
if (inptr > insize || LG(h) != LOCSIG) {
- fprintf(stderr, "\n%s: %s: not a valid zip file\n",
- progname, ifname);
- exit_code = ERROR;
- return ERROR;
+ fprintf(stderr, "\n%s: %s: not a valid zip file\n",
+ program_name, ifname);
+ exit_code = ERROR;
+ return ERROR;
}
method = h[LOCHOW];
if (method != STORED && method != DEFLATED) {
- fprintf(stderr,
- "\n%s: %s: first entry not deflated or stored -- use unzip\n",
- progname, ifname);
- exit_code = ERROR;
- return ERROR;
+ fprintf(stderr,
+ "\n%s: %s: first entry not deflated or stored -- use unzip\n",
+ program_name, ifname);
+ exit_code = ERROR;
+ return ERROR;
}
/* If entry encrypted, decrypt and validate encryption header */
if ((decrypt = h[LOCFLG] & CRPFLG) != 0) {
- fprintf(stderr, "\n%s: %s: encrypted file -- use unzip\n",
- progname, ifname);
- exit_code = ERROR;
- return ERROR;
+ fprintf(stderr, "\n%s: %s: encrypted file -- use unzip\n",
+ program_name, ifname);
+ exit_code = ERROR;
+ return ERROR;
}
/* Save flags for unzip() */
ext_header = (h[LOCFLG] & EXTFLG) != 0;
pkzip = 1;
- /* Get ofname and time stamp from local header (to be done) */
+ /* Get ofname and timestamp from local header (to be done) */
return OK;
}
ulg orig_len = 0; /* original uncompressed length */
int n;
uch buf[EXTHDR]; /* extended local header */
+ int err = OK;
ifd = in;
ofd = out;
updcrc(NULL, 0); /* initialize crc */
if (pkzip && !ext_header) { /* crc and length at the end otherwise */
- orig_crc = LG(inbuf + LOCCRC);
- orig_len = LG(inbuf + LOCLEN);
+ orig_crc = LG(inbuf + LOCCRC);
+ orig_len = LG(inbuf + LOCLEN);
}
/* Decompress */
if (method == DEFLATED) {
- int res = inflate();
+ int res = inflate();
- if (res == 3) {
- error("out of memory");
- } else if (res != 0) {
- error("invalid compressed data--format violated");
- }
+ if (res == 3) {
+ xalloc_die ();
+ } else if (res != 0) {
+ gzip_error ("invalid compressed data--format violated");
+ }
} else if (pkzip && method == STORED) {
- register ulg n = LG(inbuf + LOCLEN);
-
- if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) {
-
- fprintf(stderr, "len %ld, siz %ld\n", n, LG(inbuf + LOCSIZ));
- error("invalid compressed data--length mismatch");
- }
- while (n--) {
- uch c = (uch)get_byte();
-#ifdef CRYPT
- if (decrypt) zdecode(c);
-#endif
- put_ubyte(c);
- }
- flush_window();
+ register ulg n = LG(inbuf + LOCLEN);
+
+ if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) {
+
+ fprintf(stderr, "len %lu, siz %lu\n", n, LG(inbuf + LOCSIZ));
+ gzip_error ("invalid compressed data--length mismatch");
+ }
+ while (n--) {
+ uch c = (uch)get_byte();
+ put_ubyte(c);
+ }
+ flush_window();
} else {
- error("internal error, invalid method");
+ gzip_error ("internal error, invalid method");
}
/* Get the crc and original length */
if (!pkzip) {
/* crc32 (see algorithm.doc)
- * uncompressed input size modulo 2^32
+ * uncompressed input size modulo 2^32
*/
- for (n = 0; n < 8; n++) {
- buf[n] = (uch)get_byte(); /* may cause an error if EOF */
- }
- orig_crc = LG(buf);
- orig_len = LG(buf+4);
+ for (n = 0; n < 8; n++) {
+ buf[n] = (uch)get_byte(); /* may cause an error if EOF */
+ }
+ orig_crc = LG(buf);
+ orig_len = LG(buf+4);
} else if (ext_header) { /* If extended header, check it */
- /* signature - 4bytes: 0x50 0x4b 0x07 0x08
- * CRC-32 value
+ /* signature - 4bytes: 0x50 0x4b 0x07 0x08
+ * CRC-32 value
* compressed size 4-bytes
* uncompressed size 4-bytes
- */
- for (n = 0; n < EXTHDR; n++) {
- buf[n] = (uch)get_byte(); /* may cause an error if EOF */
- }
- orig_crc = LG(buf+4);
- orig_len = LG(buf+12);
+ */
+ for (n = 0; n < EXTHDR; n++) {
+ buf[n] = (uch)get_byte(); /* may cause an error if EOF */
+ }
+ orig_crc = LG(buf+4);
+ orig_len = LG(buf+12);
}
/* Validate decompression */
if (orig_crc != updcrc(outbuf, 0)) {
- error("invalid compressed data--crc error");
+ fprintf(stderr, "\n%s: %s: invalid compressed data--crc error\n",
+ program_name, ifname);
+ err = ERROR;
}
- if (orig_len != (ulg)bytes_out) {
- error("invalid compressed data--length error");
+ if (orig_len != (ulg)(bytes_out & 0xffffffff)) {
+ fprintf(stderr, "\n%s: %s: invalid compressed data--length error\n",
+ program_name, ifname);
+ err = ERROR;
}
/* Check if there are more entries in a pkzip file */
if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
- if (to_stdout) {
- WARN((stderr,
- "%s: %s has more than one entry--rest ignored\n",
- progname, ifname));
- } else {
- /* Don't destroy the input zip file */
- fprintf(stderr,
- "%s: %s has more than one entry -- unchanged\n",
- progname, ifname);
- exit_code = ERROR;
- ext_header = pkzip = 0;
- return ERROR;
- }
+ if (to_stdout) {
+ WARN((stderr,
+ "%s: %s has more than one entry--rest ignored\n",
+ program_name, ifname));
+ } else {
+ /* Don't destroy the input zip file */
+ fprintf(stderr,
+ "%s: %s has more than one entry -- unchanged\n",
+ program_name, ifname);
+ err = ERROR;
+ }
}
ext_header = pkzip = 0; /* for next file */
- return OK;
+ if (err == OK) return OK;
+ exit_code = ERROR;
+ if (!test) abort_gzip();
+ return err;
}