Test for bug 535298, crashes which occur during NPP_New or NPP_Destroy

This commit is contained in:
Benjamin Smedberg 2009-12-21 12:37:32 -05:00
parent 8ff8aeed5a
commit 47b4c82551
4 changed files with 122 additions and 17 deletions

View File

@ -72,6 +72,7 @@ _MOCHITEST_FILES = \
ifdef MOZ_IPC
_MOCHITEST_FILES += \
test_crashing.html \
test_crashing2.html \
crashing_subpage.html \
$(NULL)
endif

View File

@ -0,0 +1,71 @@
<head>
<title>Plugin crashing</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 onload="mainLoaded()">
<iframe id="iframe1" src="about:blank" width="600" height="600"></iframe>
<script class="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
var iframe = document.getElementById('iframe1');
function mainLoaded() {
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.createElement('embed');
p.setAttribute('id', 'plugin1');
p.setAttribute('type', 'application/x-test');
p.setAttribute('width', '400');
p.setAttribute('height', '400');
p.setAttribute('drawmode', 'solid');
p.setAttribute('color', 'FF00FFFF');
p.setAttribute('newCrash', 'true');
iframe.contentDocument.body.appendChild(p);
try {
p.setColor('FFFF0000');
ok(false, "plugin crashes on creation");
}
catch (e) {
ok(true, "plugin crashes on creation");
}
window.frameLoaded = reloaded1;
iframe.contentWindow.location.replace('crashing_subpage.html');
}
function reloaded1() {
var p = iframe.contentDocument.getElementById('plugin1');
try {
p.setColor('FF00FF00');
ok(true, "Reloading worked");
}
catch (e) {
ok(false, "Reloading didn't give us a usable plugin");
}
p.crashOnDestroy();
window.frameLoaded = reloaded2;
iframe.contentWindow.location.reload();
}
function reloaded2() {
var p = iframe.contentDocument.getElementById('plugin1');
try {
p.setColor('FF00FF00');
ok(true, "Reloading worked");
}
catch (e) {
ok(false, "Reloading didn't give us a usable plugin");
}
SimpleTest.finish();
}
</script>

View File

@ -58,6 +58,32 @@
#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
//
// Intentional crash
//
static void
Crash()
{
char* bloatLog = getenv("XPCOM_MEM_BLOAT_LOG");
if (bloatLog) {
char* logExt = strstr(bloatLog, ".log");
if (logExt) {
bloatLog[strlen(bloatLog) - strlen(logExt)] = '\0';
}
ostringstream bloatName;
bloatName << bloatLog << "_plugin_pid" << getpid();
if (logExt) {
bloatName << ".log";
}
FILE* processfd = fopen(bloatName.str().c_str(), "a");
fprintf(processfd, "==> process %d will purposefully crash\n", getpid());
fclose(processfd);
}
void (*funcptr)() = NULL;
funcptr(); // Crash calling null function pointer
}
//
// static data
//
@ -103,6 +129,7 @@ static bool convertPointX(NPObject* npobj, const NPVariant* args, uint32_t argCo
static bool convertPointY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool streamTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool crashOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static const NPUTF8* sPluginMethodIdentifierNames[] = {
"npnEvaluateTest",
@ -132,6 +159,7 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
"convertPointY",
"streamTest",
"crash",
"crashOnDestroy",
};
static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMethodIdentifierNames)] = {
@ -162,6 +190,7 @@ static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMetho
convertPointY,
streamTest,
crashPlugin,
crashOnDestroy,
};
struct URLNotifyData
@ -500,6 +529,7 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char*
instanceData->writeCount = 0;
instanceData->writeReadyCount = 0;
memset(&instanceData->window, 0, sizeof(instanceData->window));
instanceData->crashOnDestroy = false;
instance->pdata = instanceData;
TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass);
@ -595,6 +625,9 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char*
strcmp(argv[i], "true") == 0) {
instanceData->npnNewStream = true;
}
if (strcmp(argn[i], "newcrash") == 0) {
Crash();
}
}
if (!browserSupportsWindowless || !pluginSupportsWindowlessMode()) {
@ -674,6 +707,9 @@ NPP_Destroy(NPP instance, NPSavedData** save)
printf("NPP_Destroy\n");
InstanceData* instanceData = (InstanceData*)(instance->pdata);
if (instanceData->crashOnDestroy)
Crash();
if (instanceData->streamBuf) {
free(instanceData->streamBuf);
}
@ -2028,23 +2064,19 @@ streamTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant*
static bool
crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
char* bloatLog = getenv("XPCOM_MEM_BLOAT_LOG");
if (bloatLog) {
char* logExt = strstr(bloatLog, ".log");
if (logExt) {
bloatLog[strlen(bloatLog) - strlen(logExt)] = '\0';
}
ostringstream bloatName;
bloatName << bloatLog << "_plugin_pid" << getpid();
if (logExt) {
bloatName << ".log";
}
FILE* processfd = fopen(bloatName.str().c_str(), "a");
fprintf(processfd, "==> process %d will purposefully crash\n", getpid());
fclose(processfd);
}
void (*funcptr)() = NULL;
funcptr(); // Crash calling null function pointer
Crash();
VOID_TO_NPVARIANT(*result);
return true;
}
static bool
crashOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
InstanceData* id = static_cast<InstanceData*>(npp->pdata);
id->crashOnDestroy = true;
VOID_TO_NPVARIANT(*result);
return true;
}

View File

@ -113,6 +113,7 @@ typedef struct InstanceData {
TestRange* testrange;
void* streamBuf;
void* fileBuf;
bool crashOnDestroy;
} InstanceData;
#endif // nptest_h_