#include "crazy_linker_debug.h"
#include "crazy_linker_system.h"
+#include "crazy_linker_util.h"
namespace {
// This marker appears at the start of local header
const uint32_t kLocalHeaderMarker = 0x04034b50;
+// http://www.pkware.com/documents/casestudies/APPNOTE.TXT Section 4.4.5
+// This value denotes that the file is stored (no compression).
+const uint32_t kCompressionMethodStored = 0;
+
// Offsets of fields in the Local Header.
+const int kOffsetCompressionMethodInLocalHeader = 4 + 2 + 2;
const int kOffsetFilenameLengthInLocalHeader =
- 4 + 2 + 2 + 2 + 2 + 2 + 4 + 4 + 4;
+ kOffsetCompressionMethodInLocalHeader + 2 + 2 + 2 + 4 + 4 + 4;
const int kOffsetExtraFieldLengthInLocalHeader =
kOffsetFilenameLengthInLocalHeader + 2;
const int kOffsetFilenameInLocalHeader =
if (!fd.OpenReadOnly(zip_file)) {
LOG_ERRNO("%s: open failed trying to open zip file %s\n",
__FUNCTION__, zip_file);
- return -1;
+ return CRAZY_OFFSET_FAILED;
}
// Find the length of the file.
if (stat(zip_file, &stat_buf) == -1) {
LOG_ERRNO("%s: stat failed trying to stat zip file %s\n",
__FUNCTION__, zip_file);
- return -1;
+ return CRAZY_OFFSET_FAILED;
}
if (stat_buf.st_size > kMaxZipFileLength) {
LOG("%s: The size %ld of %s is too large to map\n",
__FUNCTION__, stat_buf.st_size, zip_file);
- return -1;
+ return CRAZY_OFFSET_FAILED;
}
// Map the file into memory.
if (mem == MAP_FAILED) {
LOG_ERRNO("%s: mmap failed trying to mmap zip file %s\n",
__FUNCTION__, zip_file);
- return -1;
+ return CRAZY_OFFSET_FAILED;
}
ScopedMMap scoped_mmap(mem, stat_buf.st_size);
if (off == -1) {
LOG("%s: Failed to find end of central directory in %s\n",
__FUNCTION__, zip_file);
- return -1;
+ return CRAZY_OFFSET_FAILED;
}
// We have located the end of central directory record, now locate
if (start_of_central_dir > off) {
LOG("%s: Found out of range offset %u for start of directory in %s\n",
__FUNCTION__, start_of_central_dir, zip_file);
- return -1;
+ return CRAZY_OFFSET_FAILED;
}
uint32_t end_of_central_dir = start_of_central_dir + length_of_central_dir;
if (end_of_central_dir > off) {
LOG("%s: Found out of range offset %u for end of directory in %s\n",
__FUNCTION__, end_of_central_dir, zip_file);
- return -1;
+ return CRAZY_OFFSET_FAILED;
}
uint32_t num_entries = ReadUInt16(
LOG("%s: Failed to find central directory header marker in %s. "
"Found 0x%x but expected 0x%x\n", __FUNCTION__,
zip_file, marker, kCentralDirHeaderMarker);
- return -1;
+ return CRAZY_OFFSET_FAILED;
}
uint32_t file_name_length =
ReadUInt16(mem_bytes, off + kOffsetFilenameLengthInCentralDirectory);
LOG("%s: Failed to find local file header marker in %s. "
"Found 0x%x but expected 0x%x\n", __FUNCTION__,
zip_file, marker, kLocalHeaderMarker);
- return -1;
+ return CRAZY_OFFSET_FAILED;
+ }
+
+ uint32_t compression_method =
+ ReadUInt16(
+ mem_bytes,
+ local_header_offset + kOffsetCompressionMethodInLocalHeader);
+ if (compression_method != kCompressionMethodStored) {
+ LOG("%s: %s is compressed within %s. "
+ "Found compression method %u but expected %u\n", __FUNCTION__,
+ filename, zip_file, compression_method, kCompressionMethodStored);
+ return CRAZY_OFFSET_FAILED;
}
uint32_t file_name_length =
}
LOG("%s: Did not find %s in %s\n", __FUNCTION__, filename, zip_file);
- return -1;
+ return CRAZY_OFFSET_FAILED;
}
} // crazy namespace