Simplify CRC table generation
[oweals/busybox.git] / libbb / unzip.c
index b843ec8124062da8e4cb200d01609a68a6908453..c28ca836c2b58899a84c0aadf9cd6d2cf5afe2c7 100644 (file)
@@ -64,13 +64,10 @@ static char *license_msg[] = {
 #include <sys/wait.h>
 #include <signal.h>
 #include <stdlib.h>
+#include <string.h>
 #include "libbb.h"
-#define BB_DECLARE_EXTERN
-#define bb_need_memory_exhausted
-#define bb_need_name_too_long
-#include "../messages.c"
 
-FILE *in_file, *out_file;
+static FILE *in_file, *out_file;
 
 /* these are freed by gz_close */
 static unsigned char *window;
@@ -94,9 +91,9 @@ static const int N_MAX = 288;         /* maximum number of codes in any set */
 static long bytes_out;         /* number of output bytes */
 static unsigned long outcnt;   /* bytes in output buffer */
 
-unsigned hufts;                /* track memory usage */
-unsigned long bb;                      /* bit buffer */
-unsigned bk;           /* bits in bit buffer */
+static unsigned hufts;         /* track memory usage */
+static unsigned long bb;                       /* bit buffer */
+static unsigned bk;            /* bits in bit buffer */
 
 typedef struct huft_s {
        unsigned char e;                /* number of extra bits or operation */
@@ -107,7 +104,7 @@ typedef struct huft_s {
        } v;
 } huft_t;
 
-unsigned short mask_bits[] = {
+static const unsigned short mask_bits[] = {
        0x0000,
        0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
        0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
@@ -118,30 +115,24 @@ unsigned short mask_bits[] = {
  * Signal and error handler.
  */
  
-static void abort_gzip()
+static void abort_gzip(void)
 {
        error_msg("gzip aborted\n");
        exit(ERROR);
 }
 
-static void make_crc_table()
+static void make_crc_table(void)
 {
-       unsigned long table_entry;      /* crc shift register */
-       unsigned long poly = 0;      /* polynomial exclusive-or pattern */
-       int i;                /* counter for all possible eight bit values */
-       int k;                /* byte being shifted into crc apparatus */
-
-       /* terms of polynomial defining this crc (except x^32): */
-       static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+       const unsigned long poly = 0xedb88320;      /* polynomial exclusive-or pattern */
+       unsigned short i;                /* counter for all possible eight bit values */
 
        crc_table = (unsigned long *) malloc(256 * sizeof(unsigned long));
 
-       /* Make exclusive-or pattern from polynomial (0xedb88320) */
-       for (i = 0; i < sizeof(p)/sizeof(int); i++)
-               poly |= 1L << (31 - p[i]);
-
        /* Compute and print table of CRC's, five per line */
        for (i = 0; i < 256; i++) {
+               unsigned long table_entry;      /* crc shift register */
+               char k; /* byte being shifted into crc apparatus */
+
                table_entry = i;
           /* The idea to initialize the register with the byte instead of
             * zero was stolen from Haruhiko Okumura's ar002
@@ -157,7 +148,7 @@ static void make_crc_table()
  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
  * (Used for the decompressed data only.)
  */
-void flush_window()
+static void flush_window(void)
 {
        int n;
 
@@ -856,7 +847,7 @@ static int inflate_block(int *e)
  *
  * GLOBAL VARIABLES: outcnt, bk, bb, hufts, inptr
  */
-static int inflate()
+static int inflate(void)
 {
        int e;                          /* last block flag */
        int r;                          /* result code */
@@ -878,6 +869,14 @@ static int inflate()
                }
        } while (!e);
 
+       /* Undo too much lookahead. The next read will be byte aligned so we
+        * can discard unused bits in the last meaningful byte.
+        */
+       while (bk >= 8) {
+               bk -= 8;
+               ungetc((bb << bk), in_file);
+       }
+
        /* flush out window */
        flush_window();
 
@@ -904,6 +903,7 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file)
        int method;
        typedef void (*sig_type) (int);
        int exit_code=0;        /* program exit code */
+       int i;
 
        in_file = l_in_file;
        out_file = l_out_file;
@@ -927,9 +927,6 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file)
        outcnt = 0;
        bytes_out = 0L;
 
-       /* set the buffer size */
-       setvbuf(in_file, NULL, _IOFBF, 0x8000);
-
        magic[0] = fgetc(in_file);
        magic[1] = fgetc(in_file);
 
@@ -949,10 +946,16 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file)
        flags = (unsigned char) fgetc(in_file);
 
        /* Ignore time stamp(4), extra flags(1), OS type(1) */
-       fseek(in_file, 6, SEEK_CUR);
+       for (i = 0; i < 6; i++)
+               fgetc(in_file);
 
        if ((flags & extra_field) != 0) {
-               fseek(in_file, (size_t) fgetc(in_file) + ((size_t)fgetc(in_file) << 8), SEEK_CUR);
+               size_t extra;
+               extra = fgetc(in_file);
+               extra += fgetc(in_file) << 8;
+
+               for (i = 0; i < extra; i++)
+                       fgetc(in_file);
        }
 
        /* Discard original name if any */
@@ -994,7 +997,7 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file)
        fread(buf, 1, 8, in_file);
 
        /* Validate decompression - crc */
-       if (((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) {
+       if ((unsigned int)((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) {
                error_msg("invalid compressed data--crc error");
        }
        /* Validate decompression - size */
@@ -1020,6 +1023,6 @@ extern void gz_close(int gunzip_pid)
        if (waitpid(gunzip_pid, NULL, 0) == -1) {
                printf("Couldnt wait ?");
        }
-       free(window);
-       free(crc_table);
+               free(window);
+               free(crc_table);
 }