aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmin Hassani <ahassani@google.com>2020-02-19 13:58:33 -0800
committerAmin Hassani <ahassani@google.com>2020-02-20 13:18:19 -0800
commit9c33d3b2833cdeb3959ca03136840d72b0cf469e (patch)
tree81a23cac8235f98ee87092f505373fc720bf7d3d
parent3204c84e377af6ae27377200d6c06a68037269a5 (diff)
downloadplatform_external_puffin-9c33d3b2833cdeb3959ca03136840d72b0cf469e.tar.gz
platform_external_puffin-9c33d3b2833cdeb3959ca03136840d72b0cf469e.tar.bz2
platform_external_puffin-9c33d3b2833cdeb3959ca03136840d72b0cf469e.zip
Don't return false if there was no compressed deflate in a stream
Currently, LocateDeflatesInGzip() fails if the stream either does not have any deflates, or the deflates are all uncompressed. This can happen for example if there are gzip files in a squashfs image compressed with gzip. With high probability, the gzip won't double compress the compressed files because that might actually increase the final size. So we should not fail on this function if there was no deflates indentified same as LocateDeflatesInZipArchive(). Bug: crbug.com/1050869 Test: cros_generate_update_payload --image gs://chromeos-releases/dev-channel/eve-kvm/12871.1.0/dlc/pita/package/dlc.img --src_image gs://chromeos-releases/dev-channel/eve-kvm/12861.0.0/dlc/pita/package/dlc.img --output delta.bin --debug Change-Id: Ic770d8cb01e14306e7e49cdaadf09b5900e49d17
-rw-r--r--src/utils.cc26
1 files changed, 17 insertions, 9 deletions
diff --git a/src/utils.cc b/src/utils.cc
index d0aece0..b9b06c1 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -7,6 +7,7 @@
#include <inttypes.h>
#include <algorithm>
+#include <iterator>
#include <set>
#include <string>
#include <vector>
@@ -176,16 +177,24 @@ bool LocateDeflatesInZlibBlocks(const string& file_path,
return true;
}
+namespace {
// For more information about gzip format, refer to RFC 1952 located at:
// https://www.ietf.org/rfc/rfc1952.txt
+bool IsValidGzipHeader(const uint8_t* header, size_t size) {
+ // Each gzip entry has the following format magic header:
+ // 0 1 0x1F
+ // 1 1 0x8B
+ // 2 1 compression method (8 denotes deflate)
+ static const uint8_t magic[] = {0x1F, 0x8B, 8};
+ return size >= 10 && std::equal(std::begin(magic), std::end(magic), header);
+}
+} // namespace
+
bool LocateDeflatesInGzip(const Buffer& data, vector<BitExtent>* deflates) {
+ TEST_AND_RETURN_FALSE(IsValidGzipHeader(data.data(), data.size()));
uint64_t member_start = 0;
- 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
- // 2 1 compression method (8 denotes deflate)
+ do {
+ // After the magic header, the gzip contains:
// 3 1 set of flags
// 4 4 modification time
// 8 1 extra flags
@@ -234,9 +243,8 @@ bool LocateDeflatesInGzip(const Buffer& data, vector<BitExtent>* deflates) {
TEST_AND_RETURN_FALSE(offset + 8 <= data.size());
offset += 8;
member_start = offset;
- }
- // Return true if we've successfully parsed at least one gzip.
- return member_start != 0;
+ } while (IsValidGzipHeader(&data[member_start], data.size() - member_start));
+ return true;
}
// For more information about the zip format, refer to