Merge "Remove cyclic symlink"
diff --git a/BUILD.gn b/BUILD.gn
index 24d9c06..100c4c4 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -16,15 +16,24 @@
deps += [ ":puffin_test" ]
}
if (use.fuzzer) {
- deps += [ ":puffin_fuzzer" ]
+ deps += [
+ ":puffin_huff_fuzzer",
+ ":puffin_puff_fuzzer",
+ ":puffin_puffpatch_fuzzer",
+ ]
}
}
pkg_config("target_defaults") {
pkg_deps = [
"libchrome-${libbase_ver}",
- "protobuf-lite",
]
+ if (use.fuzzer) {
+ # Link against protobuf for fuzzers so we can use libprotobuf-mutator.
+ pkg_deps += [ "protobuf" ]
+ } else {
+ pkg_deps += [ "protobuf-lite" ]
+ }
cflags = [ "-Wextra" ]
cflags_cc = [ "-Wnon-virtual-dtor" ]
include_dirs = [ "src/include" ]
@@ -95,7 +104,7 @@
pkg_config("libbrillo") {
pkg_deps = [
- "libbrillo-${libbase_ver}",
+ "libbrillo",
]
}
@@ -138,7 +147,33 @@
}
if (use.fuzzer) {
- executable("puffin_fuzzer") {
+ executable("puffin_huff_fuzzer") {
+ configs += [
+ "//common-mk/common_fuzzer",
+ ":libbrillo",
+ ":target_defaults",
+ ]
+ deps = [
+ ":libpuffpatch",
+ ]
+ sources = [
+ "src/fuzzer_huff.cc",
+ ]
+ }
+ executable("puffin_puff_fuzzer") {
+ configs += [
+ "//common-mk/common_fuzzer",
+ ":libbrillo",
+ ":target_defaults",
+ ]
+ deps = [
+ ":libpuffpatch",
+ ]
+ sources = [
+ "src/fuzzer_puff.cc",
+ ]
+ }
+ executable("puffin_puffpatch_fuzzer") {
configs += [
"//common-mk/common_fuzzer",
":libbrillo",
@@ -148,7 +183,7 @@
":libpuffdiff",
]
sources = [
- "src/fuzzer.cc",
+ "src/fuzzer_puffpatch.cc",
]
}
}
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..ee8f0ca
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "puffin_unittest"
+ }
+ ]
+}
diff --git a/src/fuzzer_huff.cc b/src/fuzzer_huff.cc
new file mode 100644
index 0000000..4002aa0
--- /dev/null
+++ b/src/fuzzer_huff.cc
@@ -0,0 +1,43 @@
+// Copyright 2019 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "brillo/test_helpers.h"
+
+#include "puffin/src/bit_writer.h"
+#include "puffin/src/include/puffin/common.h"
+#include "puffin/src/include/puffin/huffer.h"
+#include "puffin/src/puff_reader.h"
+
+using puffin::Buffer;
+using puffin::BufferBitWriter;
+using puffin::BufferPuffReader;
+using puffin::ByteExtent;
+using puffin::Huffer;
+
+namespace {
+void FuzzHuff(const uint8_t* data, size_t size) {
+ BufferPuffReader puff_reader(data, size);
+ Buffer deflate_buffer(size);
+ BufferBitWriter bit_writer(deflate_buffer.data(), deflate_buffer.size());
+ Huffer huffer;
+ huffer.HuffDeflate(&puff_reader, &bit_writer);
+}
+
+class Environment {
+ public:
+ Environment() {
+ // To turn off the logging.
+ logging::SetMinLogLevel(logging::LOG_FATAL);
+ }
+};
+
+} // namespace
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ static Environment env;
+
+ FuzzHuff(data, size);
+ return 0;
+}
diff --git a/src/fuzzer_puff.cc b/src/fuzzer_puff.cc
new file mode 100644
index 0000000..c4d26f6
--- /dev/null
+++ b/src/fuzzer_puff.cc
@@ -0,0 +1,47 @@
+// Copyright 2019 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "base/logging.h"
+#include "brillo/test_helpers.h"
+
+#include "puffin/src/bit_reader.h"
+#include "puffin/src/include/puffin/common.h"
+#include "puffin/src/include/puffin/puffer.h"
+#include "puffin/src/puff_writer.h"
+
+using puffin::BitExtent;
+using puffin::Buffer;
+using puffin::BufferBitReader;
+using puffin::BufferPuffWriter;
+using puffin::Puffer;
+using std::vector;
+
+namespace {
+void FuzzPuff(const uint8_t* data, size_t size) {
+ BufferBitReader bit_reader(data, size);
+ Buffer puff_buffer(size * 2);
+ BufferPuffWriter puff_writer(puff_buffer.data(), puff_buffer.size());
+ vector<BitExtent> bit_extents;
+ Puffer puffer;
+ puffer.PuffDeflate(&bit_reader, &puff_writer, &bit_extents);
+}
+
+class Environment {
+ public:
+ Environment() {
+ // To turn off the logging.
+ logging::SetMinLogLevel(logging::LOG_FATAL);
+ }
+};
+
+} // namespace
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ static Environment env;
+
+ FuzzPuff(data, size);
+ return 0;
+}
diff --git a/src/fuzzer.cc b/src/fuzzer_puffpatch.cc
similarity index 73%
rename from src/fuzzer.cc
rename to src/fuzzer_puffpatch.cc
index b870ac4..28ee5bc 100644
--- a/src/fuzzer.cc
+++ b/src/fuzzer_puffpatch.cc
@@ -7,27 +7,14 @@
#include "base/logging.h"
#include "brillo/test_helpers.h"
-#include "puffin/src/bit_reader.h"
-#include "puffin/src/bit_writer.h"
#include "puffin/src/include/puffin/common.h"
-#include "puffin/src/include/puffin/huffer.h"
-#include "puffin/src/include/puffin/puffer.h"
#include "puffin/src/include/puffin/puffpatch.h"
#include "puffin/src/memory_stream.h"
-#include "puffin/src/puff_reader.h"
-#include "puffin/src/puff_writer.h"
using puffin::BitExtent;
using puffin::Buffer;
-using puffin::BufferBitReader;
-using puffin::BufferBitWriter;
-using puffin::BufferPuffReader;
-using puffin::BufferPuffWriter;
using puffin::ByteExtent;
-using puffin::Huffer;
using puffin::MemoryStream;
-using puffin::Puffer;
-using puffin::UniqueStreamPtr;
using std::vector;
namespace puffin {
@@ -45,23 +32,6 @@
} // namespace puffin
namespace {
-void FuzzPuff(const uint8_t* data, size_t size) {
- BufferBitReader bit_reader(data, size);
- Buffer puff_buffer(size * 2);
- BufferPuffWriter puff_writer(puff_buffer.data(), puff_buffer.size());
- vector<BitExtent> bit_extents;
- Puffer puffer;
- puffer.PuffDeflate(&bit_reader, &puff_writer, &bit_extents);
-}
-
-void FuzzHuff(const uint8_t* data, size_t size) {
- BufferPuffReader puff_reader(data, size);
- Buffer deflate_buffer(size);
- BufferBitWriter bit_writer(deflate_buffer.data(), deflate_buffer.size());
- Huffer huffer;
- huffer.HuffDeflate(&puff_reader, &bit_writer);
-}
-
template <typename T>
bool TestExtentsArrayForFuzzer(const vector<T>& extents) {
const size_t kMaxArraySize = 100;
@@ -114,7 +84,8 @@
}
}
-struct Environment {
+class Environment {
+ public:
Environment() {
// To turn off the logging.
logging::SetMinLogLevel(logging::LOG_FATAL);
@@ -123,13 +94,12 @@
std::cerr.setstate(std::ios_base::failbit);
}
};
-Environment* env = new Environment();
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- FuzzPuff(data, size);
- FuzzHuff(data, size);
+ static Environment env;
+
FuzzPuffPatch(data, size);
return 0;
}
diff --git a/src/puffdiff.cc b/src/puffdiff.cc
index 9e3de72..15d0fa6 100644
--- a/src/puffdiff.cc
+++ b/src/puffdiff.cc
@@ -68,7 +68,9 @@
header.mutable_src()->set_puff_length(src_puff_size);
header.mutable_dst()->set_puff_length(dst_puff_size);
- const uint32_t header_size = header.ByteSize();
+ const size_t header_size_long = header.ByteSizeLong();
+ TEST_AND_RETURN_FALSE(header_size_long <= UINT32_MAX);
+ const uint32_t header_size = header_size_long;
uint64_t offset = 0;
patch->resize(kMagicLength + sizeof(header_size) + header_size +
diff --git a/src/utils.cc b/src/utils.cc
index 708684d..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 @@
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 @@
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
@@ -244,7 +252,7 @@
bool LocateDeflatesInZipArchive(const Buffer& data,
vector<BitExtent>* deflates) {
uint64_t pos = 0;
- while (pos <= data.size() - 30) {
+ while (pos + 30 <= data.size()) {
// TODO(xunchang) add support for big endian system when searching for
// magic numbers.
if (get_unaligned<uint32_t>(data.data() + pos) != 0x04034b50) {