diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-14 03:23:32 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-14 03:23:32 +0000 |
commit | c690ff68f65729ee90b47fb9646ee302053d7824 (patch) | |
tree | 0bee2ba4f366fbc73b2764fc0cde799d792d5ccf | |
parent | 380f186d176e52cdbc54c6ceabfe5d5a7958cfba (diff) | |
download | chromium_src-c690ff68f65729ee90b47fb9646ee302053d7824.zip chromium_src-c690ff68f65729ee90b47fb9646ee302053d7824.tar.gz chromium_src-c690ff68f65729ee90b47fb9646ee302053d7824.tar.bz2 |
This CL fixes the document-open.html and window-open.html plugin layout tests. These were landed in webkit
as fixes for bug https://bugs.webkit.org/show_bug.cgi?id=31067
The layout test plugin changes are on similar lines as the version upstream.
We need to rebaseline the expectations as the line numbers differ in test shell and dumprendertree.
The document-open.html crashes in test_shell as this test causes the existing document to be taken down
which takes down the plugin instance and the associated plugin stream. This works in the webkit plugin
implementation as they grab a reference on the plugin stream before calling into the plugin to protect
from the stream being destroyed.
Our fix is on similar lines.
Bug=27164
Review URL: http://codereview.chromium.org/393017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31991 0039d316-1c4b-4281-b951-d872f2087c98
11 files changed, 175 insertions, 41 deletions
diff --git a/webkit/data/layout_tests/platform/chromium-linux/LayoutTests/plugins/document-open-expected.txt b/webkit/data/layout_tests/platform/chromium-linux/LayoutTests/plugins/document-open-expected.txt new file mode 100644 index 0000000..5c32f92 --- /dev/null +++ b/webkit/data/layout_tests/platform/chromium-linux/LayoutTests/plugins/document-open-expected.txt @@ -0,0 +1 @@ +CONSOLE MESSAGE: line 1: PLUGIN: DOCUMENT OPEN SUCCESS diff --git a/webkit/data/layout_tests/platform/chromium-linux/LayoutTests/plugins/window-open-expected.txt b/webkit/data/layout_tests/platform/chromium-linux/LayoutTests/plugins/window-open-expected.txt new file mode 100644 index 0000000..29ee4e7 --- /dev/null +++ b/webkit/data/layout_tests/platform/chromium-linux/LayoutTests/plugins/window-open-expected.txt @@ -0,0 +1,3 @@ +CONSOLE MESSAGE: line 1: PLUGIN: WINDOW OPEN SUCCESS + +This tests that window.open invoked by a plugin via NPN_Invoke without a javascript context succeeds. diff --git a/webkit/data/layout_tests/platform/chromium-mac/LayoutTests/plugins/document-open-expected.txt b/webkit/data/layout_tests/platform/chromium-mac/LayoutTests/plugins/document-open-expected.txt new file mode 100644 index 0000000..5c32f92 --- /dev/null +++ b/webkit/data/layout_tests/platform/chromium-mac/LayoutTests/plugins/document-open-expected.txt @@ -0,0 +1 @@ +CONSOLE MESSAGE: line 1: PLUGIN: DOCUMENT OPEN SUCCESS diff --git a/webkit/data/layout_tests/platform/chromium-mac/LayoutTests/plugins/window-open-expected.txt b/webkit/data/layout_tests/platform/chromium-mac/LayoutTests/plugins/window-open-expected.txt new file mode 100644 index 0000000..29ee4e7 --- /dev/null +++ b/webkit/data/layout_tests/platform/chromium-mac/LayoutTests/plugins/window-open-expected.txt @@ -0,0 +1,3 @@ +CONSOLE MESSAGE: line 1: PLUGIN: WINDOW OPEN SUCCESS + +This tests that window.open invoked by a plugin via NPN_Invoke without a javascript context succeeds. diff --git a/webkit/data/layout_tests/platform/chromium-win/LayoutTests/plugins/document-open-expected.txt b/webkit/data/layout_tests/platform/chromium-win/LayoutTests/plugins/document-open-expected.txt new file mode 100644 index 0000000..5c32f92 --- /dev/null +++ b/webkit/data/layout_tests/platform/chromium-win/LayoutTests/plugins/document-open-expected.txt @@ -0,0 +1 @@ +CONSOLE MESSAGE: line 1: PLUGIN: DOCUMENT OPEN SUCCESS diff --git a/webkit/data/layout_tests/platform/chromium-win/LayoutTests/plugins/window-open-expected.txt b/webkit/data/layout_tests/platform/chromium-win/LayoutTests/plugins/window-open-expected.txt new file mode 100644 index 0000000..29ee4e7 --- /dev/null +++ b/webkit/data/layout_tests/platform/chromium-win/LayoutTests/plugins/window-open-expected.txt @@ -0,0 +1,3 @@ +CONSOLE MESSAGE: line 1: PLUGIN: WINDOW OPEN SUCCESS + +This tests that window.open invoked by a plugin via NPN_Invoke without a javascript context succeeds. diff --git a/webkit/glue/plugins/plugin_stream_url.cc b/webkit/glue/plugins/plugin_stream_url.cc index ae26e62..602733d 100644 --- a/webkit/glue/plugins/plugin_stream_url.cc +++ b/webkit/glue/plugins/plugin_stream_url.cc @@ -29,6 +29,9 @@ PluginStreamUrl::~PluginStreamUrl() { } bool PluginStreamUrl::Close(NPReason reason) { + // Protect the stream against it being destroyed or the whole plugin instance + // being destroyed within the destroy stream handler. + scoped_refptr<PluginStream> protect(this); CancelRequest(); bool result = PluginStream::Close(reason); instance()->RemoveStream(this); @@ -45,6 +48,10 @@ void PluginStreamUrl::DidReceiveResponse(const std::string& mime_type, uint32 expected_length, uint32 last_modified, bool request_is_seekable) { + // Protect the stream against it being destroyed or the whole plugin instance + // being destroyed within the new stream handler. + scoped_refptr<PluginStream> protect(this); + bool opened = Open(mime_type, headers, expected_length, @@ -64,6 +71,10 @@ void PluginStreamUrl::DidReceiveData(const char* buffer, int length, if (!open()) return; + // Protect the stream against it being destroyed or the whole plugin instance + // being destroyed within the write handlers + scoped_refptr<PluginStream> protect(this); + if (length > 0) { // The PluginStreamUrl instance could get deleted if the plugin fails to // accept data in NPP_Write. diff --git a/webkit/glue/plugins/plugin_string_stream.cc b/webkit/glue/plugins/plugin_string_stream.cc index 3997fba..f174267 100644 --- a/webkit/glue/plugins/plugin_string_stream.cc +++ b/webkit/glue/plugins/plugin_string_stream.cc @@ -21,6 +21,10 @@ PluginStringStream::~PluginStringStream() { void PluginStringStream::SendToPlugin(const std::string &data, const std::string &mime_type) { + // Protect the stream against it being destroyed or the whole plugin instance + // being destroyed within the plugin stream callbacks. + scoped_refptr<PluginStringStream> protect(this); + int length = static_cast<int>(data.length()); if (Open(mime_type, std::string(), length, 0, false)) { // TODO - check if it was not fully sent, and figure out a backup plan. diff --git a/webkit/tools/npapi_layout_test_plugin/PluginObject.cpp b/webkit/tools/npapi_layout_test_plugin/PluginObject.cpp index f06e099..922faf3 100644 --- a/webkit/tools/npapi_layout_test_plugin/PluginObject.cpp +++ b/webkit/tools/npapi_layout_test_plugin/PluginObject.cpp @@ -33,6 +33,60 @@ #define snprintf sprintf_s #endif +static void logWithWindowObject(NPObject* windowObject, NPP instance, const char* message) +{ + NPVariant consoleVariant; + if (!browser->getproperty(instance, windowObject, browser->getstringidentifier("console"), &consoleVariant)) { + fprintf(stderr, "Failed to retrieve console object while logging: %s\n", message); + return; + } + + NPObject* consoleObject = NPVARIANT_TO_OBJECT(consoleVariant); + + NPVariant messageVariant; + STRINGZ_TO_NPVARIANT(message, messageVariant); + + NPVariant result; + if (!browser->invoke(instance, consoleObject, browser->getstringidentifier("log"), &messageVariant, 1, &result)) { + fprintf(stderr, "Failed to invoke console.log while logging: %s\n", message); + browser->releaseobject(consoleObject); + return; + } + + browser->releasevariantvalue(&result); + browser->releaseobject(consoleObject); +} + +static void logWithWindowObjectVariableArgs(NPObject* windowObject, NPP instance, const char* format, ...) +{ + va_list args; + va_start(args, format); + char message[2048] = "PLUGIN: "; + vsprintf(message + strlen(message), format, args); + va_end(args); + + logWithWindowObject(windowObject, instance, message); +} + +void log(NPP instance, const char* format, ...) +{ + va_list args; + va_start(args, format); + char message[2048] = "PLUGIN: "; + vsprintf(message + strlen(message), format, args); + va_end(args); + + NPObject* windowObject = 0; + NPError error = browser->getvalue(instance, NPNVWindowNPObject, &windowObject); + if (error != NPERR_NO_ERROR) { + fprintf(stderr, "Failed to retrieve window object while logging: %s\n", message); + return; + } + + logWithWindowObject(windowObject, instance, message); + browser->releaseobject(windowObject); +} + static void pluginInvalidate(NPObject*); static bool pluginHasProperty(NPObject*, NPIdentifier name); static bool pluginHasMethod(NPObject*, NPIdentifier name); @@ -629,6 +683,76 @@ static bool testConstruct(PluginObject* obj, const NPVariant* args, uint32_t arg return browser->construct(obj->npp, NPVARIANT_TO_OBJECT(args[0]), args + 1, argCount - 1, result); } +// Helper function to notify the layout test controller that the test completed. +void notifyTestCompletion(NPP npp, NPObject* object) +{ + NPVariant result; + NPString script; + script.UTF8Characters = "javascript:window.layoutTestController.notifyDone();"; + script.UTF8Length = strlen("javascript:window.layoutTestController.notifyDone();"); + browser->evaluate(npp, object, &script, &result); + browser->releasevariantvalue(&result); +} + +bool testDocumentOpen(NPP npp) +{ + NPIdentifier documentId = browser->getstringidentifier("document"); + NPIdentifier openId = browser->getstringidentifier("open"); + + NPObject *windowObject = NULL; + browser->getvalue(npp, NPNVWindowNPObject, &windowObject); + if (!windowObject) + return false; + + NPVariant docVariant; + browser->getproperty(npp, windowObject, documentId, &docVariant); + if (docVariant.type != NPVariantType_Object) + return false; + + NPObject *documentObject = NPVARIANT_TO_OBJECT(docVariant); + + NPVariant openArgs[2]; + STRINGZ_TO_NPVARIANT("text/html", openArgs[0]); + STRINGZ_TO_NPVARIANT("_blank", openArgs[1]); + + NPVariant result; + browser->invoke(npp, documentObject, openId, openArgs, 2, &result); + browser->releaseobject(documentObject); + + if (result.type == NPVariantType_Object) { + logWithWindowObjectVariableArgs(windowObject, npp, "DOCUMENT OPEN SUCCESS"); + notifyTestCompletion(npp, result.value.objectValue); + browser->releaseobject(result.value.objectValue); + return true; + } + + return false; +} + +bool testWindowOpen(NPP npp) +{ + NPIdentifier openId = browser->getstringidentifier("open"); + + NPObject *windowObject = NULL; + browser->getvalue(npp, NPNVWindowNPObject, &windowObject); + if (!windowObject) + return false; + + NPVariant openArgs[2]; + STRINGZ_TO_NPVARIANT("about:blank", openArgs[0]); + STRINGZ_TO_NPVARIANT("_blank", openArgs[1]); + + NPVariant result; + browser->invoke(npp, windowObject, openId, openArgs, 2, &result); + if (result.type == NPVariantType_Object) { + logWithWindowObjectVariableArgs(windowObject, npp, "WINDOW OPEN SUCCESS"); + notifyTestCompletion(npp, result.value.objectValue); + browser->releaseobject(result.value.objectValue); + return true; + } + return false; +} + static bool pluginInvoke(NPObject* header, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result) { PluginObject* plugin = reinterpret_cast<PluginObject*>(header); @@ -838,6 +962,9 @@ static NPObject *pluginAllocate(NPP npp, NPClass *theClass) newInstance->lastUrl = NULL; newInstance->lastHeaders = NULL; + newInstance->testDocumentOpenInDestroyStream = FALSE; + newInstance->testWindowOpen = FALSE; + return (NPObject*)newInstance; } diff --git a/webkit/tools/npapi_layout_test_plugin/PluginObject.h b/webkit/tools/npapi_layout_test_plugin/PluginObject.h index 7162954..7d86d19 100644 --- a/webkit/tools/npapi_layout_test_plugin/PluginObject.h +++ b/webkit/tools/npapi_layout_test_plugin/PluginObject.h @@ -36,6 +36,8 @@ typedef struct { NPBool returnErrorFromNewStream; NPObject* testObject; NPStream* stream; + NPBool testWindowOpen; + NPBool testDocumentOpenInDestroyStream; char* onStreamLoad; char* onStreamDestroy; char* onURLNotify; @@ -49,3 +51,6 @@ extern NPClass *getPluginClass(void); extern void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData); extern void notifyStream(PluginObject* object, const char *url, const char *headers); extern void testNPRuntime(NPP npp); +extern bool testDocumentOpen(NPP npp); +extern bool testWindowOpen(NPP npp); +extern void log(NPP instance, const char* format, ...); diff --git a/webkit/tools/npapi_layout_test_plugin/main.cpp b/webkit/tools/npapi_layout_test_plugin/main.cpp index 032985f..1b41f7e6 100644 --- a/webkit/tools/npapi_layout_test_plugin/main.cpp +++ b/webkit/tools/npapi_layout_test_plugin/main.cpp @@ -53,46 +53,6 @@ #include <X11/Xlib.h> #endif -static void log(NPP instance, const char* format, ...) -{ - va_list args; - va_start(args, format); - char message[2048] = "PLUGIN: "; - vsprintf(message + strlen(message), format, args); - va_end(args); - - NPObject* windowObject = 0; - NPError error = browser->getvalue(instance, NPNVWindowNPObject, &windowObject); - if (error != NPERR_NO_ERROR) { - fprintf(stderr, "Failed to retrieve window object while logging: %s\n", message); - return; - } - - NPVariant consoleVariant; - if (!browser->getproperty(instance, windowObject, browser->getstringidentifier("console"), &consoleVariant)) { - fprintf(stderr, "Failed to retrieve console object while logging: %s\n", message); - browser->releaseobject(windowObject); - return; - } - - NPObject* consoleObject = NPVARIANT_TO_OBJECT(consoleVariant); - - NPVariant messageVariant; - STRINGZ_TO_NPVARIANT(message, messageVariant); - - NPVariant result; - if (!browser->invoke(instance, consoleObject, browser->getstringidentifier("log"), &messageVariant, 1, &result)) { - fprintf(stderr, "Failed to invoke console.log while logging: %s\n", message); - browser->releaseobject(consoleObject); - browser->releaseobject(windowObject); - return; - } - - browser->releasevariantvalue(&result); - browser->releaseobject(consoleObject); - browser->releaseobject(windowObject); -} - // Plugin entry points extern "C" { EXPORT NPError NPAPI NP_Initialize(NPNetscapeFuncs *browserFuncs @@ -174,8 +134,13 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, ch fflush(stdout); } } - } else if (strcasecmp(argn[i], "cleardocumentduringnew") == 0) + } else if (strcasecmp(argn[i], "cleardocumentduringnew") == 0) { executeScript(obj, "document.body.innerHTML = ''"); + } else if (strcasecmp(argn[i], "testdocumentopenindestroystream") == 0) { + obj->testDocumentOpenInDestroyStream = TRUE; + } else if (strcasecmp(argn[i], "testwindowopen") == 0) { + obj->testWindowOpen = TRUE; + } } instance->pdata = obj; @@ -219,6 +184,11 @@ NPError NPP_SetWindow(NPP instance, NPWindow *window) fflush(stdout); obj->logSetWindow = false; } + + if (obj->testWindowOpen) { + testWindowOpen(instance); + obj->testWindowOpen = FALSE; + } } return NPERR_NO_ERROR; @@ -264,6 +234,11 @@ NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) if (obj->onStreamDestroy) executeScript(obj, obj->onStreamDestroy); + if (obj->testDocumentOpenInDestroyStream) { + testDocumentOpen(instance); + obj->testDocumentOpenInDestroyStream = FALSE; + } + return NPERR_NO_ERROR; } |