summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gilbert <floppym@gentoo.org>2019-05-27 23:59:55 -0400
committerMike Gilbert <floppym@gentoo.org>2019-05-28 00:01:28 -0400
commitf142549e0ec9bb068bbf9160fbeb116eff93770f (patch)
treeee0ee9743b187690c98ebce4d0cf0c015176cd38 /www-client/chromium/files
parentapp-shells/ksh: backport fix for gcc 9 (diff)
downloadgentoo-f142549e0ec9bb068bbf9160fbeb116eff93770f.tar.gz
gentoo-f142549e0ec9bb068bbf9160fbeb116eff93770f.tar.bz2
gentoo-f142549e0ec9bb068bbf9160fbeb116eff93770f.zip
www-client/chromium: bump to 74.0.3729.169
Package-Manager: Portage-2.3.66_p2, Repoman-2.3.12_p111 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
Diffstat (limited to 'www-client/chromium/files')
-rw-r--r--www-client/chromium/files/chromium-74-2f28731.patch483
-rw-r--r--www-client/chromium/files/chromium-74-7685422.patch42
-rw-r--r--www-client/chromium/files/chromium-74-c2c467f.patch75
-rw-r--r--www-client/chromium/files/chromium-74-e1b1f3a.patch587
-rw-r--r--www-client/chromium/files/chromium-compiler-r8.patch169
-rw-r--r--www-client/chromium/files/quiche-00f47df.patch38
6 files changed, 1394 insertions, 0 deletions
diff --git a/www-client/chromium/files/chromium-74-2f28731.patch b/www-client/chromium/files/chromium-74-2f28731.patch
new file mode 100644
index 000000000000..83452619fe06
--- /dev/null
+++ b/www-client/chromium/files/chromium-74-2f28731.patch
@@ -0,0 +1,483 @@
+From 2f28731c17b246bd70075f828dcafcd23547da5d Mon Sep 17 00:00:00 2001
+From: David 'Digit' Turner <digit@google.com>
+Date: Wed, 3 Apr 2019 14:32:09 +0000
+Subject: [PATCH] base: Fix Value layout for GCC
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It turns out that the previous changes to the base::Value
+layout broke GCC compilation (see [1] for details).
+
+This CL fixes the situation by using a new DoubleStorage
+type that will store double values in a 4-byte aligned
+struct, with bit_cast<> being used to convert between
+double and DoubleStorage values in the implementation.
+
+This ensures that base::Value remains as small as possible
+in all cases. The small penalty is that loading/storing
+double values on 32-bit ARM is slightly slower due to
+the fact that the value is no longer 8-byte aligned.
+
++ Fix the ValuesTest.SizeOfValue test to work correctly,
+ and disable it for debug builds, so it doesn't fail
+ because debug versions of the internal containers
+ are larger on certain systems.
+
+[1] https://chromium-review.googlesource.com/c/chromium/src/+/1472716
+
+BUG=646113
+R=dcheng@chromium.org, pasko@chromium.org, lizeb@chromium.org, jdoerrie@chromium.org, jose.dapena@lge.com
+
+Change-Id: I9a365407dc064ba1bdc19859706f4154a495921e
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1550363
+Commit-Queue: David Turner <digit@chromium.org>
+Reviewed-by: Jan Wilken Dörrie <jdoerrie@chromium.org>
+Cr-Commit-Position: refs/heads/master@{#647271}
+---
+ base/values.cc | 67 +++++++++++++---------------
+ base/values.h | 94 ++++++++++------------------------------
+ base/values_unittest.cc | 96 ++++++++++++++++++++++++++++++-----------
+ 3 files changed, 124 insertions(+), 133 deletions(-)
+
+diff --git a/base/values.cc b/base/values.cc
+index 9fed5b52d60e..16d686b0bee5 100644
+--- a/base/values.cc
++++ b/base/values.cc
+@@ -12,6 +12,7 @@
+ #include <ostream>
+ #include <utility>
+
++#include "base/bit_cast.h"
+ #include "base/json/json_writer.h"
+ #include "base/logging.h"
+ #include "base/memory/ptr_util.h"
+@@ -36,6 +37,9 @@ static_assert(std::is_standard_layout<Value>::value,
+ "base::Value should be a standard-layout C++ class in order "
+ "to avoid undefined behaviour in its implementation!");
+
++static_assert(sizeof(Value::DoubleStorage) == sizeof(double),
++ "The double and DoubleStorage types should have the same size");
++
+ namespace {
+
+ const char* const kTypeNames[] = {"null", "boolean", "integer", "double",
+@@ -110,8 +114,6 @@ Value::Value(Value&& that) noexcept {
+ InternalMoveConstructFrom(std::move(that));
+ }
+
+-Value::Value() noexcept : type_(Type::NONE) {}
+-
+ Value::Value(Type type) : type_(type) {
+ // Initialize with the default value.
+ switch (type_) {
+@@ -125,7 +127,7 @@ Value::Value(Type type) : type_(type) {
+ int_value_ = 0;
+ return;
+ case Type::DOUBLE:
+- double_value_ = 0.0;
++ double_value_ = bit_cast<DoubleStorage>(0.0);
+ return;
+ case Type::STRING:
+ new (&string_value_) std::string();
+@@ -149,21 +151,16 @@ Value::Value(Type type) : type_(type) {
+ CHECK(false);
+ }
+
+-Value::Value(bool in_bool)
+- : bool_type_(Type::BOOLEAN),
+- bool_value_(in_bool) {}
++Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {}
+
+-Value::Value(int in_int)
+- : int_type_(Type::INTEGER),
+- int_value_(in_int) {}
++Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {}
+
+ Value::Value(double in_double)
+- : double_type_(Type::DOUBLE),
+- double_value_(in_double) {
+- if (!std::isfinite(double_value_)) {
++ : type_(Type::DOUBLE), double_value_(bit_cast<DoubleStorage>(in_double)) {
++ if (!std::isfinite(in_double)) {
+ NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
+ << "values cannot be represented in JSON";
+- double_value_ = 0.0;
++ double_value_ = bit_cast<DoubleStorage>(0.0);
+ }
+ }
+
+@@ -172,8 +169,7 @@ Value::Value(const char* in_string) : Value(std::string(in_string)) {}
+ Value::Value(StringPiece in_string) : Value(std::string(in_string)) {}
+
+ Value::Value(std::string&& in_string) noexcept
+- : string_type_(Type::STRING),
+- string_value_(std::move(in_string)) {
++ : type_(Type::STRING), string_value_(std::move(in_string)) {
+ DCHECK(IsStringUTF8(string_value_));
+ }
+
+@@ -182,19 +178,15 @@ Value::Value(const char16* in_string16) : Value(StringPiece16(in_string16)) {}
+ Value::Value(StringPiece16 in_string16) : Value(UTF16ToUTF8(in_string16)) {}
+
+ Value::Value(const std::vector<char>& in_blob)
+- : binary_type_(Type::BINARY),
+- binary_value_(in_blob.begin(), in_blob.end()) {}
++ : type_(Type::BINARY), binary_value_(in_blob.begin(), in_blob.end()) {}
+
+ Value::Value(base::span<const uint8_t> in_blob)
+- : binary_type_(Type::BINARY),
+- binary_value_(in_blob.begin(), in_blob.end()) {}
++ : type_(Type::BINARY), binary_value_(in_blob.begin(), in_blob.end()) {}
+
+ Value::Value(BlobStorage&& in_blob) noexcept
+- : binary_type_(Type::BINARY),
+- binary_value_(std::move(in_blob)) {}
++ : type_(Type::BINARY), binary_value_(std::move(in_blob)) {}
+
+-Value::Value(const DictStorage& in_dict)
+- : dict_type_(Type::DICTIONARY), dict_() {
++Value::Value(const DictStorage& in_dict) : type_(Type::DICTIONARY), dict_() {
+ dict_.reserve(in_dict.size());
+ for (const auto& it : in_dict) {
+ dict_.try_emplace(dict_.end(), it.first,
+@@ -203,18 +195,16 @@ Value::Value(const DictStorage& in_dict)
+ }
+
+ Value::Value(DictStorage&& in_dict) noexcept
+- : dict_type_(Type::DICTIONARY),
+- dict_(std::move(in_dict)) {}
++ : type_(Type::DICTIONARY), dict_(std::move(in_dict)) {}
+
+-Value::Value(const ListStorage& in_list) : list_type_(Type::LIST), list_() {
++Value::Value(const ListStorage& in_list) : type_(Type::LIST), list_() {
+ list_.reserve(in_list.size());
+ for (const auto& val : in_list)
+ list_.emplace_back(val.Clone());
+ }
+
+ Value::Value(ListStorage&& in_list) noexcept
+- : list_type_(Type::LIST),
+- list_(std::move(in_list)) {}
++ : type_(Type::LIST), list_(std::move(in_list)) {}
+
+ Value& Value::operator=(Value&& that) noexcept {
+ InternalCleanup();
+@@ -223,6 +213,10 @@ Value& Value::operator=(Value&& that) noexcept {
+ return *this;
+ }
+
++double Value::AsDoubleInternal() const {
++ return bit_cast<double>(double_value_);
++}
++
+ Value Value::Clone() const {
+ switch (type_) {
+ case Type::NONE:
+@@ -232,7 +226,7 @@ Value Value::Clone() const {
+ case Type::INTEGER:
+ return Value(int_value_);
+ case Type::DOUBLE:
+- return Value(double_value_);
++ return Value(AsDoubleInternal());
+ case Type::STRING:
+ return Value(string_value_);
+ case Type::BINARY:
+@@ -277,7 +271,7 @@ int Value::GetInt() const {
+
+ double Value::GetDouble() const {
+ if (is_double())
+- return double_value_;
++ return AsDoubleInternal();
+ if (is_int())
+ return int_value_;
+ CHECK(false);
+@@ -342,9 +336,10 @@ base::Optional<double> Value::FindDoubleKey(StringPiece key) const {
+ const Value* result = FindKey(key);
+ if (result) {
+ if (result->is_int())
+- return base::make_optional(static_cast<double>(result->int_value_));
+- if (result->is_double())
+- return base::make_optional(result->double_value_);
++ return static_cast<double>(result->int_value_);
++ if (result->is_double()) {
++ return result->AsDoubleInternal();
++ }
+ }
+ return base::nullopt;
+ }
+@@ -601,7 +596,7 @@ bool Value::GetAsInteger(int* out_value) const {
+
+ bool Value::GetAsDouble(double* out_value) const {
+ if (out_value && is_double()) {
+- *out_value = double_value_;
++ *out_value = AsDoubleInternal();
+ return true;
+ }
+ if (out_value && is_int()) {
+@@ -696,7 +691,7 @@ bool operator==(const Value& lhs, const Value& rhs) {
+ case Value::Type::INTEGER:
+ return lhs.int_value_ == rhs.int_value_;
+ case Value::Type::DOUBLE:
+- return lhs.double_value_ == rhs.double_value_;
++ return lhs.AsDoubleInternal() == rhs.AsDoubleInternal();
+ case Value::Type::STRING:
+ return lhs.string_value_ == rhs.string_value_;
+ case Value::Type::BINARY:
+@@ -741,7 +736,7 @@ bool operator<(const Value& lhs, const Value& rhs) {
+ case Value::Type::INTEGER:
+ return lhs.int_value_ < rhs.int_value_;
+ case Value::Type::DOUBLE:
+- return lhs.double_value_ < rhs.double_value_;
++ return lhs.AsDoubleInternal() < rhs.AsDoubleInternal();
+ case Value::Type::STRING:
+ return lhs.string_value_ < rhs.string_value_;
+ case Value::Type::BINARY:
+diff --git a/base/values.h b/base/values.h
+index 486fe7ff3976..c455936d4961 100644
+--- a/base/values.h
++++ b/base/values.h
+@@ -83,6 +83,8 @@ class BASE_EXPORT Value {
+ using BlobStorage = std::vector<uint8_t>;
+ using DictStorage = flat_map<std::string, std::unique_ptr<Value>>;
+ using ListStorage = std::vector<Value>;
++ // See technical note below explaining why this is used.
++ using DoubleStorage = struct { alignas(4) char v[sizeof(double)]; };
+
+ enum class Type {
+ NONE = 0,
+@@ -111,7 +113,10 @@ class BASE_EXPORT Value {
+ static std::unique_ptr<Value> ToUniquePtrValue(Value val);
+
+ Value(Value&& that) noexcept;
+- Value() noexcept; // A null value.
++ Value() noexcept {} // A null value
++ // Fun fact: using '= default' above instead of '{}' does not work because
++ // the compiler complains that the default constructor was deleted since
++ // the inner union contains fields with non-default constructors.
+
+ // Value's copy constructor and copy assignment operator are deleted. Use this
+ // to obtain a deep copy explicitly.
+@@ -405,82 +410,29 @@ class BASE_EXPORT Value {
+ size_t EstimateMemoryUsage() const;
+
+ protected:
+- // Technical note:
+- // The naive way to implement a tagged union leads to wasted bytes
+- // in the object on CPUs like ARM ones, which impose an 8-byte alignment
+- // for double values. I.e. if one does something like:
++ // Special case for doubles, which are aligned to 8 bytes on some
++ // 32-bit architectures. In this case, a simple declaration as a
++ // double member would make the whole union 8 byte-aligned, which
++ // would also force 4 bytes of wasted padding space before it in
++ // the Value layout.
+ //
+- // struct TaggedValue {
+- // int type_; // size = 1, align = 4
+- // union {
+- // bool bool_value_; // size = 1, align = 1
+- // int int_value_; // size = 4, align = 4
+- // double double_value_; // size = 8, align = 8
+- // std::string string_value_; // size = 12, align = 4 (32-bit)
+- // };
+- // };
+- //
+- // The end result is that the union will have an alignment of 8, and a size
+- // of 16, due to 4 extra padding bytes following |string_value_| to respect
+- // the alignment requirement.
+- //
+- // As a consequence, the struct TaggedValue will have a size of 24 bytes,
+- // due to the size of the union (16), the size of |type_| (4) and 4 bytes
+- // of padding between |type_| and the union to respect its alignment.
+- //
+- // This means 8 bytes of unused memory per instance on 32-bit ARM!
+- //
+- // To reclaim these, a union of structs is used instead, in order to ensure
+- // that |double_value_| below is always located at an offset that is a
+- // multiple of 8, relative to the start of the overall data structure.
+- //
+- // Each struct must declare its own |type_| field, which must have a different
+- // name, to appease the C++ compiler.
+- //
+- // Using this technique sizeof(base::Value) == 16 on 32-bit ARM instead
+- // of 24, without losing any information. Results are unchanged for x86,
+- // x86_64 and arm64 (16, 32 and 32 bytes respectively).
++ // To override this, store the value as an array of 32-bit integers, and
++ // perform the appropriate bit casts when reading / writing to it.
++ Type type_ = Type::NONE;
++
+ union {
+- struct {
+- // TODO(crbug.com/646113): Make these private once DictionaryValue and
+- // ListValue are properly inlined.
+- Type type_ : 8;
+- };
+- struct {
+- Type bool_type_ : 8;
+- bool bool_value_;
+- };
+- struct {
+- Type int_type_ : 8;
+- int int_value_;
+- };
+- struct {
+- Type double_type_ : 8;
+- // Subtle: On architectures that require it, the compiler will ensure
+- // that |double_value_|'s offset is a multiple of 8 (e.g. 32-bit ARM).
+- // See technical note above to understand why it is important.
+- double double_value_;
+- };
+- struct {
+- Type string_type_ : 8;
+- std::string string_value_;
+- };
+- struct {
+- Type binary_type_ : 8;
+- BlobStorage binary_value_;
+- };
+- struct {
+- Type dict_type_ : 8;
+- DictStorage dict_;
+- };
+- struct {
+- Type list_type_ : 8;
+- ListStorage list_;
+- };
++ bool bool_value_;
++ int int_value_;
++ DoubleStorage double_value_;
++ std::string string_value_;
++ BlobStorage binary_value_;
++ DictStorage dict_;
++ ListStorage list_;
+ };
+
+ private:
+ friend class ValuesTest_SizeOfValue_Test;
++ double AsDoubleInternal() const;
+ void InternalMoveConstructFrom(Value&& that);
+ void InternalCleanup();
+
+diff --git a/base/values_unittest.cc b/base/values_unittest.cc
+index 2dd1c76afaa9..f3536a8612b1 100644
+--- a/base/values_unittest.cc
++++ b/base/values_unittest.cc
+@@ -26,45 +26,89 @@
+
+ namespace base {
+
+-// Test is currently incorrect on Windows x86.
+-#if !defined(OS_WIN) || !defined(ARCH_CPU_X86)
++// Ensure that base::Value is as small as possible, i.e. that there is
++// no wasted space after the inner value due to alignment constraints.
++// Distinguish between the 'header' that includes |type_| and and the inner
++// value that follows it, which can be a bool, int, double, string, blob, list
++// or dict.
++//
++// This test is only enabled when NDEBUG is defined. This way the test will not
++// fail in debug builds that sometimes contain larger versions of the standard
++// containers used inside base::Value.
++#if defined(NDEBUG)
++
++static size_t AlignSizeTo(size_t size, size_t alignment) {
++ EXPECT_TRUE((alignment & (alignment - 1)) == 0)
++ << "Alignment " << alignment << " is not a power of 2!";
++ return (size + (alignment - 1u)) & ~(alignment - 1u);
++}
++
+ TEST(ValuesTest, SizeOfValue) {
+- // Ensure that base::Value is as small as possible, i.e. that there is
+- // no wasted space after the inner value due to alignment constraints.
+- // Distinguish between the 'header' that includes |type_| and and the inner
+- // value that follows it, which can be a bool, int, double, string, blob, list
+- // or dict.
+-#define INNER_TYPES_LIST(X) \
+- X(bool, bool_value_) \
+- X(int, int_value_) \
+- X(double, double_value_) \
+- X(std::string, string_value_) \
+- X(Value::BlobStorage, binary_value_) \
+- X(Value::ListStorage, list_) \
++#define INNER_TYPES_LIST(X) \
++ X(bool, bool_value_) \
++ X(int, int_value_) \
++ X(Value::DoubleStorage, double_value_) \
++ X(std::string, string_value_) \
++ X(Value::BlobStorage, binary_value_) \
++ X(Value::ListStorage, list_) \
+ X(Value::DictStorage, dict_)
+
+-#define INNER_STRUCT_LIMIT(type, value) offsetof(Value, value) + sizeof(type),
++#define INNER_FIELD_ALIGNMENT(type, value) alignof(type),
++
++ // The maximum alignment of each inner struct value field inside base::Value
++ size_t max_inner_value_alignment =
++ std::max({INNER_TYPES_LIST(INNER_FIELD_ALIGNMENT)});
++
++ // Check that base::Value has the smallest alignment possible. This would
++ // fail if the header would contain something that has a larger alignment
++ // than necessary.
++ EXPECT_EQ(max_inner_value_alignment, alignof(Value));
++
++ // Find the offset of each inner value. Which should normally not be
++ // larger than 4. Note that we use std::max(4, ...) because bool_value_
++ // could be stored just after the |bool_type_| field, with an offset of
++ // 1, and that would be ok.
++#define INNER_VALUE_START_OFFSET(type, value) offsetof(Value, value),
++
++ size_t min_inner_value_offset =
++ std::min({INNER_TYPES_LIST(INNER_VALUE_START_OFFSET)});
+
+- // Return the maximum size in bytes of each inner struct inside base::Value
+- size_t max_inner_struct_limit =
+- std::max({INNER_TYPES_LIST(INNER_STRUCT_LIMIT)});
++ // Inner fields may contain pointers, which have an alignment of 8
++ // on most 64-bit platforms.
++ size_t expected_min_offset = alignof(void*);
++
++ EXPECT_EQ(expected_min_offset, min_inner_value_offset);
+
+ // Ensure that base::Value is not larger than necessary, i.e. that there is
+- // no un-necessary padding afte the structs due to alignment constraints of
++ // no un-necessary padding after the structs due to alignment constraints of
+ // one of the inner fields.
+- EXPECT_EQ(max_inner_struct_limit, sizeof(Value));
+- if (max_inner_struct_limit != sizeof(Value)) {
++#define INNER_STRUCT_END_OFFSET(type, value) \
++ offsetof(Value, value) + sizeof(type),
++
++ // The maximum size in bytes of each inner struct inside base::Value,
++ size_t max_inner_struct_end_offset =
++ std::max({INNER_TYPES_LIST(INNER_STRUCT_END_OFFSET)});
++
++ // The expected value size.
++ size_t expected_value_size =
++ AlignSizeTo(max_inner_struct_end_offset, alignof(Value));
++
++ EXPECT_EQ(expected_value_size, sizeof(Value));
++ if (min_inner_value_offset != expected_min_offset ||
++ expected_value_size != sizeof(Value)) {
+ // The following are useful to understand what's wrong when the EXPECT_EQ()
+- // above actually fails.
+-#define PRINT_INNER_FIELD_INFO(x, y) \
+- LOG(INFO) << #y " type=" #x " size=" << sizeof(x) << " align=" << alignof(x);
++ // above actually fail.
++#define PRINT_INNER_FIELD_INFO(x, y) \
++ LOG(INFO) << #y " type=" #x " offset=" << offsetof(Value, y) \
++ << " size=" << sizeof(x) << " align=" << alignof(x);
+
+ LOG(INFO) << "Value size=" << sizeof(Value) << " align=" << alignof(Value);
+ INNER_TYPES_LIST(PRINT_INNER_FIELD_INFO)
+- LOG(INFO) << "max_inner_struct_limit=" << max_inner_struct_limit;
++ LOG(INFO) << "max_inner_struct_end_offset=" << max_inner_struct_end_offset;
+ }
+ }
+-#endif
++
++#endif // NDEBUG
+
+ TEST(ValuesTest, TestNothrow) {
+ static_assert(std::is_nothrow_move_constructible<Value>::value,
+--
+2.21.0
+
diff --git a/www-client/chromium/files/chromium-74-7685422.patch b/www-client/chromium/files/chromium-74-7685422.patch
new file mode 100644
index 000000000000..19747245bd78
--- /dev/null
+++ b/www-client/chromium/files/chromium-74-7685422.patch
@@ -0,0 +1,42 @@
+From 7685422a90e1da829cb32d685a4b970d30738098 Mon Sep 17 00:00:00 2001
+From: Jose Dapena Paz <jose.dapena@lge.com>
+Date: Wed, 3 Apr 2019 18:35:04 +0000
+Subject: [PATCH] base: Value::Type enum class size should be 8-bit.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+GCC is complaining because, when base::Type is used to declare the different
+variants of Type in its union, they are forced to take 8-bit, that is smaller
+than the enum class default size (same as int).
+
+So this change sets explicitely the enum class underlying type to be unsigned
+char.
+
+BUG=chromium:819294
+
+Change-Id: I1765e2503e2c3d3675c73ecb0f7f5bc33456e6f0
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1550366
+Commit-Queue: José Dapena Paz <jose.dapena@lge.com>
+Reviewed-by: Jan Wilken Dörrie <jdoerrie@chromium.org>
+Cr-Commit-Position: refs/heads/master@{#647382}
+---
+ base/values.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/base/values.h b/base/values.h
+index c455936d4961..14b76acec02f 100644
+--- a/base/values.h
++++ b/base/values.h
+@@ -86,7 +86,7 @@ class BASE_EXPORT Value {
+ // See technical note below explaining why this is used.
+ using DoubleStorage = struct { alignas(4) char v[sizeof(double)]; };
+
+- enum class Type {
++ enum class Type : unsigned char {
+ NONE = 0,
+ BOOLEAN,
+ INTEGER,
+--
+2.21.0
+
diff --git a/www-client/chromium/files/chromium-74-c2c467f.patch b/www-client/chromium/files/chromium-74-c2c467f.patch
new file mode 100644
index 000000000000..e9e5d22e4a87
--- /dev/null
+++ b/www-client/chromium/files/chromium-74-c2c467f.patch
@@ -0,0 +1,75 @@
+From c2c467f69fc00d353879d7add5f2c04a6acabbb1 Mon Sep 17 00:00:00 2001
+From: David 'Digit' Turner <digit@google.com>
+Date: Wed, 20 Mar 2019 21:41:09 +0000
+Subject: [PATCH] base: Value::FindDoubleKey() converts integers to doubles
+
+Ensure that FindDoubleKey() can return the value of an
+INTEGER key as a double. This is consistent with the behaviour
+of Value::GetDouble() which will auto-convert INTEGER values
+to doubles.
+
+BUG=646113
+R=dcheng@chromium.org,jdoerrie@chromium.org,sdefresne@chromium.org,hidehiko@chromium.org
+
+Change-Id: I2c08cb91b6cfd5db268a182ffffe16682d848008
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1529017
+Reviewed-by: Sylvain Defresne <sdefresne@chromium.org>
+Reviewed-by: Daniel Cheng <dcheng@chromium.org>
+Commit-Queue: David Turner <digit@chromium.org>
+Cr-Commit-Position: refs/heads/master@{#642680}
+---
+ base/values.cc | 10 ++++++++--
+ base/values.h | 2 ++
+ base/values_unittest.cc | 2 +-
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/base/values.cc b/base/values.cc
+index 035aa2350cde..69d66ff8ab00 100644
+--- a/base/values.cc
++++ b/base/values.cc
+@@ -339,8 +339,14 @@ base::Optional<int> Value::FindIntKey(StringPiece key) const {
+ }
+
+ base::Optional<double> Value::FindDoubleKey(StringPiece key) const {
+- const Value* result = FindKeyOfType(key, Type::DOUBLE);
+- return result ? base::make_optional(result->double_value_) : base::nullopt;
++ const Value* result = FindKey(key);
++ if (result) {
++ if (result->is_int())
++ return base::make_optional(static_cast<double>(result->int_value_));
++ if (result->is_double())
++ return base::make_optional(result->double_value_);
++ }
++ return base::nullopt;
+ }
+
+ const std::string* Value::FindStringKey(StringPiece key) const {
+diff --git a/base/values.h b/base/values.h
+index e31cadd83102..6f2cd3cc3d79 100644
+--- a/base/values.h
++++ b/base/values.h
+@@ -200,6 +200,8 @@ class BASE_EXPORT Value {
+ // function's name.
+ base::Optional<bool> FindBoolKey(StringPiece key) const;
+ base::Optional<int> FindIntKey(StringPiece key) const;
++ // Note FindDoubleKey() will auto-convert INTEGER keys to their double
++ // value, for consistency with GetDouble().
+ base::Optional<double> FindDoubleKey(StringPiece key) const;
+
+ // |FindStringKey| returns |nullptr| if value is not found or not a string.
+diff --git a/base/values_unittest.cc b/base/values_unittest.cc
+index b23fd8332491..7c545c09d947 100644
+--- a/base/values_unittest.cc
++++ b/base/values_unittest.cc
+@@ -674,7 +674,7 @@ TEST(ValuesTest, FindDoubleKey) {
+ const Value dict(std::move(storage));
+ EXPECT_EQ(base::nullopt, dict.FindDoubleKey("null"));
+ EXPECT_EQ(base::nullopt, dict.FindDoubleKey("bool"));
+- EXPECT_EQ(base::nullopt, dict.FindDoubleKey("int"));
++ EXPECT_NE(base::nullopt, dict.FindDoubleKey("int"));
+ EXPECT_NE(base::nullopt, dict.FindDoubleKey("double"));
+ EXPECT_EQ(base::nullopt, dict.FindDoubleKey("string"));
+ EXPECT_EQ(base::nullopt, dict.FindDoubleKey("blob"));
+--
+2.21.0
+
diff --git a/www-client/chromium/files/chromium-74-e1b1f3a.patch b/www-client/chromium/files/chromium-74-e1b1f3a.patch
new file mode 100644
index 000000000000..344b0874b812
--- /dev/null
+++ b/www-client/chromium/files/chromium-74-e1b1f3a.patch
@@ -0,0 +1,587 @@
+From e1b1f3a5f273c8da533fad495b9de316e2c83c9b Mon Sep 17 00:00:00 2001
+From: jdoerrie <jdoerrie@chromium.org>
+Date: Sat, 16 Mar 2019 04:08:01 +0000
+Subject: [PATCH] [base] Add Dead Type to base::Value
+
+This change adds a temporary DEAD type to base::Value which should help
+to track down use-after-free bugs. Furthermore, this change also removes
+the now unneeded is_alive_ flag.
+
+Bug: 859477, 941404
+Change-Id: I9b7a2f3cbb0b22d7e3ed35b2453537419f3f7e55
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1478897
+Reviewed-by: Pavol Marko <pmarko@chromium.org>
+Reviewed-by: Tao Bai <michaelbai@chromium.org>
+Reviewed-by: Thomas Anderson <thomasanderson@chromium.org>
+Reviewed-by: Mike Pinkerton <pinkerton@chromium.org>
+Reviewed-by: Bill Budge <bbudge@chromium.org>
+Reviewed-by: Ken Rockot <rockot@google.com>
+Reviewed-by: Steven Bennetts <stevenjb@chromium.org>
+Reviewed-by: Daniel Cheng <dcheng@chromium.org>
+Reviewed-by: David Turner <digit@chromium.org>
+Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
+Cr-Commit-Position: refs/heads/master@{#641404}
+---
+ base/json/json_writer.cc | 5 ++
+ base/values.cc | 68 ++++++++++++-------
+ base/values.h | 23 ++-----
+ base/values_unittest.cc | 10 ++-
+ .../ui/cocoa/applescript/apple_event_util.mm | 10 +++
+ chromeos/network/onc/variable_expander.cc | 6 ++
+ .../core/browser/android/policy_converter.cc | 11 ++-
+ .../core/common/policy_loader_win_unittest.cc | 8 ++-
+ .../policy/core/common/policy_test_utils.cc | 5 ++
+ .../policy/core/common/registry_dict.cc | 4 ++
+ .../gin_java_script_to_java_types_coercion.cc | 8 ++-
+ ipc/ipc_message_utils.cc | 11 ++-
+ mojo/public/cpp/base/values_mojom_traits.h | 7 +-
+ .../ppb_x509_certificate_private_shared.cc | 2 +
+ 14 files changed, 127 insertions(+), 51 deletions(-)
+
+diff --git a/base/json/json_writer.cc b/base/json/json_writer.cc
+index 376a459f9a46..cd020e7fa0c0 100644
+--- a/base/json/json_writer.cc
++++ b/base/json/json_writer.cc
+@@ -179,6 +179,11 @@ bool JSONWriter::BuildJSONString(const Value& node, size_t depth) {
+ // Successful only if we're allowed to omit it.
+ DLOG_IF(ERROR, !omit_binary_values_) << "Cannot serialize binary value.";
+ return omit_binary_values_;
++
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case Value::Type::DEAD:
++ CHECK(false);
++ return false;
+ }
+
+ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+diff --git a/base/values.cc b/base/values.cc
+index 0c002551b317..035aa2350cde 100644
+--- a/base/values.cc
++++ b/base/values.cc
+@@ -90,8 +90,6 @@ std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) {
+
+ } // namespace
+
+-constexpr uint16_t Value::kMagicIsAlive;
+-
+ // static
+ std::unique_ptr<Value> Value::CreateWithCopiedBuffer(const char* buffer,
+ size_t size) {
+@@ -112,9 +110,9 @@ Value::Value(Value&& that) noexcept {
+ InternalMoveConstructFrom(std::move(that));
+ }
+
+-Value::Value() noexcept : type_(Type::NONE), is_alive_(kMagicIsAlive) {}
++Value::Value() noexcept : type_(Type::NONE) {}
+
+-Value::Value(Type type) : type_(type), is_alive_(kMagicIsAlive) {
++Value::Value(Type type) : type_(type) {
+ // Initialize with the default value.
+ switch (type_) {
+ case Type::NONE:
+@@ -141,22 +139,26 @@ Value::Value(Type type) : type_(type), is_alive_(kMagicIsAlive) {
+ case Type::LIST:
+ new (&list_) ListStorage();
+ return;
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case Type::DEAD:
++ CHECK(false);
++ return;
+ }
++
++ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
++ CHECK(false);
+ }
+
+ Value::Value(bool in_bool)
+ : bool_type_(Type::BOOLEAN),
+- bool_is_alive_(kMagicIsAlive),
+ bool_value_(in_bool) {}
+
+ Value::Value(int in_int)
+ : int_type_(Type::INTEGER),
+- int_is_alive_(kMagicIsAlive),
+ int_value_(in_int) {}
+
+ Value::Value(double in_double)
+ : double_type_(Type::DOUBLE),
+- double_is_alive_(kMagicIsAlive),
+ double_value_(in_double) {
+ if (!std::isfinite(double_value_)) {
+ NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
+@@ -171,7 +173,6 @@ Value::Value(StringPiece in_string) : Value(std::string(in_string)) {}
+
+ Value::Value(std::string&& in_string) noexcept
+ : string_type_(Type::STRING),
+- string_is_alive_(kMagicIsAlive),
+ string_value_(std::move(in_string)) {
+ DCHECK(IsStringUTF8(string_value_));
+ }
+@@ -182,21 +183,18 @@ Value::Value(StringPiece16 in_string16) : Value(UTF16ToUTF8(in_string16)) {}
+
+ Value::Value(const std::vector<char>& in_blob)
+ : binary_type_(Type::BINARY),
+- binary_is_alive_(kMagicIsAlive),
+ binary_value_(in_blob.begin(), in_blob.end()) {}
+
+ Value::Value(base::span<const uint8_t> in_blob)
+ : binary_type_(Type::BINARY),
+- binary_is_alive_(kMagicIsAlive),
+ binary_value_(in_blob.begin(), in_blob.end()) {}
+
+ Value::Value(BlobStorage&& in_blob) noexcept
+ : binary_type_(Type::BINARY),
+- binary_is_alive_(kMagicIsAlive),
+ binary_value_(std::move(in_blob)) {}
+
+ Value::Value(const DictStorage& in_dict)
+- : dict_type_(Type::DICTIONARY), dict_is_alive_(kMagicIsAlive), dict_() {
++ : dict_type_(Type::DICTIONARY), dict_() {
+ dict_.reserve(in_dict.size());
+ for (const auto& it : in_dict) {
+ dict_.try_emplace(dict_.end(), it.first,
+@@ -206,11 +204,9 @@ Value::Value(const DictStorage& in_dict)
+
+ Value::Value(DictStorage&& in_dict) noexcept
+ : dict_type_(Type::DICTIONARY),
+- dict_is_alive_(kMagicIsAlive),
+ dict_(std::move(in_dict)) {}
+
+-Value::Value(const ListStorage& in_list)
+- : list_type_(Type::LIST), list_is_alive_(kMagicIsAlive), list_() {
++Value::Value(const ListStorage& in_list) : list_type_(Type::LIST), list_() {
+ list_.reserve(in_list.size());
+ for (const auto& val : in_list)
+ list_.emplace_back(val.Clone());
+@@ -218,7 +214,6 @@ Value::Value(const ListStorage& in_list)
+
+ Value::Value(ListStorage&& in_list) noexcept
+ : list_type_(Type::LIST),
+- list_is_alive_(kMagicIsAlive),
+ list_(std::move(in_list)) {}
+
+ Value& Value::operator=(Value&& that) noexcept {
+@@ -246,15 +241,21 @@ Value Value::Clone() const {
+ return Value(dict_);
+ case Type::LIST:
+ return Value(list_);
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case Type::DEAD:
++ CHECK(false);
++ return Value();
+ }
+
+- NOTREACHED();
++ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
++ CHECK(false);
+ return Value();
+ }
+
+ Value::~Value() {
+ InternalCleanup();
+- is_alive_ = 0;
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ type_ = Type::DEAD;
+ }
+
+ // static
+@@ -654,9 +655,14 @@ bool operator==(const Value& lhs, const Value& rhs) {
+ });
+ case Value::Type::LIST:
+ return lhs.list_ == rhs.list_;
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case Value::Type::DEAD:
++ CHECK(false);
++ return false;
+ }
+
+- NOTREACHED();
++ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
++ CHECK(false);
+ return false;
+ }
+
+@@ -693,9 +699,14 @@ bool operator<(const Value& lhs, const Value& rhs) {
+ });
+ case Value::Type::LIST:
+ return lhs.list_ < rhs.list_;
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case Value::Type::DEAD:
++ CHECK(false);
++ return false;
+ }
+
+- NOTREACHED();
++ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
++ CHECK(false);
+ return false;
+ }
+
+@@ -733,7 +744,6 @@ size_t Value::EstimateMemoryUsage() const {
+
+ void Value::InternalMoveConstructFrom(Value&& that) {
+ type_ = that.type_;
+- is_alive_ = that.is_alive_;
+
+ switch (type_) {
+ case Type::NONE:
+@@ -759,12 +769,17 @@ void Value::InternalMoveConstructFrom(Value&& that) {
+ case Type::LIST:
+ new (&list_) ListStorage(std::move(that.list_));
+ return;
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case Type::DEAD:
++ CHECK(false);
++ return;
+ }
++
++ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
++ CHECK(false);
+ }
+
+ void Value::InternalCleanup() {
+- CHECK_EQ(is_alive_, kMagicIsAlive);
+-
+ switch (type_) {
+ case Type::NONE:
+ case Type::BOOLEAN:
+@@ -785,7 +800,14 @@ void Value::InternalCleanup() {
+ case Type::LIST:
+ list_.~ListStorage();
+ return;
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case Type::DEAD:
++ CHECK(false);
++ return;
+ }
++
++ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
++ CHECK(false);
+ }
+
+ ///////////////////// DictionaryValue ////////////////////
+diff --git a/base/values.h b/base/values.h
+index 429ef1dfdebd..e31cadd83102 100644
+--- a/base/values.h
++++ b/base/values.h
+@@ -92,7 +92,9 @@ class BASE_EXPORT Value {
+ STRING,
+ BINARY,
+ DICTIONARY,
+- LIST
++ LIST,
++ // TODO(crbug.com/859477): Remove once root cause is found.
++ DEAD
+ // Note: Do not add more types. See the file-level comment above for why.
+ };
+
+@@ -375,10 +377,6 @@ class BASE_EXPORT Value {
+ size_t EstimateMemoryUsage() const;
+
+ protected:
+- // Magic IsAlive signature to debug double frees.
+- // TODO(crbug.com/859477): Remove once root cause is found.
+- static constexpr uint16_t kMagicIsAlive = 0x2f19;
+-
+ // Technical note:
+ // The naive way to implement a tagged union leads to wasted bytes
+ // in the object on CPUs like ARM ones, which impose an 8-byte alignment
+@@ -408,8 +406,8 @@ class BASE_EXPORT Value {
+ // that |double_value_| below is always located at an offset that is a
+ // multiple of 8, relative to the start of the overall data structure.
+ //
+- // Each struct must declare its own |type_| and |is_alive_| field, which
+- // must have a different name, to appease the C++ compiler.
++ // Each struct must declare its own |type_| field, which must have a different
++ // name, to appease the C++ compiler.
+ //
+ // Using this technique sizeof(base::Value) == 16 on 32-bit ARM instead
+ // of 24, without losing any information. Results are unchanged for x86,
+@@ -419,24 +417,17 @@ class BASE_EXPORT Value {
+ // TODO(crbug.com/646113): Make these private once DictionaryValue and
+ // ListValue are properly inlined.
+ Type type_ : 8;
+-
+- // IsAlive member to debug double frees.
+- // TODO(crbug.com/859477): Remove once root cause is found.
+- uint16_t is_alive_ = kMagicIsAlive;
+ };
+ struct {
+ Type bool_type_ : 8;
+- uint16_t bool_is_alive_;
+ bool bool_value_;
+ };
+ struct {
+ Type int_type_ : 8;
+- uint16_t int_is_alive_;
+ int int_value_;
+ };
+ struct {
+ Type double_type_ : 8;
+- uint16_t double_is_alive_;
+ // Subtle: On architectures that require it, the compiler will ensure
+ // that |double_value_|'s offset is a multiple of 8 (e.g. 32-bit ARM).
+ // See technical note above to understand why it is important.
+@@ -444,22 +435,18 @@ class BASE_EXPORT Value {
+ };
+ struct {
+ Type string_type_ : 8;
+- uint16_t string_is_alive_;
+ std::string string_value_;
+ };
+ struct {
+ Type binary_type_ : 8;
+- uint16_t binary_is_alive_;
+ BlobStorage binary_value_;
+ };
+ struct {
+ Type dict_type_ : 8;
+- uint16_t dict_is_alive_;
+ DictStorage dict_;
+ };
+ struct {
+ Type list_type_ : 8;
+- uint16_t list_is_alive_;
+ ListStorage list_;
+ };
+ };
+diff --git a/base/values_unittest.cc b/base/values_unittest.cc
+index 0a641bcc7ef4..b23fd8332491 100644
+--- a/base/values_unittest.cc
++++ b/base/values_unittest.cc
+@@ -20,17 +20,20 @@
+ #include "base/strings/string16.h"
+ #include "base/strings/string_piece.h"
+ #include "base/strings/utf_string_conversions.h"
++#include "build/build_config.h"
+ #include "testing/gmock/include/gmock/gmock.h"
+ #include "testing/gtest/include/gtest/gtest.h"
+
+ namespace base {
+
++// Test is currently incorrect on Windows x86.
++#if !defined(OS_WIN) || !defined(ARCH_CPU_X86)
+ TEST(ValuesTest, SizeOfValue) {
+ // Ensure that base::Value is as small as possible, i.e. that there is
+ // no wasted space after the inner value due to alignment constraints.
+- // Distinguish between the 'header' that includes |type_| and |is_alive_|
+- // and the inner value that follows it, which can be a bool, int, double,
+- // string, blob, list or dict.
++ // Distinguish between the 'header' that includes |type_| and and the inner
++ // value that follows it, which can be a bool, int, double, string, blob, list
++ // or dict.
+ #define INNER_TYPES_LIST(X) \
+ X(bool, bool_value_) \
+ X(int, int_value_) \
+@@ -61,6 +64,7 @@ TEST(ValuesTest, SizeOfValue) {
+ LOG(INFO) << "max_inner_struct_limit=" << max_inner_struct_limit;
+ }
+ }
++#endif
+
+ TEST(ValuesTest, TestNothrow) {
+ static_assert(std::is_nothrow_move_constructible<Value>::value,
+diff --git a/chrome/browser/ui/cocoa/applescript/apple_event_util.mm b/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
+index 16d685607ced..25a59338ee73 100644
+--- a/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
++++ b/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
+@@ -96,6 +96,16 @@ NSAppleEventDescriptor* ValueToAppleEventDescriptor(const base::Value* value) {
+ }
+ break;
+ }
++
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case base::Value::Type::DEAD:
++ CHECK(false);
++ break;
++
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ default:
++ CHECK(false);
++ break;
+ }
+
+ return descriptor;
+diff --git a/chromeos/network/onc/variable_expander.cc b/chromeos/network/onc/variable_expander.cc
+index fd72752c2aa6..cd5bbb238eb3 100644
+--- a/chromeos/network/onc/variable_expander.cc
++++ b/chromeos/network/onc/variable_expander.cc
+@@ -145,6 +145,12 @@ bool VariableExpander::ExpandValue(base::Value* value) const {
+ // Nothing to do here.
+ break;
+ }
++
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case base::Value::Type::DEAD: {
++ CHECK(false);
++ break;
++ }
+ }
+ return no_error;
+ }
+diff --git a/components/policy/core/browser/android/policy_converter.cc b/components/policy/core/browser/android/policy_converter.cc
+index b711a64febc9..9d41ad0d1507 100644
+--- a/components/policy/core/browser/android/policy_converter.cc
++++ b/components/policy/core/browser/android/policy_converter.cc
+@@ -175,10 +175,17 @@ std::unique_ptr<base::Value> PolicyConverter::ConvertValueToSchema(
+ }
+ return value;
+ }
++
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case base::Value::Type::DEAD: {
++ CHECK(false);
++ return nullptr;
++ }
+ }
+
+- NOTREACHED();
+- return std::unique_ptr<base::Value>();
++ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
++ CHECK(false);
++ return nullptr;
+ }
+
+ void PolicyConverter::SetPolicyValue(const std::string& key,
+diff --git a/components/policy/core/common/policy_loader_win_unittest.cc b/components/policy/core/common/policy_loader_win_unittest.cc
+index 311e7fb122fc..0377307c5e28 100644
+--- a/components/policy/core/common/policy_loader_win_unittest.cc
++++ b/components/policy/core/common/policy_loader_win_unittest.cc
+@@ -133,8 +133,14 @@ bool InstallValue(const base::Value& value,
+
+ case base::Value::Type::BINARY:
+ return false;
++
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case base::Value::Type::DEAD:
++ CHECK(false);
++ return false;
+ }
+- NOTREACHED();
++ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
++ CHECK(false);
+ return false;
+ }
+
+diff --git a/components/policy/core/common/policy_test_utils.cc b/components/policy/core/common/policy_test_utils.cc
+index 5af98b47275c..919f004153ec 100644
+--- a/components/policy/core/common/policy_test_utils.cc
++++ b/components/policy/core/common/policy_test_utils.cc
+@@ -137,6 +137,11 @@ CFPropertyListRef ValueToProperty(const base::Value& value) {
+ // because there's no equivalent JSON type, and policy values can only
+ // take valid JSON values.
+ break;
++
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case base::Value::Type::DEAD:
++ CHECK(false);
++ break;
+ }
+
+ return NULL;
+diff --git a/components/policy/core/common/registry_dict.cc b/components/policy/core/common/registry_dict.cc
+index f3ed372bdcb3..696ba7e04abe 100644
+--- a/components/policy/core/common/registry_dict.cc
++++ b/components/policy/core/common/registry_dict.cc
+@@ -135,6 +135,10 @@ std::unique_ptr<base::Value> ConvertRegistryValue(const base::Value& value,
+ case base::Value::Type::BINARY:
+ // No conversion possible.
+ break;
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case base::Value::Type::DEAD:
++ CHECK(false);
++ return nullptr;
+ }
+
+ LOG(WARNING) << "Failed to convert " << value.type() << " to "
+diff --git a/content/browser/android/java/gin_java_script_to_java_types_coercion.cc b/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
+index dabd66ba8c72..84fd5489a414 100644
+--- a/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
++++ b/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
+@@ -722,8 +722,14 @@ jvalue CoerceJavaScriptValueToJavaValue(JNIEnv* env,
+ case base::Value::Type::BINARY:
+ return CoerceGinJavaBridgeValueToJavaValue(
+ env, value, target_type, coerce_to_string, object_refs, error);
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case base::Value::Type::DEAD:
++ CHECK(false);
++ return jvalue();
+ }
+- NOTREACHED();
++
++ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
++ CHECK(false);
+ return jvalue();
+ }
+
+diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
+index ec04c77c6c18..df6ec39bd663 100644
+--- a/ipc/ipc_message_utils.cc
++++ b/ipc/ipc_message_utils.cc
+@@ -92,7 +92,7 @@ void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
+
+ switch (value->type()) {
+ case base::Value::Type::NONE:
+- break;
++ break;
+ case base::Value::Type::BOOLEAN: {
+ bool val;
+ result = value->GetAsBoolean(&val);
+@@ -147,6 +147,11 @@ void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
+ }
+ break;
+ }
++
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ default:
++ CHECK(false);
++ break;
+ }
+ }
+
+@@ -260,7 +265,9 @@ bool ReadValue(const base::Pickle* m,
+ break;
+ }
+ default:
+- return false;
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ CHECK(false);
++ return false;
+ }
+
+ return true;
+diff --git a/mojo/public/cpp/base/values_mojom_traits.h b/mojo/public/cpp/base/values_mojom_traits.h
+index cdb9bbbd94df..66752b7c90d8 100644
+--- a/mojo/public/cpp/base/values_mojom_traits.h
++++ b/mojo/public/cpp/base/values_mojom_traits.h
+@@ -86,8 +86,13 @@ struct COMPONENT_EXPORT(MOJO_BASE_SHARED_TRAITS)
+ return mojo_base::mojom::ValueDataView::Tag::DICTIONARY_VALUE;
+ case base::Value::Type::LIST:
+ return mojo_base::mojom::ValueDataView::Tag::LIST_VALUE;
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case base::Value::Type::DEAD:
++ CHECK(false);
++ return mojo_base::mojom::ValueDataView::Tag::NULL_VALUE;
+ }
+- NOTREACHED();
++ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
++ CHECK(false);
+ return mojo_base::mojom::ValueDataView::Tag::NULL_VALUE;
+ }
+
+diff --git a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
+index 6ffff36337e0..7f392d50f718 100644
+--- a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
++++ b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
+@@ -73,6 +73,8 @@ PP_Var PPB_X509Certificate_Fields::GetFieldAsPPVar(
+ }
+ case base::Value::Type::DICTIONARY:
+ case base::Value::Type::LIST:
++ // TODO(crbug.com/859477): Remove after root cause is found.
++ case base::Value::Type::DEAD:
+ // Not handled.
+ break;
+ }
+--
+2.21.0
+
diff --git a/www-client/chromium/files/chromium-compiler-r8.patch b/www-client/chromium/files/chromium-compiler-r8.patch
new file mode 100644
index 000000000000..5d8bd0efecd5
--- /dev/null
+++ b/www-client/chromium/files/chromium-compiler-r8.patch
@@ -0,0 +1,169 @@
+From aff4a3a1c35dc37141a61d2c6b7e703a55f9b371 Mon Sep 17 00:00:00 2001
+From: Mike Gilbert <floppym@gentoo.org>
+Date: Sat, 23 Mar 2019 12:12:37 -0400
+Subject: [PATCH] Disable various compiler configs
+
+---
+ build/config/compiler/BUILD.gn | 55 ++++++++++++----------------------
+ 1 file changed, 19 insertions(+), 36 deletions(-)
+
+diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
+index ca6ff2b13809..b614709cd1db 100644
+--- a/build/config/compiler/BUILD.gn
++++ b/build/config/compiler/BUILD.gn
+@@ -240,8 +240,6 @@ config("compiler") {
+
+ configs += [
+ # See the definitions below.
+- ":clang_revision",
+- ":compiler_cpu_abi",
+ ":compiler_codegen",
+ ":compiler_deterministic",
+ ]
+@@ -489,17 +487,6 @@ config("compiler") {
+ }
+ }
+
+- if (is_clang && !is_nacl && !use_xcode_clang) {
+- cflags += [
+- # TODO(hans): Remove this once Clang generates better optimized debug info
+- # by default. https://crbug.com/765793
+- "-Xclang",
+- "-mllvm",
+- "-Xclang",
+- "-instcombine-lower-dbg-declare=0",
+- ]
+- }
+-
+ # Print absolute paths in diagnostics. There is no precedent for doing this
+ # on Linux/Mac (GCC doesn't support it), but MSVC does this with /FC and
+ # Windows developers rely on it (crbug.com/636109) so only do this on Windows.
+@@ -1540,7 +1527,7 @@ config("chromium_code") {
+ defines = [ "_HAS_NODISCARD" ]
+ }
+ } else {
+- cflags = [ "-Wall" ]
++ cflags = []
+ if (treat_warnings_as_errors) {
+ cflags += [ "-Werror" ]
+
+@@ -1549,10 +1536,6 @@ config("chromium_code") {
+ # well.
+ ldflags = [ "-Werror" ]
+ }
+- if (is_clang) {
+- # Enable extra warnings for chromium_code when we control the compiler.
+- cflags += [ "-Wextra" ]
+- }
+
+ # In Chromium code, we define __STDC_foo_MACROS in order to get the
+ # C99 macros on Mac and Linux.
+@@ -1561,15 +1544,6 @@ config("chromium_code") {
+ "__STDC_FORMAT_MACROS",
+ ]
+
+- if (!is_debug && !using_sanitizer && current_cpu != "s390x" &&
+- current_cpu != "s390" && current_cpu != "ppc64" &&
+- current_cpu != "mips" && current_cpu != "mips64") {
+- # Non-chromium code is not guaranteed to compile cleanly with
+- # _FORTIFY_SOURCE. Also, fortified build may fail when optimizations are
+- # disabled, so only do that for Release build.
+- defines += [ "_FORTIFY_SOURCE=2" ]
+- }
+-
+ if (is_mac) {
+ cflags_objc = [ "-Wobjc-missing-property-synthesis" ]
+ cflags_objcc = [ "-Wobjc-missing-property-synthesis" ]
+@@ -1949,7 +1923,8 @@ config("default_stack_frames") {
+ }
+
+ # Default "optimization on" config.
+-config("optimize") {
++config("optimize") { }
++config("xoptimize") {
+ if (is_win) {
+ # TODO(thakis): Remove is_clang here, https://crbug.com/598772
+ if (is_official_build && full_wpo_on_official && !is_clang) {
+@@ -1983,7 +1958,8 @@ config("optimize") {
+ }
+
+ # Same config as 'optimize' but without the WPO flag.
+-config("optimize_no_wpo") {
++config("optimize_no_wpo") { }
++config("xoptimize_no_wpo") {
+ if (is_win) {
+ # Favor size over speed, /O1 must be before the common flags. The GYP
+ # build also specifies /Os and /GF but these are implied by /O1.
+@@ -2006,7 +1982,8 @@ config("optimize_no_wpo") {
+ }
+
+ # Turn off optimizations.
+-config("no_optimize") {
++config("no_optimize") { }
++config("xno_optimize") {
+ if (is_win) {
+ cflags = [
+ "/Od", # Disable optimization.
+@@ -2034,7 +2011,8 @@ config("no_optimize") {
+ # Turns up the optimization level. On Windows, this implies whole program
+ # optimization and link-time code generation which is very expensive and should
+ # be used sparingly.
+-config("optimize_max") {
++config("optimize_max") { }
++config("xoptimize_max") {
+ if (is_nacl && is_nacl_irt) {
+ # The NaCl IRT is a special case and always wants its own config.
+ # Various components do:
+@@ -2081,7 +2059,8 @@ config("optimize_max") {
+ #
+ # TODO(crbug.com/621335) - rework how all of these configs are related
+ # so that we don't need this disclaimer.
+-config("optimize_speed") {
++config("optimize_speed") { }
++config("xoptimize_speed") {
+ if (is_nacl && is_nacl_irt) {
+ # The NaCl IRT is a special case and always wants its own config.
+ # Various components do:
+@@ -2119,7 +2098,8 @@ config("optimize_speed") {
+ }
+ }
+
+-config("optimize_fuzzing") {
++config("optimize_fuzzing") { }
++config("xoptimize_fuzzing") {
+ cflags = [ "-O1" ] + common_optimize_on_cflags
+ ldflags = common_optimize_on_ldflags
+ visibility = [ ":default_optimization" ]
+@@ -2221,7 +2201,8 @@ config("win_pdbaltpath") {
+ }
+
+ # Full symbols.
+-config("symbols") {
++config("symbols") { }
++config("xsymbols") {
+ if (is_win) {
+ if (use_goma || is_clang) {
+ # Note that with VC++ this requires is_win_fastlink, enforced elsewhere.
+@@ -2328,7 +2309,8 @@ config("symbols") {
+ # Minimal symbols.
+ # This config guarantees to hold symbol for stack trace which are shown to user
+ # when crash happens in unittests running on buildbot.
+-config("minimal_symbols") {
++config("minimal_symbols") { }
++config("xminimal_symbols") {
+ if (is_win) {
+ # Linker symbols for backtraces only.
+ cflags = []
+@@ -2380,7 +2362,8 @@ config("minimal_symbols") {
+ }
+
+ # No symbols.
+-config("no_symbols") {
++config("no_symbols") { }
++config("xno_symbols") {
+ if (!is_win) {
+ cflags = [ "-g0" ]
+ asmflags = cflags
+--
+2.21.0
+
diff --git a/www-client/chromium/files/quiche-00f47df.patch b/www-client/chromium/files/quiche-00f47df.patch
new file mode 100644
index 000000000000..720edf934d30
--- /dev/null
+++ b/www-client/chromium/files/quiche-00f47df.patch
@@ -0,0 +1,38 @@
+From 00f47df999c9b19e80fdc01db0ae9ca1b6a12b3a Mon Sep 17 00:00:00 2001
+From: vasilvv <vasilvv@google.com>
+Date: Wed, 3 Apr 2019 13:58:53 -0700
+Subject: [PATCH] GCC: do not delete move constructor of QuicStreamSendBuffer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+QuicStreamSendBuffer constructor is implicitely required in the
+initialization of the vector of substreams in QuicCryptoStream.
+Though clang apparently ignores that, GCC fails to build.
+
+BUG=chromium:819294
+
+Originally submitted by José Dapena Paz <jose.dapena@lge.com> at https://quiche-review.googlesource.com/c/quiche/+/2420
+
+PiperOrigin-RevId: 241800134
+Change-Id: I4e3c97d6e5895d85340e8c1b740e6196d9104066
+---
+ quic/core/quic_stream_send_buffer.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/quic/core/quic_stream_send_buffer.h b/quic/core/quic_stream_send_buffer.h
+index e34514b..74e9d0d 100644
+--- a/net/third_party/quic/core/quic_stream_send_buffer.h
++++ b/net/third_party/quic/core/quic_stream_send_buffer.h
+@@ -62,7 +62,7 @@ class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
+ public:
+ explicit QuicStreamSendBuffer(QuicBufferAllocator* allocator);
+ QuicStreamSendBuffer(const QuicStreamSendBuffer& other) = delete;
+- QuicStreamSendBuffer(QuicStreamSendBuffer&& other) = delete;
++ QuicStreamSendBuffer(QuicStreamSendBuffer&& other) = default;
+ ~QuicStreamSendBuffer();
+
+ // Save |data_length| of data starts at |iov_offset| in |iov| to send buffer.
+--
+2.21.0
+