| 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 |