Merge "Upgrade zlib to 898c6c0dd91fa0efb38a10949f76102e42cc47f0" am: 28b8c108fa am: 2ac6e5bb34

Original change: https://android-review.googlesource.com/c/platform/external/zlib/+/1423414

Change-Id: I2b807b66b4943afea84ca17103d1e61b04633ea7
diff --git a/BUILD.gn b/BUILD.gn
index 50540d9..34d8c0a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -29,6 +29,20 @@
   }
 }
 
+source_set("zlib_common_headers") {
+  sources = [
+    "chromeconf.h",
+    "deflate.h",
+    "inffast.h",
+    "inffixed.h",
+    "inflate.h",
+    "inftrees.h",
+    "zconf.h",
+    "zlib.h",
+    "zutil.h",
+  ]
+}
+
 use_arm_neon_optimizations = false
 if ((current_cpu == "arm" || current_cpu == "arm64") &&
     !(is_win && !is_clang)) {
@@ -81,6 +95,8 @@
   configs += [ ":zlib_internal_config" ]
 
   public_configs = [ ":zlib_adler32_simd_config" ]
+
+  public_deps = [ ":zlib_common_headers" ]
 }
 
 if (use_arm_neon_optimizations) {
@@ -127,6 +143,8 @@
     configs += [ ":zlib_internal_config" ]
 
     public_configs = [ ":zlib_arm_crc32_config" ]
+
+    public_deps = [ ":zlib_common_headers" ]
   }
 }
 
@@ -170,6 +188,8 @@
   configs += [ "//build/config/compiler:no_chromium_code" ]
 
   public_configs = [ ":zlib_inflate_chunk_simd_config" ]
+
+  public_deps = [ ":zlib_common_headers" ]
 }
 
 config("zlib_crc32_simd_config") {
@@ -198,6 +218,7 @@
   configs += [ ":zlib_internal_config" ]
 
   public_configs = [ ":zlib_crc32_simd_config" ]
+  public_deps = [ ":zlib_common_headers" ]
 }
 
 config("zlib_x86_simd_config") {
@@ -229,6 +250,8 @@
   configs += [ ":zlib_internal_config" ]
 
   public_configs = [ ":zlib_x86_simd_config" ]
+
+  public_deps = [ ":zlib_common_headers" ]
 }
 
 config("zlib_warnings") {
@@ -403,6 +426,7 @@
     sources = [
       "contrib/tests/infcover.cc",
       "contrib/tests/infcover.h",
+      "contrib/tests/run_all_unittests.cc",
       "contrib/tests/utils_unittest.cc",
       "google/compression_utils_portable.cc",
       "google/compression_utils_portable.h",
@@ -410,8 +434,8 @@
 
     deps = [
       ":zlib",
+      "//base/test:test_support",
       "//testing/gtest",
-      "//testing/gtest:gtest_main",
     ]
 
     include_dirs = [
diff --git a/METADATA b/METADATA
index 162753b..b708053 100644
--- a/METADATA
+++ b/METADATA
@@ -5,11 +5,11 @@
     type: GIT
     value: "https://chromium.googlesource.com/chromium/src/third_party/zlib/"
   }
-  version: "7492de9a52f656b070f41968e39a6efa603590d5"
+  version: "898c6c0dd91fa0efb38a10949f76102e42cc47f0"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 8
-    day: 10
+    month: 9
+    day: 9
   }
 }
diff --git a/DEPS b/contrib/tests/DEPS
similarity index 74%
rename from DEPS
rename to contrib/tests/DEPS
index b6dcfc6..4275174 100644
--- a/DEPS
+++ b/contrib/tests/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
     "+testing/gtest",
