commit 7d6cfb3a6f950e30a8c5297f3bb1021a24843dfd
parent 5c65944662b0e06cb69d48f597d2f1bd6fdf33a9
Author: Alexandru Marc <amarc@mozilla.com>
Date: Fri, 31 Oct 2025 16:57:59 +0200
Revert "Bug 1995614: Atomize ATTR_TYPE strings and any single digit strings during tokenization. r=hsivonen" for causing Bug 1997489 This reverts commit eee6488f783ab72b1afc95c0a824629b25e1458b.
Diffstat:
9 files changed, 39 insertions(+), 165 deletions(-)
diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp
@@ -2844,40 +2844,7 @@ nsresult Element::SetAttr(int32_t aNamespaceID, nsAtom* aName, nsAtom* aPrefix,
nsIPrincipal* aSubjectPrincipal, bool aNotify) {
// Keep this in sync with SetParsedAttr below and SetSingleClassFromParser
// above.
- const nsAttrValueOrString valueForComparison(aValue);
- return SetAttrInternal(aNamespaceID, aName, aPrefix, valueForComparison,
- aSubjectPrincipal, aNotify,
- [&](nsAttrValue& attrValue) {
- if (!ParseAttribute(aNamespaceID, aName, aValue,
- aSubjectPrincipal, attrValue)) {
- attrValue.SetTo(aValue);
- }
- });
-}
-nsresult Element::SetAttr(int32_t aNamespaceID, nsAtom* aName, nsAtom* aPrefix,
- nsAtom* aValue, nsIPrincipal* aSubjectPrincipal,
- bool aNotify) {
- // Keep this in sync with SetParsedAttr below and SetSingleClassFromParser
- // above.
- const nsDependentAtomString valueString(aValue);
- const nsAttrValueOrString valueForComparison(valueString);
- return SetAttrInternal(aNamespaceID, aName, aPrefix, valueForComparison,
- aSubjectPrincipal, aNotify,
- [&](nsAttrValue& attrValue) {
- if (!ParseAttribute(aNamespaceID, aName, valueString,
- aSubjectPrincipal, attrValue)) {
- attrValue.SetTo(aValue);
- }
- });
-}
-
-template <typename ParseFunc>
-nsresult Element::SetAttrInternal(int32_t aNamespaceID, nsAtom* aName,
- nsAtom* aPrefix,
- const nsAttrValueOrString& aValue,
- nsIPrincipal* aSubjectPrincipal, bool aNotify,
- ParseFunc&& aParseFn) {
NS_ENSURE_ARG_POINTER(aName);
NS_ASSERTION(aNamespaceID != kNameSpaceID_Unknown,
"Don't call SetAttr with unknown namespace");
@@ -2886,10 +2853,13 @@ nsresult Element::SetAttrInternal(int32_t aNamespaceID, nsAtom* aName,
nsAttrValue oldValue;
bool oldValueSet;
- if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, aValue, aNotify,
- oldValue, &modType, &oldValueSet)) {
- OnAttrSetButNotChanged(aNamespaceID, aName, aValue, aNotify);
- return NS_OK;
+ {
+ const nsAttrValueOrString value(aValue);
+ if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify,
+ oldValue, &modType, &oldValueSet)) {
+ OnAttrSetButNotChanged(aNamespaceID, aName, value, aNotify);
+ return NS_OK;
+ }
}
// Hold a script blocker while calling ParseAttribute since that can call
@@ -2903,7 +2873,10 @@ nsresult Element::SetAttrInternal(int32_t aNamespaceID, nsAtom* aName,
}
nsAttrValue attrValue;
- aParseFn(attrValue);
+ if (!ParseAttribute(aNamespaceID, aName, aValue, aSubjectPrincipal,
+ attrValue)) {
+ attrValue.SetTo(aValue);
+ }
BeforeSetAttr(aNamespaceID, aName, &attrValue, aNotify);
diff --git a/dom/base/Element.h b/dom/base/Element.h
@@ -1044,10 +1044,6 @@ class Element : public FragmentOrElement {
const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal, bool aNotify);
- nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName, nsAtom* aPrefix,
- nsAtom* aValue, nsIPrincipal* aMaybeScriptedPrincipal,
- bool aNotify);
-
/**
* Remove an attribute so that it is no longer explicitly specified.
*
@@ -2037,16 +2033,6 @@ class Element : public FragmentOrElement {
static const DOMTokenListSupportedToken sSupportedBlockingValues[];
/**
- * Common implementation for SetAttr overloads. Takes a callback to perform
- * the type-specific parsing and value setting.
- */
- template <typename ParseFunc>
- nsresult SetAttrInternal(int32_t aNamespaceID, nsAtom* aName, nsAtom* aPrefix,
- const nsAttrValueOrString& aValueForComparison,
- nsIPrincipal* aSubjectPrincipal, bool aNotify,
- ParseFunc&& aParseFn);
-
- /**
* Set attribute and (if needed) notify documentobservers. This will send the
* AttributeChanged notification. Callers of this method are responsible for
* calling AttributeWillChange, since that needs to happen before the new attr
diff --git a/parser/html/javasrc/Tokenizer.java b/parser/html/javasrc/Tokenizer.java
@@ -1001,21 +1001,8 @@ public class Tokenizer implements Locator, Locator2 {
* @return the buffer as a string
*/
@Inline protected String strBufToString() {
- // CPPONLY: String digitAtom = TryAtomizeForSingleDigit();
- // CPPONLY: if (digitAtom) {
- // CPPONLY: return digitAtom;
- // CPPONLY: }
- // CPPONLY:
- // CPPONLY: boolean maybeAtomize = false;
- // CPPONLY: if (!newAttributesEachTime) {
- // CPPONLY: if (attributeName == AttributeName.CLASS ||
- // CPPONLY: attributeName == AttributeName.TYPE) {
- // CPPONLY: maybeAtomize = true;
- // CPPONLY: }
- // CPPONLY: }
- // CPPONLY:
String str = Portability.newStringFromBuffer(strBuf, 0, strBufLen
- // CPPONLY: , tokenHandler, maybeAtomize
+ // CPPONLY: , tokenHandler, !newAttributesEachTime && attributeName == AttributeName.CLASS
);
clearStrBufAfterUse();
return str;
diff --git a/parser/html/nsHtml5Tokenizer.h b/parser/html/nsHtml5Tokenizer.h
@@ -363,19 +363,10 @@ class nsHtml5Tokenizer {
protected:
inline nsHtml5String strBufToString() {
- nsHtml5String digitAtom = TryAtomizeForSingleDigit();
- if (digitAtom) {
- return digitAtom;
- }
- bool maybeAtomize = false;
- if (!newAttributesEachTime) {
- if (attributeName == nsHtml5AttributeName::ATTR_CLASS ||
- attributeName == nsHtml5AttributeName::ATTR_TYPE) {
- maybeAtomize = true;
- }
- }
nsHtml5String str = nsHtml5Portability::newStringFromBuffer(
- strBuf, 0, strBufLen, tokenHandler, maybeAtomize);
+ strBuf, 0, strBufLen, tokenHandler,
+ !newAttributesEachTime &&
+ attributeName == nsHtml5AttributeName::ATTR_CLASS);
clearStrBufAfterUse();
return str;
}
diff --git a/parser/html/nsHtml5TokenizerCppSupplement.h b/parser/html/nsHtml5TokenizerCppSupplement.h
@@ -108,21 +108,6 @@ void nsHtml5Tokenizer::SetViewSourceOpSink(nsAHtml5TreeOpSink* aOpSink) {
void nsHtml5Tokenizer::RewindViewSource() { mViewSource->Rewind(); }
-nsHtml5String nsHtml5Tokenizer::TryAtomizeForSingleDigit() {
- if (!newAttributesEachTime && strBufLen == 1 && strBuf[0] >= '0' &&
- strBuf[0] <= '9') {
- static nsStaticAtom* const digitAtoms[10] = {
- nsGkAtoms::_0, nsGkAtoms::_1, nsGkAtoms::_2, nsGkAtoms::_3,
- nsGkAtoms::_4, nsGkAtoms::_5, nsGkAtoms::_6, nsGkAtoms::_7,
- nsGkAtoms::_8, nsGkAtoms::_9};
- nsAtom* atom = digitAtoms[strBuf[0] - '0'];
- nsHtml5String result = nsHtml5String::FromAtom(do_AddRef(atom));
- clearStrBufAfterUse();
- return result;
- }
- return nullptr;
-}
-
void nsHtml5Tokenizer::errWarnLtSlashInRcdata() {}
// The null checks below annotated MOZ_LIKELY are not actually necessary.
diff --git a/parser/html/nsHtml5TokenizerHSupplement.h b/parser/html/nsHtml5TokenizerHSupplement.h
@@ -67,8 +67,6 @@ inline nsHtml5HtmlAttributes* GetAttributes() { return attributes; }
*/
bool EnsureBufferSpace(int32_t aLength);
-nsHtml5String TryAtomizeForSingleDigit();
-
bool TemplatePushedOrHeadPopped();
void RememberGt(int32_t aPos);
diff --git a/parser/html/nsHtml5TreeBuilder.h b/parser/html/nsHtml5TreeBuilder.h
@@ -33,7 +33,6 @@
#include "jArray.h"
#include "mozilla/ImportScanner.h"
-#include "mozilla/Likely.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsAtom.h"
#include "nsContentUtils.h"
diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp
@@ -426,19 +426,10 @@ nsresult nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
if (!node->HasAttr(nsuri, localName) &&
!(nsuri == kNameSpaceID_None && localName == nsGkAtoms::nonce)) {
- nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
- nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
-
- // If value is already an atom, use it directly to avoid string
- // allocation.
- nsAtom* valAtom = val.MaybeAsAtom();
- if (valAtom) {
- node->SetAttr(nsuri, localName, prefix, valAtom, nullptr, true);
- } else {
- nsString value; // Not Auto, because using it to hold nsStringBuffer*
- val.ToString(value);
- node->SetAttr(nsuri, localName, prefix, value, true);
- }
+ nsString value; // Not Auto, because using it to hold nsStringBuffer*
+ aAttributes->getValueNoBoundsCheck(i).ToString(value);
+ node->SetAttr(nsuri, localName, aAttributes->getPrefixNoBoundsCheck(i),
+ value, true);
// XXX what to do with nsresult?
}
}
@@ -454,23 +445,13 @@ void nsHtml5TreeOperation::SetHTMLElementAttributes(
}
for (int32_t i = 0; i < len; i++) {
nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
- nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
- if (localName == nsGkAtoms::_class) {
- nsAtom* klass = val.MaybeAsAtom();
- if (klass) {
- aElement->SetClassAttrFromParser(klass);
- continue;
- }
- }
-
- nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
- int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
-
- // If value is already an atom, use it directly to avoid string allocation.
- nsAtom* valAtom = val.MaybeAsAtom();
- if (valAtom) {
- aElement->SetAttr(nsuri, localName, prefix, valAtom, nullptr, false);
+ nsAtom* klass = val.MaybeAsAtom();
+ if (klass) {
+ aElement->SetClassAttrFromParser(klass);
} else {
+ nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
+ nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
+ int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
nsString value; // Not Auto, because using it to hold nsStringBuffer*
val.ToString(value);
aElement->SetAttr(nsuri, localName, prefix, value, false);
@@ -596,23 +577,14 @@ nsIContent* nsHtml5TreeOperation::CreateSVGElement(
int32_t len = aAttributes->getLength();
for (int32_t i = 0; i < len; i++) {
nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
- nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
- if (localName == nsGkAtoms::_class) {
- nsAtom* klass = val.MaybeAsAtom();
- if (klass) {
- newContent->SetClassAttrFromParser(klass);
- continue;
- }
- }
-
- nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
- int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
-
- // If value is already an atom, use it directly to avoid string allocation.
- nsAtom* valAtom = val.MaybeAsAtom();
- if (valAtom) {
- newContent->SetAttr(nsuri, localName, prefix, valAtom, nullptr, false);
+ nsAtom* klass = val.MaybeAsAtom();
+ if (klass) {
+ newContent->SetClassAttrFromParser(klass);
} else {
+ nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
+ nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
+ int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
+
nsString value; // Not Auto, because using it to hold nsStringBuffer*
val.ToString(value);
newContent->SetAttr(nsuri, localName, prefix, value, false);
@@ -657,23 +629,14 @@ nsIContent* nsHtml5TreeOperation::CreateMathMLElement(
int32_t len = aAttributes->getLength();
for (int32_t i = 0; i < len; i++) {
nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
- nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
- if (localName == nsGkAtoms::_class) {
- nsAtom* klass = val.MaybeAsAtom();
- if (klass) {
- newContent->SetClassAttrFromParser(klass);
- continue;
- }
- }
-
- nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
- int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
-
- // If value is already an atom, use it directly to avoid string allocation.
- nsAtom* valAtom = val.MaybeAsAtom();
- if (valAtom) {
- newContent->SetAttr(nsuri, localName, prefix, valAtom, nullptr, false);
+ nsAtom* klass = val.MaybeAsAtom();
+ if (klass) {
+ newContent->SetClassAttrFromParser(klass);
} else {
+ nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
+ nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
+ int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
+
nsString value; // Not Auto, because using it to hold nsStringBuffer*
val.ToString(value);
newContent->SetAttr(nsuri, localName, prefix, value, false);
diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py
@@ -37,14 +37,6 @@ STATIC_ATOMS = [
Atom("_empty", ""),
Atom("_0", "0"),
Atom("_1", "1"),
- Atom("_2", "2"),
- Atom("_3", "3"),
- Atom("_4", "4"),
- Atom("_5", "5"),
- Atom("_6", "6"),
- Atom("_7", "7"),
- Atom("_8", "8"),
- Atom("_9", "9"),
Atom("mozframetype", "mozframetype"),
Atom("_moz_abspos", "_moz_abspos"),
Atom("_moz_activated", "_moz_activated"),