commit 9a0627d238cd984b8e57bd997f81e6996a007a05
parent 9d4624d9f1111a080b258cc780418909b1be4102
Author: Tom Schuster <tschuster@mozilla.com>
Date: Thu, 16 Oct 2025 21:25:28 +0000
Bug 1989215 - Sanitizer: Throw on duplicates. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D267196
Diffstat:
3 files changed, 55 insertions(+), 55 deletions(-)
diff --git a/dom/security/sanitizer/Sanitizer.cpp b/dom/security/sanitizer/Sanitizer.cpp
@@ -280,9 +280,13 @@ static CanonicalName CanonicalizeAttribute(
}
// https://wicg.github.io/sanitizer-api/#canonicalize-a-sanitizer-element-with-attributes
+//
+// If aErrorMsg is not nullptr, this function will abort for duplicate
+// attributes and set an error message, but otherwise they are ignored.
template <typename SanitizerElementWithAttributes>
static CanonicalElementAttributes CanonicalizeElementAttributes(
- const SanitizerElementWithAttributes& aElement) {
+ const SanitizerElementWithAttributes& aElement,
+ nsACString* aErrorMsg = nullptr) {
// Step 1. Let result be the result of canonicalize a sanitizer element with
// element.
//
@@ -302,7 +306,13 @@ static CanonicalElementAttributes CanonicalizeElementAttributes(
for (const auto& attribute : elem.mAttributes.Value()) {
// Step 2.1.2.1. Append the result of canonicalize a sanitizer attribute
// with attribute to attributes.
- attributes.Insert(CanonicalizeAttribute(attribute));
+ if (!attributes.EnsureInserted(CanonicalizeAttribute(attribute))) {
+ if (aErrorMsg) {
+ aErrorMsg->AssignLiteral(
+ "Duplicate attribute in local 'attributes'");
+ return CanonicalElementAttributes();
+ }
+ }
}
// Step 2.1.3. Set result["attributes"] to attributes.
@@ -318,7 +328,13 @@ static CanonicalElementAttributes CanonicalizeElementAttributes(
for (const auto& attribute : elem.mRemoveAttributes.Value()) {
// Step 2.2.2.1. Append the result of canonicalize a sanitizer attribute
// with attribute to attributes.
- attributes.Insert(CanonicalizeAttribute(attribute));
+ if (!attributes.EnsureInserted(CanonicalizeAttribute(attribute))) {
+ if (aErrorMsg) {
+ aErrorMsg->AssignLiteral(
+ "Duplicate attribute in local 'removeAttributes'");
+ return CanonicalElementAttributes();
+ }
+ }
}
// Step 2.2.3. Set result["removeAttributes"] to attributes.
@@ -339,8 +355,9 @@ static CanonicalElementAttributes CanonicalizeElementAttributes(
}
// https://wicg.github.io/sanitizer-api/#configuration-canonicalize
-void Sanitizer::CanonicalizeConfiguration(
- const SanitizerConfig& aConfig, bool aAllowCommentsAndDataAttributes) {
+void Sanitizer::CanonicalizeConfiguration(const SanitizerConfig& aConfig,
+ bool aAllowCommentsAndDataAttributes,
+ ErrorResult& aRv) {
// This function is only called while constructing a new Sanitizer object.
AssertNoLists();
@@ -364,15 +381,23 @@ void Sanitizer::CanonicalizeConfiguration(
// Step 3.1. Let elements be « [] »
CanonicalElementMap elements;
+ nsAutoCString errorMsg;
// Step 3.2. For each element of configuration["elements"] do:
for (const auto& element : aConfig.mElements.Value()) {
// Step 3.3.2.1. Append the result of canonicalize a sanitizer element
// with attributes element to elements.
- // XX duplicates.
CanonicalName elementName = CanonicalizeElement(element);
+ if (elements.Contains(elementName)) {
+ return aRv.ThrowTypeError("Duplicate element in 'elements'");
+ }
+
CanonicalElementAttributes elementAttributes =
- CanonicalizeElementAttributes(element);
+ CanonicalizeElementAttributes(element, &errorMsg);
+ if (!errorMsg.IsEmpty()) {
+ return aRv.ThrowTypeError(errorMsg);
+ }
+
elements.InsertOrUpdate(elementName, std::move(elementAttributes));
}
@@ -389,9 +414,10 @@ void Sanitizer::CanonicalizeConfiguration(
for (const auto& element : aConfig.mRemoveElements.Value()) {
// Step 4.2.1. Append the result of canonicalize a sanitizer element
// element to elements.
-
- // xxx
- elements.Insert(CanonicalizeElement(element));
+ if (!elements.EnsureInserted(CanonicalizeElement(element))) {
+ aRv.ThrowTypeError("Duplicate element in 'removeElements'");
+ return;
+ }
}
// Step 4.3. Set configuration["removeElements"] to elements.
@@ -408,9 +434,11 @@ void Sanitizer::CanonicalizeConfiguration(
for (const auto& element : aConfig.mReplaceWithChildrenElements.Value()) {
// Step 5.2.1. Append the result of canonicalize a sanitizer element
// element to elements.
-
- // XXX
- elements.Insert(CanonicalizeElement(element));
+ if (!elements.EnsureInserted(CanonicalizeElement(element))) {
+ aRv.ThrowTypeError(
+ "Duplicate element in 'replaceWithChildrenElements'");
+ return;
+ }
}
// Step 5.3. Set configuration["replaceWithChildrenElements"] to elements.
@@ -426,9 +454,10 @@ void Sanitizer::CanonicalizeConfiguration(
for (const auto& attribute : aConfig.mAttributes.Value()) {
// Step 6.2.1. Append the result of canonicalize a sanitizer attribute
// attribute to attributes.
-
- // XXX Remember duplicates.
- attributes.Insert(CanonicalizeAttribute(attribute));
+ if (!attributes.EnsureInserted(CanonicalizeAttribute(attribute))) {
+ aRv.ThrowTypeError("Duplicate attribute in 'attributes'");
+ return;
+ }
}
// Step 6.3. Set configuration["attributes"] to attributes.
@@ -444,7 +473,10 @@ void Sanitizer::CanonicalizeConfiguration(
for (const auto& attribute : aConfig.mRemoveAttributes.Value()) {
// Step 7.2.2. Append the result of canonicalize a sanitizer attribute
// attribute to attributes.
- attributes.Insert(CanonicalizeAttribute(attribute));
+ if (!attributes.EnsureInserted(CanonicalizeAttribute(attribute))) {
+ aRv.ThrowTypeError("Duplicate attribute in 'removeAttributes'");
+ return;
+ }
}
// Step 7.3. Set configuration["removeAttributes"] to attributes.
@@ -502,27 +534,6 @@ void Sanitizer::IsValid(ErrorResult& aRv) {
// Step 4. None of config[elements], config[removeElements],
// config[replaceWithChildrenElements], config[attributes], or
// config[removeAttributes], if they exist, has duplicates.
- // if (mElements && mElements->HasDuplicates()) {
- // aRv.ThrowTypeError("Duplicate element in 'elements'");
- // return;
- // }
- // if (mRemoveElements && mRemoveElements->HasDuplicates()) {
- // aRv.ThrowTypeError("Duplicate element in 'removeElement'");
- // return;
- // }
- // if (mReplaceWithChildrenElements &&
- // mReplaceWithChildrenElements->HasDuplicates()) {
- // aRv.ThrowTypeError("Duplicate element in 'replaceWithChildrenElements'");
- // return;
- // }
- // if (mAttributes && mAttributes->HasDuplicates()) {
- // aRv.ThrowTypeError("Duplicate attribute in 'attributes'");
- // return;
- // }
- // if (mRemoveAttributes && mRemoveAttributes->HasDuplicates()) {
- // aRv.ThrowTypeError("Duplicate attribute in 'removeAttributes'");
- // return;
- // }
// Step 5. If both config[elements] and config[replaceWithChildrenElements]
// exist, then the intersection of config[elements] and
@@ -562,16 +573,6 @@ void Sanitizer::IsValid(ErrorResult& aRv) {
// Step 7.1.1.1. Neither element[attributes] or
// element[removeAttributes], if they exist, has duplicates.
- /*
- if (elem.mAttributes && elem.mAttributes->HasDuplicates()) {
- aRv.ThrowTypeError("Duplicate attribute in local 'attributes'");
- return;
- }
- if (elem.mRemoveAttributes && elem.mRemoveAttributes->HasDuplicates()) {
- aRv.ThrowTypeError("Duplicate attribute in local 'removeAttributes'");
- return;
- }
- */
// Step 7.1.1.2. The intersection of config[attributes] and
// element[attributes] with default « [] » is empty.
@@ -694,7 +695,10 @@ void Sanitizer::SetConfig(const SanitizerConfig& aConfig,
bool aAllowCommentsAndDataAttributes,
ErrorResult& aRv) {
// Step 1. Canonicalize configuration with allowCommentsAndDataAttributes.
- CanonicalizeConfiguration(aConfig, aAllowCommentsAndDataAttributes);
+ CanonicalizeConfiguration(aConfig, aAllowCommentsAndDataAttributes, aRv);
+ if (aRv.Failed()) {
+ return;
+ }
// Step 2. If configuration is not valid, then return false.
IsValid(aRv);
diff --git a/dom/security/sanitizer/Sanitizer.h b/dom/security/sanitizer/Sanitizer.h
@@ -77,7 +77,8 @@ class Sanitizer final : public nsISupports, public nsWrapperCache {
~Sanitizer() = default;
void CanonicalizeConfiguration(const SanitizerConfig& aConfig,
- bool aAllowCommentsAndDataAttributes);
+ bool aAllowCommentsAndDataAttributes,
+ ErrorResult& aRv);
void IsValid(ErrorResult& aRv);
void SetDefaultConfig();
diff --git a/testing/web-platform/meta/sanitizer-api/sanitizer-config.tentative.html.ini b/testing/web-platform/meta/sanitizer-api/sanitizer-config.tentative.html.ini
@@ -1,5 +0,0 @@
-[sanitizer-config.tentative.html]
- [Duplicates in element\[removeAttributes\] should not be allowed.]
- expected: FAIL
- [Duplicates in element\[attributes\] should not be allowed.]
- expected: FAIL