-]
\ No newline at end of file
+    "+base",
+]
diff --git a/contrib/tests/run_all_unittests.cc b/contrib/tests/run_all_unittests.cc
new file mode 100644
index 0000000..65ed57e
--- /dev/null
+++ b/contrib/tests/run_all_unittests.cc
@@ -0,0 +1,14 @@
+// Copyright 2020 The Chromium 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/bind.h"
+#include "base/test/launcher/unit_test_launcher.h"
+#include "base/test/test_suite.h"
+
+int main(int argc, char** argv) {
+  base::TestSuite test_suite(argc, argv);
+  return base::LaunchUnitTests(
+      argc, argv,
+      base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite)));
+}
diff --git a/contrib/tests/utils_unittest.cc b/contrib/tests/utils_unittest.cc
index 45796f6..8d5eab6 100644
--- a/contrib/tests/utils_unittest.cc
+++ b/contrib/tests/utils_unittest.cc
@@ -144,3 +144,69 @@
   ret = inflateEnd(&decomp_strm);
   EXPECT_EQ(ret, Z_OK);
 }
+
+TEST(ZlibTest, CRCHashBitsCollision) {
+  // The CRC32c of the hex sequences 2a,14,14,14 and 2a,14,db,14 have the same
+  // lower 9 bits. Since longest_match doesn't check match[2], a bad match could
+  // be chosen when the number of hash bits is <= 9. For this reason, the number
+  // of hash bits must be set higher, regardless of the memlevel parameter, when
+  // using CRC32c hashing for string matching. See https://crbug.com/1113596
+
+  std::vector<uint8_t> src = {
+      // Random byte; zlib doesn't match at offset 0.
+      123,
+
+      // This will look like 5-byte match.
+      0x2a,
+      0x14,
+      0xdb,
+      0x14,
+      0x15,
+
+      // Offer a 4-byte match to bump the next expected match length to 5.
+      0x2a,
+      0x14,
+      0x14,
+      0x14,
+
+      0x2a,
+      0x14,
+      0x14,
+      0x14,
+      0x15,
+  };
+
+  z_stream stream;
+  stream.zalloc = nullptr;
+  stream.zfree = nullptr;
+
+  // Using a low memlevel to try to reduce the number of hash bits. Negative
+  // windowbits means raw deflate, i.e. without the zlib header.
+  int ret = deflateInit2(&stream, /*comp level*/ 2, /*method*/ Z_DEFLATED,
+                         /*windowbits*/ -15, /*memlevel*/ 2,
+                         /*strategy*/ Z_DEFAULT_STRATEGY);
+  ASSERT_EQ(ret, Z_OK);
+  std::vector<uint8_t> compressed(100, '\0');
+  stream.next_out = compressed.data();
+  stream.avail_out = compressed.size();
+  stream.next_in = src.data();
+  stream.avail_in = src.size();
+  ret = deflate(&stream, Z_FINISH);
+  ASSERT_EQ(ret, Z_STREAM_END);
+  compressed.resize(compressed.size() - stream.avail_out);
+  deflateEnd(&stream);
+
+  ret = inflateInit2(&stream, /*windowbits*/ -15);
+  ASSERT_EQ(ret, Z_OK);
+  std::vector<uint8_t> decompressed(src.size(), '\0');
+  stream.next_in = compressed.data();
+  stream.avail_in = compressed.size();
+  stream.next_out = decompressed.data();
+  stream.avail_out = decompressed.size();
+  ret = inflate(&stream, Z_FINISH);
+  ASSERT_EQ(ret, Z_STREAM_END);
+  EXPECT_EQ(0U, stream.avail_out);
+  inflateEnd(&stream);
+
+  EXPECT_EQ(src, decompressed);
+}
diff --git a/deflate.c b/deflate.c
index 1597196..e5a69dd 100644
--- a/deflate.c
+++ b/deflate.c
@@ -304,10 +304,9 @@
     s->w_size = 1 << s->w_bits;
     s->w_mask = s->w_size - 1;
 
-    if (x86_cpu_enable_simd) {
+    s->hash_bits = memLevel + 7;
+    if ((x86_cpu_enable_simd || arm_cpu_enable_crc32) && s->hash_bits < 15) {
         s->hash_bits = 15;
-    } else {
-        s->hash_bits = memLevel + 7;
     }
 
     s->hash_size = 1 << s->hash_bits;