From: Robert Pengelly Date: Wed, 1 Oct 2025 12:16:00 +0000 (+0100) Subject: Support ZIP_STORE and fix check X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=06f79f25bad9619912ab7e8dd801ad9926bfe51e;p=unzip.git Support ZIP_STORE and fix check --- diff --git a/inflate.c b/inflate.c index eebdd2b..e1d1634 100644 --- a/inflate.c +++ b/inflate.c @@ -446,7 +446,7 @@ static inf_stat_t inf_noncomp_block (istream_t *is, FILE *outfile, uint64_t dst_ len = array_to_integer (p, 2, 0), p += 2; nlen = array_to_integer (p, 2, 0), p += 2; - if (nlen != (-len & 0xffff)) { + if (nlen != (~len & 0xffff)) { return HWINF_ERR; } @@ -458,6 +458,10 @@ static inf_stat_t inf_noncomp_block (istream_t *is, FILE *outfile, uint64_t dst_ return HWINF_ERR; /* Not enough room to output. */ } + if (fseek (outfile, *dst_pos, SEEK_SET)) { + return HWINF_ERR; + } + if (fwrite (p, 1, len, outfile) != len) { return HWINF_ERR; /* Something went wrong. */ } diff --git a/unzip.c b/unzip.c index 6ac3c78..20c684d 100755 --- a/unzip.c +++ b/unzip.c @@ -1,6 +1,7 @@ /****************************************************************************** * @file unzip.c *****************************************************************************/ +#include #include #include #include @@ -205,7 +206,7 @@ static int find_eocdr (struct eocdr *r) { struct cfh { uint16_t made_by_ver; /* Version made by. */ - uint16_t extrcat_ver; /* Version needed to extract. */ + uint16_t extract_ver; /* Version needed to extract. */ uint16_t gp_flag; /* General-purpose bit flag. */ uint16_t method; /* Compression method. */ uint16_t mod_time; /* Modification time. */ @@ -250,7 +251,7 @@ static int read_cfh (struct cfh *cfh) { } cfh->made_by_ver = array_to_integer (p, 2, 0), p += 2; - cfh->extrcat_ver = array_to_integer (p, 2, 0), p += 2; + cfh->extract_ver = array_to_integer (p, 2, 0), p += 2; cfh->gp_flag = array_to_integer (p, 2, 0), p += 2; cfh->method = array_to_integer (p, 2, 0), p += 2; cfh->mod_time = array_to_integer (p, 2, 0), p += 2; @@ -490,7 +491,7 @@ static int is_relative (const char *name, uint64_t name_len) { struct lfh { - uint16_t extrcat_ver; /* Version needed to extract. */ + uint16_t extract_ver; /* Version needed to extract. */ uint16_t gp_flag; /* General-purpose bit flag. */ uint16_t method; /* Compression method. */ uint16_t mod_time; /* Modification time. */ @@ -526,7 +527,7 @@ static int read_lfh (struct lfh *lfh) { return -1; } - lfh->extrcat_ver = array_to_integer (p, 2, 0), p += 2; + lfh->extract_ver = array_to_integer (p, 2, 0), p += 2; lfh->gp_flag = array_to_integer (p, 2, 0), p += 2; lfh->method = array_to_integer (p, 2, 0), p += 2; lfh->mod_time = array_to_integer (p, 2, 0), p += 2; @@ -578,7 +579,7 @@ static int read_lfh (struct lfh *lfh) { static int validate_structs (struct cfh *cfh, struct lfh *lfh) { - if (cfh->extrcat_ver != lfh->extrcat_ver) { + if (cfh->extract_ver != lfh->extract_ver) { return -1; } @@ -870,9 +871,9 @@ static void extract_zip (const char *path) { continue; } - if (cfh.method != ZIP_DEFLATE) { + if (cfh.method != ZIP_STORE && cfh.method != ZIP_DEFLATE) { - report_at (program_name, 0, REPORT_ERROR, "currently only ZIP_DEFLATE is supported"); + report_at (program_name, 0, REPORT_ERROR, "currently only ZIP_STORE && ZIP_DEFLATE are supported"); break; } @@ -914,7 +915,7 @@ static void extract_zip (const char *path) { report_at (program_name, 0, REPORT_ERROR, "failed to process Local File Header"); - fseek (fp, cfh.lfh_offset, SEEK_SET); + fseek (fp, orig_offset, SEEK_SET); free (temp); break; @@ -924,9 +925,8 @@ 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, cfh.lfh_offset, SEEK_SET); - free (data); + fseek (fp, orig_offset, SEEK_SET); free (temp); break; @@ -935,7 +935,7 @@ static void extract_zip (const char *path) { if (!(data = malloc (cfh.comp_size))) { - fseek (fp, cfh.lfh_offset, SEEK_SET); + fseek (fp, orig_offset, SEEK_SET); free (temp); break; @@ -944,7 +944,7 @@ static void extract_zip (const char *path) { if (fread (data, 1, lfh.comp_size, fp) != lfh.comp_size) { - fseek (fp, cfh.lfh_offset, SEEK_SET); + fseek (fp, orig_offset, SEEK_SET); free (data); free (temp); @@ -962,7 +962,38 @@ static void extract_zip (const char *path) { } - if (cfh.method == ZIP_DEFLATE) { + if (cfh.method == ZIP_STORE) { + + assert (lfh.comp_size == lfh.uncomp_size); + + if (!(outfile = fopen (temp, "w+b"))) { + + report_at (program_name, 0, REPORT_ERROR, "failed to open '%s' for writing", temp); + remove (temp); + + free (data); + free (temp); + + break; + + } + + if (fwrite (data, 1, lfh.uncomp_size, outfile) != lfh.uncomp_size) { + + report_at (program_name, 0, REPORT_ERROR, "failed to extract %s", temp); + fclose (outfile); + + free (data); + remove (temp); + + break; + + } + + free (data); + fclose (outfile); + + } else if (cfh.method == ZIP_DEFLATE) { if (!(outfile = fopen (temp, "w+b"))) { diff --git a/unzip.h b/unzip.h index 15f44ff..ee4bdd0 100755 --- a/unzip.h +++ b/unzip.h @@ -25,6 +25,7 @@ extern const char *program_name; #define EXT_ATTR_DIR (1U << 4) #define EXT_ATTR_ARC (1U << 5); +#define ZIP_STORE 0 #define ZIP_DEFLATE 8 typedef enum {