Bug 789856. Fire error events on <script> elements which completely fail to start the load. r=sicking

This commit is contained in:
Boris Zbarsky 2012-09-18 23:24:27 -04:00
parent 76cb861fd1
commit c658c872ec
8 changed files with 97 additions and 20 deletions

View File

@ -17,8 +17,8 @@
#include "mozilla/CORSMode.h"
#define NS_ISCRIPTELEMENT_IID \
{ 0x24ab3ff2, 0xd75e, 0x4be4, \
{ 0x8d, 0x50, 0xd6, 0x75, 0x31, 0x29, 0xab, 0x65 } }
{ 0x491628bc, 0xce7c, 0x4db4, \
{ 0x93, 0x3f, 0xce, 0x1b, 0x75, 0xee, 0x75, 0xce } }
/**
* Internal interface implemented by script elements
@ -235,6 +235,11 @@ public:
return mozilla::CORS_NONE;
}
/**
* Fire an error event
*/
virtual nsresult FireErrorEvent() = 0;
protected:
/**
* Processes the script if it's in the document-tree and links to or

View File

@ -25,19 +25,24 @@ nsScriptElement::ScriptAvailable(nsresult aResult,
int32_t aLineNo)
{
if (!aIsInline && NS_FAILED(aResult)) {
nsCOMPtr<nsIContent> cont =
do_QueryInterface((nsIScriptElement*) this);
return nsContentUtils::DispatchTrustedEvent(cont->OwnerDoc(),
cont,
NS_LITERAL_STRING("error"),
false /* bubbles */,
false /* cancelable */);
return FireErrorEvent();
}
return NS_OK;
}
/* virtual */ nsresult
nsScriptElement::FireErrorEvent()
{
nsCOMPtr<nsIContent> cont =
do_QueryInterface((nsIScriptElement*) this);
return nsContentUtils::DispatchTrustedEvent(cont->OwnerDoc(),
cont,
NS_LITERAL_STRING("error"),
false /* bubbles */,
false /* cancelable */);
}
NS_IMETHODIMP
nsScriptElement::ScriptEvaluated(nsresult aResult,
nsIScriptElement *aElement,

View File

@ -31,6 +31,8 @@ public:
{
}
virtual nsresult FireErrorEvent();
protected:
// Internal methods

View File

@ -482,6 +482,10 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
// external script
nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
if (!scriptURI) {
// Asynchronously report the failure to create a URI object
NS_DispatchToCurrentThread(
NS_NewRunnableMethod(aElement,
&nsIScriptElement::FireErrorEvent));
return false;
}
CORSMode ourCORSMode = aElement->GetCORSMode();
@ -516,7 +520,13 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
request->mIsInline = false;
request->mLoading = true;
rv = StartLoad(request, type);
NS_ENSURE_SUCCESS(rv, false);
if (NS_FAILED(rv)) {
// Asynchronously report the load failure
NS_DispatchToCurrentThread(
NS_NewRunnableMethod(aElement,
&nsIScriptElement::FireErrorEvent));
return false;
}
}
request->mJSVersion = version;

View File

@ -560,6 +560,7 @@ MOCHITEST_FILES_B = \
test_mixed_content_blocker.html \
file_mixed_content_main.html \
file_mixed_content_server.sjs \
test_bug789856.html \
$(NULL)
MOCHITEST_CHROME_FILES = \

View File

@ -16,23 +16,35 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=606729
</div>
<pre id="test">
<script>
SimpleTest.waitForExplicitFinish();
var events = 0;
var expectedEvents = 2;
function eventFired() {
++events;
if (events == expectedEvents) {
SimpleTest.finish();
}
}
</script>
<script
src="data:"
onerror="ok(false, 'Script with src=data: should not fire onerror.');"
onload="ok(false, 'Script with src=data: should not fire onload.');"
onerror="ok(true, 'Script with src=data: should fire onerror.');
eventFired();"
onload="ok(false, 'Script with src=data: should not fire onload.');
eventFired();"
>
ok(false, "Script with src=data: should not run textContent.");
</script>
<script
src="bogus:"
onerror="ok(false, 'Script with src=bogus: should not fire onerror.');"
onload="ok(false, 'Script with src=bogus: should not fire onload.');"
onerror="ok(true, 'Script with src=bogus: should fire onerror.');
eventFired();"
onload="ok(false, 'Script with src=bogus: should not fire onload.');
eventFired();"
>
ok(false, "Script with src=bogus: should not run textContent.");
</script>
<script class="testbody" type="text/javascript">
ok(true, "Obligatory succeeding test assertion.");
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=789856
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 789856</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=789856">Mozilla Bug 789856</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 789856 **/
SimpleTest.waitForExplicitFinish();
var script = document.createElement("script");
script.onload = function() {
ok(false, "This script should not load");
SimpleTest.finish();
}
script.onerror = function() {
ok(true, "This script should fail to load");
SimpleTest.finish();
}
// If neither one fires, the test fails, as it should
// Use a URL the test is not allowed to load
script.src = "file:///tmp/"
document.body.appendChild(script);
</script>
</pre>
</body>
</html>

View File

@ -39,7 +39,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=371375
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
is(load1Called, false, "Load handler should not be called");
is(error1Called, false, "Error handler should not be called");
is(error1Called, true, "Error handler should be called");
is(load2Called, true, "Load handler for valid script should be called");
is(error2Called, false,
"Error handler for valid script should not be called");