forked from mirrors/gecko-dev
Merge backout
This commit is contained in:
commit
929a9d57ed
6 changed files with 7 additions and 154 deletions
|
|
@ -116,7 +116,6 @@ endif
|
||||||
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
|
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
|
||||||
_MOCHITEST_FILES += \
|
_MOCHITEST_FILES += \
|
||||||
test_copyText.html \
|
test_copyText.html \
|
||||||
test_crash_nested_loop.html \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Plugin crashing in nested loop</title>
|
|
||||||
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
|
||||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<iframe id="iframe1" src="crashing_subpage.html" width="600" height="600"></iframe>
|
|
||||||
|
|
||||||
<script class="testbody" type="application/javascript">
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
var iframe = document.getElementById('iframe1');
|
|
||||||
|
|
||||||
window.frameLoaded = function frameLoaded_toCrash() {
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
var prefs = Components.classes['@mozilla.org/preferences-service;1']
|
|
||||||
.getService(Components.interfaces.nsIPrefBranch);
|
|
||||||
if (!prefs.getBoolPref('dom.ipc.plugins.enabled')) {
|
|
||||||
ok(true, "Skipping this test when IPC plugins are not enabled.");
|
|
||||||
SimpleTest.finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var p = iframe.contentDocument.getElementById('plugin1');
|
|
||||||
|
|
||||||
try {
|
|
||||||
p.crashInNestedLoop();
|
|
||||||
ok(false, "p.crashInNestedLoop() should throw an exception");
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
ok(true, "p.crashInNestedLoop() should throw an exception");
|
|
||||||
}
|
|
||||||
|
|
||||||
// this test is for bug 550026, which is inherently
|
|
||||||
// nondeterministic. if we hit that bug, the browser process
|
|
||||||
// would have crashed by now. if not, we'll pass "spuriously"
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
@ -60,8 +60,6 @@
|
||||||
#define PLUGIN_VERSION "1.0.0.0"
|
#define PLUGIN_VERSION "1.0.0.0"
|
||||||
|
|
||||||
#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
|
#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
|
||||||
#define STATIC_ASSERT(condition) \
|
|
||||||
extern void np_static_assert(int arg[(condition) ? 1 : -1])
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Intentional crash
|
// Intentional crash
|
||||||
|
|
@ -69,7 +67,7 @@
|
||||||
|
|
||||||
int gCrashCount = 0;
|
int gCrashCount = 0;
|
||||||
|
|
||||||
void
|
static void
|
||||||
NoteIntentionalCrash()
|
NoteIntentionalCrash()
|
||||||
{
|
{
|
||||||
char* bloatLog = getenv("XPCOM_MEM_BLOAT_LOG");
|
char* bloatLog = getenv("XPCOM_MEM_BLOAT_LOG");
|
||||||
|
|
@ -89,9 +87,11 @@ NoteIntentionalCrash()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
IntentionalCrash()
|
IntentionalCrash()
|
||||||
{
|
{
|
||||||
|
NoteIntentionalCrash();
|
||||||
|
|
||||||
int *pi = NULL;
|
int *pi = NULL;
|
||||||
*pi = 55; // Crash dereferencing null pointer
|
*pi = 55; // Crash dereferencing null pointer
|
||||||
++gCrashCount;
|
++gCrashCount;
|
||||||
|
|
@ -156,7 +156,6 @@ static bool checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCoun
|
||||||
static bool hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
static bool hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||||
static bool getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
static bool getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||||
static bool callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
static bool callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||||
static bool crashPluginInNestedLoop(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
|
||||||
|
|
||||||
static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
||||||
"npnEvaluateTest",
|
"npnEvaluateTest",
|
||||||
|
|
@ -198,10 +197,9 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
||||||
"hang",
|
"hang",
|
||||||
"getClipboardText",
|
"getClipboardText",
|
||||||
"callOnDestroy",
|
"callOnDestroy",
|
||||||
"crashInNestedLoop",
|
|
||||||
};
|
};
|
||||||
static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
|
static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
|
||||||
static const ScriptableFunction sPluginMethodFunctions[] = {
|
static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMethodIdentifierNames)] = {
|
||||||
npnEvaluateTest,
|
npnEvaluateTest,
|
||||||
npnInvokeTest,
|
npnInvokeTest,
|
||||||
npnInvokeDefaultTest,
|
npnInvokeDefaultTest,
|
||||||
|
|
@ -241,12 +239,8 @@ static const ScriptableFunction sPluginMethodFunctions[] = {
|
||||||
hangPlugin,
|
hangPlugin,
|
||||||
getClipboardText,
|
getClipboardText,
|
||||||
callOnDestroy,
|
callOnDestroy,
|
||||||
crashPluginInNestedLoop,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) ==
|
|
||||||
ARRAY_LENGTH(sPluginMethodFunctions));
|
|
||||||
|
|
||||||
struct URLNotifyData
|
struct URLNotifyData
|
||||||
{
|
{
|
||||||
const char* cookie;
|
const char* cookie;
|
||||||
|
|
@ -711,7 +705,6 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char*
|
||||||
instanceData->npnNewStream = true;
|
instanceData->npnNewStream = true;
|
||||||
}
|
}
|
||||||
if (strcmp(argn[i], "newcrash") == 0) {
|
if (strcmp(argn[i], "newcrash") == 0) {
|
||||||
NoteIntentionalCrash();
|
|
||||||
IntentionalCrash();
|
IntentionalCrash();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -794,10 +787,8 @@ NPP_Destroy(NPP instance, NPSavedData** save)
|
||||||
printf("NPP_Destroy\n");
|
printf("NPP_Destroy\n");
|
||||||
InstanceData* instanceData = (InstanceData*)(instance->pdata);
|
InstanceData* instanceData = (InstanceData*)(instance->pdata);
|
||||||
|
|
||||||
if (instanceData->crashOnDestroy) {
|
if (instanceData->crashOnDestroy)
|
||||||
NoteIntentionalCrash();
|
|
||||||
IntentionalCrash();
|
IntentionalCrash();
|
||||||
}
|
|
||||||
|
|
||||||
if (instanceData->callOnDestroy) {
|
if (instanceData->callOnDestroy) {
|
||||||
NPVariant result;
|
NPVariant result;
|
||||||
|
|
@ -2154,7 +2145,6 @@ streamTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant*
|
||||||
static bool
|
static bool
|
||||||
crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
|
crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
|
||||||
{
|
{
|
||||||
NoteIntentionalCrash();
|
|
||||||
IntentionalCrash();
|
IntentionalCrash();
|
||||||
VOID_TO_NPVARIANT(*result);
|
VOID_TO_NPVARIANT(*result);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -2641,29 +2631,12 @@ getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
crashPluginInNestedLoop(NPObject* npobj, const NPVariant* args,
|
|
||||||
uint32_t argCount, NPVariant* result)
|
|
||||||
{
|
|
||||||
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
|
|
||||||
InstanceData* id = static_cast<InstanceData*>(npp->pdata);
|
|
||||||
return pluginCrashInNestedLoop(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
bool
|
bool
|
||||||
getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||||
NPVariant* result)
|
NPVariant* result)
|
||||||
{
|
{
|
||||||
// XXX Not implemented!
|
/// XXX Not implemented!
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
crashPluginInNestedLoop(NPObject* npobj, const NPVariant* args,
|
|
||||||
uint32_t argCount, NPVariant* result)
|
|
||||||
{
|
|
||||||
// XXX Not implemented!
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,4 @@ typedef struct InstanceData {
|
||||||
|
|
||||||
void notifyDidPaint(InstanceData* instanceData);
|
void notifyDidPaint(InstanceData* instanceData);
|
||||||
|
|
||||||
void NoteIntentionalCrash();
|
|
||||||
void IntentionalCrash();
|
|
||||||
|
|
||||||
#endif // nptest_h_
|
#endif // nptest_h_
|
||||||
|
|
|
||||||
|
|
@ -35,15 +35,12 @@
|
||||||
|
|
||||||
#include "nptest_platform.h"
|
#include "nptest_platform.h"
|
||||||
#include "npapi.h"
|
#include "npapi.h"
|
||||||
#include <pthread.h>
|
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
#ifdef MOZ_X11
|
#ifdef MOZ_X11
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
#endif
|
#endif
|
||||||
#include <glib.h>
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -638,68 +635,3 @@ pluginGetClipboardText(InstanceData* instanceData)
|
||||||
|
|
||||||
return retText;
|
return retText;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// NB: this test is quite gross in that it's not only
|
|
||||||
// nondeterministic, but dependent on the guts of the nested glib
|
|
||||||
// event loop handling code in PluginModule. We first sleep long
|
|
||||||
// enough to make sure that the "detection timer" will be pending when
|
|
||||||
// we enter the nested glib loop, then similarly for the "process browser
|
|
||||||
// events" timer. Then we "schedule" the crasher thread to run at about the
|
|
||||||
// same time we expect that the PluginModule "process browser events" task
|
|
||||||
// will run. If all goes well, the plugin process will crash and generate the
|
|
||||||
// XPCOM "plugin crashed" task, and the browser will run that task while still
|
|
||||||
// in the "process some events" loop.
|
|
||||||
|
|
||||||
static void*
|
|
||||||
CrasherThread(void* data)
|
|
||||||
{
|
|
||||||
// Give the parent thread a chance to send the message.
|
|
||||||
usleep(200);
|
|
||||||
|
|
||||||
IntentionalCrash();
|
|
||||||
|
|
||||||
// not reached
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
pluginCrashInNestedLoop(InstanceData* instanceData)
|
|
||||||
{
|
|
||||||
// wait at least long enough for nested loop detector task to be pending ...
|
|
||||||
sleep(1);
|
|
||||||
|
|
||||||
// Run the nested loop detector. Other events are not expected.
|
|
||||||
if (!g_main_context_iteration(NULL, TRUE)) {
|
|
||||||
g_warning("DetectNestedEventLoop did not fire");
|
|
||||||
return true; // trigger a test failure
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait at least long enough for the "process browser events" task to be
|
|
||||||
// pending ...
|
|
||||||
sleep(1);
|
|
||||||
|
|
||||||
// we'll be crashing soon, note that fact now to avoid messing with
|
|
||||||
// timing too much
|
|
||||||
NoteIntentionalCrash();
|
|
||||||
|
|
||||||
// schedule the crasher thread ...
|
|
||||||
pthread_t crasherThread;
|
|
||||||
if (0 != pthread_create(&crasherThread, NULL, CrasherThread, NULL)) {
|
|
||||||
g_warning("Failed to create thread");
|
|
||||||
return true; // trigger a test failure
|
|
||||||
}
|
|
||||||
|
|
||||||
// .. and hope the time it takes to spawn means that it crashes at about the
|
|
||||||
// same time as the "process browser events" task that should run next is
|
|
||||||
// being processed in the parent. Other events are not expected.
|
|
||||||
if (g_main_context_iteration(NULL, TRUE)) {
|
|
||||||
g_warning("Should have crashed in ProcessBrowserEvents");
|
|
||||||
} else {
|
|
||||||
g_warning("ProcessBrowserEvents did not fire");
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we get here without crashing, then we'll trigger a test failure
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -126,12 +126,4 @@ void pluginDoInternalConsistencyCheck(InstanceData* instanceData, std::string& e
|
||||||
*/
|
*/
|
||||||
std::string pluginGetClipboardText(InstanceData* instanceData);
|
std::string pluginGetClipboardText(InstanceData* instanceData);
|
||||||
|
|
||||||
/**
|
|
||||||
* Crash while in a nested event loop. The goal is to catch the
|
|
||||||
* browser processing the XPCOM event generated from the plugin's
|
|
||||||
* crash while other plugin code is still on the stack.
|
|
||||||
* See https://bugzilla.mozilla.org/show_bug.cgi?id=550026.
|
|
||||||
*/
|
|
||||||
bool pluginCrashInNestedLoop(InstanceData* instanceData);
|
|
||||||
|
|
||||||
#endif // nptest_platform_h_
|
#endif // nptest_platform_h_
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue