Internal change PiperOrigin-RevId: 157616381 Change-Id: Iba58f10617dc6c5a60dcb085037d5c7acb990bb0
diff --git a/import.sh b/import.sh index 1d95c38..f6e20b3 100644 --- a/import.sh +++ b/import.sh
@@ -4,7 +4,7 @@ top=/tmp/chromium mkdir $top prefix=https://chromium.googlesource.com/chromium/src.git/+archive -for version in 56.0.2924.87 57.0.2987.133 +for version in 57.0.2987.133 58.0.3029.110 do mkdir $top/$version cd $top/$version
diff --git a/src/base/strings/string_util.h b/src/base/strings/string_util.h index 035179b..59359dd 100644 --- a/src/base/strings/string_util.h +++ b/src/base/strings/string_util.h
@@ -39,8 +39,6 @@ BASE_EXPORT bool IsStringASCII(const StringPiece& str); BASE_EXPORT bool IsStringASCII(const StringPiece16& str); -// A convenience adaptor for WebStrings, as they don't convert into -// StringPieces directly. BASE_EXPORT bool IsStringASCII(const string16& str); #if defined(WCHAR_T_IS_UTF32) BASE_EXPORT bool IsStringASCII(const std::wstring& str);
diff --git a/src/url/gurl.cc b/src/url/gurl.cc index 606eedb..8c88afa 100644 --- a/src/url/gurl.cc +++ b/src/url/gurl.cc
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" +// include "base/trace_event/memory_usage_estimator.h" #include "url/url_canon_stdstring.h" #include "url/url_util.h" @@ -347,6 +348,19 @@ return url::IsStandard(spec_.data(), parsed_.scheme); } +bool GURL::IsAboutBlank() const { + if (!SchemeIs(url::kAboutScheme)) + return false; + + if (has_host() || has_username() || has_password() || has_port()) + return false; + + if (path() != url::kAboutBlankPath && path() != url::kAboutBlankWithHashPath) + return false; + + return true; +} + bool GURL::SchemeIs(url::base::StringPiece lower_ascii_scheme) const { DCHECK(url::base::IsStringASCII(lower_ascii_scheme)); DCHECK(url::base::ToLowerASCII(lower_ascii_scheme) == lower_ascii_scheme); @@ -467,6 +481,14 @@ return url::DomainIs(host_piece(), lower_ascii_domain); } +bool GURL::EqualsIgnoringRef(const GURL& other) const { + int ref_position = parsed_.CountCharactersBefore(url::Parsed::REF, true); + int ref_position_other = + other.parsed_.CountCharactersBefore(url::Parsed::REF, true); + return url::base::StringPiece(spec_).substr(0, ref_position) == + url::base::StringPiece(other.spec_).substr(0, ref_position_other); +} + void GURL::Swap(GURL* other) { spec_.swap(other->spec_); std::swap(is_valid_, other->is_valid_); @@ -474,6 +496,16 @@ inner_url_.swap(other->inner_url_); } +size_t GURL::EstimateMemoryUsage() const { +#if 0 + return base::trace_event::EstimateMemoryUsage(spec_) + + base::trace_event::EstimateMemoryUsage(inner_url_) + +#endif + return spec_.size() + + (inner_url_ ? inner_url_->EstimateMemoryUsage() : 0) + + (parsed_.inner_parsed() ? sizeof(url::Parsed) : 0); +} + std::ostream& operator<<(std::ostream& out, const GURL& url) { return out << url.possibly_invalid_spec(); }
diff --git a/src/url/gurl.h b/src/url/gurl.h index aeb77aa..1fd6c14 100644 --- a/src/url/gurl.h +++ b/src/url/gurl.h
@@ -203,6 +203,10 @@ // by calling SchemeIsFile[System]. bool IsStandard() const; + // Returns true when the url is of the form about:blank, about:blank?foo or + // about:blank/#foo. + bool IsAboutBlank() const; + // Returns true if the given parameter (should be lower-case ASCII to match // the canonicalized scheme) is the scheme for this URL. Do not include a // colon. @@ -385,6 +389,10 @@ // object constructions are done. bool DomainIs(url::base::StringPiece lower_ascii_domain) const; + // Checks whether or not two URLs are differing only in the ref (the part + // after the # character). + bool EqualsIgnoringRef(const GURL& other) const; + // Swaps the contents of this GURL object with |other|, without doing // any memory allocations. void Swap(GURL* other); @@ -405,6 +413,10 @@ return inner_url_.get(); } + // Estimates dynamic memory usage. + // See base/trace_event/memory_usage_estimator.h for more info. + size_t EstimateMemoryUsage() const; + private: // Variant of the string parsing constructor that allows the caller to elect // retain trailing whitespace, if any, on the passed URL spec, but only if
diff --git a/src/url/gurl_unittest.cc b/src/url/gurl_unittest.cc index 5998b07..a0764e8 100644 --- a/src/url/gurl_unittest.cc +++ b/src/url/gurl_unittest.cc
@@ -740,4 +740,77 @@ } } +TEST(GURLTest, IsAboutBlank) { + const std::string kAboutBlankUrls[] = {"about:blank", "about:blank?foo", + "about:blank/#foo", + "about:blank?foo#foo"}; + for (const auto& url : kAboutBlankUrls) + EXPECT_TRUE(GURL(url).IsAboutBlank()) << url; + + const std::string kNotAboutBlankUrls[] = { + "http:blank", "about:blan", "about://blank", + "about:blank/foo", "about://:8000/blank", "about://foo:foo@/blank", + "foo@about:blank", "foo:bar@about:blank", "about:blank:8000"}; + for (const auto& url : kNotAboutBlankUrls) + EXPECT_FALSE(GURL(url).IsAboutBlank()) << url; +} + +TEST(GURLTest, EqualsIgnoringRef) { + const struct { + const char* url_a; + const char* url_b; + bool are_equals; + } kTestCases[] = { + // No ref. + {"http://a.com", "http://a.com", true}, + {"http://a.com", "http://b.com", false}, + + // Same Ref. + {"http://a.com#foo", "http://a.com#foo", true}, + {"http://a.com#foo", "http://b.com#foo", false}, + + // Different Refs. + {"http://a.com#foo", "http://a.com#bar", true}, + {"http://a.com#foo", "http://b.com#bar", false}, + + // One has a ref, the other doesn't. + {"http://a.com#foo", "http://a.com", true}, + {"http://a.com#foo", "http://b.com", false}, + + // Empty refs. + {"http://a.com#", "http://a.com#", true}, + {"http://a.com#", "http://a.com", true}, + + // URLs that differ only by their last character. + {"http://aaa", "http://aab", false}, + {"http://aaa#foo", "http://aab#foo", false}, + + // Different size of the part before the ref. + {"http://123#a", "http://123456#a", false}, + + // Blob URLs + {"blob:http://a.com#foo", "blob:http://a.com#foo", true}, + {"blob:http://a.com#foo", "blob:http://a.com#bar", true}, + {"blob:http://a.com#foo", "blob:http://b.com#bar", false}, + + // Filesystem URLs + {"filesystem:http://a.com#foo", "filesystem:http://a.com#foo", true}, + {"filesystem:http://a.com#foo", "filesystem:http://a.com#bar", true}, + {"filesystem:http://a.com#foo", "filesystem:http://b.com#bar", false}, + }; + + for (const auto& test_case : kTestCases) { + SCOPED_TRACE(testing::Message() + << std::endl + << "url_a = " << test_case.url_a << std::endl + << "url_b = " << test_case.url_b << std::endl); + // A versus B. + EXPECT_EQ(test_case.are_equals, + GURL(test_case.url_a).EqualsIgnoringRef(GURL(test_case.url_b))); + // B versus A. + EXPECT_EQ(test_case.are_equals, + GURL(test_case.url_b).EqualsIgnoringRef(GURL(test_case.url_a))); + } +} + } // namespace url
diff --git a/src/url/origin_unittest.cc b/src/url/origin_unittest.cc index 412d03e..d09030a 100644 --- a/src/url/origin_unittest.cc +++ b/src/url/origin_unittest.cc
@@ -262,7 +262,7 @@ "https-so://.", "https-so://foo", "https-so://.foo", "https-so://foo.", }; - for (const auto& test_case : failure_cases) { + for (auto* test_case : failure_cases) { SCOPED_TRACE(test_case); GURL url(test_case); EXPECT_TRUE(url.is_valid());
diff --git a/src/url/url_canon.h b/src/url/url_canon.h index ff66c6e..d093f35 100644 --- a/src/url/url_canon.h +++ b/src/url/url_canon.h
@@ -118,8 +118,9 @@ } void ReserveSizeIfNeeded(int estimated_size) { + // Reserve a bit extra to account for escaped chars. if (estimated_size > buffer_len_) - Resize(estimated_size); + Resize(estimated_size + 8); } protected:
diff --git a/src/url/url_canon_relative.cc b/src/url/url_canon_relative.cc index 8259056..851368d 100644 --- a/src/url/url_canon_relative.cc +++ b/src/url/url_canon_relative.cc
@@ -288,7 +288,7 @@ // possible escaped characters. output->ReserveSizeIfNeeded( base_parsed.path.begin + - std::max(path.end(), std::max(query.end(), ref.end())) + 8); + std::max(path.end(), std::max(query.end(), ref.end()))); output->Append(base_url, base_parsed.path.begin); if (path.len > 0) { @@ -406,7 +406,7 @@ // base URL. output->ReserveSizeIfNeeded( replacements.components().Length() + - base_parsed.CountCharactersBefore(Parsed::USERNAME, false) + 8); + base_parsed.CountCharactersBefore(Parsed::USERNAME, false)); return ReplaceStandardURL(base_url, base_parsed, replacements, query_converter, output, out_parsed); }
diff --git a/src/url/url_canon_stdstring.cc b/src/url/url_canon_stdstring.cc index 366a2e0..c81a0a9 100644 --- a/src/url/url_canon_stdstring.cc +++ b/src/url/url_canon_stdstring.cc
@@ -9,7 +9,6 @@ StdStringCanonOutput::StdStringCanonOutput(std::string* str) : CanonOutput(), str_(str) { cur_len_ = static_cast<int>(str_->size()); // Append to existing data. - str_->resize(str_->capacity()); buffer_ = str_->empty() ? NULL : &(*str_)[0]; buffer_len_ = static_cast<int>(str_->size()); }
diff --git a/src/url/url_canon_stdstring.h b/src/url/url_canon_stdstring.h index aefc76a..18afa8c 100644 --- a/src/url/url_canon_stdstring.h +++ b/src/url/url_canon_stdstring.h
@@ -22,8 +22,7 @@ // throughout the lifetime of this object. // // The given string will be appended to; any existing data in the string will -// be preserved. The caller should reserve() the amount of data in the string -// they expect to be written. We will resize if necessary, but that's slow. +// be preserved. // // Note that when canonicalization is complete, the string will likely have // unused space at the end because we make the string very big to start out
diff --git a/src/url/url_constants.cc b/src/url/url_constants.cc index 73c9a76..37fc82c 100644 --- a/src/url/url_constants.cc +++ b/src/url/url_constants.cc
@@ -8,6 +8,9 @@ const char kAboutBlankURL[] = "about:blank"; +const char kAboutBlankPath[] = "blank"; +const char kAboutBlankWithHashPath[] = "blank/"; + const char kAboutScheme[] = "about"; const char kBlobScheme[] = "blob"; const char kContentScheme[] = "content";
diff --git a/src/url/url_constants.h b/src/url/url_constants.h index c110589..7e5cb53 100644 --- a/src/url/url_constants.h +++ b/src/url/url_constants.h
@@ -13,6 +13,9 @@ URL_EXPORT extern const char kAboutBlankURL[]; +URL_EXPORT extern const char kAboutBlankPath[]; +URL_EXPORT extern const char kAboutBlankWithHashPath[]; + URL_EXPORT extern const char kAboutScheme[]; URL_EXPORT extern const char kBlobScheme[]; // The content scheme is specific to Android for identifying a stored file.
diff --git a/src/url/url_util.cc b/src/url/url_util.cc index 97ebeff..c00b7ee 100644 --- a/src/url/url_util.cc +++ b/src/url/url_util.cc
@@ -74,6 +74,15 @@ kDataScheme, }; +const char* kWebStorageSchemes[] = { + kHttpScheme, + kHttpsScheme, + kFileScheme, + kFtpScheme, + kWsScheme, + kWssScheme, +}; + bool initialized = false; // Lists of the currently installed standard and referrer schemes. These lists @@ -87,6 +96,8 @@ std::vector<std::string>* local_schemes = nullptr; std::vector<std::string>* no_access_schemes = nullptr; std::vector<std::string>* cors_enabled_schemes = nullptr; +std::vector<std::string>* web_storage_schemes = nullptr; +std::vector<std::string>* csp_bypassing_schemes = nullptr; // See the LockSchemeRegistries declaration in the header. bool scheme_registries_locked = false; @@ -194,9 +205,7 @@ CharsetConverter* charset_converter, CanonOutput* output, Parsed* output_parsed) { - // Reserve enough room in the output for the input, plus some extra so that - // we have room if we have to escape a few things without reallocating. - output->ReserveSizeIfNeeded(spec_len + 8); + output->ReserveSizeIfNeeded(spec_len); // Remove any whitespace from the middle of the relative URL if necessary. // Possibly this will result in copying to the new buffer. @@ -424,7 +433,7 @@ // in callers below, and the code checks to see which components are being // replaced, and with what length. If this ends up being a hot spot it should // be changed. - output->ReserveSizeIfNeeded(spec_len + 8); + output->ReserveSizeIfNeeded(spec_len); // If we get here, then we know the scheme doesn't need to be replaced, so can // just key off the scheme in the spec to know how to do the replacements. @@ -517,6 +526,9 @@ arraysize(kNoAccessSchemes)); InitSchemes(&cors_enabled_schemes, kCORSEnabledSchemes, arraysize(kCORSEnabledSchemes)); + InitSchemes(&web_storage_schemes, kWebStorageSchemes, + arraysize(kWebStorageSchemes)); + InitSchemes(&csp_bypassing_schemes, nullptr, 0); initialized = true; } @@ -534,6 +546,10 @@ no_access_schemes = nullptr; delete cors_enabled_schemes; cors_enabled_schemes = nullptr; + delete web_storage_schemes; + web_storage_schemes = nullptr; + delete csp_bypassing_schemes; + csp_bypassing_schemes = nullptr; } void AddStandardScheme(const char* new_scheme, SchemeType type) { @@ -586,6 +602,26 @@ return *cors_enabled_schemes; } +void AddWebStorageScheme(const char* new_scheme) { + Initialize(); + DoAddScheme(new_scheme, web_storage_schemes); +} + +const std::vector<std::string>& GetWebStorageSchemes() { + Initialize(); + return *web_storage_schemes; +} + +void AddCSPBypassingScheme(const char* new_scheme) { + Initialize(); + DoAddScheme(new_scheme, csp_bypassing_schemes); +} + +const std::vector<std::string>& GetCSPBypassingSchemes() { + Initialize(); + return *csp_bypassing_schemes; +} + void LockSchemeRegistries() { scheme_registries_locked = true; }
diff --git a/src/url/url_util.h b/src/url/url_util.h index a4b74b1..d0a8f22 100644 --- a/src/url/url_util.h +++ b/src/url/url_util.h
@@ -96,6 +96,19 @@ URL_EXPORT void AddCORSEnabledScheme(const char* new_scheme); URL_EXPORT const std::vector<std::string>& GetCORSEnabledSchemes(); +// Adds an application-defined scheme to the list of web schemes that can be +// used by web to store data (e.g. cookies, local storage, ...). This is +// to differentiate them from schemes that can store data but are not used on +// web (e.g. application's internal schemes) or schemes that are used on web but +// cannot store data. +URL_EXPORT void AddWebStorageScheme(const char* new_scheme); +URL_EXPORT const std::vector<std::string>& GetWebStorageSchemes(); + +// Adds an application-defined scheme to the list of schemes that can bypass the +// Content-Security-Policy(CSP) checks. +URL_EXPORT void AddCSPBypassingScheme(const char* new_scheme); +URL_EXPORT const std::vector<std::string>& GetCSPBypassingSchemes(); + // Sets a flag to prevent future calls to Add*Scheme from succeeding. // // This is designed to help prevent errors for multithreaded applications.