Loading libzipfile/centraldir.c +56 −4 Original line number Original line Diff line number Diff line Loading @@ -60,16 +60,20 @@ read_central_dir_values(Zipfile* file, const unsigned char* buf, int len) return 0; return 0; } } static const int kCompressionStored = 0x0; static const int kCompressionDeflate = 0x8; static int static int read_central_directory_entry(Zipfile* file, Zipentry* entry, read_central_directory_entry(Zipfile* file, Zipentry* entry, const unsigned char** buf, ssize_t* len) const unsigned char** buf, ssize_t* len) { { const unsigned char* p; const unsigned char* p; size_t remaining; const unsigned char* bufLimit; unsigned short versionMadeBy; unsigned short versionMadeBy; unsigned short versionToExtract; unsigned short versionToExtract; unsigned short gpBitFlag; unsigned short gpBitFlag; unsigned short compressionMethod; unsigned short lastModFileTime; unsigned short lastModFileTime; unsigned short lastModFileDate; unsigned short lastModFileDate; unsigned long crc32; unsigned long crc32; Loading @@ -84,8 +88,9 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry, unsigned int dataOffset; unsigned int dataOffset; unsigned short lfhExtraFieldSize; unsigned short lfhExtraFieldSize; p = *buf; p = *buf; remaining = *len; bufLimit = file->buf + file->bufsize; if (*len < ENTRY_LEN) { if (*len < ENTRY_LEN) { fprintf(stderr, "cde entry not large enough\n"); fprintf(stderr, "cde entry not large enough\n"); Loading Loading @@ -115,41 +120,88 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry, localHeaderRelOffset = read_le_int(&p[0x2a]); localHeaderRelOffset = read_le_int(&p[0x2a]); p += ENTRY_LEN; p += ENTRY_LEN; remaining -= ENTRY_LEN; // filename // filename if (entry->fileNameLength != 0) { if (entry->fileNameLength != 0) { if (entry->fileNameLength > remaining) { fprintf(stderr, "cde entry not large enough for file name.\n"); return 1; } entry->fileName = p; entry->fileName = p; } else { } else { entry->fileName = NULL; fprintf(stderr, "cde entry does not contain a file name.\n"); return 1; } } p += entry->fileNameLength; p += entry->fileNameLength; remaining -= entry->fileNameLength; // extra field // extra field, if any if (extraFieldLength != 0) { if (extraFieldLength != 0) { if (extraFieldLength > remaining) { fprintf(stderr, "cde entry not large enough for extra field.\n"); return 1; } extraField = p; extraField = p; } else { } else { extraField = NULL; extraField = NULL; } } p += extraFieldLength; p += extraFieldLength; remaining -= extraFieldLength; // comment, if any // comment, if any if (fileCommentLength != 0) { if (fileCommentLength != 0) { if (fileCommentLength > remaining) { fprintf(stderr, "cde entry not large enough for file comment.\n"); return 1; } fileComment = p; fileComment = p; } else { } else { fileComment = NULL; fileComment = NULL; } } p += fileCommentLength; p += fileCommentLength; remaining -= fileCommentLength; *buf = p; *buf = p; *len = remaining; // the size of the extraField in the central dir is how much data there is, // the size of the extraField in the central dir is how much data there is, // but the one in the local file header also contains some padding. // but the one in the local file header also contains some padding. p = file->buf + localHeaderRelOffset; p = file->buf + localHeaderRelOffset; if (p >= bufLimit) { fprintf(stderr, "Invalid local header offset for entry.\n"); return 1; } extraFieldLength = read_le_short(&p[0x1c]); extraFieldLength = read_le_short(&p[0x1c]); dataOffset = localHeaderRelOffset + LFH_SIZE dataOffset = localHeaderRelOffset + LFH_SIZE + entry->fileNameLength + extraFieldLength; + entry->fileNameLength + extraFieldLength; entry->data = file->buf + dataOffset; entry->data = file->buf + dataOffset; // Sanity check: make sure that the start of the entry data is within // our allocated buffer. if ((entry->data < file->buf) || (entry->data >= bufLimit)) { fprintf(stderr, "Invalid data offset for entry.\n"); return 1; } // Sanity check: make sure that the end of the entry data is within // our allocated buffer. We need to look at the uncompressedSize for // stored entries and the compressed size for deflated entries. if ((entry->compressionMethod == kCompressionStored) && (entry->uncompressedSize > (unsigned int) (bufLimit - entry->data))) { fprintf(stderr, "Invalid uncompressed size for stored entry.\n"); return 1; } if ((entry->compressionMethod == kCompressionDeflate) && (entry->compressedSize > (unsigned int) (bufLimit - entry->data))) { fprintf(stderr, "Invalid uncompressed size for deflated entry.\n"); return 1; } #if 0 #if 0 printf("file->buf=%p entry->data=%p dataOffset=%x localHeaderRelOffset=%d " printf("file->buf=%p entry->data=%p dataOffset=%x localHeaderRelOffset=%d " "entry->fileNameLength=%d extraFieldLength=%d\n", "entry->fileNameLength=%d extraFieldLength=%d\n", Loading libzipfile/test_zipfile.c +0 −1 Original line number Original line Diff line number Diff line Loading @@ -75,7 +75,6 @@ main(int argc, char** argv) unsize = get_zipentry_size(entry); unsize = get_zipentry_size(entry); size = unsize * 1.001; size = unsize * 1.001; scratch = malloc(size); scratch = malloc(size); printf("scratch=%p\n", scratch); err = decompress_zipentry(entry, scratch, size); err = decompress_zipentry(entry, scratch, size); if (err != 0) { if (err != 0) { fprintf(stderr, "error decompressing file\n"); fprintf(stderr, "error decompressing file\n"); Loading Loading
libzipfile/centraldir.c +56 −4 Original line number Original line Diff line number Diff line Loading @@ -60,16 +60,20 @@ read_central_dir_values(Zipfile* file, const unsigned char* buf, int len) return 0; return 0; } } static const int kCompressionStored = 0x0; static const int kCompressionDeflate = 0x8; static int static int read_central_directory_entry(Zipfile* file, Zipentry* entry, read_central_directory_entry(Zipfile* file, Zipentry* entry, const unsigned char** buf, ssize_t* len) const unsigned char** buf, ssize_t* len) { { const unsigned char* p; const unsigned char* p; size_t remaining; const unsigned char* bufLimit; unsigned short versionMadeBy; unsigned short versionMadeBy; unsigned short versionToExtract; unsigned short versionToExtract; unsigned short gpBitFlag; unsigned short gpBitFlag; unsigned short compressionMethod; unsigned short lastModFileTime; unsigned short lastModFileTime; unsigned short lastModFileDate; unsigned short lastModFileDate; unsigned long crc32; unsigned long crc32; Loading @@ -84,8 +88,9 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry, unsigned int dataOffset; unsigned int dataOffset; unsigned short lfhExtraFieldSize; unsigned short lfhExtraFieldSize; p = *buf; p = *buf; remaining = *len; bufLimit = file->buf + file->bufsize; if (*len < ENTRY_LEN) { if (*len < ENTRY_LEN) { fprintf(stderr, "cde entry not large enough\n"); fprintf(stderr, "cde entry not large enough\n"); Loading Loading @@ -115,41 +120,88 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry, localHeaderRelOffset = read_le_int(&p[0x2a]); localHeaderRelOffset = read_le_int(&p[0x2a]); p += ENTRY_LEN; p += ENTRY_LEN; remaining -= ENTRY_LEN; // filename // filename if (entry->fileNameLength != 0) { if (entry->fileNameLength != 0) { if (entry->fileNameLength > remaining) { fprintf(stderr, "cde entry not large enough for file name.\n"); return 1; } entry->fileName = p; entry->fileName = p; } else { } else { entry->fileName = NULL; fprintf(stderr, "cde entry does not contain a file name.\n"); return 1; } } p += entry->fileNameLength; p += entry->fileNameLength; remaining -= entry->fileNameLength; // extra field // extra field, if any if (extraFieldLength != 0) { if (extraFieldLength != 0) { if (extraFieldLength > remaining) { fprintf(stderr, "cde entry not large enough for extra field.\n"); return 1; } extraField = p; extraField = p; } else { } else { extraField = NULL; extraField = NULL; } } p += extraFieldLength; p += extraFieldLength; remaining -= extraFieldLength; // comment, if any // comment, if any if (fileCommentLength != 0) { if (fileCommentLength != 0) { if (fileCommentLength > remaining) { fprintf(stderr, "cde entry not large enough for file comment.\n"); return 1; } fileComment = p; fileComment = p; } else { } else { fileComment = NULL; fileComment = NULL; } } p += fileCommentLength; p += fileCommentLength; remaining -= fileCommentLength; *buf = p; *buf = p; *len = remaining; // the size of the extraField in the central dir is how much data there is, // the size of the extraField in the central dir is how much data there is, // but the one in the local file header also contains some padding. // but the one in the local file header also contains some padding. p = file->buf + localHeaderRelOffset; p = file->buf + localHeaderRelOffset; if (p >= bufLimit) { fprintf(stderr, "Invalid local header offset for entry.\n"); return 1; } extraFieldLength = read_le_short(&p[0x1c]); extraFieldLength = read_le_short(&p[0x1c]); dataOffset = localHeaderRelOffset + LFH_SIZE dataOffset = localHeaderRelOffset + LFH_SIZE + entry->fileNameLength + extraFieldLength; + entry->fileNameLength + extraFieldLength; entry->data = file->buf + dataOffset; entry->data = file->buf + dataOffset; // Sanity check: make sure that the start of the entry data is within // our allocated buffer. if ((entry->data < file->buf) || (entry->data >= bufLimit)) { fprintf(stderr, "Invalid data offset for entry.\n"); return 1; } // Sanity check: make sure that the end of the entry data is within // our allocated buffer. We need to look at the uncompressedSize for // stored entries and the compressed size for deflated entries. if ((entry->compressionMethod == kCompressionStored) && (entry->uncompressedSize > (unsigned int) (bufLimit - entry->data))) { fprintf(stderr, "Invalid uncompressed size for stored entry.\n"); return 1; } if ((entry->compressionMethod == kCompressionDeflate) && (entry->compressedSize > (unsigned int) (bufLimit - entry->data))) { fprintf(stderr, "Invalid uncompressed size for deflated entry.\n"); return 1; } #if 0 #if 0 printf("file->buf=%p entry->data=%p dataOffset=%x localHeaderRelOffset=%d " printf("file->buf=%p entry->data=%p dataOffset=%x localHeaderRelOffset=%d " "entry->fileNameLength=%d extraFieldLength=%d\n", "entry->fileNameLength=%d extraFieldLength=%d\n", Loading
libzipfile/test_zipfile.c +0 −1 Original line number Original line Diff line number Diff line Loading @@ -75,7 +75,6 @@ main(int argc, char** argv) unsize = get_zipentry_size(entry); unsize = get_zipentry_size(entry); size = unsize * 1.001; size = unsize * 1.001; scratch = malloc(size); scratch = malloc(size); printf("scratch=%p\n", scratch); err = decompress_zipentry(entry, scratch, size); err = decompress_zipentry(entry, scratch, size); if (err != 0) { if (err != 0) { fprintf(stderr, "error decompressing file\n"); fprintf(stderr, "error decompressing file\n"); Loading