Index: Source/platform/weborigin/SecurityOrigin.cpp |
diff --git a/Source/platform/weborigin/SecurityOrigin.cpp b/Source/platform/weborigin/SecurityOrigin.cpp |
index d971d8bf965743227ffc4b41a6df2d6cef541c4c..3ec07226683780109ee37e1da96dde8333785ae5 100644 |
--- a/Source/platform/weborigin/SecurityOrigin.cpp |
+++ b/Source/platform/weborigin/SecurityOrigin.cpp |
@@ -29,6 +29,7 @@ |
#include "config.h" |
#include "platform/weborigin/SecurityOrigin.h" |
+#include "platform/RuntimeEnabledFeatures.h" |
#include "platform/weborigin/KURL.h" |
#include "platform/weborigin/KnownPorts.h" |
#include "platform/weborigin/SchemeRegistry.h" |
@@ -37,6 +38,7 @@ |
#include "url/url_canon_ip.h" |
#include "wtf/HexNumber.h" |
#include "wtf/MainThread.h" |
+#include "wtf/NotFound.h" |
#include "wtf/StdLibExtras.h" |
#include "wtf/text/StringBuilder.h" |
@@ -62,6 +64,12 @@ static SecurityOrigin* cachedOrigin(const KURL& url) |
return 0; |
} |
+static bool sameSuborigin(const SecurityOrigin* origin1, const SecurityOrigin* origin2) |
+{ |
+ // If either origin has a suborigin set, both must have the same suborigin. |
+ return origin1->suboriginName() == origin2->suboriginName(); |
+} |
+ |
bool SecurityOrigin::shouldUseInnerURL(const KURL& url) |
{ |
// FIXME: Blob URLs don't have inner URLs. Their form is "blob:<inner-origin>/<UUID>", so treating the part after "blob:" as a URL is incorrect. |
@@ -126,6 +134,11 @@ SecurityOrigin::SecurityOrigin(const KURL& url) |
, m_enforceFilePathSeparation(false) |
, m_needsDatabaseIdentifierQuirkForFiles(false) |
{ |
+ // Suborigins are serialized into the host, so extract it if necessary. |
+ String suboriginName; |
+ if (deserializeSuboriginAndHost(m_host, suboriginName, m_host)) |
+ addSuborigin(suboriginName); |
+ |
// document.domain starts as m_host, but can be set by the DOM. |
m_domain = m_host; |
@@ -143,6 +156,7 @@ SecurityOrigin::SecurityOrigin() |
: m_protocol("") |
, m_host("") |
, m_domain("") |
+ , m_suboriginName(WTF::String()) |
, m_port(InvalidPort) |
, m_isUnique(true) |
, m_universalAccess(false) |
@@ -158,6 +172,7 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) |
, m_host(other->m_host.isolatedCopy()) |
, m_domain(other->m_domain.isolatedCopy()) |
, m_filePath(other->m_filePath.isolatedCopy()) |
+ , m_suboriginName(other->m_suboriginName) |
, m_port(other->m_port) |
, m_isUnique(other->m_isUnique) |
, m_universalAccess(other->m_universalAccess) |
@@ -200,6 +215,16 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::createUnique() |
return origin.release(); |
} |
+void SecurityOrigin::addSuborigin(const String& suborigin) |
+{ |
+ ASSERT(RuntimeEnabledFeatures::suboriginsEnabled()); |
+ // Changing suborigins midstream is bad. Very bad. It should not happen. |
+ // This is, in fact, one of the very basic invariants that makes suborigins |
+ // an effective security tool. |
+ RELEASE_ASSERT(m_suboriginName.isNull() || m_suboriginName == suborigin); |
+ m_suboriginName = suborigin; |
+} |
+ |
PassRefPtr<SecurityOrigin> SecurityOrigin::isolatedCopy() const |
{ |
return adoptRef(new SecurityOrigin(this)); |
@@ -473,6 +498,25 @@ String SecurityOrigin::toRawString() const |
return result.toString(); |
} |
+// Returns true if and only if a suborigin component was found. If false, no |
+// guarantees about the return value |suboriginName| are made. |
+bool SecurityOrigin::deserializeSuboriginAndHost(const String& oldHost, String& suboriginName, String& newHost) |
+{ |
+ if (!RuntimeEnabledFeatures::suboriginsEnabled()) |
+ return false; |
+ |
+ size_t suboriginEnd = oldHost.find('_'); |
jochen (gone - plz use gerrit)
2015/04/27 19:35:10
underscore looks odd but is ok i guess
jww
2015/05/30 01:11:07
Yeah, I'm happy to discuss what we should use as a
|
+ // Suborigins cannot be empty |
+ if (suboriginEnd == 0 || suboriginEnd == WTF::kNotFound) |
+ return false; |
+ |
+ suboriginName = oldHost.substring(0, suboriginEnd); |
+ newHost = oldHost.substring(suboriginEnd + 1); |
+ |
+ return true; |
+} |
+ |
+ |
AtomicString SecurityOrigin::toRawAtomicString() const |
{ |
if (m_protocol == "file") |
@@ -483,11 +527,14 @@ AtomicString SecurityOrigin::toRawAtomicString() const |
return result.toAtomicString(); |
} |
-inline void SecurityOrigin::buildRawString(StringBuilder& builder) const |
+void SecurityOrigin::buildRawString(StringBuilder& builder) const |
{ |
- builder.reserveCapacity(m_protocol.length() + m_host.length() + 10); |
builder.append(m_protocol); |
builder.appendLiteral("://"); |
+ if (hasSuborigin()) { |
+ builder.append(m_suboriginName); |
+ builder.appendLiteral("_"); |
+ } |
builder.append(m_host); |
if (m_port) { |
@@ -511,6 +558,9 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::create(const String& protocol, const |
bool SecurityOrigin::isSameSchemeHostPort(const SecurityOrigin* other) const |
{ |
+ if (!sameSuborigin(this, other)) |
+ return false; |
+ |
if (m_host != other->m_host) |
return false; |