Bug 645998. Improve the recursion detection in the CSS loader to detect mutual recursion scenarios. r=sicking

This commit is contained in:
Boris Zbarsky 2011-08-07 22:23:51 -04:00
parent 60ea673f0b
commit ec80057178
5 changed files with 70 additions and 10 deletions

View File

@ -1869,6 +1869,36 @@ Loader::LoadStyleLink(nsIContent* aElement,
return rv;
}
static PRBool
HaveAncestorDataWithURI(SheetLoadData *aData, nsIURI *aURI)
{
if (!aData->mURI) {
// Inline style; this won't have any ancestors
NS_ABORT_IF_FALSE(!aData->mParentData,
"How does inline style have a parent?");
return PR_FALSE;
}
PRBool equal;
if (NS_FAILED(aData->mURI->Equals(aURI, &equal)) || equal) {
return PR_TRUE;
}
// Datas down the mNext chain have the same URI as aData, so we
// don't have to compare to them. But they might have different
// parents, and we have to check all of those.
while (aData) {
if (aData->mParentData &&
HaveAncestorDataWithURI(aData->mParentData, aURI)) {
return PR_TRUE;
}
aData = aData->mNext;
}
return PR_FALSE;
}
nsresult
Loader::LoadChildSheet(nsCSSStyleSheet* aParentSheet,
nsIURI* aURL,
@ -1923,16 +1953,11 @@ Loader::LoadChildSheet(nsCSSStyleSheet* aParentSheet,
LOG((" Have a parent load"));
parentData = mParsingDatas.ElementAt(count - 1);
// Check for cycles
SheetLoadData* data = parentData;
while (data && data->mURI) {
PRBool equal;
if (NS_SUCCEEDED(data->mURI->Equals(aURL, &equal)) && equal) {
// Houston, we have a loop, blow off this child and pretend this never
// happened
LOG_ERROR((" @import cycle detected, dropping load"));
return NS_OK;
}
data = data->mParentData;
if (HaveAncestorDataWithURI(parentData, aURL)) {
// Houston, we have a loop, blow off this child and pretend this never
// happened
LOG_ERROR((" @import cycle detected, dropping load"));
return NS_OK;
}
NS_ASSERTION(parentData->mSheet == aParentSheet,

View File

@ -129,6 +129,9 @@ _TEST_FILES = test_acid3_test46.html \
test_bug657143.html \
test_bug664955.html \
test_bug667520.html \
test_bug645998.html \
file_bug645998-1.css \
file_bug645998-2.css \
test_cascade.html \
test_compute_data_with_start_struct.html \
test_computed_style.html \

View File

@ -0,0 +1 @@
@import url("file_bug645998-2.css");

View File

@ -0,0 +1 @@
@import url("file_bug645998-1.css");

View File

@ -0,0 +1,30 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=645998
-->
<head>
<title>Test for Bug 645998</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<!-- This is the real test: will these stylesheets ever finish loading? -->
<link rel="stylesheet" href="file_bug645998-1.css">
<link rel="stylesheet" href="file_bug645998-2.css">
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=645998">Mozilla Bug 645998</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 645998 **/
ok(true, "Hey, we got here! That's a good sign");
</script>
</pre>
</body>
</html>