diff options
author | mkwst <mkwst@chromium.org> | 2015-07-24 22:18:48 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-25 05:19:39 +0000 |
commit | d8335d98a4c056ab97c5cdff1e95a7fa2c7dfc10 (patch) | |
tree | cb4965114068af0ec9095fa015b34d0caaca9289 /url | |
parent | c8b870d08efb3ffc6c2bedcec36462ece2326017 (diff) | |
download | chromium_src-d8335d98a4c056ab97c5cdff1e95a7fa2c7dfc10.zip chromium_src-d8335d98a4c056ab97c5cdff1e95a7fa2c7dfc10.tar.gz chromium_src-d8335d98a4c056ab97c5cdff1e95a7fa2c7dfc10.tar.bz2 |
Teach IPC about 'url::Origin'.
We'll need to pass Origin objects back and forth between the renderer
and browser processes. This patch teaches IPC about the object in order
to make that possible.
BUG=512731
Review URL: https://codereview.chromium.org/1251063002
Cr-Commit-Position: refs/heads/master@{#340399}
Diffstat (limited to 'url')
-rw-r--r-- | url/origin.cc | 13 | ||||
-rw-r--r-- | url/origin.h | 18 | ||||
-rw-r--r-- | url/origin_unittest.cc | 91 | ||||
-rw-r--r-- | url/scheme_host_port.cc | 29 | ||||
-rw-r--r-- | url/scheme_host_port_unittest.cc | 62 |
5 files changed, 203 insertions, 10 deletions
diff --git a/url/origin.cc b/url/origin.cc index e80eb72..7b8d805 100644 --- a/url/origin.cc +++ b/url/origin.cc @@ -38,9 +38,22 @@ Origin::Origin(const GURL& url) : unique_(true) { unique_ = tuple_.IsInvalid(); } +Origin::Origin(base::StringPiece scheme, base::StringPiece host, uint16 port) + : tuple_(scheme, host, port) { + unique_ = tuple_.IsInvalid(); +} + Origin::~Origin() { } +// static +Origin Origin::UnsafelyCreateOriginWithoutNormalization( + base::StringPiece scheme, + base::StringPiece host, + uint16 port) { + return Origin(scheme, host, port); +} + std::string Origin::Serialize() const { if (unique()) return "null"; diff --git a/url/origin.h b/url/origin.h index 01703ef..3746de9 100644 --- a/url/origin.h +++ b/url/origin.h @@ -8,6 +8,7 @@ #include <string> #include "base/strings/string16.h" +#include "base/strings/string_piece.h" #include "url/scheme_host_port.h" #include "url/third_party/mozilla/url_parse.h" #include "url/url_canon.h" @@ -86,6 +87,19 @@ class URL_EXPORT Origin { // 3. 'file' URLs all parse as ("file", "", 0). explicit Origin(const GURL& url); + // Creates an Origin from a |scheme|, |host|, and |port|. All the parameters + // must be valid and canonicalized. In particular, note that this cannot be + // used to create unique origins; 'url::Origin()' is the right way to do that. + // + // This constructor should be used in order to pass 'Origin' objects back and + // forth over IPC (as transitioning through GURL would risk potentially + // dangerous recanonicalization); other potential callers should prefer the + // 'GURL'-based constructor. + static Origin UnsafelyCreateOriginWithoutNormalization( + base::StringPiece scheme, + base::StringPiece host, + uint16 port); + ~Origin(); // For unique origins, these return ("", "", 0). @@ -108,10 +122,10 @@ class URL_EXPORT Origin { bool operator<(const Origin& other) const; private: + Origin(base::StringPiece scheme, base::StringPiece host, uint16 port); + SchemeHostPort tuple_; bool unique_; - - DISALLOW_COPY_AND_ASSIGN(Origin); }; URL_EXPORT std::ostream& operator<<(std::ostream& out, diff --git a/url/origin_unittest.cc b/url/origin_unittest.cc index a774c62..ec4ec65 100644 --- a/url/origin_unittest.cc +++ b/url/origin_unittest.cc @@ -2,6 +2,7 @@ // 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 "url/origin.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -157,4 +158,94 @@ TEST(OriginTest, Comparison) { } } +TEST(OriginTest, UnsafelyCreate) { + struct TestCase { + const char* scheme; + const char* host; + uint16 port; + } cases[] = { + {"http", "example.com", 80}, + {"http", "example.com", 123}, + {"https", "example.com", 443}, + {"https", "example.com", 123}, + {"file", "", 0}, + {"file", "example.com", 0}, + }; + + for (const auto& test : cases) { + SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":" + << test.port); + url::Origin origin = url::Origin::UnsafelyCreateOriginWithoutNormalization( + test.scheme, test.host, test.port); + EXPECT_EQ(test.scheme, origin.scheme()); + EXPECT_EQ(test.host, origin.host()); + EXPECT_EQ(test.port, origin.port()); + EXPECT_FALSE(origin.unique()); + EXPECT_TRUE(origin.IsSameOriginWith(origin)); + } +} + +TEST(OriginTest, UnsafelyCreateUniqueOnInvalidInput) { + struct TestCases { + const char* scheme; + const char* host; + uint16 port; + } cases[] = {{"", "", 0}, + {"data", "", 0}, + {"blob", "", 0}, + {"filesystem", "", 0}, + {"data", "example.com", 80}, + {"http", "☃.net", 80}, + {"http\nmore", "example.com", 80}, + {"http\rmore", "example.com", 80}, + {"http\n", "example.com", 80}, + {"http\r", "example.com", 80}, + {"http", "example.com\nnot-example.com", 80}, + {"http", "example.com\rnot-example.com", 80}, + {"http", "example.com\n", 80}, + {"http", "example.com\r", 80}, + {"http", "example.com", 0}, + {"file", "", 80}}; + + for (const auto& test : cases) { + SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":" + << test.port); + url::Origin origin = url::Origin::UnsafelyCreateOriginWithoutNormalization( + test.scheme, test.host, test.port); + EXPECT_EQ("", origin.scheme()); + EXPECT_EQ("", origin.host()); + EXPECT_EQ(0, origin.port()); + EXPECT_TRUE(origin.unique()); + EXPECT_FALSE(origin.IsSameOriginWith(origin)); + } +} + +TEST(OriginTest, UnsafelyCreateUniqueViaEmbeddedNulls) { + struct TestCases { + const char* scheme; + size_t scheme_length; + const char* host; + size_t host_length; + uint16 port; + } cases[] = {{"http\0more", 9, "example.com", 11, 80}, + {"http\0", 5, "example.com", 11, 80}, + {"\0http", 5, "example.com", 11, 80}, + {"http", 4, "example.com\0not-example.com", 27, 80}, + {"http", 4, "example.com\0", 12, 80}, + {"http", 4, "\0example.com", 12, 80}}; + + for (const auto& test : cases) { + SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":" + << test.port); + url::Origin origin = url::Origin::UnsafelyCreateOriginWithoutNormalization( + std::string(test.scheme, test.scheme_length), + std::string(test.host, test.host_length), test.port); + EXPECT_EQ("", origin.scheme()); + EXPECT_EQ("", origin.host()); + EXPECT_EQ(0, origin.port()); + EXPECT_TRUE(origin.unique()); + EXPECT_FALSE(origin.IsSameOriginWith(origin)); + } +} + } // namespace url diff --git a/url/scheme_host_port.cc b/url/scheme_host_port.cc index cb2d5cc..c2fe830 100644 --- a/url/scheme_host_port.cc +++ b/url/scheme_host_port.cc @@ -25,10 +25,6 @@ SchemeHostPort::SchemeHostPort(base::StringPiece scheme, : scheme_(scheme.data(), scheme.length()), host_(host.data(), host.length()), port_(port) { -#if DCHECK_IS_ON() - DCHECK(url::IsStandard(scheme.data(), - url::Component(0, static_cast<int>(scheme.length())))); - // Try to canonicalize the host (copy/pasted from net/base. :( ). const url::Component raw_host_component(0, static_cast<int>(host.length())); std::string canon_host; @@ -46,11 +42,28 @@ SchemeHostPort::SchemeHostPort(base::StringPiece scheme, // Empty host, or canonicalization failed. canon_host.clear(); } - DCHECK_EQ(host, canon_host); - DCHECK(scheme == kFileScheme ? port == 0 : port != 0); - DCHECK(!host.empty() || port == 0); -#endif + // Return an invalid SchemeHostPort object if any of the following conditions + // hold: + // + // 1. The provided scheme is non-standard, 'blob:', or 'filesystem:'. + // 2. The provided host is non-canonical. + // 3. The scheme is 'file' and the port is non-zero. + // 4. The scheme is not 'file', and the port is zero or the host is empty. + bool isUnsupportedScheme = + !url::IsStandard(scheme.data(), + url::Component(0, static_cast<int>(scheme.length()))) || + scheme == kFileSystemScheme || scheme == kBlobScheme; + bool isNoncanonicalHost = host != canon_host; + bool isFileSchemeWithPort = scheme == kFileScheme && port != 0; + bool isNonFileSchemeWithoutPortOrHost = + scheme != kFileScheme && (port == 0 || host.empty()); + if (isUnsupportedScheme || isNoncanonicalHost || isFileSchemeWithPort || + isNonFileSchemeWithoutPortOrHost) { + scheme_.clear(); + host_.clear(); + port_ = 0; + } } SchemeHostPort::SchemeHostPort(const GURL& url) : port_(0) { diff --git a/url/scheme_host_port_unittest.cc b/url/scheme_host_port_unittest.cc index 3001d24..817631d 100644 --- a/url/scheme_host_port_unittest.cc +++ b/url/scheme_host_port_unittest.cc @@ -62,6 +62,68 @@ TEST(SchemeHostPortTest, ExplicitConstruction) { } } +TEST(SchemeHostPortTest, InvalidConstruction) { + struct TestCases { + const char* scheme; + const char* host; + uint16 port; + } cases[] = {{"", "", 0}, + {"data", "", 0}, + {"blob", "", 0}, + {"filesystem", "", 0}, + {"http", "", 80}, + {"data", "example.com", 80}, + {"http", "☃.net", 80}, + {"http\nmore", "example.com", 80}, + {"http\rmore", "example.com", 80}, + {"http\n", "example.com", 80}, + {"http\r", "example.com", 80}, + {"http", "example.com\nnot-example.com", 80}, + {"http", "example.com\rnot-example.com", 80}, + {"http", "example.com\n", 80}, + {"http", "example.com\r", 80}, + {"http", "example.com", 0}, + {"file", "", 80}}; + + for (const auto& test : cases) { + SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":" + << test.port); + url::SchemeHostPort tuple(test.scheme, test.host, test.port); + EXPECT_EQ("", tuple.scheme()); + EXPECT_EQ("", tuple.host()); + EXPECT_EQ(0, tuple.port()); + EXPECT_TRUE(tuple.IsInvalid()); + EXPECT_TRUE(tuple.Equals(tuple)); + } +} + +TEST(SchemeHostPortTest, InvalidConstructionWithEmbeddedNulls) { + struct TestCases { + const char* scheme; + size_t scheme_length; + const char* host; + size_t host_length; + uint16 port; + } cases[] = {{"http\0more", 9, "example.com", 11, 80}, + {"http\0", 5, "example.com", 11, 80}, + {"\0http", 5, "example.com", 11, 80}, + {"http", 4, "example.com\0not-example.com", 27, 80}, + {"http", 4, "example.com\0", 12, 80}, + {"http", 4, "\0example.com", 12, 80}}; + + for (const auto& test : cases) { + SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":" + << test.port); + url::SchemeHostPort tuple(std::string(test.scheme, test.scheme_length), + std::string(test.host, test.host_length), + test.port); + EXPECT_EQ("", tuple.scheme()); + EXPECT_EQ("", tuple.host()); + EXPECT_EQ(0, tuple.port()); + EXPECT_TRUE(tuple.IsInvalid()); + } +} + TEST(SchemeHostPortTest, GURLConstruction) { struct TestCases { const char* url; |