diff options
Diffstat (limited to 'archival/unzip.c')
-rw-r--r-- | archival/unzip.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/archival/unzip.c b/archival/unzip.c index 56a5eb625..8462822f1 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -41,8 +41,10 @@ enum { | |||
41 | #endif | 41 | #endif |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #define ZIP_HEADER_LEN 26 | ||
45 | |||
44 | typedef union { | 46 | typedef union { |
45 | uint8_t raw[26]; | 47 | uint8_t raw[ZIP_HEADER_LEN]; |
46 | struct { | 48 | struct { |
47 | uint16_t version; /* 0-1 */ | 49 | uint16_t version; /* 0-1 */ |
48 | uint16_t flags; /* 2-3 */ | 50 | uint16_t flags; /* 2-3 */ |
@@ -57,8 +59,14 @@ typedef union { | |||
57 | } formatted ATTRIBUTE_PACKED; | 59 | } formatted ATTRIBUTE_PACKED; |
58 | } zip_header_t; | 60 | } zip_header_t; |
59 | 61 | ||
62 | /* Check the offset of the last element, not the length. This leniency | ||
63 | * allows for poor packing, whereby the overall struct may be too long, | ||
64 | * even though the elements are all in the right place. | ||
65 | */ | ||
60 | struct BUG_zip_header_must_be_26_bytes { | 66 | struct BUG_zip_header_must_be_26_bytes { |
61 | char BUG_zip_header_must_be_26_bytes[sizeof(zip_header_t) == 26 ? 1 : -1]; | 67 | char BUG_zip_header_must_be_26_bytes[ |
68 | offsetof(zip_header_t, formatted.extra_len) + 2 == | ||
69 | ZIP_HEADER_LEN ? 1 : -1]; | ||
62 | }; | 70 | }; |
63 | 71 | ||
64 | #define FIX_ENDIANNESS(zip_header) do { \ | 72 | #define FIX_ENDIANNESS(zip_header) do { \ |
@@ -256,7 +264,7 @@ int unzip_main(int argc, char **argv) | |||
256 | bb_error_msg_and_die("invalid zip magic %08X", magic); | 264 | bb_error_msg_and_die("invalid zip magic %08X", magic); |
257 | 265 | ||
258 | /* Read the file header */ | 266 | /* Read the file header */ |
259 | xread(src_fd, zip_header.raw, sizeof(zip_header)); | 267 | xread(src_fd, zip_header.raw, ZIP_HEADER_LEN); |
260 | FIX_ENDIANNESS(zip_header); | 268 | FIX_ENDIANNESS(zip_header); |
261 | if ((zip_header.formatted.method != 0) && (zip_header.formatted.method != 8)) { | 269 | if ((zip_header.formatted.method != 0) && (zip_header.formatted.method != 8)) { |
262 | bb_error_msg_and_die("unsupported method %d", zip_header.formatted.method); | 270 | bb_error_msg_and_die("unsupported method %d", zip_header.formatted.method); |