1/* 2 * Copyright (C) 2010 Apple 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 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "NPRemoteObjectMap.h" 28 29#if ENABLE(NETSCAPE_PLUGIN_API) 30 31#include "NPObjectMessageReceiver.h" 32#include "NPObjectProxy.h" 33#include "NPRuntimeUtilities.h" 34#include "NPVariantData.h" 35 36namespace WebKit { 37 38static uint64_t generateNPObjectID() 39{ 40 static uint64_t generateNPObjectID; 41 return ++generateNPObjectID; 42} 43 44PassRefPtr<NPRemoteObjectMap> NPRemoteObjectMap::create(IPC::Connection* connection) 45{ 46 return adoptRef(new NPRemoteObjectMap(connection)); 47} 48 49NPRemoteObjectMap::NPRemoteObjectMap(IPC::Connection* connection) 50 : m_connection(connection) 51{ 52} 53 54NPRemoteObjectMap::~NPRemoteObjectMap() 55{ 56 ASSERT(m_npObjectProxies.isEmpty()); 57 ASSERT(m_registeredNPObjects.isEmpty()); 58} 59 60NPObject* NPRemoteObjectMap::createNPObjectProxy(uint64_t remoteObjectID, Plugin* plugin) 61{ 62 NPObjectProxy* npObjectProxy = NPObjectProxy::create(this, plugin, remoteObjectID); 63 64 m_npObjectProxies.add(npObjectProxy); 65 66 return npObjectProxy; 67} 68 69void NPRemoteObjectMap::npObjectProxyDestroyed(NPObject* npObject) 70{ 71 NPObjectProxy* npObjectProxy = NPObjectProxy::toNPObjectProxy(npObject); 72 ASSERT(m_npObjectProxies.contains(npObjectProxy)); 73 74 m_npObjectProxies.remove(npObjectProxy); 75} 76 77uint64_t NPRemoteObjectMap::registerNPObject(NPObject* npObject, Plugin* plugin) 78{ 79 uint64_t npObjectID = generateNPObjectID(); 80 m_registeredNPObjects.set(npObjectID, std::make_unique<NPObjectMessageReceiver>(this, plugin, npObjectID, npObject).release()); 81 82 return npObjectID; 83} 84 85void NPRemoteObjectMap::unregisterNPObject(uint64_t npObjectID) 86{ 87 m_registeredNPObjects.remove(npObjectID); 88} 89 90static uint64_t remoteNPObjectID(Plugin* plugin, NPObject* npObject) 91{ 92 if (!NPObjectProxy::isNPObjectProxy(npObject)) 93 return 0; 94 95 NPObjectProxy* npObjectProxy = NPObjectProxy::toNPObjectProxy(npObject); 96 if (npObjectProxy->plugin() != plugin) 97 return 0; 98 99 return npObjectProxy->npObjectID(); 100} 101 102NPVariantData NPRemoteObjectMap::npVariantToNPVariantData(const NPVariant& variant, Plugin* plugin) 103{ 104 switch (variant.type) { 105 case NPVariantType_Void: 106 return NPVariantData::makeVoid(); 107 108 case NPVariantType_Null: 109 return NPVariantData::makeNull(); 110 111 case NPVariantType_Bool: 112 return NPVariantData::makeBool(variant.value.boolValue); 113 114 case NPVariantType_Int32: 115 return NPVariantData::makeInt32(variant.value.intValue); 116 117 case NPVariantType_Double: 118 return NPVariantData::makeDouble(variant.value.doubleValue); 119 120 case NPVariantType_String: 121 return NPVariantData::makeString(variant.value.stringValue.UTF8Characters, variant.value.stringValue.UTF8Length); 122 123 case NPVariantType_Object: { 124 NPObject* npObject = variant.value.objectValue; 125 126 if (uint64_t npObjectID = remoteNPObjectID(plugin, npObject)) { 127 // FIXME: Under some circumstances, this might leak the NPObjectProxy object. 128 // Figure out how to avoid that. 129 retainNPObject(npObject); 130 return NPVariantData::makeRemoteNPObjectID(npObjectID); 131 } 132 133 uint64_t npObjectID = registerNPObject(npObject, plugin); 134 return NPVariantData::makeLocalNPObjectID(npObjectID); 135 } 136 137 } 138 139 ASSERT_NOT_REACHED(); 140 return NPVariantData::makeVoid(); 141} 142 143NPVariant NPRemoteObjectMap::npVariantDataToNPVariant(const NPVariantData& npVariantData, Plugin* plugin) 144{ 145 NPVariant npVariant; 146 147 switch (npVariantData.type()) { 148 case NPVariantData::Void: 149 VOID_TO_NPVARIANT(npVariant); 150 break; 151 case NPVariantData::Null: 152 NULL_TO_NPVARIANT(npVariant); 153 break; 154 case NPVariantData::Bool: 155 BOOLEAN_TO_NPVARIANT(npVariantData.boolValue(), npVariant); 156 break; 157 case NPVariantData::Int32: 158 INT32_TO_NPVARIANT(npVariantData.int32Value(), npVariant); 159 break; 160 case NPVariantData::Double: 161 DOUBLE_TO_NPVARIANT(npVariantData.doubleValue(), npVariant); 162 break; 163 case NPVariantData::String: { 164 NPString npString = createNPString(npVariantData.stringValue()); 165 STRINGN_TO_NPVARIANT(npString.UTF8Characters, npString.UTF8Length, npVariant); 166 break; 167 } 168 case NPVariantData::LocalNPObjectID: { 169 uint64_t npObjectID = npVariantData.localNPObjectIDValue(); 170 ASSERT(npObjectID); 171 172 NPObjectMessageReceiver* npObjectMessageReceiver = m_registeredNPObjects.get(npObjectID); 173 if (!npObjectMessageReceiver) { 174 ASSERT_NOT_REACHED(); 175 VOID_TO_NPVARIANT(npVariant); 176 break; 177 } 178 179 NPObject* npObject = npObjectMessageReceiver->npObject(); 180 ASSERT(npObject); 181 182 retainNPObject(npObject); 183 OBJECT_TO_NPVARIANT(npObject, npVariant); 184 break; 185 } 186 case NPVariantData::RemoteNPObjectID: { 187 NPObject* npObjectProxy = createNPObjectProxy(npVariantData.remoteNPObjectIDValue(), plugin); 188 OBJECT_TO_NPVARIANT(npObjectProxy, npVariant); 189 break; 190 } 191 } 192 193 return npVariant; 194} 195 196void NPRemoteObjectMap::pluginDestroyed(Plugin* plugin) 197{ 198 // Gather and delete the receivers associated with this plug-in. 199 Vector<NPObjectMessageReceiver*> receivers; 200 for (auto* receiver : m_registeredNPObjects.values()) { 201 if (receiver->plugin() == plugin) 202 receivers.append(receiver); 203 } 204 for (auto* receiver : receivers) 205 delete receiver; 206 207 // Invalidate and remove all proxies associated with this plug-in. 208 Vector<NPObjectProxy*> proxies; 209 for (auto* proxy : m_npObjectProxies) { 210 if (proxy->plugin() == plugin) 211 proxies.append(proxy); 212 } 213 for (auto* proxy : proxies) { 214 proxy->invalidate(); 215 ASSERT(m_npObjectProxies.contains(proxy)); 216 m_npObjectProxies.remove(proxy); 217 } 218} 219 220void NPRemoteObjectMap::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder) 221{ 222 NPObjectMessageReceiver* messageReceiver = m_registeredNPObjects.get(decoder.destinationID()); 223 if (!messageReceiver) 224 return; 225 226 messageReceiver->didReceiveSyncNPObjectMessageReceiverMessage(connection, decoder, replyEncoder); 227} 228 229} // namespace WebKit 230 231#endif // ENABLE(NETSCAPE_PLUGIN_API) 232