OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 10 matching lines...) Expand all Loading... |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #ifndef DOMWrapperWorld_h | 31 // This file has been moved to platform/bindings/DOMWrapperWorld.h. |
32 #define DOMWrapperWorld_h | 32 // TODO(adithyas): Remove this file. |
33 | 33 #include "platform/bindings/DOMWrapperWorld.h" |
34 #include <memory> | |
35 | |
36 #include "bindings/core/v8/ScriptState.h" | |
37 #include "core/CoreExport.h" | |
38 #include "platform/weborigin/SecurityOrigin.h" | |
39 #include "platform/wtf/PassRefPtr.h" | |
40 #include "platform/wtf/RefCounted.h" | |
41 #include "platform/wtf/RefPtr.h" | |
42 #include "v8/include/v8.h" | |
43 | |
44 namespace blink { | |
45 | |
46 class DOMDataStore; | |
47 class DOMObjectHolderBase; | |
48 | |
49 // This class represent a collection of DOM wrappers for a specific world. This | |
50 // is identified by a world id that is a per-thread global identifier (see | |
51 // WorldId enum). | |
52 class CORE_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { | |
53 public: | |
54 // Per-thread global identifiers for DOMWrapperWorld. | |
55 enum WorldId { | |
56 kInvalidWorldId = -1, | |
57 kMainWorldId = 0, | |
58 | |
59 // Embedder isolated worlds can use IDs in [1, 1<<29). | |
60 kEmbedderWorldIdLimit = (1 << 29), | |
61 kDocumentXMLTreeViewerWorldId, | |
62 kIsolatedWorldIdLimit, | |
63 | |
64 // Other worlds can use IDs after this. Don't manually pick up an ID from | |
65 // this range. generateWorldIdForType() picks it up on behalf of you. | |
66 kUnspecifiedWorldIdStart, | |
67 }; | |
68 | |
69 enum class WorldType { | |
70 kMain, | |
71 kIsolated, | |
72 kGarbageCollector, | |
73 kRegExp, | |
74 kTesting, | |
75 kWorker, | |
76 }; | |
77 | |
78 // Creates a world other than IsolatedWorld. | |
79 static PassRefPtr<DOMWrapperWorld> Create(v8::Isolate*, WorldType); | |
80 | |
81 // Ensures an IsolatedWorld for |worldId|. | |
82 static PassRefPtr<DOMWrapperWorld> EnsureIsolatedWorld(v8::Isolate*, | |
83 int world_id); | |
84 ~DOMWrapperWorld(); | |
85 void Dispose(); | |
86 | |
87 // Called from performance-sensitive functions, so we should keep this simple | |
88 // and fast as much as possible. | |
89 static bool NonMainWorldsExistInMainThread() { | |
90 return number_of_non_main_worlds_in_main_thread_; | |
91 } | |
92 | |
93 static void AllWorldsInCurrentThread(Vector<RefPtr<DOMWrapperWorld>>& worlds); | |
94 static void MarkWrappersInAllWorlds(ScriptWrappable*, | |
95 const ScriptWrappableVisitor*); | |
96 | |
97 static DOMWrapperWorld& World(v8::Local<v8::Context> context) { | |
98 return ScriptState::From(context)->World(); | |
99 } | |
100 | |
101 static DOMWrapperWorld& Current(v8::Isolate* isolate) { | |
102 return World(isolate->GetCurrentContext()); | |
103 } | |
104 | |
105 static DOMWrapperWorld& MainWorld(); | |
106 | |
107 static void SetIsolatedWorldHumanReadableName(int world_id, const String&); | |
108 String IsolatedWorldHumanReadableName(); | |
109 | |
110 // Associates an isolated world (see above for description) with a security | |
111 // origin. XMLHttpRequest instances used in that world will be considered | |
112 // to come from that origin, not the frame's. | |
113 static void SetIsolatedWorldSecurityOrigin(int world_id, | |
114 PassRefPtr<SecurityOrigin>); | |
115 SecurityOrigin* IsolatedWorldSecurityOrigin(); | |
116 | |
117 // Associated an isolated world with a Content Security Policy. Resources | |
118 // embedded into the main world's DOM from script executed in an isolated | |
119 // world should be restricted based on the isolated world's DOM, not the | |
120 // main world's. | |
121 // | |
122 // FIXME: Right now, resource injection simply bypasses the main world's | |
123 // DOM. More work is necessary to allow the isolated world's policy to be | |
124 // applied correctly. | |
125 static void SetIsolatedWorldContentSecurityPolicy(int world_id, | |
126 const String& policy); | |
127 bool IsolatedWorldHasContentSecurityPolicy(); | |
128 | |
129 bool IsMainWorld() const { return world_type_ == WorldType::kMain; } | |
130 bool IsWorkerWorld() const { return world_type_ == WorldType::kWorker; } | |
131 bool IsIsolatedWorld() const { return world_type_ == WorldType::kIsolated; } | |
132 | |
133 int GetWorldId() const { return world_id_; } | |
134 DOMDataStore& DomDataStore() const { return *dom_data_store_; } | |
135 | |
136 template <typename T> | |
137 void RegisterDOMObjectHolder(v8::Isolate* isolate, | |
138 T* object, | |
139 v8::Local<v8::Value> wrapper) { | |
140 RegisterDOMObjectHolderInternal( | |
141 DOMObjectHolder<T>::Create(isolate, object, wrapper)); | |
142 } | |
143 | |
144 private: | |
145 class DOMObjectHolderBase { | |
146 USING_FAST_MALLOC(DOMObjectHolderBase); | |
147 | |
148 public: | |
149 DOMObjectHolderBase(v8::Isolate* isolate, v8::Local<v8::Value> wrapper) | |
150 : wrapper_(isolate, wrapper), world_(nullptr) {} | |
151 virtual ~DOMObjectHolderBase() {} | |
152 | |
153 DOMWrapperWorld* World() const { return world_; } | |
154 void SetWorld(DOMWrapperWorld* world) { world_ = world; } | |
155 void SetWeak(v8::WeakCallbackInfo<DOMObjectHolderBase>::Callback callback) { | |
156 wrapper_.SetWeak(this, callback); | |
157 } | |
158 | |
159 private: | |
160 ScopedPersistent<v8::Value> wrapper_; | |
161 DOMWrapperWorld* world_; | |
162 }; | |
163 | |
164 template <typename T> | |
165 class DOMObjectHolder : public DOMObjectHolderBase { | |
166 public: | |
167 static std::unique_ptr<DOMObjectHolder<T>> | |
168 Create(v8::Isolate* isolate, T* object, v8::Local<v8::Value> wrapper) { | |
169 return WTF::WrapUnique(new DOMObjectHolder(isolate, object, wrapper)); | |
170 } | |
171 | |
172 private: | |
173 DOMObjectHolder(v8::Isolate* isolate, | |
174 T* object, | |
175 v8::Local<v8::Value> wrapper) | |
176 : DOMObjectHolderBase(isolate, wrapper), object_(object) {} | |
177 | |
178 Persistent<T> object_; | |
179 }; | |
180 | |
181 DOMWrapperWorld(v8::Isolate*, WorldType, int world_id); | |
182 | |
183 static void WeakCallbackForDOMObjectHolder( | |
184 const v8::WeakCallbackInfo<DOMObjectHolderBase>&); | |
185 void RegisterDOMObjectHolderInternal(std::unique_ptr<DOMObjectHolderBase>); | |
186 void UnregisterDOMObjectHolder(DOMObjectHolderBase*); | |
187 | |
188 static unsigned number_of_non_main_worlds_in_main_thread_; | |
189 | |
190 // Returns an identifier for a given world type. This must not be called for | |
191 // WorldType::IsolatedWorld because an identifier for the world is given from | |
192 // out of DOMWrapperWorld. | |
193 static int GenerateWorldIdForType(WorldType); | |
194 | |
195 // Dissociates all wrappers in all worlds associated with |script_wrappable|. | |
196 // | |
197 // Do not use this function except for DOMWindow. Only DOMWindow needs to | |
198 // dissociate wrappers from the ScriptWrappable because of the following two | |
199 // reasons. | |
200 // | |
201 // Reason 1) Case of the main world | |
202 // A DOMWindow may be collected by Blink GC *before* V8 GC collects the | |
203 // wrapper because the wrapper object associated with a DOMWindow is a global | |
204 // proxy, which remains after navigations. We don't want V8 GC to reset the | |
205 // weak persistent handle to a wrapper within the DOMWindow | |
206 // (ScriptWrappable::main_world_wrapper_) *after* Blink GC collects the | |
207 // DOMWindow because it's use-after-free. Thus, we need to dissociate the | |
208 // wrapper in advance. | |
209 // | |
210 // Reason 2) Case of isolated worlds | |
211 // As same, a DOMWindow may be collected before the wrapper gets collected. | |
212 // A DOMWrapperMap supports mapping from ScriptWrappable* to v8::Global<T>, | |
213 // and we don't want to leave an entry of an already-dead DOMWindow* to the | |
214 // persistent handle for the global proxy object, especially considering that | |
215 // the address to the already-dead DOMWindow* may be re-used. | |
216 friend class DOMWindow; | |
217 static void DissociateDOMWindowWrappersInAllWorlds(ScriptWrappable*); | |
218 | |
219 const WorldType world_type_; | |
220 const int world_id_; | |
221 std::unique_ptr<DOMDataStore> dom_data_store_; | |
222 HashSet<std::unique_ptr<DOMObjectHolderBase>> dom_object_holders_; | |
223 }; | |
224 | |
225 } // namespace blink | |
226 | |
227 #endif // DOMWrapperWorld_h | |
OLD | NEW |