Bug 1959727 - Add the sanitizer option to setHTMLUnsafe. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D247233
This commit is contained in:
Tom Schuster
2025-05-07 17:34:30 +00:00
committed by tschuster@mozilla.com
parent 3a84b03088
commit 1faeaa00f5
5 changed files with 55 additions and 24 deletions

View File

@@ -20265,7 +20265,11 @@ static already_AddRefed<Document> CreateHTMLDocument(GlobalObject& aGlobal,
/* static */
already_AddRefed<Document> Document::ParseHTMLUnsafe(
GlobalObject& aGlobal, const TrustedHTMLOrString& aHTML,
nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) {
const SetHTMLUnsafeOptions& aOptions, nsIPrincipal* aSubjectPrincipal,
ErrorResult& aError) {
// Step 1. Let compliantHTML be the result of invoking the Get Trusted Type
// compliant string algorithm with TrustedHTML, thiss relevant global object,
// html, "Document parseHTMLUnsafe", and "script".
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
constexpr nsLiteralString sink = u"Document parseHTMLUnsafe"_ns;
Maybe<nsAutoString> compliantStringHolder;
@@ -20277,16 +20281,50 @@ already_AddRefed<Document> Document::ParseHTMLUnsafe(
return nullptr;
}
RefPtr<Document> doc = CreateHTMLDocument(aGlobal, false, aError);
// TODO: Always initialize the sanitizer.
bool sanitize = aOptions.mSanitizer.WasPassed();
// Step 2. Let document be a new Document, whose content type is "text/html".
// Step 3. Set documents allow declarative shadow roots to true.
// TODO: Figure out if we can always loadAsData.
RefPtr<Document> doc =
CreateHTMLDocument(aGlobal, /* aLoadedAsData */ sanitize, aError);
if (aError.Failed()) {
return nullptr;
}
aError = nsContentUtils::ParseDocumentHTML(*compliantString, doc, false);
// Step 4. Parse HTML from a string given document and compliantHTML.
// TODO(bug 1960845): Investigate the behavior around <noscript> with
// parseHTML
aError = nsContentUtils::ParseDocumentHTML(
*compliantString, doc,
/* aScriptingEnabledForNoscriptParsing */ !sanitize);
if (aError.Failed()) {
return nullptr;
}
if (sanitize) {
// Step 5. Let sanitizer be the result of calling get a sanitizer instance
// from options with options and false.
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(aGlobal.GetAsSupports());
RefPtr<Sanitizer> sanitizer = Sanitizer::GetInstance(
global, aOptions.mSanitizer.Value(), true, aError);
if (aError.Failed()) {
return nullptr;
}
// Step 6. Call sanitize on documents root node with sanitizer and false.
nsCOMPtr<nsINode> root = doc->GetRootElement();
MOZ_DIAGNOSTIC_ASSERT(root,
"HTML parser should have create the <html> root");
sanitizer->Sanitize(root, /* aSafe */ true, aError);
if (aError.Failed()) {
return nullptr;
}
}
// Step 7. Return document.
return doc.forget();
}
@@ -20298,7 +20336,8 @@ already_AddRefed<Document> Document::ParseHTML(GlobalObject& aGlobal,
ErrorResult& aError) {
// Step 1. Let document be a new Document, whose content type is "text/html".
// Step 2. Set documents allow declarative shadow roots to true.
RefPtr<Document> doc = CreateHTMLDocument(aGlobal, true, aError);
RefPtr<Document> doc =
CreateHTMLDocument(aGlobal, /* aLoadedAsData */ true, aError);
if (aError.Failed()) {
return nullptr;
}

View File

@@ -5619,7 +5619,8 @@ class Document : public nsINode,
MOZ_CAN_RUN_SCRIPT static already_AddRefed<Document> ParseHTMLUnsafe(
GlobalObject& aGlobal, const TrustedHTMLOrString& aHTML,
nsIPrincipal* aSubjectPrincipal, ErrorResult& aError);
const SetHTMLUnsafeOptions& aOptions, nsIPrincipal* aSubjectPrincipal,
ErrorResult& aError);
static already_AddRefed<Document> ParseHTML(GlobalObject& aGlobal,
const nsAString& aHTML,

View File

@@ -123,7 +123,7 @@ interface Document : Node {
// https://html.spec.whatwg.org/multipage/dom.html#the-document-object
partial interface Document {
[Throws, NeedsSubjectPrincipal=NonSystem]
static Document parseHTMLUnsafe((TrustedHTML or DOMString) html);
static Document parseHTMLUnsafe((TrustedHTML or DOMString) html, optional SetHTMLUnsafeOptions options = {});
[PutForwards=href, LegacyUnforgeable] readonly attribute Location? location;
[SetterThrows] attribute DOMString domain;

View File

@@ -11,18 +11,6 @@
[parseHTMLUnsafe testcase elements/2, "<div><p>Hello <b>World!</b>"]
expected: FAIL
[parseHTMLUnsafe testcase elements/3, "<div><p>Hello <b>World!</b>"]
expected: FAIL
[parseHTMLUnsafe testcase elements/4, "<div><p>Hello <b>World!</b>"]
expected: FAIL
[parseHTMLUnsafe testcase attributes/1, "<p id="hello" style="font-weight: bold">x"]
expected: FAIL
[parseHTMLUnsafe testcase attributes/2, "<p id="hello" style="font-weight: bold">x"]
expected: FAIL
[setHTMLUnsafe testcase attributes-per-element/0, "<div style="font-weight: bold" class="bourgeoisie">"]
expected: FAIL
@@ -38,9 +26,6 @@
[parseHTMLUnsafe testcase attributes-per-element/1, "<div style="font-weight: bold" class="bourgeoisie">"]
expected: FAIL
[parseHTMLUnsafe testcase comments/1, "a <!-- comment --> b"]
expected: FAIL
[setHTML testcase dataAttributes/0, "<p data-x="1" data-y="2" data-z="3">"]
expected: FAIL
@@ -187,3 +172,12 @@
[ShadowRoot.setHTMLUnsafe testcase namespaces/9, "<svg xml:space="default" xlink:href="about:blank" xmlns:foo="barspace">"]
expected: FAIL
[parseHTMLUnsafe testcase namespaces/2, "<svg><rect>"]
expected: FAIL
[parseHTMLUnsafe testcase namespaces/5, "<math><mi>x"]
expected: FAIL
[parseHTMLUnsafe testcase namespaces/7, "<svg xml:space="default" xlink:href="about:blank" xmlns:foo="barspace">"]
expected: FAIL

View File

@@ -1,6 +1,3 @@
[sanitizer-boolean-defaults.tentative.html]
[comments]
expected: FAIL
[data attributes]
expected: FAIL