Don't assume that Local File Header is valid
authorRobert Pengelly <robertapengelly@hotmail.com>
Wed, 1 Oct 2025 14:45:41 +0000 (15:45 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Wed, 1 Oct 2025 14:45:41 +0000 (15:45 +0100)
unzip.c
unzip.h

diff --git a/unzip.c b/unzip.c
index 20c684d7c10ba4e4c141e79185b4aa86ab02f1eb..056bc88d0d2a2d692ddc0baa2305091b13a84000 100755 (executable)
--- a/unzip.c
+++ b/unzip.c
@@ -287,9 +287,9 @@ static int read_cfh (struct cfh *cfh) {
     
     }
     
-    if ((cfh->extra = malloc (cfh->extra_len + 1))) {
+    if ((cfh->extra = malloc (cfh->extra_len))) {
     
-        memset (cfh->extra, 0, cfh->extra_len + 1);
+        memset (cfh->extra, 0, cfh->extra_len);
         
         if (fread (cfh->extra, 1, cfh->extra_len, fp) != cfh->extra_len) {
         
@@ -577,52 +577,6 @@ static int read_lfh (struct lfh *lfh) {
 
 }
 
-static int validate_structs (struct cfh *cfh, struct lfh *lfh) {
-
-    if (cfh->extract_ver != lfh->extract_ver) {
-        return -1;
-    }
-    
-    if (cfh->gp_flag != lfh->gp_flag) {
-        return -1;
-    }
-    
-    if (cfh->method != lfh->method) {
-        return -1;
-    }
-    
-    if (cfh->mod_date != lfh->mod_date) {
-        return -1;
-    }
-    
-    if (cfh->mod_time != lfh->mod_time) {
-        return -1;
-    }
-    
-    if (cfh->crc32 != lfh->crc32) {
-        return -1;
-    }
-    
-    if (cfh->comp_size != lfh->comp_size) {
-        return -1;
-    }
-    
-    if (cfh->uncomp_size != lfh->uncomp_size) {
-        return -1;
-    }
-    
-    if (cfh->name_len != lfh->name_len) {
-        return -1;
-    }
-    
-    if (!lfh->name || strcmp (lfh->name, cfh->name)) {
-        return -1;
-    }
-    
-    return 0;
-
-}
-
 static void extract_zip (const char *path) {
 
     struct eocdr eocdr = { 0 };
@@ -737,7 +691,7 @@ static void extract_zip (const char *path) {
         
         }
         
-        if (cfh.ext_attrs & EXT_ATTR_DIR) {
+        if (cfh.ext_attrs & EXT_ATTR_DIR || cfh.name[cfh.name_len - 1] == '/') {
         
             if (state->exdir) {
             
@@ -779,19 +733,19 @@ static void extract_zip (const char *path) {
                 }
                 
                 sprintf (temp, "%s", cfh.name);
-            
-            }
-            
-            if (!is_relative (temp, cfh.name_len)) {
-            
-                free (temp);
-                free (cfh.name);
                 
-                if (cfh.comment) { free (cfh.comment); }
-                if (cfh.extra) { free (cfh.extra); }
+                if (!is_relative (temp, cfh.name_len)) {
+                
+                    free (temp);
+                    free (cfh.name);
+                    
+                    if (cfh.comment) { free (cfh.comment); }
+                    if (cfh.extra) { free (cfh.extra); }
+                    
+                    memset (&cfh, 0, sizeof (cfh));
+                    continue;
                 
-                memset (&cfh, 0, sizeof (cfh));
-                continue;
+                }
             
             }
             
@@ -922,17 +876,6 @@ static void extract_zip (const char *path) {
         
         }
         
-        if (validate_structs (&cfh, &lfh)) {
-        
-            report_at (program_name, 0, REPORT_ERROR, "Centeral File Header and Local File Header mismatch");
-            
-            fseek (fp, orig_offset, SEEK_SET);
-            free (temp);
-            
-            break;
-        
-        }
-        
         if (!(data = malloc (cfh.comp_size))) {
         
             fseek (fp, orig_offset, SEEK_SET);
@@ -942,7 +885,7 @@ static void extract_zip (const char *path) {
         
         }
         
-        if (fread (data, 1, lfh.comp_size, fp) != lfh.comp_size) {
+        if (fread (data, 1, cfh.comp_size, fp) != cfh.comp_size) {
         
             fseek (fp, orig_offset, SEEK_SET);
             
@@ -964,7 +907,7 @@ static void extract_zip (const char *path) {
         
         if (cfh.method == ZIP_STORE) {
         
-            assert (lfh.comp_size == lfh.uncomp_size);
+            assert (cfh.comp_size == cfh.uncomp_size);
             
             if (!(outfile = fopen (temp, "w+b"))) {
             
@@ -978,7 +921,7 @@ static void extract_zip (const char *path) {
             
             }
             
-            if (fwrite (data, 1, lfh.uncomp_size, outfile) != lfh.uncomp_size) {
+            if (fwrite (data, 1, cfh.uncomp_size, outfile) != cfh.uncomp_size) {
             
                 report_at (program_name, 0, REPORT_ERROR, "failed to extract %s", temp);
                 fclose (outfile);
@@ -1009,7 +952,7 @@ static void extract_zip (const char *path) {
             
             printf ("  inflating: %s\n", temp);
             
-            if (hwinflate (data, lfh.comp_size, &src_used, outfile, lfh.uncomp_size, &dst_used) != HWINF_OK) {
+            if (hwinflate (data, cfh.comp_size, &src_used, outfile, cfh.uncomp_size, &dst_used) != HWINF_OK) {
             
                 report_at (program_name, 0, REPORT_ERROR, "failed to extract %s", temp);
                 fclose (outfile);
@@ -1024,10 +967,9 @@ static void extract_zip (const char *path) {
             free (data);
             fclose (outfile);
             
-            if (src_used != lfh.comp_size || dst_used != lfh.uncomp_size) {
+            if (src_used != cfh.comp_size || dst_used != cfh.uncomp_size) {
             
-                report_at (program_name, 0, REPORT_ERROR, "%lld, %d, %lld, %d: failed to extract %s",
-                    src_used, lfh.comp_size, dst_used, lfh.uncomp_size, temp);
+                report_at (program_name, 0, REPORT_ERROR, "failed to extract %s", temp);
                 
                 remove (temp);
                 break;
diff --git a/unzip.h b/unzip.h
index ee4bdd0d8707ce759e6567f3cedd1f99c7f88216..e1757f8985f7172de28e28696c5c30313e790715 100755 (executable)
--- a/unzip.h
+++ b/unzip.h
@@ -23,7 +23,7 @@ extern struct unzip_state *state;
 extern const char *program_name;
 
 #define     EXT_ATTR_DIR                (1U << 4)
-#define     EXT_ATTR_ARC                (1U << 5);
+#define     EXT_ATTR_ARC                (1U << 5)
 
 #define     ZIP_STORE                   0
 #define     ZIP_DEFLATE                 8