Allow gzip with padding data in LocateDeflatesInGzip.
Files stored in filesystem are padded with 0 to fill the block, we
shouldn't return false in this case.
Test: generate a delta payload extracting deflates in gzip
Test: puffin_unittest
Change-Id: I90d4f76243ea686913dab802476b53a08c6fccee
diff --git a/src/utils.cc b/src/utils.cc
index 668ec3f..de3cc6c 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -181,7 +181,8 @@
// https://www.ietf.org/rfc/rfc1952.txt
bool LocateDeflatesInGzip(const Buffer& data, vector<BitExtent>* deflates) {
uint64_t member_start = 0;
- while (member_start < data.size()) {
+ while (member_start + 10 <= data.size() && data[member_start + 0] == 0x1F &&
+ data[member_start + 1] == 0x8B && data[member_start + 2] == 8) {
// Each member entry has the following format
// 0 1 0x1F
// 1 1 0x8B
@@ -190,10 +191,6 @@
// 4 4 modification time
// 8 1 extra flags
// 9 1 operating system
- TEST_AND_RETURN_FALSE(member_start + 10 <= data.size());
- TEST_AND_RETURN_FALSE(data[member_start + 0] == 0x1F);
- TEST_AND_RETURN_FALSE(data[member_start + 1] == 0x8B);
- TEST_AND_RETURN_FALSE(data[member_start + 2] == 8);
uint64_t offset = member_start + 10;
int flag = data[member_start + 3];
@@ -239,7 +236,8 @@
offset += 8;
member_start = offset;
}
- return true;
+ // Return true if we've successfully parsed at least one gzip.
+ return member_start != 0;
}
// For more information about the zip format, refer to
diff --git a/src/utils_unittest.cc b/src/utils_unittest.cc
index 737b765..43f18d0 100644
--- a/src/utils_unittest.cc
+++ b/src/utils_unittest.cc
@@ -195,6 +195,24 @@
EXPECT_EQ(deflates, expected_deflates);
}
+TEST(UtilsTest, LocateDeflatesInGzipFail) {
+ Buffer gzip_data(kGzipEntryWithMultipleMembers,
+ std::end(kGzipEntryWithMultipleMembers));
+ gzip_data[0] ^= 1;
+ vector<BitExtent> deflates;
+ EXPECT_FALSE(LocateDeflatesInGzip(gzip_data, &deflates));
+}
+
+TEST(UtilsTest, LocateDeflatesInGzipWithPadding) {
+ Buffer gzip_data(kGzipEntryWithMultipleMembers,
+ std::end(kGzipEntryWithMultipleMembers));
+ gzip_data.resize(gzip_data.size() + 100);
+ vector<BitExtent> deflates;
+ vector<BitExtent> expected_deflates = {{160, 98}, {488, 98}};
+ EXPECT_TRUE(LocateDeflatesInGzip(gzip_data, &deflates));
+ EXPECT_EQ(deflates, expected_deflates);
+}
+
TEST(UtilsTest, LocateDeflatesInGzipWithExtraField) {
Buffer gzip_data(kGzipEntryWithExtraField,
std::end(kGzipEntryWithExtraField));