1 /* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 29 */ 30 31 #include "config.h" 32 #include "bindings/v8/DOMWrapperWorld.h" 33 34 #include "bindings/core/v8/V8Window.h" 35 #include "bindings/v8/DOMDataStore.h" 36 #include "bindings/v8/ScriptController.h" 37 #include "bindings/v8/V8Binding.h" 38 #include "bindings/v8/V8DOMActivityLogger.h" 39 #include "bindings/v8/V8DOMWrapper.h" 40 #include "bindings/v8/V8WindowShell.h" 41 #include "bindings/v8/WrapperTypeInfo.h" 42 #include "core/dom/ExecutionContext.h" 43 #include "wtf/HashTraits.h" 44 #include "wtf/StdLibExtras.h" 45 46 namespace WebCore { 47 48 unsigned DOMWrapperWorld::isolatedWorldCount = 0; 49 DOMWrapperWorld* DOMWrapperWorld::worldOfInitializingWindow = 0; 50 51 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::create(int worldId, int extensionGroup) 52 { 53 return adoptRef(new DOMWrapperWorld(worldId, extensionGroup)); 54 } 55 56 DOMWrapperWorld::DOMWrapperWorld(int worldId, int extensionGroup) 57 : m_worldId(worldId) 58 , m_extensionGroup(extensionGroup) 59 , m_domDataStore(adoptPtr(new DOMDataStore(isMainWorld()))) 60 { 61 } 62 63 DOMWrapperWorld& DOMWrapperWorld::mainWorld() 64 { 65 ASSERT(isMainThread()); 66 DEFINE_STATIC_REF(DOMWrapperWorld, cachedMainWorld, (DOMWrapperWorld::create(MainWorldId, mainWorldExtensionGroup))); 67 return *cachedMainWorld; 68 } 69 70 typedef HashMap<int, DOMWrapperWorld*> WorldMap; 71 static WorldMap& isolatedWorldMap() 72 { 73 ASSERT(isMainThread()); 74 DEFINE_STATIC_LOCAL(WorldMap, map, ()); 75 return map; 76 } 77 78 void DOMWrapperWorld::allWorldsInMainThread(Vector<RefPtr<DOMWrapperWorld> >& worlds) 79 { 80 ASSERT(isMainThread()); 81 worlds.append(&mainWorld()); 82 WorldMap& isolatedWorlds = isolatedWorldMap(); 83 for (WorldMap::iterator it = isolatedWorlds.begin(); it != isolatedWorlds.end(); ++it) 84 worlds.append(it->value); 85 } 86 87 DOMWrapperWorld::~DOMWrapperWorld() 88 { 89 ASSERT(!isMainWorld()); 90 91 dispose(); 92 93 if (!isIsolatedWorld()) 94 return; 95 96 WorldMap& map = isolatedWorldMap(); 97 WorldMap::iterator it = map.find(m_worldId); 98 if (it == map.end()) { 99 ASSERT_NOT_REACHED(); 100 return; 101 } 102 ASSERT(it->value == this); 103 104 map.remove(it); 105 isolatedWorldCount--; 106 ASSERT(map.size() == isolatedWorldCount); 107 } 108 109 void DOMWrapperWorld::dispose() 110 { 111 m_domDataStore.clear(); 112 } 113 114 #ifndef NDEBUG 115 static bool isIsolatedWorldId(int worldId) 116 { 117 return MainWorldId < worldId && worldId < IsolatedWorldIdLimit; 118 } 119 #endif 120 121 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::ensureIsolatedWorld(int worldId, int extensionGroup) 122 { 123 ASSERT(isIsolatedWorldId(worldId)); 124 125 WorldMap& map = isolatedWorldMap(); 126 WorldMap::AddResult result = map.add(worldId, 0); 127 RefPtr<DOMWrapperWorld> world = result.storedValue->value; 128 if (world) { 129 ASSERT(world->worldId() == worldId); 130 ASSERT(world->extensionGroup() == extensionGroup); 131 return world.release(); 132 } 133 134 world = DOMWrapperWorld::create(worldId, extensionGroup); 135 result.storedValue->value = world.get(); 136 isolatedWorldCount++; 137 ASSERT(map.size() == isolatedWorldCount); 138 139 return world.release(); 140 } 141 142 typedef HashMap<int, RefPtr<SecurityOrigin> > IsolatedWorldSecurityOriginMap; 143 static IsolatedWorldSecurityOriginMap& isolatedWorldSecurityOrigins() 144 { 145 ASSERT(isMainThread()); 146 DEFINE_STATIC_LOCAL(IsolatedWorldSecurityOriginMap, map, ()); 147 return map; 148 } 149 150 SecurityOrigin* DOMWrapperWorld::isolatedWorldSecurityOrigin() 151 { 152 ASSERT(this->isIsolatedWorld()); 153 IsolatedWorldSecurityOriginMap& origins = isolatedWorldSecurityOrigins(); 154 IsolatedWorldSecurityOriginMap::iterator it = origins.find(worldId()); 155 return it == origins.end() ? 0 : it->value.get(); 156 } 157 158 void DOMWrapperWorld::setIsolatedWorldSecurityOrigin(int worldId, PassRefPtr<SecurityOrigin> securityOrigin) 159 { 160 ASSERT(isIsolatedWorldId(worldId)); 161 if (securityOrigin) 162 isolatedWorldSecurityOrigins().set(worldId, securityOrigin); 163 else 164 isolatedWorldSecurityOrigins().remove(worldId); 165 } 166 167 typedef HashMap<int, bool> IsolatedWorldContentSecurityPolicyMap; 168 static IsolatedWorldContentSecurityPolicyMap& isolatedWorldContentSecurityPolicies() 169 { 170 ASSERT(isMainThread()); 171 DEFINE_STATIC_LOCAL(IsolatedWorldContentSecurityPolicyMap, map, ()); 172 return map; 173 } 174 175 bool DOMWrapperWorld::isolatedWorldHasContentSecurityPolicy() 176 { 177 ASSERT(this->isIsolatedWorld()); 178 IsolatedWorldContentSecurityPolicyMap& policies = isolatedWorldContentSecurityPolicies(); 179 IsolatedWorldContentSecurityPolicyMap::iterator it = policies.find(worldId()); 180 return it == policies.end() ? false : it->value; 181 } 182 183 void DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(int worldId, const String& policy) 184 { 185 ASSERT(isIsolatedWorldId(worldId)); 186 if (!policy.isEmpty()) 187 isolatedWorldContentSecurityPolicies().set(worldId, true); 188 else 189 isolatedWorldContentSecurityPolicies().remove(worldId); 190 } 191 192 } // namespace WebCore 193