1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/renderer/core/execution_context/window_agent_factory.h"
6 #include "third_party/blink/renderer/core/execution_context/window_agent.h"
7 #include "third_party/blink/renderer/platform/heap/persistent.h"
8 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
9 #include "third_party/blink/renderer/platform/weborigin/security_origin_hash.h"
10 #include "third_party/blink/renderer/platform/wtf/hash_functions.h"
11 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
12 #include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
13 
14 namespace blink {
15 
16 WindowAgentFactory::WindowAgentFactory() = default;
17 
GetAgentForOrigin(bool has_potential_universal_access_privilege,v8::Isolate * isolate,const SecurityOrigin * origin)18 WindowAgent* WindowAgentFactory::GetAgentForOrigin(
19     bool has_potential_universal_access_privilege,
20     v8::Isolate* isolate,
21     const SecurityOrigin* origin) {
22   if (has_potential_universal_access_privilege) {
23     if (!universal_access_agent_) {
24       universal_access_agent_ = MakeGarbageCollected<WindowAgent>(isolate);
25     }
26     return universal_access_agent_;
27   }
28 
29   // For `file:` scheme origins.
30   if (origin->IsLocal()) {
31     if (!file_url_agent_)
32       file_url_agent_ = MakeGarbageCollected<WindowAgent>(isolate);
33     return file_url_agent_;
34   }
35 
36   // For opaque origins.
37   if (origin->IsOpaque()) {
38     auto inserted = opaque_origin_agents_.insert(origin, nullptr);
39     if (inserted.is_new_entry)
40       inserted.stored_value->value = MakeGarbageCollected<WindowAgent>(isolate);
41     return inserted.stored_value->value;
42   }
43 
44   // For tuple origins.
45   String registrable_domain = origin->RegistrableDomain();
46   if (registrable_domain.IsNull())
47     registrable_domain = origin->Host();
48 
49   TupleOriginAgents* tuple_origin_agents = &tuple_origin_agents_;
50 
51   // All chrome extensions need to share the same agent because they can
52   // access each other's windows directly.
53   if (origin->Protocol() == "chrome-extension") {
54     DEFINE_STATIC_LOCAL(Persistent<TupleOriginAgents>, static_origin_agents,
55                         (MakeGarbageCollected<TupleOriginAgents>()));
56     tuple_origin_agents = static_origin_agents;
57   }
58 
59   SchemeAndRegistrableDomain key(origin->Protocol(), registrable_domain);
60   auto inserted = tuple_origin_agents->insert(key, nullptr);
61   if (inserted.is_new_entry)
62     inserted.stored_value->value = MakeGarbageCollected<WindowAgent>(isolate);
63   return inserted.stored_value->value;
64 }
65 
Trace(Visitor * visitor) const66 void WindowAgentFactory::Trace(Visitor* visitor) const {
67   visitor->Trace(universal_access_agent_);
68   visitor->Trace(file_url_agent_);
69   visitor->Trace(opaque_origin_agents_);
70   visitor->Trace(tuple_origin_agents_);
71 }
72 
73 // static
GetHash(const SchemeAndRegistrableDomain & value)74 unsigned WindowAgentFactory::SchemeAndRegistrableDomainHash::GetHash(
75     const SchemeAndRegistrableDomain& value) {
76   return WTF::HashInts(StringHash::GetHash(value.scheme),
77                        StringHash::GetHash(value.registrable_domain));
78 }
79 
80 // static
Equal(const SchemeAndRegistrableDomain & x,const SchemeAndRegistrableDomain & y)81 bool WindowAgentFactory::SchemeAndRegistrableDomainHash::Equal(
82     const SchemeAndRegistrableDomain& x,
83     const SchemeAndRegistrableDomain& y) {
84   return x.scheme == y.scheme && x.registrable_domain == y.registrable_domain;
85 }
86 
87 // static
IsEmptyValue(const SchemeAndRegistrableDomain & value)88 bool WindowAgentFactory::SchemeAndRegistrableDomainTraits::IsEmptyValue(
89     const SchemeAndRegistrableDomain& value) {
90   return HashTraits<String>::IsEmptyValue(value.scheme);
91 }
92 
93 // static
IsDeletedValue(const SchemeAndRegistrableDomain & value)94 bool WindowAgentFactory::SchemeAndRegistrableDomainTraits::IsDeletedValue(
95     const SchemeAndRegistrableDomain& value) {
96   return HashTraits<String>::IsDeletedValue(value.scheme);
97 }
98 
99 // static
100 void WindowAgentFactory::SchemeAndRegistrableDomainTraits::
ConstructDeletedValue(SchemeAndRegistrableDomain & slot,bool zero_value)101     ConstructDeletedValue(SchemeAndRegistrableDomain& slot, bool zero_value) {
102   HashTraits<String>::ConstructDeletedValue(slot.scheme, zero_value);
103 }
104 
105 }  // namespace blink
106