summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2016-09-21 17:35:52 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-09-21 17:35:52 +0000
commitaf43cd033c64384c521a9cb1fb68660d7799435c (patch)
treee8b37e5fbeeee31ede838568a70e86e1365267bd
parent0f6c4a0e8fe270528613f91a5b3c82eb3f118e59 (diff)
parentb5f75c458270fc49ea4c61ed7126155531c5ca63 (diff)
downloadcore-af43cd033c64384c521a9cb1fb68660d7799435c.tar.gz
resolve merge conflicts of a47780b to lmp-dev am: 61f27551c7
am: b5f75c4582 Change-Id: Iacea86ad3c142d6f14b5fbdfb5b615f4705b1bd1
-rw-r--r--libzipfile/centraldir.c55
-rw-r--r--libzipfile/test_zipfile.c1
2 files changed, 54 insertions, 2 deletions
diff --git a/libzipfile/centraldir.c b/libzipfile/centraldir.c
index 69cf47a19..98eef73e0 100644
--- a/libzipfile/centraldir.c
+++ b/libzipfile/centraldir.c
@@ -62,11 +62,16 @@ read_central_dir_values(Zipfile* file, const unsigned char* buf, int len)
return 0;
}
+static const int kCompressionStored = 0x0;
+static const int kCompressionDeflate = 0x8;
+
static int
read_central_directory_entry(Zipfile* file, Zipentry* entry,
const unsigned char** buf, ssize_t* len)
{
const unsigned char* p;
+ size_t remaining;
+ const unsigned char* bufLimit;
unsigned short extraFieldLength;
unsigned short fileCommentLength;
@@ -74,6 +79,8 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry,
unsigned int dataOffset;
p = *buf;
+ remaining = *len;
+ bufLimit = file->buf + file->bufsize;
if (*len < ENTRY_LEN) {
fprintf(stderr, "cde entry not large enough\n");
@@ -94,31 +101,77 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry,
localHeaderRelOffset = read_le_int(&p[0x2a]);
p += ENTRY_LEN;
+ remaining -= ENTRY_LEN;
// filename
if (entry->fileNameLength != 0) {
+ if (entry->fileNameLength > remaining) {
+ fprintf(stderr, "cde entry not large enough for file name.\n");
+ return 1;
+ }
+
entry->fileName = p;
} else {
- entry->fileName = NULL;
+ fprintf(stderr, "cde entry does not contain a file name.\n");
+ return 1;
}
p += entry->fileNameLength;
+ remaining -= entry->fileNameLength;
// extra field
+ if (extraFieldLength > remaining) {
+ fprintf(stderr, "cde entry not large enough for extra field.\n");
+ return 1;
+ }
p += extraFieldLength;
+ remaining -= extraFieldLength;
// comment, if any
+ if (fileCommentLength > remaining) {
+ fprintf(stderr, "cde entry not large enough for file comment.\n");
+ return 1;
+ }
+
p += fileCommentLength;
+ remaining -= fileCommentLength;
*buf = p;
+ *len = remaining;
// 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.
p = file->buf + localHeaderRelOffset;
+ if (p >= bufLimit) {
+ fprintf(stderr, "Invalid local header offset for entry.\n");
+ return 1;
+ }
+
extraFieldLength = read_le_short(&p[0x1c]);
dataOffset = localHeaderRelOffset + LFH_SIZE
+ entry->fileNameLength + extraFieldLength;
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
printf("file->buf=%p entry->data=%p dataOffset=%x localHeaderRelOffset=%d "
"entry->fileNameLength=%d extraFieldLength=%d\n",
diff --git a/libzipfile/test_zipfile.c b/libzipfile/test_zipfile.c
index 1aaa9132d..a2f6bc7e5 100644
--- a/libzipfile/test_zipfile.c
+++ b/libzipfile/test_zipfile.c
@@ -75,7 +75,6 @@ main(int argc, char** argv)
unsize = get_zipentry_size(entry);
size = unsize * 1.001;
scratch = malloc(size);
- printf("scratch=%p\n", scratch);
err = decompress_zipentry(entry, scratch, size);
if (err != 0) {
fprintf(stderr, "error decompressing file\n");