Chromium Code Reviews| 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; |