Commit 857357f3 authored by andersca@apple.com's avatar andersca@apple.com

2011-03-15 Anders Carlsson <andersca@apple.com>

        Reviewed by Sam Weinig.

        Make sure that NP_Shutdown is always the last NPP function called
        https://bugs.webkit.org/show_bug.cgi?id=56391
        <rdar://problem/8989902>

        Make sure to always increment the load count whenever a web process connection
        is opened to a plug-in process, and decrement it when the last web process connection
        goes away.

        * PluginProcess/PluginProcess.cpp:
        (WebKit::PluginProcess::createWebProcessConnection):
        (WebKit::PluginProcess::startShutdownTimerIfNecessary):
        * Shared/Plugins/Netscape/NetscapePluginModule.cpp:
        * Shared/Plugins/Netscape/NetscapePluginModule.h:
        * WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
        (WebKit::NetscapePlugin::NetscapePlugin):
        (WebKit::NetscapePlugin::~NetscapePlugin):
2011-03-15  Anders Carlsson  <andersca@apple.com>

        Reviewed by Sam Weinig.

        Make sure that NP_Shutdown is always the last NPP function called
        https://bugs.webkit.org/show_bug.cgi?id=56391
        <rdar://problem/8989902>

        Add test.

        * plugins/npruntime/np-deallocate-called-before-np-shutdown-expected.txt: Added.
        * plugins/npruntime/np-deallocate-called-before-np-shutdown.html: Added.
2011-03-15  Anders Carlsson  <andersca@apple.com>

        Reviewed by Sam Weinig.

        Make sure that NP_Shutdown is always the last NPP function called
        https://bugs.webkit.org/show_bug.cgi?id=56391

        Add a test that times out if an NP_Deallocate object is called after NP_Shutdown.

        * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
        * DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp:
        (PluginTest::PluginTest):
        (PluginTest::NP_Shutdown):
        (PluginTest::registerNPShutdownFunction):
        * DumpRenderTree/TestNetscapePlugIn/PluginTest.h:
        * DumpRenderTree/TestNetscapePlugIn/Tests/NPDeallocateCalledBeforeNPShutdown.cpp: Added.
        (NPDeallocateCalledBeforeNPShutdown::NPDeallocateCalledBeforeNPShutdown):
        (NPDeallocateCalledBeforeNPShutdown::TestObject::~TestObject):
        (NPDeallocateCalledBeforeNPShutdown::ScriptableObject::hasProperty):
        (NPDeallocateCalledBeforeNPShutdown::ScriptableObject::getProperty):
        (NPDeallocateCalledBeforeNPShutdown::NPP_New):
        (NPDeallocateCalledBeforeNPShutdown::NPP_GetValue):
        (NPDeallocateCalledBeforeNPShutdown::shutdown):
        * DumpRenderTree/TestNetscapePlugIn/main.cpp:
        (NP_Shutdown):
        * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj:
        * DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro:
        * GNUmakefile.am:


