diff --git a/DEPS b/DEPS index 4d9810f..fb23eca 100644 --- a/DEPS +++ b/DEPS
@@ -39,7 +39,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '6950de6c4166fabb35e6c756fc009e0cf1c47819', + 'skia_revision': 'f514eae53227bcd9f5125cd4479942644f0d4c84', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other.
diff --git a/base/trace_event/malloc_dump_provider.h b/base/trace_event/malloc_dump_provider.h index f463d0a6..63fc1b0 100644 --- a/base/trace_event/malloc_dump_provider.h +++ b/base/trace_event/malloc_dump_provider.h
@@ -13,8 +13,8 @@ #include "build/build_config.h" #if defined(OS_LINUX) || defined(OS_ANDROID) || \ - (defined(OS_MACOXS) && !defined(OS_IOS)) -#define SUPPORTS_MALLOC_MEMORY_TRACING + (defined(OS_MACOSX) && !defined(OS_IOS)) +#define MALLOC_MEMORY_TRACING_SUPPORTED #endif namespace base {
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index 43c784b..19bdcc4 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -96,7 +96,7 @@ // static const char* const MemoryDumpManager::kSystemAllocatorPoolName = -#if defined(SUPPORTS_MALLOC_MEMORY_TRACING) +#if defined(MALLOC_MEMORY_TRACING_SUPPORTED) MallocDumpProvider::kAllocatedObjects; #elif defined(OS_WIN) WinHeapDumpProvider::kAllocatedObjects; @@ -155,7 +155,7 @@ "ProcessMemoryTotals", nullptr); #endif -#if defined(SUPPORTS_MALLOC_MEMORY_TRACING) +#if defined(MALLOC_MEMORY_TRACING_SUPPORTED) RegisterDumpProvider(MallocDumpProvider::GetInstance(), "Malloc", nullptr); #endif
diff --git a/chrome/VERSION b/chrome/VERSION index dce00fe8..636f02d4 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=48 MINOR=0 -BUILD=2558 +BUILD=2559 PATCH=0
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 4fe43d0de..03056240 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -7618.0.0 \ No newline at end of file +7621.0.0 \ No newline at end of file
diff --git a/net/cert/ct_log_response_parser.cc b/net/cert/ct_log_response_parser.cc index 0069fc70..0c006cc 100644 --- a/net/cert/ct_log_response_parser.cc +++ b/net/cert/ct_log_response_parser.cc
@@ -7,6 +7,7 @@ #include "base/base64.h" #include "base/json/json_value_converter.h" #include "base/logging.h" +#include "base/memory/scoped_vector.h" #include "base/strings/string_piece.h" #include "base/time/time.h" #include "base/values.h" @@ -101,6 +102,33 @@ return true; } +// Structure for making JSON decoding easier. The string fields +// are base64-encoded so will require further decoding. +struct JsonConsistencyProof { + ScopedVector<std::string> proof_nodes; + + static void RegisterJSONConverter( + base::JSONValueConverter<JsonConsistencyProof>* converter); +}; + +bool ConvertIndividualProofNode(const base::Value* value, std::string* result) { + std::string b64_encoded_node; + if (!value->GetAsString(&b64_encoded_node)) + return false; + + if (!ConvertSHA256RootHash(b64_encoded_node, result)) + return false; + + return true; +} + +void JsonConsistencyProof::RegisterJSONConverter( + base::JSONValueConverter<JsonConsistencyProof>* converter) { + converter->RegisterRepeatedCustomValue<std::string>( + "consistency", &JsonConsistencyProof::proof_nodes, + &ConvertIndividualProofNode); +} + } // namespace bool FillSignedTreeHead(const base::Value& json_signed_tree_head, @@ -127,6 +155,23 @@ return true; } +bool FillConsistencyProof(const base::Value& json_consistency_proof, + std::vector<std::string>* consistency_proof) { + JsonConsistencyProof parsed_proof; + base::JSONValueConverter<JsonConsistencyProof> converter; + if (!converter.Convert(json_consistency_proof, &parsed_proof)) { + DVLOG(1) << "Invalid consistency proof."; + return false; + } + + consistency_proof->reserve(parsed_proof.proof_nodes.size()); + for (std::string* proof_node : parsed_proof.proof_nodes) { + consistency_proof->push_back(*proof_node); + } + + return true; +} + } // namespace ct } // namespace net
diff --git a/net/cert/ct_log_response_parser.h b/net/cert/ct_log_response_parser.h index b7a012b..403f8bfb 100644 --- a/net/cert/ct_log_response_parser.h +++ b/net/cert/ct_log_response_parser.h
@@ -5,6 +5,9 @@ #ifndef NET_CERT_CT_LOG_RESPONSE_PARSER_H_ #define NET_CERT_CT_LOG_RESPONSE_PARSER_H_ +#include <string> +#include <vector> + #include "base/strings/string_piece.h" #include "net/base/net_export.h" @@ -24,6 +27,10 @@ NET_EXPORT bool FillSignedTreeHead(const base::Value& json_signed_tree_head, SignedTreeHead* signed_tree_head); +NET_EXPORT bool FillConsistencyProof( + const base::Value& json_signed_tree_head, + std::vector<std::string>* consistency_proof); + } // namespace ct } // namespace net
diff --git a/net/cert/ct_log_response_parser_unittest.cc b/net/cert/ct_log_response_parser_unittest.cc index 9f02699..d2c192e7 100644 --- a/net/cert/ct_log_response_parser_unittest.cc +++ b/net/cert/ct_log_response_parser_unittest.cc
@@ -95,6 +95,47 @@ ASSERT_FALSE(FillSignedTreeHead(*too_short_hash_json.get(), &tree_head)); } +TEST(CTLogResponseParserTest, ParsesConsistencyProofSuccessfully) { + std::string first(32, 'a'); + std::string second(32, 'b'); + std::string third(32, 'c'); + + std::vector<std::string> raw_nodes; + raw_nodes.push_back(first); + raw_nodes.push_back(second); + raw_nodes.push_back(third); + scoped_ptr<base::Value> sample_consistency_proof = + ParseJson(CreateConsistencyProofJsonString(raw_nodes)); + + std::vector<std::string> output; + + ASSERT_TRUE(FillConsistencyProof(*sample_consistency_proof.get(), &output)); + + EXPECT_EQ(output[0], first); + EXPECT_EQ(output[1], second); + EXPECT_EQ(output[2], third); +} + +TEST(CTLogResponseParserTest, FailsOnInvalidProofJson) { + std::vector<std::string> output; + + scoped_ptr<base::Value> badly_encoded = + ParseJson(std::string("{\"consistency\": [\"notbase64\"]}")); + EXPECT_FALSE(FillConsistencyProof(*badly_encoded.get(), &output)); + + scoped_ptr<base::Value> not_a_string = + ParseJson(std::string("{\"consistency\": [42, 16]}")); + EXPECT_FALSE(FillConsistencyProof(*badly_encoded.get(), &output)); +} + +TEST(CTLogResponseParserTest, ParsesProofJsonWithExtraFields) { + std::vector<std::string> output; + + scoped_ptr<base::Value> badly_encoded = + ParseJson(std::string("{\"consistency\": [], \"somethingelse\": 3}")); + EXPECT_TRUE(FillConsistencyProof(*badly_encoded.get(), &output)); +} + } // namespace ct } // namespace net
diff --git a/net/test/ct_test_util.cc b/net/test/ct_test_util.cc index 65a8122..3bd30ff4 100644 --- a/net/test/ct_test_util.cc +++ b/net/test/ct_test_util.cc
@@ -312,6 +312,23 @@ return sth_json; } +std::string CreateConsistencyProofJsonString( + const std::vector<std::string>& raw_nodes) { + std::string consistency_proof_json = std::string("{\"consistency\":["); + + for (auto it = raw_nodes.begin(); it != raw_nodes.end(); ++it) { + std::string proof_node_b64; + base::Base64Encode(*it, &proof_node_b64); + consistency_proof_json += + base::StringPrintf("\"%s\"", proof_node_b64.c_str()); + if (it + 1 != raw_nodes.end()) + consistency_proof_json += std::string(","); + } + consistency_proof_json += std::string("]}"); + + return consistency_proof_json; +} + } // namespace ct } // namespace net
diff --git a/net/test/ct_test_util.h b/net/test/ct_test_util.h index 5701a288..5bb2d7a 100644 --- a/net/test/ct_test_util.h +++ b/net/test/ct_test_util.h
@@ -6,6 +6,7 @@ #define NET_CERT_CT_TEST_UTIL_H_ #include <string> +#include <vector> #include "base/memory/ref_counted.h" @@ -86,6 +87,10 @@ std::string sha256_root_hash, std::string tree_head_signature); +// Assembles, and returns, a sample consistency proof in JSON format using +// the provided raw nodes (i.e. the raw nodes will be base64-encoded). +std::string CreateConsistencyProofJsonString( + const std::vector<std::string>& raw_nodes); } // namespace ct } // namespace net
diff --git a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp index 3cff622e..db5fa17 100644 --- a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp +++ b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
@@ -147,7 +147,7 @@ m_invalidationEntries.append(Entry(&invalidationSet, invalidationLimit)); } -ALWAYS_INLINE bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(Element& element, RecursionData& recursionData) +bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(Element& element, RecursionData& recursionData) const { bool thisElementNeedsStyleRecalc = false; ASSERT(!recursionData.wholeSubtreeInvalid()); @@ -155,6 +155,7 @@ unsigned index = 0; while (index < m_invalidationEntries.size()) { if (m_elementIndex > m_invalidationEntries[index].m_invalidationLimit) { + // m_invalidationEntries[index] only applies to earlier siblings. Remove it. m_invalidationEntries[index] = m_invalidationEntries.last(); m_invalidationEntries.removeLast(); continue; @@ -186,6 +187,26 @@ return thisElementNeedsStyleRecalc; } +void StyleInvalidator::pushInvalidationSetsForElement(Element& element, RecursionData& recursionData, SiblingData& siblingData) +{ + PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&element); + ASSERT(pendingInvalidations); + + for (const auto& invalidationSet : pendingInvalidations->siblings()) + siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSet)); + + if (!pendingInvalidations->descendants().isEmpty()) { + for (const auto& invalidationSet : pendingInvalidations->descendants()) + recursionData.pushInvalidationSet(toDescendantInvalidationSet(*invalidationSet)); + if (UNLIKELY(*s_tracingEnabled)) { + TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), + "StyleInvalidatorInvalidationTracking", + TRACE_EVENT_SCOPE_THREAD, + "data", InspectorStyleInvalidatorInvalidateEvent::invalidationList(element, pendingInvalidations->descendants())); + } + } +} + ALWAYS_INLINE bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element& element, RecursionData& recursionData, SiblingData& siblingData) { if (element.styleChangeType() >= SubtreeStyleChange || recursionData.wholeSubtreeInvalid()) { @@ -194,36 +215,21 @@ } bool thisElementNeedsStyleRecalc = recursionData.matchesCurrentInvalidationSets(element); - thisElementNeedsStyleRecalc |= siblingData.matchCurrentInvalidationSets(element, recursionData); + if (UNLIKELY(!siblingData.isEmpty())) + thisElementNeedsStyleRecalc |= siblingData.matchCurrentInvalidationSets(element, recursionData); - if (UNLIKELY(element.needsStyleInvalidation())) { - PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&element); - ASSERT(pendingInvalidations); - - for (const auto& invalidationSet : pendingInvalidations->siblings()) - siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSet)); - - if (!pendingInvalidations->descendants().isEmpty()) { - for (const auto& invalidationSet : pendingInvalidations->descendants()) - recursionData.pushInvalidationSet(toDescendantInvalidationSet(*invalidationSet)); - if (UNLIKELY(*s_tracingEnabled)) { - TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), - "StyleInvalidatorInvalidationTracking", - TRACE_EVENT_SCOPE_THREAD, - "data", InspectorStyleInvalidatorInvalidateEvent::invalidationList(element, pendingInvalidations->descendants())); - } - } - } + if (UNLIKELY(element.needsStyleInvalidation())) + pushInvalidationSetsForElement(element, recursionData, siblingData); return thisElementNeedsStyleRecalc; } -bool StyleInvalidator::invalidateChildren(Element& element, RecursionData& recursionData) +bool StyleInvalidator::invalidateShadowRootChildren(Element& element, RecursionData& recursionData) { - SiblingData siblingData; bool someChildrenNeedStyleRecalc = false; for (ShadowRoot* root = element.youngestShadowRoot(); root; root = root->olderShadowRoot()) { if (!recursionData.treeBoundaryCrossing() && !root->childNeedsStyleInvalidation() && !root->needsStyleInvalidation()) continue; + SiblingData siblingData; for (Element* child = ElementTraversal::firstChild(*root); child; child = ElementTraversal::nextSibling(*child)) { bool childRecalced = invalidate(*child, recursionData, siblingData); someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced; @@ -231,6 +237,17 @@ root->clearChildNeedsStyleInvalidation(); root->clearNeedsStyleInvalidation(); } + return someChildrenNeedStyleRecalc; +} + +bool StyleInvalidator::invalidateChildren(Element& element, RecursionData& recursionData) +{ + SiblingData siblingData; + bool someChildrenNeedStyleRecalc = false; + if (UNLIKELY(!!element.youngestShadowRoot())) { + someChildrenNeedStyleRecalc = invalidateShadowRootChildren(element, recursionData); + } + for (Element* child = ElementTraversal::firstChild(element); child; child = ElementTraversal::nextSibling(*child)) { bool childRecalced = invalidate(*child, recursionData, siblingData); someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced; @@ -240,8 +257,8 @@ bool StyleInvalidator::invalidate(Element& element, RecursionData& recursionData, SiblingData& siblingData) { - RecursionCheckpoint checkpoint(&recursionData); siblingData.advance(); + RecursionCheckpoint checkpoint(&recursionData); bool thisElementNeedsStyleRecalc = checkInvalidationSetsAgainstElement(element, recursionData, siblingData);
diff --git a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h index f99f005..dabe953 100644 --- a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h +++ b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h
@@ -63,8 +63,9 @@ { } void pushInvalidationSet(const SiblingInvalidationSet&); - bool matchCurrentInvalidationSets(Element&, RecursionData&); + bool matchCurrentInvalidationSets(Element&, RecursionData&) const; + bool isEmpty() const { return m_invalidationEntries.isEmpty(); } void advance() { m_elementIndex++; } private: @@ -79,13 +80,15 @@ unsigned m_invalidationLimit; }; - Vector<Entry, 16> m_invalidationEntries; + mutable Vector<Entry, 16> m_invalidationEntries; unsigned m_elementIndex; }; bool invalidate(Element&, RecursionData&, SiblingData&); + bool invalidateShadowRootChildren(Element&, RecursionData&); bool invalidateChildren(Element&, RecursionData&); bool checkInvalidationSetsAgainstElement(Element&, RecursionData&, SiblingData&); + void pushInvalidationSetsForElement(Element&, RecursionData&, SiblingData&); class RecursionCheckpoint { public: