Bug 1263696 - Block embed content loading when ancestor of object element with content; r=bz

This commit is contained in:
Kyle Machulis 2016-04-28 14:57:34 -07:00
Родитель dbae54ae82
Коммит 85146b9ee1
10 изменённых файлов: 124 добавлений и 20 удалений

Просмотреть файл

@ -86,6 +86,7 @@
#include "mozilla/EventStates.h"
#include "mozilla/Telemetry.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "mozilla/dom/HTMLSharedObjectElement.h"
#ifdef XP_WIN
// Thanks so much, Microsoft! :(
@ -3093,24 +3094,35 @@ nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) {
aType = eFallbackAlternate;
}
// We'll set this to null no matter what now, doing it here means we'll load
// child embeds as we find them in the upcoming loop.
mType = eType_Null;
// Do a breadth-first traverse of node tree with the current element as root,
// looking for the first embed we can find.
nsTArray<nsINodeList*> childNodes;
if ((thisContent->IsHTMLElement(nsGkAtoms::object) ||
thisContent->IsHTMLElement(nsGkAtoms::applet)) &&
(aType == eFallbackUnsupported ||
aType == eFallbackDisabled ||
aType == eFallbackBlocklisted))
{
// Show alternate content instead, if it exists
for (nsIContent* child = thisContent->GetFirstChild();
child; child = child->GetNextSibling()) {
if (!child->IsHTMLElement(nsGkAtoms::param) &&
for (nsIContent* child = thisContent->GetFirstChild(); child;
child = child->GetNextNode(thisContent)) {
if (aType != eFallbackAlternate &&
!child->IsHTMLElement(nsGkAtoms::param) &&
nsStyleUtil::IsSignificantChild(child, true, false)) {
aType = eFallbackAlternate;
break;
}
if (child->IsHTMLElement(nsGkAtoms::embed)) {
HTMLSharedObjectElement* object = static_cast<HTMLSharedObjectElement*>(child);
if (object) {
object->StartObjectLoad(true, true);
}
}
}
}
mType = eType_Null;
mFallbackType = aType;
// Notify

Просмотреть файл

@ -0,0 +1,12 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/REC-html401-19991224/strict.dtd">
<html>
<head>
<title>Bug 1263696 - iframe that should not be loaded</title>
</head>
<body>
<script>
parent.SimpleTest.ok(false, "this iframe should not load");
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,13 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/REC-html401-19991224/strict.dtd">
<html>
<head>
<title>Bug 1263696 - iframe that should be loaded</title>
</head>
<body>
<script>
parent.index = parent.index + 1;
parent.SimpleTest.ok(true, "this iframe should load");
</script>
</body>
</html>

Просмотреть файл

@ -157,6 +157,8 @@ support-files =
file_bug902350_frame.html
file_bug907892.html
file_bug945152.jar
file_bug1263696_frame_pass.html
file_bug1263696_frame_fail.html
file_general_document.html
file_html_in_xhr.html
file_html_in_xhr.sjs
@ -894,3 +896,4 @@ skip-if = buildapp == 'b2g' #no ssl support
[test_document_register.html]
[test_bug962251.html]
[test_bug1259588.html]
[test_bug1263696.html]

Просмотреть файл

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<meta><charset="utf-8"/>
<title>Test Embed/Object Node Conflicts</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="plugin-utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
var index = 0;
function startTest() {
is(index, 12, "Should have loaded all passing frames.");
SimpleTest.finish();
}
</script>
</head>
<body onload="startTest()">
<object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px">
<embed type="text/html" src="file_bug1263696_frame_fail.html" />
</object>
<object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
</object>
<object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
<div></div>
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
</object>
<object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
<div>
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
</div>
</object>
<object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
<object data="file_bug1263696_frame_pass.html">
<embed type="text/html" src="file_bug1263696_frame_fail.html" />
</object>
<object data="data:application/x-does-not-exist,test">
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
</object>
</object>
<div>
<object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px"></object>
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
</div>
<div>
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
<object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px"></object>
</div>
</body>
</html>

Просмотреть файл

@ -20,8 +20,8 @@
#ifdef XP_MACOSX
#include "mozilla/EventDispatcher.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/HTMLObjectElement.h"
#endif
#include "mozilla/dom/HTMLObjectElement.h"
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(SharedObject)
@ -85,7 +85,7 @@ HTMLSharedObjectElement::DoneAddingChildren(bool aHaveNotified)
// If we're already in a document, we need to trigger the load
// Otherwise, BindToTree takes care of that.
if (IsInComposedDoc()) {
StartObjectLoad(aHaveNotified);
StartObjectLoad(aHaveNotified, false);
}
}
}
@ -322,7 +322,7 @@ HTMLSharedObjectElement::GetAttributeMappingFunction() const
}
void
HTMLSharedObjectElement::StartObjectLoad(bool aNotify)
HTMLSharedObjectElement::StartObjectLoad(bool aNotify, bool aForceLoad)
{
// BindToTree can call us asynchronously, and we may be removed from the tree
// in the interim
@ -331,7 +331,7 @@ HTMLSharedObjectElement::StartObjectLoad(bool aNotify)
return;
}
LoadObject(aNotify);
LoadObject(aNotify, aForceLoad);
SetIsNetworkCreated(false);
}
@ -416,6 +416,15 @@ HTMLSharedObjectElement::BlockEmbedContentLoading()
if (parent->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) {
return true;
}
// If we have an ancestor that is an object with a source, it'll have an
// associated displayed type. If that type is not null, don't load content
// for the embed.
if (HTMLObjectElement* object = HTMLObjectElement::FromContent(parent)) {
uint32_t type = object->DisplayedType();
if (type != eType_Null) {
return true;
}
}
}
return false;
}

