java-topology/defects/firefox/patch/firefox-0002-domtokenlist-addremove-quadratic.patch

61 lines
2.1 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UNDF: UNDF-2026-000000846
# CWE-407: Algorithmic Complexity — Firefox nsDOMTokenList O(T²) classList add/remove
#
# File: dom/base/nsDOMTokenList.cpp
# Methods: AddInternal(), RemoveInternal()
#
# AddInternal() builds an `addedClasses` nsTArray and checks
# `addedClasses.Contains(aToken)` inside the loop over aTokens,
# making deduplication O(T²) where T = number of tokens being added.
#
# RemoveInternal() checks `aTokens.Contains(atom)` for each atom
# in the existing attribute, making removal O(A×T) where A = existing
# class count and T = tokens to remove.
#
# classList.add() and classList.remove() are called frequently in
# DOM-heavy applications (frameworks like React, Angular, etc.).
#
# Severity: MEDIUM — classList operations with many tokens are quadratic.
# At T=500 tokens, AddInternal does ~125,000 string comparisons instead
# of ~500 with a hash set.
#
# Fix: Use a hash set for dedup in AddInternal and for membership
# testing in RemoveInternal.
#
--- a/dom/base/nsDOMTokenList.cpp
+++ b/dom/base/nsDOMTokenList.cpp
@@ -159,7 +159,7 @@
- AutoTArray<nsString, 10> addedClasses;
+ nsTHashSet<nsString> addedClasses;
for (uint32_t i = 0, l = aTokens.Length(); i < l; ++i) {
const nsString& aToken = aTokens[i];
- if ((aAttr && aAttr->Contains(aToken)) || addedClasses.Contains(aToken)) {
+ if ((aAttr && aAttr->Contains(aToken)) || addedClasses.Contains(aToken)) {
continue;
}
@@ -171,7 +171,7 @@
resultStr.Append(aToken);
- addedClasses.AppendElement(aToken);
+ addedClasses.Insert(aToken);
}
@@ -196,10 +196,12 @@
void nsDOMTokenList::RemoveInternal(const nsAttrValue* aAttr,
const nsTArray<nsString>& aTokens) {
MOZ_ASSERT(aAttr, "Need an attribute");
RemoveDuplicates(aAttr);
+ nsTHashSet<nsString> tokenSet;
+ for (const auto& t : aTokens) { tokenSet.Insert(t); }
+
nsAutoString resultStr;
for (uint32_t i = 0; i < aAttr->GetAtomCount(); i++) {
- if (aTokens.Contains(nsDependentAtomString(aAttr->AtomAt(i)))) {
+ if (tokenSet.Contains(nsDependentAtomString(aAttr->AtomAt(i)))) {
continue;
}