Bug 1330294 - Fixing disabled script tags that cause crashes in disabled SVG nodes r=hsivonen,smaug

MozReview-Commit-ID: Lr4s98aZM4W

--HG--
extra : rebase_source : 6dca1899d3b69a8eb7e82a02a60fd59f6a9a335e
This commit is contained in:
Jonathan Kingston 2017-01-11 16:29:13 +00:00
parent 1b60bc19eb
commit 673d193089
9 changed files with 65 additions and 18 deletions

View File

@ -476,8 +476,12 @@ nsXMLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|| aNodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_SVG)
) {
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(content);
if (sele) {
sele->SetScriptLineNumber(aLineNumber);
sele->SetCreatorParser(GetParser());
} else {
MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Node didn't QI to script, but SVG wasn't disabled.");
}
}
// XHTML needs some special attention
@ -555,6 +559,10 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
|| nodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_SVG)
) {
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aContent);
if (!sele) {
MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Node didn't QI to script, but SVG wasn't disabled.");
return NS_OK;
}
if (mPreventScriptExecution) {
sele->PreventExecution();

View File

@ -227,8 +227,11 @@ nsXMLFragmentContentSink::CloseElement(nsIContent* aContent)
(aContent->IsHTMLElement(nsGkAtoms::script),
aContent->IsSVGElement(nsGkAtoms::script))) {
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aContent);
NS_ASSERTION(sele, "script did QI correctly!");
if (sele) {
sele->PreventExecution();
} else {
NS_ASSERTION(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Script did QI correctly, but wasn't a disabled SVG!");
}
}
return NS_OK;
}

View File

@ -296,7 +296,7 @@ txMozillaXMLOutput::endElement()
} else if (element->IsSVGElement(nsGkAtoms::script) ||
element->IsHTMLElement(nsGkAtoms::script)) {
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(element);
MOZ_ASSERT(sele, "script elements need to implement nsIScriptElement");
if (sele) {
bool block = sele->AttemptToExecute();
// If the act of insertion evaluated the script, we're fine.
// Else, add this script element to the array of loading scripts.
@ -304,6 +304,9 @@ txMozillaXMLOutput::endElement()
rv = mNotifier->AddScriptElement(sele);
NS_ENSURE_SUCCESS(rv, rv);
}
} else {
MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Script elements need to implement nsIScriptElement and SVG wasn't disabled.");
}
} else if (element->IsAnyOfHTMLElements(nsGkAtoms::input,
nsGkAtoms::button,
nsGkAtoms::menuitem,

View File

@ -2,5 +2,6 @@
support-files =
svg_example_test.html
svg_example_script.svg
[test_disabled_chrome.html]

View File

@ -0,0 +1,7 @@
<svg version="1.1">
<script>
document.documentElement.style.backgroundColor = 'rebeccapurple';
throw "badment, should never fire.";
</script>
<g><circle cx="25.8" cy="9.3" r="1.5"/></g>
</svg>

After

Width:  |  Height:  |  Size: 207 B

View File

@ -34,6 +34,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=744830
`;
is(t.firstChild.tagName.toLowerCase(), 'svg');
// This test crashes if the script tags are not handled correctly
t.innerHTML = `<svg version="1.1">
<scri` + `pt>
throw "badment, should never fire.";
</scri` + `pt>
<g><circle cx="25.8" cy="9.3" r="1.5"/></g>
</svg>`;
is(t.firstChild.tagName.toLowerCase(), 'svg');
t.innerHTML = null;
t.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg"));
is(t.firstChild.namespaceURI, "http://www.w3.org/2000/svg");

View File

@ -37,13 +37,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=744830
yield loadPromise;
const contentBR = iframeEl.contentDocument.body.getBoundingClientRect();
yield new Promise(_ => setTimeout(_, 1000));
ok(chromeBR.height > contentBR.height, "Chrome content height should be bigger than content due to layout");
ok(!("hasExtension" in iframeEl.contentDocument.getElementById('svgel')), 'SVG is disabled so no hasExtension support is available in content iframe');
ok(chromeIframeEl.contentDocument.getElementById('svgel').hasExtension("http://www.w3.org/1998/Math/MathML"), 'SVG namespace support is enabled in chrome iframe');
url = "http://mochi.test:8888/chrome/layout/svg/tests/svg_example_script.svg";
const iframeElScript = document.createElement("iframe");
let loadPromiseScript = ContentTaskUtils.waitForEvent(iframeElScript, "load", false);
iframeElScript.src = url;
t.appendChild(iframeElScript);
yield loadPromiseScript;
ok(!iframeElScript.contentDocument.documentElement.style, "Content should not be styled");
SpecialPowers.setBoolPref("svg.disabled", initialPrefValue);
});
</script>

View File

@ -647,6 +647,10 @@ nsHtml5TreeOpExecutor::RunScript(nsIContent* aScriptElement)
NS_ASSERTION(aScriptElement, "No script to run");
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aScriptElement);
if (!sele) {
MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Node didn't QI to script, but SVG wasn't disabled.");
return;
}
if (!mParser) {
NS_ASSERTION(sele->IsMalformed(), "Script wasn't marked as malformed.");

View File

@ -596,8 +596,11 @@ void
nsHtml5TreeOperation::PreventScriptExecution(nsIContent* aNode)
{
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aNode);
MOZ_ASSERT(sele);
if (sele) {
sele->PreventExecution();
} else {
MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Node didn't QI to script, but SVG wasn't disabled.");
}
}
void
@ -834,9 +837,12 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
case eTreeOpSetScriptLineNumberAndFreeze: {
nsIContent* node = *(mOne.node);
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(node);
NS_ASSERTION(sele, "Node didn't QI to script.");
if (sele) {
sele->SetScriptLineNumber(mFour.integer);
sele->FreezeUriAsyncDefer();
} else {
MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Node didn't QI to script, but SVG wasn't disabled.");
}
return NS_OK;
}
case eTreeOpSvgLoad: {