Просмотреть файл

@ -80,7 +80,7 @@ public:
nsresult CopyInnerTo(Element* aDest);
void StartObjectLoad() { StartObjectLoad(true); }
void StartObjectLoad() { StartObjectLoad(true, false); }
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLSharedObjectElement,
nsGenericHTMLElement)
@ -192,13 +192,12 @@ public:
return GetContentDocument();
}
private:
virtual ~HTMLSharedObjectElement();
/**
* Calls LoadObject with the correct arguments to start the plugin load.
*/
void StartObjectLoad(bool aNotify);
void StartObjectLoad(bool aNotify, bool aForceLoad);
private:
virtual ~HTMLSharedObjectElement();
nsIAtom *URIAttrName() const
{
@ -228,6 +227,8 @@ private:
* the content:
*
* - If the embed node is the child of a media element
* - If the embed node is the child of an object node that already has
* content being loaded.
*
* In these cases, this function will return false, which will cause
* us to skip calling LoadObject.

Просмотреть файл

@ -94,8 +94,8 @@ function checkOrder(entries, name) {
<p id="display"></p>
<div id="content">
<img src="http://mochi.test:8888/tests/image/test/mochitest/over.png">
<object data="http://mochi.test:8888/tests/image/test/mochitest/clear.png" type="image/png"/>
<embed src="http://mochi.test:8888/tests/image/test/mochitest/green.png" type="image/png"/>
<object data="http://mochi.test:8888/tests/image/test/mochitest/clear.png" type="image/png"></object>
<embed src="http://mochi.test:8888/tests/image/test/mochitest/green.png" type="image/png"/>
</div>
</body>
</html>

Просмотреть файл

@ -276,9 +276,9 @@ function iframeTestsCompleted() {
<p id="display"></p>
<div id="content">
<img src="http://mochi.test:8888/tests/image/test/mochitest/blue.png">
<object data="http://mochi.test:8888/tests/image/test/mochitest/red.png" type="image/png"/>
<embed src="http://mochi.test:8888/tests/image/test/mochitest/big.png" type="image/png"/>
<iframe sandbox="allow-same-origin allow-scripts" id="if_2" src="resource_timing_iframe.html" height="10" width="10"></iframe>
<object data="http://mochi.test:8888/tests/image/test/mochitest/red.png" type="image/png"></object>
<embed src="http://mochi.test:8888/tests/image/test/mochitest/big.png" type="image/png"/>
<iframe sandbox="allow-same-origin allow-scripts" id="if_2" src="resource_timing_iframe.html" height="10" width="10"></iframe>
</div>
</body>
</html>

Просмотреть файл

@ -26,6 +26,7 @@
#undef GetBinaryType
#undef RemoveDirectory
#undef LoadIcon
#undef GetObject
#endif
class nsPresContext;