aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/singlejar/input_jar.cc
diff options
context:
space:
mode:
authorGravatar Sasha Smundak <asmundak@google.com>2016-08-23 12:58:31 +0000
committerGravatar John Cater <jcater@google.com>2016-08-23 22:57:24 +0000
commit0943498edc05ada655cc2862a644071e503dd034 (patch)
tree6c93ed5e47add9ebcbd4e3f2d39337fddb4bbd2b /src/tools/singlejar/input_jar.cc
parent3d4248c6da9630e315f58a18e9d69c2608cd9de5 (diff)
Fix empty archive handling.
RELNOTES: -- MOS_MIGRATED_REVID=131046379
Diffstat (limited to 'src/tools/singlejar/input_jar.cc')
-rw-r--r--src/tools/singlejar/input_jar.cc69
1 files changed, 37 insertions, 32 deletions
diff --git a/src/tools/singlejar/input_jar.cc b/src/tools/singlejar/input_jar.cc
index 980a90c6f8..348733689d 100644
--- a/src/tools/singlejar/input_jar.cc
+++ b/src/tools/singlejar/input_jar.cc
@@ -83,7 +83,7 @@ bool InputJar::Open(const std::string &path) {
mapped_file_.Close();
return false;
}
- if (mapped_file_.offset(ecd) <= cen_position) {
+ if (mapped_file_.offset(ecd) < cen_position) {
diag_warnx("%s:%d: %s is corrupt: End of Central Directory at 0x%" PRIx64
" precedes Central Directory at 0x%" PRIx64,
__FILE__, __LINE__, path.c_str(), mapped_file_.offset(ecd),
@@ -102,41 +102,46 @@ bool InputJar::Open(const std::string &path) {
return false;
}
}
-
- auto ecd64loc = reinterpret_cast<const ECD64Locator *>(byte_ptr(ecd) -
- sizeof(ECD64Locator));
- if (ecd64loc->is()) {
- auto ecd64 =
- reinterpret_cast<const ECD64 *>(byte_ptr(ecd64loc) - sizeof(ECD64));
- if (!ecd64->is()) {
- diag_warnx(
- "%s:%d: %s is corrupt, expected ECD64 record at offset 0x%" PRIx64
- " is missing",
- __FILE__, __LINE__, path.c_str(), mapped_file_.offset(ecd64));
- mapped_file_.Close();
- return false;
- }
- cdh_ = reinterpret_cast<const CDH *>(byte_ptr(ecd64) - ecd64->cen_size());
- preamble_size_ = mapped_file_.offset(cdh_) - ecd64->cen_offset();
- // Find CEN and preamble size.
+ if (cen_size == 0) {
+ // Empty archive, let cdh_ point to End of Central Directory.
+ cdh_ = reinterpret_cast<const CDH *>(ecd);
+ preamble_size_ = mapped_file_.offset(cdh_) - cen_position;
} else {
- if (cen_size == 0xFFFFFFFF || cen_position == 0xFFFFFFFF) {
+ auto ecd64loc = reinterpret_cast<const ECD64Locator *>(
+ byte_ptr(ecd) - sizeof(ECD64Locator));
+ if (ecd64loc->is()) {
+ auto ecd64 =
+ reinterpret_cast<const ECD64 *>(byte_ptr(ecd64loc) - sizeof(ECD64));
+ if (!ecd64->is()) {
+ diag_warnx(
+ "%s:%d: %s is corrupt, expected ECD64 record at offset 0x%" PRIx64
+ " is missing",
+ __FILE__, __LINE__, path.c_str(), mapped_file_.offset(ecd64));
+ mapped_file_.Close();
+ return false;
+ }
+ cdh_ = reinterpret_cast<const CDH *>(byte_ptr(ecd64) - ecd64->cen_size());
+ preamble_size_ = mapped_file_.offset(cdh_) - ecd64->cen_offset();
+ // Find CEN and preamble size.
+ } else {
+ if (cen_size == 0xFFFFFFFF || cen_position == 0xFFFFFFFF) {
+ diag_warnx(
+ "%s:%d: %s is corrupt, expected ECD64 locator record at "
+ "offset 0x%" PRIx64 " is missing",
+ __FILE__, __LINE__, path.c_str(), mapped_file_.offset(ecd64loc));
+ return false;
+ }
+ cdh_ = reinterpret_cast<const CDH *>(byte_ptr(ecd) - cen_size);
+ preamble_size_ = mapped_file_.offset(cdh_) - cen_position;
+ }
+ if (!cdh_->is()) {
diag_warnx(
- "%s:%d: %s is corrupt, expected ECD64 locator record at "
- "offset 0x%" PRIx64 " is missing",
- __FILE__, __LINE__, path.c_str(), mapped_file_.offset(ecd64loc));
+ "%s:%d: In %s, expected central file header signature at "
+ "offset0x%" PRIx64,
+ __FILE__, __LINE__, path.c_str(), mapped_file_.offset(cdh_));
+ mapped_file_.Close();
return false;
}
- cdh_ = reinterpret_cast<const CDH *>(byte_ptr(ecd) - cen_size);
- preamble_size_ = mapped_file_.offset(cdh_) - cen_position;
- }
- if (!cdh_->is()) {
- diag_warnx(
- "%s:%d: In %s, expected central file header signature at "
- "offset0x%" PRIx64,
- __FILE__, __LINE__, path.c_str(), mapped_file_.offset(cdh_));
- mapped_file_.Close();
- return false;
}
path_ = path;
return true;