git-svn-id: svn://svn.chromium.org/blink/trunk@81157 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 83a6ac21
2011-03-15 Anders Carlsson <andersca@apple.com>
Reviewed by Sam Weinig.
Make sure that NP_Shutdown is always the last NPP function called
https://bugs.webkit.org/show_bug.cgi?id=56391
<rdar://problem/8989902>
Add test.
* plugins/npruntime/np-deallocate-called-before-np-shutdown-expected.txt: Added.
* plugins/npruntime/np-deallocate-called-before-np-shutdown.html: Added.
2011-03-15 Ilya Sherman <isherman@chromium.org>
Reviewed by Tony Chang.
This tests that the NP_Deallocate function of an NPObject isn't called before the NP_Shutdown function.
SUCCESS
<script>
function runTest() {
if (window.layoutTestController)
layoutTestController.dumpAsText();
var testObject = document.getElementById('plugin').testObject;
// Remove the plug-in. The plug-in asserts that shutdown isn't called before
// any calls to NP_Deallocate, so this test will time out if that happens.
document.getElementById('container').innerHTML = '';
document.getElementById('result').innerHTML = 'SUCCESS';
}
</script>
<body onload="runTest()">
<div id="container">
<embed id="plugin" type="application/x-webkit-test-netscape" test="np-deallocate-called-before-np-shutdown" width=100 height=100></embed>
</div>
<div>This tests that the NP_Deallocate function of an NPObject isn't called before the NP_Shutdown function.</div>
<div id="result">FAILURE</div>
\ No newline at end of file
2011-03-15 Anders Carlsson <andersca@apple.com>
Reviewed by Sam Weinig.
Make sure that NP_Shutdown is always the last NPP function called
https://bugs.webkit.org/show_bug.cgi?id=56391
<rdar://problem/8989902>
Make sure to always increment the load count whenever a web process connection
is opened to a plug-in process, and decrement it when the last web process connection
goes away.
* PluginProcess/PluginProcess.cpp:
(WebKit::PluginProcess::createWebProcessConnection):
(WebKit::PluginProcess::startShutdownTimerIfNecessary):
* Shared/Plugins/Netscape/NetscapePluginModule.cpp:
* Shared/Plugins/Netscape/NetscapePluginModule.h:
* WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
(WebKit::NetscapePlugin::NetscapePlugin):
(WebKit::NetscapePlugin::~NetscapePlugin):
2011-03-15 Martin Robinson <mrobinson@igalia.com>
Reviewed by Adam Barth.
......
......@@ -133,6 +133,8 @@ void PluginProcess::createWebProcessConnection()
mach_port_t listeningPort;
mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
bool didHaveAnyWebProcessConnections = !m_webProcessConnections.isEmpty();
// Create a listening connection.
RefPtr<WebProcessConnection> connection = WebProcessConnection::create(listeningPort);
m_webProcessConnections.append(connection.release());
......@@ -140,6 +142,14 @@ void PluginProcess::createWebProcessConnection()
CoreIPC::MachPort clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND);
m_connection->send(Messages::PluginProcessProxy::DidCreateWebProcessConnection(clientPort), 0);
if (NetscapePluginModule* module = netscapePluginModule()) {
if (!didHaveAnyWebProcessConnections) {
// Increment the load count. This is matched by a call to decrementLoadCount in startShutdownTimerIfNecessary.
// We do this so that the plug-in module's NP_Shutdown won't be called until right before exiting.
module->incrementLoadCount();
}
}
// Stop the shutdown timer.
m_shutdownTimer.stop();
}
......@@ -177,6 +187,10 @@ void PluginProcess::startShutdownTimerIfNecessary()
if (!m_webProcessConnections.isEmpty())
return;
// Decrement the load count. This is balanced by a call to incrementLoadCount in createWebProcessConnection.
if (m_pluginModule)
m_pluginModule->decrementLoadCount();
// Start the shutdown timer.
m_shutdownTimer.startOneShot(shutdownTimeout);
}
......
......@@ -58,16 +58,6 @@ NetscapePluginModule::~NetscapePluginModule()
ASSERT(initializedNetscapePluginModules().find(this) == notFound);
}
void NetscapePluginModule::pluginCreated()
{
incrementLoadCount();
}
void NetscapePluginModule::pluginDestroyed()
{
decrementLoadCount();
}
Vector<String> NetscapePluginModule::sitesWithData()
{
Vector<String> sites;
......
......@@ -45,9 +45,9 @@ public:
~NetscapePluginModule();
const NPPluginFuncs& pluginFuncs() const { return m_pluginFuncs; }
void pluginCreated();
void pluginDestroyed();
void incrementLoadCount();
void decrementLoadCount();
static bool getPluginInfo(const String& pluginPath, PluginInfoStore::Plugin&);
......@@ -68,9 +68,6 @@ private:
void applyX11QuirksBeforeLoad();
#endif
void incrementLoadCount();
void decrementLoadCount();
bool tryGetSitesWithData(Vector<String>&);
bool tryClearSiteData(const String& site, uint64_t flags, uint64_t maxAge);
......
......@@ -84,14 +84,14 @@ NetscapePlugin::NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule)
m_npp.ndata = this;
m_npp.pdata = 0;
m_pluginModule->pluginCreated();
m_pluginModule->incrementLoadCount();
}
NetscapePlugin::~NetscapePlugin()
{
ASSERT(!m_isStarted);
m_pluginModule->pluginDestroyed();
m_pluginModule->decrementLoadCount();
}
PassRefPtr<NetscapePlugin> NetscapePlugin::fromNPP(NPP npp)
......
2011-03-15 Anders Carlsson <andersca@apple.com>
Reviewed by Sam Weinig.
Make sure that NP_Shutdown is always the last NPP function called
https://bugs.webkit.org/show_bug.cgi?id=56391
Add a test that times out if an NP_Deallocate object is called after NP_Shutdown.
* DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
* DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp:
(PluginTest::PluginTest):
(PluginTest::NP_Shutdown):
(PluginTest::registerNPShutdownFunction):
* DumpRenderTree/TestNetscapePlugIn/PluginTest.h:
* DumpRenderTree/TestNetscapePlugIn/Tests/NPDeallocateCalledBeforeNPShutdown.cpp: Added.
(NPDeallocateCalledBeforeNPShutdown::NPDeallocateCalledBeforeNPShutdown):
(NPDeallocateCalledBeforeNPShutdown::TestObject::~TestObject):
(NPDeallocateCalledBeforeNPShutdown::ScriptableObject::hasProperty):
(NPDeallocateCalledBeforeNPShutdown::ScriptableObject::getProperty):
(NPDeallocateCalledBeforeNPShutdown::NPP_New):
(NPDeallocateCalledBeforeNPShutdown::NPP_GetValue):
(NPDeallocateCalledBeforeNPShutdown::shutdown):
* DumpRenderTree/TestNetscapePlugIn/main.cpp:
(NP_Shutdown):
* DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj:
* DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro:
* GNUmakefile.am:
2011-03-15 Ilya Sherman <isherman@chromium.org>
Reviewed by Tony Chang.
......
......@@ -42,6 +42,7 @@
1AC6C84A0D07638600CD3161 /* PluginObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C7800D07589B00CD3161 /* PluginObject.cpp */; };
1AC6C84B0D07638600CD3161 /* TestObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C7810D07589B00CD3161 /* TestObject.cpp */; };
1AC77DCF120605B6005C19EF /* NPRuntimeRemoveProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC77DCE120605B6005C19EF /* NPRuntimeRemoveProperty.cpp */; };
1ACF898D132EF41C00E915D4 /* NPDeallocateCalledBeforeNPShutdown.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACF898B132EF41C00E915D4 /* NPDeallocateCalledBeforeNPShutdown.cpp */; };
1AD4CB2212A6D1350027A7AF /* GetUserAgentWithNullNPPFromNPPNew.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD4CB2012A6D1350027A7AF /* GetUserAgentWithNullNPPFromNPPNew.cpp */; };
1AD9D2FE12028409001A70D1 /* PluginScriptableNPObjectInvokeDefault.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD9D2FD12028409001A70D1 /* PluginScriptableNPObjectInvokeDefault.cpp */; };
23BCB8900EA57623003C6289 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 23BCB88F0EA57623003C6289 /* OpenGL.framework */; };
......@@ -214,6 +215,7 @@
1AC6C7800D07589B00CD3161 /* PluginObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginObject.cpp; sourceTree = "<group>"; };
1AC6C7810D07589B00CD3161 /* TestObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestObject.cpp; sourceTree = "<group>"; };
1AC77DCE120605B6005C19EF /* NPRuntimeRemoveProperty.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NPRuntimeRemoveProperty.cpp; sourceTree = "<group>"; };
1ACF898B132EF41C00E915D4 /* NPDeallocateCalledBeforeNPShutdown.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NPDeallocateCalledBeforeNPShutdown.cpp; sourceTree = "<group>"; };
1AD4CB2012A6D1350027A7AF /* GetUserAgentWithNullNPPFromNPPNew.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetUserAgentWithNullNPPFromNPPNew.cpp; sourceTree = "<group>"; };
1AD9D2FD12028409001A70D1 /* PluginScriptableNPObjectInvokeDefault.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginScriptableNPObjectInvokeDefault.cpp; sourceTree = "<group>"; };
23BCB88F0EA57623003C6289 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
......@@ -477,6 +479,7 @@
C0E720741281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp */,
1A3E28A91311D73B00501349 /* GetURLWithJavaScriptURLDestroyingPlugin.cpp */,
1AD4CB2012A6D1350027A7AF /* GetUserAgentWithNullNPPFromNPPNew.cpp */,
1ACF898B132EF41C00E915D4 /* NPDeallocateCalledBeforeNPShutdown.cpp */,
1A24BAA8120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp */,
1AC77DCE120605B6005C19EF /* NPRuntimeRemoveProperty.cpp */,
C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */,
......@@ -770,6 +773,7 @@
C0E720751281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp in Sources */,
1AD4CB2212A6D1350027A7AF /* GetUserAgentWithNullNPPFromNPPNew.cpp in Sources */,
1A3E28AA1311D73B00501349 /* GetURLWithJavaScriptURLDestroyingPlugin.cpp in Sources */,
1ACF898D132EF41C00E915D4 /* NPDeallocateCalledBeforeNPShutdown.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -31,6 +31,8 @@
using namespace std;
extern NPNetscapeFuncs *browser;
static void (*shutdownFunction)();
PluginTest* PluginTest::create(NPP npp, const string& identifier)
{
if (identifier.empty())
......@@ -47,12 +49,26 @@ PluginTest::PluginTest(NPP npp, const string& identifier)
: m_npp(npp)
, m_identifier(identifier)
{
// Reset the shutdown function.
shutdownFunction = 0;
}
PluginTest::~PluginTest()
{
}
void PluginTest::NP_Shutdown()
{
if (shutdownFunction)
shutdownFunction();
}
void PluginTest::registerNPShutdownFunction(void (*func)())
{
assert(!shutdownFunction);
shutdownFunction = func;
}
NPError PluginTest::NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved)
{
return NPERR_NO_ERROR;
......
......@@ -54,6 +54,8 @@ public:
static PluginTest* create(NPP, const std::string& identifier);
virtual ~PluginTest();
static void NP_Shutdown();
// NPP functions.
virtual NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved);
virtual NPError NPP_Destroy(NPSavedData**);
......@@ -74,6 +76,8 @@ public:
void executeScript(const char*);
void registerNPShutdownFunction(void (*)());
template<typename TestClassTy> class Register {
public:
Register(const std::string& identifier)
......
/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PluginTest.h"
using namespace std;
static bool wasShutdownCalled = false;
class NPDeallocateCalledBeforeNPShutdown : public PluginTest {
public:
NPDeallocateCalledBeforeNPShutdown(NPP npp, const string& identifier)
: PluginTest(npp, identifier)
{
}
private:
// This is the test object.
class TestObject : public Object<TestObject> {
public:
~TestObject()
{
// This should really be an assert, but there's no way for the test framework
// to know that the plug-in process crashed, so we'll just sleep for a while
// to ensure that the test times out.
if (wasShutdownCalled)
sleep(1000);
}
};
// This is the scriptable object. It has a single "testObject" property.
class ScriptableObject : public Object<ScriptableObject> {
public:
bool hasProperty(NPIdentifier propertyName)
{
return propertyName == pluginTest()->NPN_GetStringIdentifier("testObject");
}
bool getProperty(NPIdentifier propertyName, NPVariant* result)
{
if (propertyName != pluginTest()->NPN_GetStringIdentifier("testObject"))
return false;
NPObject* testObject = TestObject::create(pluginTest());
OBJECT_TO_NPVARIANT(testObject, *result);
return true;
}
};
virtual NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved)
{
registerNPShutdownFunction(shutdown);
return NPERR_NO_ERROR;
}
virtual NPError NPP_GetValue(NPPVariable variable, void *value)
{
if (variable != NPPVpluginScriptableNPObject)
return NPERR_GENERIC_ERROR;
*(NPObject**)value = ScriptableObject::create(this);
return NPERR_NO_ERROR;
}
static void shutdown()
{
wasShutdownCalled = true;
}
};
static PluginTest::Register<NPDeallocateCalledBeforeNPShutdown> npRuntimeObjectFromDestroyedPlugin("np-deallocate-called-before-np-shutdown");
......@@ -123,6 +123,7 @@ NPError STDCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs)
extern "C"
void STDCALL NP_Shutdown(void)
{
PluginTest::NP_Shutdown();
}
static void executeScript(const PluginObject* obj, const char* script);
......
......@@ -405,6 +405,10 @@
RelativePath="..\Tests\GetUserAgentWithNullNPPFromNPPNew.cpp"
>
</File>
<File
RelativePath="..\Tests\NPDeallocateCalledBeforeNPShutdown.cpp"
>
</File>
<File
RelativePath="..\Tests\NPRuntimeObjectFromDestroyedPlugin.cpp"
>
......
......@@ -32,6 +32,7 @@ SOURCES = PluginObject.cpp \
Tests/EvaluateJSAfterRemovingPluginElement.cpp \
Tests/GetURLWithJavaScriptURLDestroyingPlugin.cpp \
Tests/GetUserAgentWithNullNPPFromNPPNew.cpp \
Tests/NPDeallocateCalledBeforeNPShutdown.cpp \
Tests/NPRuntimeObjectFromDestroyedPlugin.cpp \
Tests/NPRuntimeRemoveProperty.cpp \
Tests/NullNPPGetValuePointer.cpp \
......
......@@ -180,6 +180,7 @@ TestNetscapePlugin_libtestnetscapeplugin_la_SOURCES = \
Tools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp \
Tools/DumpRenderTree/TestNetscapePlugIn/Tests/GetURLWithJavaScriptURLDestroyingPlugin.cpp \
Tools/DumpRenderTree/TestNetscapePlugIn/Tests/GetUserAgentWithNullNPPFromNPPNew.cpp \
Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NPDeallocateCalledBeforeNPShutdown.cpp \
Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NPRuntimeObjectFromDestroyedPlugin.cpp \
Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NPRuntimeRemoveProperty.cpp \
Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NullNPPGetValuePointer.cpp \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment