tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Mdom/security/sanitizer/Sanitizer.cpp | 102+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mdom/security/sanitizer/Sanitizer.h | 3++-
Dtesting/web-platform/meta/sanitizer-api/sanitizer-config.tentative.html.ini | 5-----
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