Bug 1669050: add `href` to the allowed SVG attributes in `nsTreeSanitizer`. r=hsivonen

This follows the pattern of `kAttributesHTML` and `kURLAttributesHTML`,
which both contain `href`. Now, `kAttributesSVG` and `kURLAttributesSVG`
contain `href` too.

Unfortunately, the WPT-support for filling and reading the clipboard is
scanty (see bug 1676643), hence adding a Mochitest.

Differential Revision: https://phabricator.services.mozilla.com/D97451
This commit is contained in:
Mirko Brodesser 2020-11-19 08:19:12 +00:00
Родитель 1d34bd022d
Коммит 059b8337cf
3 изменённых файлов: 117 добавлений и 2 удалений

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

@ -6,6 +6,7 @@
#include "nsTreeSanitizer.h"
#include "mozilla/Algorithm.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/BindingStyleRule.h"
#include "mozilla/DeclarationBlock.h"
@ -27,6 +28,8 @@
#include "mozilla/dom/Document.h"
#include "nsQueryObject.h"
#include <iterator>
using namespace mozilla;
using namespace mozilla::dom;
@ -380,7 +383,7 @@ const nsStaticAtom* const kElementsSVG[] = {
// vkern
nullptr};
const nsStaticAtom* const kAttributesSVG[] = {
constexpr const nsStaticAtom* const kAttributesSVG[] = {
// accent-height
nsGkAtoms::accumulate, // accumulate
nsGkAtoms::additive, // additive
@ -454,6 +457,7 @@ const nsStaticAtom* const kAttributesSVG[] = {
nsGkAtoms::gradientTransform, // gradientTransform
nsGkAtoms::gradientUnits, // gradientUnits
nsGkAtoms::height, // height
nsGkAtoms::href,
// horiz-adv-x
// horiz-origin-x
// horiz-origin-y
@ -613,7 +617,17 @@ const nsStaticAtom* const kAttributesSVG[] = {
nsGkAtoms::zoomAndPan, // zoomAndPan
nullptr};
const nsStaticAtom* const kURLAttributesSVG[] = {nsGkAtoms::href, nullptr};
constexpr const nsStaticAtom* const kURLAttributesSVG[] = {nsGkAtoms::href,
nullptr};
static_assert(AllOf(std::begin(kURLAttributesSVG), std::end(kURLAttributesSVG),
[](auto aURLAttributeSVG) {
return AnyOf(std::begin(kAttributesSVG),
std::end(kAttributesSVG),
[&](auto aAttributeSVG) {
return aAttributeSVG == aURLAttributeSVG;
});
}));
const nsStaticAtom* const kElementsMathML[] = {
nsGkAtoms::abs_, // abs

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

@ -751,6 +751,8 @@ skip-if = xorigin # JavaScript error: http://mochi.test:8888/tests/SimpleTest/Si
[test_open_null_features.html]
[test_openDialogChromeOnly.html]
tags = openwindow
[test_pasting_svg_image.html]
skip-if = headless # Bug 1669923.
[test_pdf_print.html]
skip-if = toolkit == 'android' # We don't ship pdf.js on Android
[test_plugin_freezing.html]

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

@ -0,0 +1,99 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test pasting &lt;svg&gt;&lt;image href&gt;</title>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
<script>
const kPasteTargetId = "pasteTarget";
const kTestContentId = "testContent";
function selectSVG() {
const testContent = document.getElementById(kTestContentId);
document.getSelection().selectAllChildren(testContent);
}
async function copyToClipboard() {
function validatorFn(aData) {
const testContent = document.getElementById(kTestContentId);
let expectedData = testContent.outerHTML;
if (navigator.platform.includes(kPlatformWindows)) {
expectedData = kTextHtmlPrefixClipboardDataWindows +
expectedData + kTextHtmlSuffixClipboardDataWindows;
}
return SimpleTest.stripLinebreaksAndWhitespaceAfterTags(aData) ==
SimpleTest.stripLinebreaksAndWhitespaceAfterTags(expectedData);
}
function setupFn() {
synthesizeKey("c", { accelKey: true } /* aEvent */);
}
const flavor = "text/html";
await SimpleTest.promiseClipboardChange(validatorFn, setupFn, flavor);
}
async function pasteTo(aTargetElement) {
document.getSelection().selectAllChildren(aTargetElement);
const promiseInputEvent = new Promise(resolve => {
document.addEventListener("input", resolve,
{ once: true } /* options */);
synthesizeKey("v", { accelKey: true } /* aEvent */);
});
await promiseInputEvent;
}
async function runTest() {
selectSVG();
await copyToClipboard();
// Get the test-content before pasting, because pasting will duplicate
// ids.
const expectedPastedInnerHTML =
SimpleTest.stripLinebreaksAndWhitespaceAfterTags(
document.getElementById(kTestContentId).outerHTML);
const pasteTargetElement = document.getElementById(kPasteTargetId);
await pasteTo(pasteTargetElement);
const pastedInnerHTMLWithoutLinebreaksAndWhitespaceAfterTags =
SimpleTest.stripLinebreaksAndWhitespaceAfterTags(
pasteTargetElement.innerHTML);
is(pastedInnerHTMLWithoutLinebreaksAndWhitespaceAfterTags,
expectedPastedInnerHTML,
"Pasted HTML is as expected.");
SimpleTest.finish()
}
function onLoad() {
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(runTest);
};
</script>
</head>
<body onload="onLoad()">
<h6>
Test for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1669050">bug 1669050</a>
</h6>
<div id="testContent">
foo
<svg>
<image
href="http://mochi.test:8888/tests/dom/base/test/name_of_some_image_file.png"
height="200" width="200">
</image>
</svg>
bar
</div>
<div contenteditable id="pasteTarget"/>
</body>
</html>