Bug 599975 - Fire error event for images with empty string src value; r=bz

MozReview-Commit-ID: AhXiTpgG9q3

--HG--
extra : rebase_source : fe03d94a08232e90a475529746b38b27c2591ec9
This commit is contained in:
Edgar Chen 2016-09-08 16:27:03 +08:00
parent 653b388b32
commit b255460f26
2 changed files with 31 additions and 21 deletions

View File

@ -757,6 +757,13 @@ nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
return NS_OK; return NS_OK;
} }
if (aNewURI.IsEmpty()) {
// Cancel image requests and then fire only error event per spec.
CancelImageRequests(aNotify);
FireEvent(NS_LITERAL_STRING("error"));
return NS_OK;
}
// Second, parse the URI string to get image URI // Second, parse the URI string to get image URI
nsCOMPtr<nsIURI> imageURI; nsCOMPtr<nsIURI> imageURI;
nsresult rv = StringToURI(aNewURI, doc, getter_AddRefs(imageURI)); nsresult rv = StringToURI(aNewURI, doc, getter_AddRefs(imageURI));
@ -768,24 +775,6 @@ nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
return NS_OK; return NS_OK;
} }
bool equal;
if (aNewURI.IsEmpty() &&
doc->GetDocumentURI() &&
NS_SUCCEEDED(doc->GetDocumentURI()->EqualsExceptRef(imageURI, &equal)) &&
equal) {
// Loading an embedded img from the same URI as the document URI will not work
// as a resource cannot recursively embed itself. Attempting to do so generally
// results in having to pre-emptively close down an in-flight HTTP transaction
// and then incurring the significant cost of establishing a new TCP channel.
// This is generally triggered from <img src="">
// In light of that, just skip loading it..
// Do make sure to drop our existing image, if any
CancelImageRequests(aNotify);
return NS_OK;
}
NS_TryToSetImmutable(imageURI); NS_TryToSetImmutable(imageURI);
return LoadImage(imageURI, aForce, aNotify, aImageLoadType, doc); return LoadImage(imageURI, aForce, aNotify, aImageLoadType, doc);

View File

@ -3,10 +3,11 @@
<title>Loading a non-parsing URL as an image should silently fail; triggering appropriate events</title> <title>Loading a non-parsing URL as an image should silently fail; triggering appropriate events</title>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<img id=myimg /> <img id=brokenurl />
<img id=emptysrc />
<script> <script>
async_test(function(t) { async_test(function(t) {
var img = document.getElementById("myimg"); var img = document.getElementById("brokenurl");
img.src = "http://also a broken url"; img.src = "http://also a broken url";
var errorevent = false; var errorevent = false;
@ -16,6 +17,26 @@ async_test(function(t) {
img.addEventListener('loadend', t.step_func_done(function() { img.addEventListener('loadend', t.step_func_done(function() {
assert_true(errorevent, "error event fired"); assert_true(errorevent, "error event fired");
})); }));
}); }, 'src="http://also a broken url"');
async_test(function(t) {
var img = document.getElementById("emptysrc");
img.src = "";
var loadendevent = false;
// Setting src to empty string triggers only error event.
// The errors should be queued in the event loop, so they should only trigger
// after this block of code finishes, not during the img.src setter itself
img.addEventListener('error', t.step_func(function() {
// Queue this check in the event loop to check there is no loadend event
// fired.
t.step_timeout(t.step_func_done(function() {
assert_false(loadendevent, "loadend event should not fired");
}), 0)
}));
img.addEventListener('loadend', t.step_func(function() {
loadendevent = true;
}));
}, 'src=""');
</script> </script>