[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756
jhoneycutt at apple.com
jhoneycutt at apple.com
Fri Feb 26 22:17:06 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit c1e21f5ac7f2f6ac799d32ccb890ad3e938cf4c1
Author: jhoneycutt at apple.com <jhoneycutt at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Feb 10 20:18:29 2010 +0000
<rdar://problem/7436875> Crash in Flash when visiting
http://www.cctv.com/default.shtml (WER ID 819298200) [watson 2502260]
Reviewed by Darin Adler.
WebCore:
Test: platform/win/plugins/plugin-delayed-destroy.html
* bridge/NP_jsobject.cpp:
(_NPN_Evaluate):
If Flash calls this to evaluate a script that destroys the PluginView,
we crash when returning to Flash code. Before evaluating the script,
call PluginView::keepAlive() to hold a ref to this instance (and release
it asynchronously).
* plugins/PluginView.cpp:
(WebCore::instanceMap):
Return a map from the NPP to the PluginView.
(WebCore::PluginView::~PluginView):
Assert that the keep alive timer is not running; remove ourselves from
the instance map.
(WebCore::PluginView::performRequest):
The parent Frame is now a RefPtr; use .get().
(WebCore::PluginView::status):
Ditto.
(WebCore::PluginView::didReceiveResponse):
Ditto.
(WebCore::PluginView::PluginView):
Add the view to the instance map.
(WebCore::PluginView::lifeSupportTimerFired):
Deref the PluginView.
(WebCore::PluginView::keepAlive):
Ref the PluginView, then start a time to release the reference
asynchronously.
(WebCore::PluginView::keepAlive):
Find the PluginView in the map, and call its keepAlive() function.
* plugins/PluginView.h:
Made m_parentFrame a RefPtr, so that it will remain valid when the
keep alive timer fires.
(WebCore::PluginView::parentFrame):
Use .get().
* plugins/gtk/PluginViewGtk.cpp:
(WebCore::PluginView::updatePluginWidget):
Use .get().
(WebCore::PluginView::handleKeyboardEvent):
Use .get().
(WebCore::PluginView::handleMouseEvent):
Use .get().
* plugins/PluginViewNone.cpp:
(WebCore::PluginView::keepAlive):
Stubbed.
WebKitTools:
* DumpRenderTree/win/TestNetscapePlugin/main.cpp:
(executeScript):
Moved to an earlier point in the file.
(NPP_New):
If the plug-in has an onDestroy attribute, store its value.
(NPP_Destroy):
If the plug-in has code to run on destruction, run it and free it.
LayoutTests:
* platform/win/plugins/plugin-delayed-destroy-expected.txt: Added.
* platform/win/plugins/plugin-delayed-destroy.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54614 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 066a663..d2bf0fa 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-02-08 Jon Honeycutt <jhoneycutt at apple.com>
+
+ <rdar://problem/7436875> Crash in Flash when visiting
+ http://www.cctv.com/default.shtml (WER ID 819298200) [watson 2502260]
+
+ Reviewed by Darin Adler.
+
+ * platform/win/plugins/plugin-delayed-destroy-expected.txt: Added.
+ * platform/win/plugins/plugin-delayed-destroy.html: Added.
+
2010-02-10 Diego Gonzalez <diego.gonzalez at openbossa.org>
Reviewed by Kenneth Rohde Christiansen.
diff --git a/LayoutTests/platform/win/plugins/plugin-delayed-destroy-expected.txt b/LayoutTests/platform/win/plugins/plugin-delayed-destroy-expected.txt
new file mode 100644
index 0000000..f5479f9
--- /dev/null
+++ b/LayoutTests/platform/win/plugins/plugin-delayed-destroy-expected.txt
@@ -0,0 +1,3 @@
+The should be printed before destroy.
+Plug-in destroyed.
+
diff --git a/LayoutTests/platform/win/plugins/plugin-delayed-destroy.html b/LayoutTests/platform/win/plugins/plugin-delayed-destroy.html
new file mode 100644
index 0000000..74c3d1f
--- /dev/null
+++ b/LayoutTests/platform/win/plugins/plugin-delayed-destroy.html
@@ -0,0 +1,31 @@
+<html>
+<body>
+ <pre id="console"></pre>
+ <div id="outer">
+ <embed id="plg" type="application/x-webkit-test-netscape" onDestroy="pluginDestroyed()"></embed>
+ </div>
+ <script>
+ function log(message)
+ {
+ document.getElementById("console").appendChild(document.createTextNode(message + "\n"));
+ }
+
+ function pluginDestroyed()
+ {
+ log("Plug-in destroyed.")
+ layoutTestController.notifyDone();
+ }
+
+ if (window.layoutTestController) {
+ layoutTestController.waitUntilDone();
+ layoutTestController.dumpAsText();
+ }
+
+ var plugin = document.getElementById("plg");
+
+ plugin.testEvaluate("window.document.getElementById('outer').innerHTML = '';");
+
+ log("The should be printed before destroy.");
+ </script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 3c49e38..dcdadd9 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,59 @@
+2010-02-08 Jon Honeycutt <jhoneycutt at apple.com>
+
+ <rdar://problem/7436875> Crash in Flash when visiting
+ http://www.cctv.com/default.shtml (WER ID 819298200) [watson 2502260]
+
+ Reviewed by Darin Adler.
+
+ Test: platform/win/plugins/plugin-delayed-destroy.html
+
+ * bridge/NP_jsobject.cpp:
+ (_NPN_Evaluate):
+ If Flash calls this to evaluate a script that destroys the PluginView,
+ we crash when returning to Flash code. Before evaluating the script,
+ call PluginView::keepAlive() to hold a ref to this instance (and release
+ it asynchronously).
+
+ * plugins/PluginView.cpp:
+ (WebCore::instanceMap):
+ Return a map from the NPP to the PluginView.
+ (WebCore::PluginView::~PluginView):
+ Assert that the keep alive timer is not running; remove ourselves from
+ the instance map.
+ (WebCore::PluginView::performRequest):
+ The parent Frame is now a RefPtr; use .get().
+ (WebCore::PluginView::status):
+ Ditto.
+ (WebCore::PluginView::didReceiveResponse):
+ Ditto.
+ (WebCore::PluginView::PluginView):
+ Add the view to the instance map.
+ (WebCore::PluginView::lifeSupportTimerFired):
+ Deref the PluginView.
+ (WebCore::PluginView::keepAlive):
+ Ref the PluginView, then start a time to release the reference
+ asynchronously.
+ (WebCore::PluginView::keepAlive):
+ Find the PluginView in the map, and call its keepAlive() function.
+
+ * plugins/PluginView.h:
+ Made m_parentFrame a RefPtr, so that it will remain valid when the
+ keep alive timer fires.
+ (WebCore::PluginView::parentFrame):
+ Use .get().
+
+ * plugins/gtk/PluginViewGtk.cpp:
+ (WebCore::PluginView::updatePluginWidget):
+ Use .get().
+ (WebCore::PluginView::handleKeyboardEvent):
+ Use .get().
+ (WebCore::PluginView::handleMouseEvent):
+ Use .get().
+
+ * plugins/PluginViewNone.cpp:
+ (WebCore::PluginView::keepAlive):
+ Stubbed.
+
2010-02-10 Jesus Sanchez-Palencia <jesus.palencia at openbossa.org>
Reviewed by Kenneth Rohde Christiansen.
diff --git a/WebCore/bridge/NP_jsobject.cpp b/WebCore/bridge/NP_jsobject.cpp
index a30b6d7..09851df 100644
--- a/WebCore/bridge/NP_jsobject.cpp
+++ b/WebCore/bridge/NP_jsobject.cpp
@@ -30,6 +30,7 @@
#include "NP_jsobject.h"
#include "PlatformString.h"
+#include "PluginView.h"
#include "StringSourceProvider.h"
#include "c_utility.h"
#include "c_instance.h"
@@ -190,7 +191,7 @@ bool _NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVariant*
return true;
}
-bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant)
+bool _NPN_Evaluate(NPP instance, NPObject* o, NPString* s, NPVariant* variant)
{
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o);
@@ -199,6 +200,10 @@ bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant)
if (!rootObject || !rootObject->isValid())
return false;
+ // There is a crash in Flash when evaluating a script that destroys the
+ // PluginView, so we destroy it asynchronously.
+ PluginView::keepAlive(instance);
+
ExecState* exec = rootObject->globalObject()->globalExec();
JSLock lock(SilenceAssertionsOnly);
String scriptString = convertNPStringToUTF16(s);
diff --git a/WebCore/plugins/PluginView.cpp b/WebCore/plugins/PluginView.cpp
index 3ff4c82..9e1d454 100644
--- a/WebCore/plugins/PluginView.cpp
+++ b/WebCore/plugins/PluginView.cpp
@@ -86,6 +86,14 @@ using namespace HTMLNames;
static int s_callingPlugin;
+typedef HashMap<NPP, PluginView*> InstanceMap;
+
+static InstanceMap& instanceMap()
+{
+ static InstanceMap& map = *new InstanceMap;
+ return map;
+}
+
static String scriptStringIfJavaScriptURL(const KURL& url)
{
if (!protocolIsJavaScript(url))
@@ -258,6 +266,10 @@ PluginView::~PluginView()
{
LOG(Plugins, "PluginView::~PluginView()");
+ ASSERT(!m_lifeSupportTimer.isActive());
+
+ instanceMap().remove(m_instance);
+
removeFromUnstartedListIfNecessary();
stop();
@@ -423,7 +435,7 @@ void PluginView::performRequest(PluginRequest* request)
// if this is not a targeted request, create a stream for it. otherwise,
// just pass it off to the loader
if (targetFrameName.isEmpty()) {
- RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame, request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
+ RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame.get(), request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
m_streams.add(stream);
stream->start();
} else {
@@ -461,7 +473,7 @@ void PluginView::performRequest(PluginRequest* request)
if (getString(parentFrame->script(), result, resultString))
cstr = resultString.utf8();
- RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame, request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
+ RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame.get(), request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
m_streams.add(stream);
stream->sendJavaScriptStream(requestURL, cstr);
}
@@ -600,7 +612,7 @@ NPError PluginView::destroyStream(NPStream* stream, NPReason reason)
void PluginView::status(const char* message)
{
if (Page* page = m_parentFrame->page())
- page->chrome()->setStatusbarText(m_parentFrame, String(message));
+ page->chrome()->setStatusbarText(m_parentFrame.get(), String(message));
}
NPError PluginView::setValue(NPPVariable variable, void* value)
@@ -792,6 +804,7 @@ PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* p
, m_requestTimer(this, &PluginView::requestTimerFired)
, m_invalidateTimer(this, &PluginView::invalidateTimerFired)
, m_popPopupsStateTimer(this, &PluginView::popPopupsStateTimerFired)
+ , m_lifeSupportTimer(this, &PluginView::lifeSupportTimerFired)
, m_mode(loadManually ? NP_FULL : NP_EMBED)
, m_paramNames(0)
, m_paramValues(0)
@@ -845,6 +858,8 @@ PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* p
m_instance->ndata = this;
m_instance->pdata = 0;
+ instanceMap().add(m_instance, this);
+
setParameters(paramNames, paramValues);
memset(&m_npWindow, 0, sizeof(m_npWindow));
@@ -871,7 +886,7 @@ void PluginView::didReceiveResponse(const ResourceResponse& response)
ASSERT(m_loadManually);
ASSERT(!m_manualStream);
- m_manualStream = PluginStream::create(this, m_parentFrame, m_parentFrame->loader()->activeDocumentLoader()->request(), false, 0, plugin()->pluginFuncs(), instance(), m_plugin->quirks());
+ m_manualStream = PluginStream::create(this, m_parentFrame.get(), m_parentFrame->loader()->activeDocumentLoader()->request(), false, 0, plugin()->pluginFuncs(), instance(), m_plugin->quirks());
m_manualStream->setLoadManually(true);
m_manualStream->didReceiveResponse(0, response);
@@ -1249,4 +1264,27 @@ String PluginView::pluginName() const
return m_plugin->name();
}
+void PluginView::lifeSupportTimerFired(Timer<PluginView>*)
+{
+ deref();
+}
+
+void PluginView::keepAlive()
+{
+ if (m_lifeSupportTimer.isActive())
+ return;
+
+ ref();
+ m_lifeSupportTimer.startOneShot(0);
+}
+
+void PluginView::keepAlive(NPP instance)
+{
+ PluginView* view = instanceMap().get(instance);
+ if (!view)
+ return;
+
+ view->keepAlive();
+}
+
} // namespace WebCore
diff --git a/WebCore/plugins/PluginView.h b/WebCore/plugins/PluginView.h
index ac60fd4..bb06f14 100644
--- a/WebCore/plugins/PluginView.h
+++ b/WebCore/plugins/PluginView.h
@@ -179,7 +179,7 @@ namespace WebCore {
virtual bool isPluginView() const { return true; }
- Frame* parentFrame() const { return m_parentFrame; }
+ Frame* parentFrame() const { return m_parentFrame.get(); }
void focusPluginElement();
@@ -213,6 +213,9 @@ namespace WebCore {
bool start();
+ static void keepAlive(NPP);
+ void keepAlive();
+
private:
PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
@@ -238,7 +241,7 @@ namespace WebCore {
static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*);
#endif
- Frame* m_parentFrame;
+ RefPtr<Frame> m_parentFrame;
RefPtr<PluginPackage> m_plugin;
Element* m_element;
bool m_isStarted;
@@ -257,6 +260,9 @@ namespace WebCore {
void popPopupsStateTimerFired(Timer<PluginView>*);
Timer<PluginView> m_popPopupsStateTimer;
+ void lifeSupportTimerFired(Timer<PluginView>*);
+ Timer<PluginView> m_lifeSupportTimer;
+
#ifndef NP_NO_CARBON
bool dispatchNPEvent(NPEvent&);
#endif
diff --git a/WebCore/plugins/PluginViewNone.cpp b/WebCore/plugins/PluginViewNone.cpp
index 725af82..8b2f17a 100644
--- a/WebCore/plugins/PluginViewNone.cpp
+++ b/WebCore/plugins/PluginViewNone.cpp
@@ -120,4 +120,8 @@ void PluginView::restart()
{
}
+void PluginView::keepAlive(NPP)
+{
+}
+
} // namespace WebCore
diff --git a/WebCore/plugins/gtk/PluginViewGtk.cpp b/WebCore/plugins/gtk/PluginViewGtk.cpp
index 8f4b2d5..6d992fb 100644
--- a/WebCore/plugins/gtk/PluginViewGtk.cpp
+++ b/WebCore/plugins/gtk/PluginViewGtk.cpp
@@ -137,7 +137,7 @@ void PluginView::updatePluginWidget()
if (m_drawable)
XFreePixmap(GDK_DISPLAY(), m_drawable);
- m_drawable = XCreatePixmap(GDK_DISPLAY(), getRootWindow(m_parentFrame),
+ m_drawable = XCreatePixmap(GDK_DISPLAY(), getRootWindow(m_parentFrame.get()),
m_windowRect.width(), m_windowRect.height(),
((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth);
XSync(GDK_DISPLAY(), False); // make sure that the server knows about the Drawable
@@ -319,7 +319,7 @@ void PluginView::handleKeyboardEvent(KeyboardEvent* event)
GdkEventKey* gdkEvent = event->keyEvent()->gdkEventKey();
xEvent.type = (event->type() == eventNames().keydownEvent) ? 2 : 3; // KeyPress/Release get unset somewhere
- xEvent.xkey.root = getRootWindow(m_parentFrame);
+ xEvent.xkey.root = getRootWindow(m_parentFrame.get());
xEvent.xkey.subwindow = 0; // we have no child window
xEvent.xkey.time = event->timeStamp();
xEvent.xkey.state = gdkEvent->state; // GdkModifierType mirrors xlib state masks
@@ -445,11 +445,11 @@ void PluginView::handleMouseEvent(MouseEvent* event)
IntPoint postZoomPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(event->absoluteLocation()));
if (event->type() == eventNames().mousedownEvent || event->type() == eventNames().mouseupEvent)
- setXButtonEventSpecificFields(&xEvent, event, postZoomPos, m_parentFrame);
+ setXButtonEventSpecificFields(&xEvent, event, postZoomPos, m_parentFrame.get());
else if (event->type() == eventNames().mousemoveEvent)
- setXMotionEventSpecificFields(&xEvent, event, postZoomPos, m_parentFrame);
+ setXMotionEventSpecificFields(&xEvent, event, postZoomPos, m_parentFrame.get());
else if (event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mouseoverEvent)
- setXCrossingEventSpecificFields(&xEvent, event, postZoomPos, m_parentFrame);
+ setXCrossingEventSpecificFields(&xEvent, event, postZoomPos, m_parentFrame.get());
else
return;
#endif
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index 44949b8..8952010 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,18 @@
+2010-02-08 Jon Honeycutt <jhoneycutt at apple.com>
+
+ <rdar://problem/7436875> Crash in Flash when visiting
+ http://www.cctv.com/default.shtml (WER ID 819298200) [watson 2502260]
+
+ Reviewed by Darin Adler.
+
+ * DumpRenderTree/win/TestNetscapePlugin/main.cpp:
+ (executeScript):
+ Moved to an earlier point in the file.
+ (NPP_New):
+ If the plug-in has an onDestroy attribute, store its value.
+ (NPP_Destroy):
+ If the plug-in has code to run on destruction, run it and free it.
+
2010-02-10 Diego Gonzalez <diego.gonzalez at openbossa.org>
Reviewed by Kenneth Rohde Christiansen.
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp
index 82b1d4d..08a2f6a 100644
--- a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp
@@ -71,6 +71,19 @@ NPError __stdcall NP_Shutdown()
return NPERR_NO_ERROR;
}
+static void executeScript(const PluginObject* object, const char* script)
+{
+ NPObject *windowScriptObject;
+ browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString npScript;
+ npScript.UTF8Characters = script;
+ npScript.UTF8Length = strlen(script);
+
+ NPVariant browserResult;
+ browser->evaluate(object->npp, windowScriptObject, &npScript, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+}
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved)
{
@@ -84,6 +97,8 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, ch
obj->onStreamDestroy = _strdup(argv[i]);
else if (_stricmp(argn[i], "onURLNotify") == 0 && !obj->onURLNotify)
obj->onURLNotify = _strdup(argv[i]);
+ else if (_stricmp(argn[i], "onDestroy") == 0 && !obj->onDestroy)
+ obj->onDestroy = _strdup(argv[i]);
else if (_stricmp(argn[i], "logSrc") == 0) {
for (int i = 0; i < argc; i++)
if (_stricmp(argn[i], "src") == 0)
@@ -113,6 +128,11 @@ NPError NPP_Destroy(NPP instance, NPSavedData **save)
if (obj->onStreamDestroy)
free(obj->onStreamDestroy);
+ if (obj->onDestroy) {
+ executeScript(obj, obj->onDestroy);
+ free(obj->onDestroy);
+ }
+
if (obj->logDestroy)
printf("PLUGIN: NPP_Destroy\n");
@@ -135,20 +155,6 @@ NPError NPP_SetWindow(NPP instance, NPWindow *window)
return NPERR_NO_ERROR;
}
-static void executeScript(const PluginObject* obj, const char* script)
-{
- NPObject *windowScriptObject;
- browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
-
- NPString npScript;
- npScript.UTF8Characters = script;
- npScript.UTF8Length = strlen(script);
-
- NPVariant browserResult;
- browser->evaluate(obj->npp, windowScriptObject, &npScript, &browserResult);
- browser->releasevariantvalue(&browserResult);
-}
-
NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
{
PluginObject* obj = (PluginObject*)instance->pdata;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list