Commit 0905cf77 authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

Blob: Move BlobURLNullOriginMap from core/fileapi/ to platform/blob/

This is a follow-up for: https://chromium-review.googlesource.com/c/chromium/src/+/1772933/3/third_party/blink/renderer/platform/weborigin/url_security_origin_map.h#42

For code simplification, this CL moves BlobURLNullOriginMap from
core/fileapi/public_url_manager.cc to its own file in platform/blob/. This
enables to remove platform/weborigin/url_security_origin_map.h that was used for
exposing BlobURLNullOriginMap from PublicURLManager in core/ to SecurityOrigin
in platform/ (see SecurityOrigin::SetBlobURLNullOriginMap() in the original
code).

Also, this CL simplifies class instance relationship. Before this CL,
BlobURLNullOriginMap was a process global object, and BlobURLOriginMap that
actually managed pairs of blob URL and "null" security origin was a thread
specific object. BlobURLNullOriginMap served as the interface of the thread
specific object.

  (process global) BlobURLNullOriginMap
    == accesses ==> (thread specific) BlobURLOriginMap
      == manages ==> pairs of blob URL and "null" origin

After this CL, BlobURLNullOriginMap is a thread specific
object and contains pairs of blob URL and "null" security origin.
An instance of BlobURLNullOriginMap is accessed via
BlobURLNullOriginMap::GetInstance().

  (thread specific) BlobURLNullOriginMap
    == manages ==> pairs of blob URL and "null" origin.

Change-Id: I17c76c41d6a2bfddc66049a53268bba955808c5f
Bug: 987130
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1864497
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMarijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709263}
parent 1818bb26
...@@ -33,77 +33,20 @@ ...@@ -33,77 +33,20 @@
#include "third_party/blink/renderer/core/fileapi/url_registry.h" #include "third_party/blink/renderer/core/fileapi/url_registry.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h" #include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/blob/blob_url.h" #include "third_party/blink/renderer/platform/blob/blob_url.h"
#include "third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/weborigin/url_security_origin_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
#include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink { namespace blink {
namespace { namespace {
// When a blob URL is created in an opaque origin or something whose static void RemoveFromNullOriginMapIfNecessary(const KURL& blob_url) {
// SecurityOrigin::SerializesAsNull() returns true, the origin is serialized
// into the URL as "null". Since that makes it impossible to parse the origin
// back out and compare it against a context's origin (to check if a context is
// allowed to dereference the URL) we store a map of blob URL to SecurityOrigin
// instance for blob URLs with such the origins.
class BlobURLNullOriginMap final : public URLSecurityOriginMap {
public:
BlobURLNullOriginMap();
// If the given blob URL has a "null" origin, returns SecurityOrigin that
// represents the "null" origin. Otherwise, returns nullptr.
SecurityOrigin* GetOrigin(const KURL& blob_url) override;
};
typedef HashMap<String, scoped_refptr<SecurityOrigin>> BlobURLOriginMap;
static ThreadSpecific<BlobURLOriginMap>& OriginMap() {
// We want to create the BlobURLNullOriginMap exactly once because it is
// shared by all the threads.
DEFINE_THREAD_SAFE_STATIC_LOCAL(BlobURLNullOriginMap, cache, ());
// BlobURLNullOriginMap's constructor does the interesting work.
(void)cache;
DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<BlobURLOriginMap>, map, ());
return map;
}
static void SaveToOriginMap(SecurityOrigin* origin, const KURL& blob_url) {
DCHECK(blob_url.ProtocolIs("blob"));
DCHECK(!blob_url.HasFragmentIdentifier());
// If the blob URL contains "null" origin, as in the context with opaque
// security origin or file URL, save the mapping between url and origin so
// that the origin can be retrieved when doing security origin check.
//
// See the definition of the origin of a Blob URL in the File API spec.
if (origin && origin->SerializesAsNull()) {
DCHECK_EQ(BlobURL::GetOrigin(blob_url), "null");
OriginMap()->insert(blob_url.GetString(), origin);
}
}
static void RemoveFromOriginMap(const KURL& blob_url) {
DCHECK(blob_url.ProtocolIs("blob")); DCHECK(blob_url.ProtocolIs("blob"));
if (BlobURL::GetOrigin(blob_url) == "null") if (BlobURL::GetOrigin(blob_url) == "null")
OriginMap()->erase(blob_url.GetString()); BlobURLNullOriginMap::GetInstance()->Remove(blob_url);
}
BlobURLNullOriginMap::BlobURLNullOriginMap() {
SecurityOrigin::SetBlobURLNullOriginMap(this);
}
SecurityOrigin* BlobURLNullOriginMap::GetOrigin(const KURL& blob_url) {
DCHECK(blob_url.ProtocolIs("blob"));
KURL blob_url_without_fragment = blob_url;
blob_url_without_fragment.RemoveFragmentIdentifier();
return OriginMap()->at(blob_url_without_fragment.GetString());
} }
} // namespace } // namespace
...@@ -138,7 +81,9 @@ String PublicURLManager::RegisterURL(URLRegistrable* registrable) { ...@@ -138,7 +81,9 @@ String PublicURLManager::RegisterURL(URLRegistrable* registrable) {
registry->RegisterURL(origin, url, registrable); registry->RegisterURL(origin, url, registrable);
url_to_registry_.insert(url_string, registry); url_to_registry_.insert(url_string, registry);
} }
SaveToOriginMap(origin, url);
if (origin->SerializesAsNull())
BlobURLNullOriginMap::GetInstance()->Add(url, origin);
return url_string; return url_string;
} }
...@@ -162,7 +107,7 @@ void PublicURLManager::Revoke(const KURL& url) { ...@@ -162,7 +107,7 @@ void PublicURLManager::Revoke(const KURL& url) {
url_store_->Revoke(url); url_store_->Revoke(url);
mojo_urls_.erase(url.GetString()); mojo_urls_.erase(url.GetString());
RemoveFromOriginMap(url); RemoveFromNullOriginMapIfNecessary(url);
auto it = url_to_registry_.find(url.GetString()); auto it = url_to_registry_.find(url.GetString());
if (it == url_to_registry_.end()) if (it == url_to_registry_.end())
return; return;
...@@ -208,10 +153,10 @@ void PublicURLManager::ContextDestroyed(ExecutionContext*) { ...@@ -208,10 +153,10 @@ void PublicURLManager::ContextDestroyed(ExecutionContext*) {
is_stopped_ = true; is_stopped_ = true;
for (auto& url_registry : url_to_registry_) { for (auto& url_registry : url_to_registry_) {
url_registry.value->UnregisterURL(KURL(url_registry.key)); url_registry.value->UnregisterURL(KURL(url_registry.key));
RemoveFromOriginMap(KURL(url_registry.key)); RemoveFromNullOriginMapIfNecessary(KURL(url_registry.key));
} }
for (const auto& url : mojo_urls_) for (const auto& url : mojo_urls_)
RemoveFromOriginMap(KURL(url)); RemoveFromNullOriginMapIfNecessary(KURL(url));
url_to_registry_.clear(); url_to_registry_.clear();
mojo_urls_.clear(); mojo_urls_.clear();
......
...@@ -1408,7 +1408,6 @@ jumbo_component("platform") { ...@@ -1408,7 +1408,6 @@ jumbo_component("platform") {
"weborigin/security_policy.cc", "weborigin/security_policy.cc",
"weborigin/security_policy.h", "weborigin/security_policy.h",
"weborigin/security_violation_reporting_policy.h", "weborigin/security_violation_reporting_policy.h",
"weborigin/url_security_origin_map.h",
"webrtc/peer_connection_remote_audio_source.cc", "webrtc/peer_connection_remote_audio_source.cc",
"webrtc/peer_connection_remote_audio_source.h", "webrtc/peer_connection_remote_audio_source.h",
"webrtc/track_observer.cc", "webrtc/track_observer.cc",
......
...@@ -27,6 +27,8 @@ blink_platform_sources("blob") { ...@@ -27,6 +27,8 @@ blink_platform_sources("blob") {
"blob_data.h", "blob_data.h",
"blob_url.cc", "blob_url.cc",
"blob_url.h", "blob_url.h",
"blob_url_null_origin_map.cc",
"blob_url_null_origin_map.h",
"serialized_blob_mojom_traits.cc", "serialized_blob_mojom_traits.cc",
"serialized_blob_mojom_traits.h", "serialized_blob_mojom_traits.h",
] ]
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h"
#include "third_party/blink/renderer/platform/blob/blob_url.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
// static
ThreadSpecific<BlobURLNullOriginMap>& BlobURLNullOriginMap::GetInstance() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<BlobURLNullOriginMap>, map,
());
return map;
}
void BlobURLNullOriginMap::Add(const KURL& blob_url, SecurityOrigin* origin) {
DCHECK(blob_url.ProtocolIs("blob"));
DCHECK_EQ(BlobURL::GetOrigin(blob_url), "null");
DCHECK(!blob_url.HasFragmentIdentifier());
DCHECK(origin->SerializesAsNull());
blob_url_null_origin_map_.insert(blob_url.GetString(), origin);
}
void BlobURLNullOriginMap::Remove(const KURL& blob_url) {
DCHECK(blob_url.ProtocolIs("blob"));
DCHECK_EQ(BlobURL::GetOrigin(blob_url), "null");
blob_url_null_origin_map_.erase(blob_url.GetString());
}
SecurityOrigin* BlobURLNullOriginMap::Get(const KURL& blob_url) {
DCHECK(blob_url.ProtocolIs("blob"));
DCHECK_EQ(BlobURL::GetOrigin(blob_url), "null");
KURL blob_url_without_fragment = blob_url;
blob_url_without_fragment.RemoveFragmentIdentifier();
return blob_url_null_origin_map_.at(blob_url_without_fragment.GetString());
}
} // namespace blink
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_URL_NULL_ORIGIN_MAP_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_URL_NULL_ORIGIN_MAP_H_
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
namespace blink {
class KURL;
class SecurityOrigin;
// BlobURLNullOriginMap contains pairs of blob URL and security origin that is
// serialized into "null". An instance of this class is per-thread, and created
// when GetInstace() is called for the first time.
//
// When a blob URL is created in an opaque origin or something whose
// SecurityOrigin::SerializesAsNull() returns true, the origin is serialized
// into the URL as "null". Since that makes it impossible to parse the origin
// back out and compare it against a context's origin (to check if a context is
// allowed to dereference the URL), this class stores a map of blob URL to such
// an origin.
class PLATFORM_EXPORT BlobURLNullOriginMap {
public:
// Returns a thread-specific instance. The instance is created when this
// function is called for the first time.
static ThreadSpecific<BlobURLNullOriginMap>& GetInstance();
// Adds a pair of |blob_url| and |origin| to the map. |blob_url| and |origin|
// must have the same "null" origin.
void Add(const KURL& blob_url, SecurityOrigin* origin);
// Removes a "null" origin keyed with |blob_url| from the map. |blob_url| must
// have the "null" origin.
void Remove(const KURL& blob_url);
// Returns a "null" origin keyed with |blob_url| from the map. |blob_url| must
// have the "null" origin.
SecurityOrigin* Get(const KURL& blob_url);
private:
friend class ThreadSpecific<BlobURLNullOriginMap>;
HashMap<String, scoped_refptr<SecurityOrigin>> blob_url_null_origin_map_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_URL_NULL_ORIGIN_MAP_H_
...@@ -12,6 +12,7 @@ include_rules = [ ...@@ -12,6 +12,7 @@ include_rules = [
"+services/network/public/cpp/cors/origin_access_entry.h", "+services/network/public/cpp/cors/origin_access_entry.h",
"+services/network/public/cpp/cors/origin_access_list.h", "+services/network/public/cpp/cors/origin_access_list.h",
"+third_party/blink/renderer/platform/blob/blob_url.h", "+third_party/blink/renderer/platform/blob/blob_url.h",
"+third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h",
"+third_party/blink/renderer/platform/platform_export.h", "+third_party/blink/renderer/platform/platform_export.h",
"+third_party/blink/renderer/platform/runtime_enabled_features.h", "+third_party/blink/renderer/platform/runtime_enabled_features.h",
"+third_party/blink/renderer/platform/testing", "+third_party/blink/renderer/platform/testing",
......
...@@ -35,13 +35,14 @@ ...@@ -35,13 +35,14 @@
#include <utility> #include <utility>
#include "net/base/url_util.h" #include "net/base/url_util.h"
#include "third_party/blink/renderer/platform/blob/blob_url.h"
#include "third_party/blink/renderer/platform/blob/blob_url_null_origin_map.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/known_ports.h" #include "third_party/blink/renderer/platform/weborigin/known_ports.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h" #include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/weborigin/url_security_origin_map.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
...@@ -63,15 +64,6 @@ const String& EnsureNonNull(const String& string) { ...@@ -63,15 +64,6 @@ const String& EnsureNonNull(const String& string) {
} // namespace } // namespace
static URLSecurityOriginMap* g_blob_url_null_origin_map = nullptr;
static SecurityOrigin* GetNullOriginFromBlobURL(const KURL& blob_url) {
DCHECK(blob_url.ProtocolIs("blob"));
if (g_blob_url_null_origin_map)
return g_blob_url_null_origin_map->GetOrigin(blob_url);
return nullptr;
}
bool SecurityOrigin::ShouldUseInnerURL(const KURL& url) { bool SecurityOrigin::ShouldUseInnerURL(const KURL& url) {
// FIXME: Blob URLs don't have inner URLs. Their form is // FIXME: Blob URLs don't have inner URLs. Their form is
// "blob:<inner-origin>/<UUID>", so treating the part after "blob:" as a URL // "blob:<inner-origin>/<UUID>", so treating the part after "blob:" as a URL
...@@ -94,12 +86,6 @@ KURL SecurityOrigin::ExtractInnerURL(const KURL& url) { ...@@ -94,12 +86,6 @@ KURL SecurityOrigin::ExtractInnerURL(const KURL& url) {
return KURL(url.GetPath()); return KURL(url.GetPath());
} }
void SecurityOrigin::SetBlobURLNullOriginMap(
URLSecurityOriginMap* blob_url_null_origin_map) {
DCHECK(!g_blob_url_null_origin_map);
g_blob_url_null_origin_map = blob_url_null_origin_map;
}
static bool ShouldTreatAsOpaqueOrigin(const KURL& url) { static bool ShouldTreatAsOpaqueOrigin(const KURL& url) {
if (!url.IsValid()) if (!url.IsValid())
return true; return true;
...@@ -205,8 +191,9 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other, ...@@ -205,8 +191,9 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other,
scoped_refptr<SecurityOrigin> SecurityOrigin::CreateWithReferenceOrigin( scoped_refptr<SecurityOrigin> SecurityOrigin::CreateWithReferenceOrigin(
const KURL& url, const KURL& url,
const SecurityOrigin* reference_origin) { const SecurityOrigin* reference_origin) {
if (url.ProtocolIs("blob")) { if (url.ProtocolIs("blob") && BlobURL::GetOrigin(url) == "null") {
if (scoped_refptr<SecurityOrigin> origin = GetNullOriginFromBlobURL(url)) if (scoped_refptr<SecurityOrigin> origin =
BlobURLNullOriginMap::GetInstance()->Get(url))
return origin; return origin;
} }
...@@ -421,8 +408,10 @@ bool SecurityOrigin::CanRequest(const KURL& url) const { ...@@ -421,8 +408,10 @@ bool SecurityOrigin::CanRequest(const KURL& url) const {
// with |this|. // with |this|.
// TODO(nhiroki): Probably we should check the equality by // TODO(nhiroki): Probably we should check the equality by
// SecurityOrigin::IsSameSchemeHostPort(). // SecurityOrigin::IsSameSchemeHostPort().
if (url.ProtocolIs("blob") && GetNullOriginFromBlobURL(url) == this) if (url.ProtocolIs("blob") && BlobURL::GetOrigin(url) == "null" &&
BlobURLNullOriginMap::GetInstance()->Get(url) == this) {
return true; return true;
}
return false; return false;
} }
......
...@@ -47,7 +47,6 @@ struct UrlOriginAdapter; ...@@ -47,7 +47,6 @@ struct UrlOriginAdapter;
namespace blink { namespace blink {
class KURL; class KURL;
class URLSecurityOriginMap;
struct SecurityOriginHash; struct SecurityOriginHash;
// An identifier which defines the source of content (e.g. a document) and // An identifier which defines the source of content (e.g. a document) and
...@@ -95,10 +94,6 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> { ...@@ -95,10 +94,6 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
static scoped_refptr<SecurityOrigin> CreateFromUrlOrigin(const url::Origin&); static scoped_refptr<SecurityOrigin> CreateFromUrlOrigin(const url::Origin&);
url::Origin ToUrlOrigin() const; url::Origin ToUrlOrigin() const;
// Sets the map to look up a SecurityOrigin instance serialized to "null" from
// a blob URL.
static void SetBlobURLNullOriginMap(URLSecurityOriginMap*);
// Some URL schemes use nested URLs for their security context. For example, // Some URL schemes use nested URLs for their security context. For example,
// filesystem URLs look like the following: // filesystem URLs look like the following:
// //
......
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_URL_SECURITY_ORIGIN_MAP_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_URL_SECURITY_ORIGIN_MAP_H_
#include "base/macros.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
class KURL;
class SecurityOrigin;
class URLSecurityOriginMap {
USING_FAST_MALLOC(URLSecurityOriginMap);
public:
URLSecurityOriginMap() = default;
virtual ~URLSecurityOriginMap() = default;
// Returns a SecurityOrigin instance that represents the origin of the given
// URL. May return nullptr.
virtual SecurityOrigin* GetOrigin(const KURL&) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(URLSecurityOriginMap);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_URL_SECURITY_ORIGIN_MAP_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment