summaryrefslogtreecommitdiffstats
path: root/url
diff options
context:
space:
mode:
authormkwst <mkwst@chromium.org>2015-07-24 22:18:48 -0700
committerCommit bot <commit-bot@chromium.org>2015-07-25 05:19:39 +0000
commitd8335d98a4c056ab97c5cdff1e95a7fa2c7dfc10 (patch)
treecb4965114068af0ec9095fa015b34d0caaca9289 /url
parentc8b870d08efb3ffc6c2bedcec36462ece2326017 (diff)
downloadchromium_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.cc13
-rw-r--r--url/origin.h18
-rw-r--r--url/origin_unittest.cc91
-rw-r--r--url/scheme_host_port.cc29
-rw-r--r--url/scheme_host_port_unittest.cc62
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;