High firefox Logic Error 🔧 Commit mapped

Overview

High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionUse-after-free in the XSLT component
ComponentDOM
Bug ClassLogic Error
Tracker2079257
Fix commit4f4cf2570503 (firefox) +17/-12
CISA KEVNot listed
CreditedMozilla
Disclosed2026-10-27

Files Changed

  • dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
  • dom/xslt/xpath/txXPathTreeWalker.h
  • dom/xslt/xslt/txInstructions.cpp
diff --git a/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp b/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
index 62eaaed5579..990888793e6 100644
--- a/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
+++ b/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
@@ -266,18 +266,21 @@ already_AddRefed<nsAtom> txXPathNodeUtils::getLocalName(
   return localName.forget();
 }
 
-nsAtom* txXPathNodeUtils::getPrefix(const txXPathNode& aNode) {
+already_AddRefed<nsAtom> txXPathNodeUtils::getPrefix(const txXPathNode& aNode) {
   if (aNode.isDocument()) {
     return nullptr;
   }
 
+  RefPtr<nsAtom> prefix;
   if (aNode.isContent()) {
     // All other nsIContent node types but elements have a null prefix
     // which is what we want here.
-    return aNode.Content()->NodeInfo()->GetPrefixAtom();
+    prefix = aNode.Content()->NodeInfo()->GetPrefixAtom();
+  } else {
+    prefix =
+        aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex)->GetPrefix();
   }
-
-  return aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex)->GetPrefix();
+  return prefix.forget();
 }
 
 /* static */
diff --git a/dom/xslt/xpath/txXPathTreeWalker.h b/dom/xslt/xpath/txXPathTreeWalker.h
index f142658ce47..bc63eb21b90 100644
--- a/dom/xslt/xpath/txXPathTreeWalker.h
+++ b/dom/xslt/xpath/txXPathTreeWalker.h
@@ -51,7 +51,7 @@ class txXPathNodeUtils {
   static bool getAttr(const txXPathNode& aNode, nsAtom* aLocalName,
                       int32_t aNSID, nsAString& aValue);
   static already_AddRefed<nsAtom> getLocalName(const txXPathNode& aNode);
-  static nsAtom* getPrefix(const txXPathNode& aNode);
+  static already_AddRefed<nsAtom> getPrefix(const txXPathNode& aNode);
   static void getLocalName(const txXPathNode& aNode, nsAString& aLocalName);
   static void getNodeName(const txXPathNode& aNode, nsAString& aName);
   static int32_t getNamespaceID(const txXPathNode& aNode);
diff --git a/dom/xslt/xslt/txInstructions.cpp b/dom/xslt/xslt/txInstructions.cpp
index 0b7aadc1669..87e83b5fc33 100644
--- a/dom/xslt/xslt/txInstructions.cpp
+++ b/dom/xslt/xslt/txInstructions.cpp
@@ -207,10 +207,11 @@ nsresult txCopyBase::copyNode(const txXPathNode& aNode, txExecutionState& aEs) {
       nsAutoString nodeValue;
       txXPathNodeUtils::appendNodeValue(aNode, nodeValue);
 
+      RefPtr<nsAtom> prefix = txXPathNodeUtils::getPrefix(aNode);
       RefPtr<nsAtom> localName = txXPathNodeUtils::getLocalName(aNode);
       return aEs.mResultHandler->attribute(
-          txXPathNodeUtils::getPrefix(aNode), localName, nullptr,
-          txXPathNodeUtils::getNamespaceID(aNode), nodeValue);
+          prefix, localName, nullptr, txXPathNodeUtils::getNamespaceID(aNode),
+          nodeValue);
     }
     case txXPathNodeType::COMMENT_NODE: {
       nsAutoString nodeValue;
@@ -229,10 +230,10 @@ nsresult txCopyBase::copyNode(const txXPathNode& aNode, txExecutionState& aEs) {
       break;
     }
     case txXPathNodeType::ELEMENT_NODE: {
+      RefPtr<nsAtom> prefix = txXPathNodeUtils::getPrefix(aNode);
       RefPtr<nsAtom> localName = txXPathNodeUtils::getLocalName(aNode);
       nsresult rv = aEs.mResultHandler->startElement(
-          txXPathNodeUtils::getPrefix(aNode), localName, nullptr,
-          txXPathNodeUtils::getNamespaceID(aNode));
+          prefix, localName, nullptr, txXPathNodeUtils::getNamespaceID(aNode));
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Copy attributes
@@ -243,9 +244,10 @@ nsresult txCopyBase::copyNode(const txXPathNode& aNode, txExecutionState& aEs) {
           walker.appendNodeValue(nodeValue);
 
           const txXPathNode& attr = walker.getCurrentPosition();
+          prefix = txXPathNodeUtils::getPrefix(attr);
           localName = txXPathNodeUtils::getLocalName(attr);
           rv = aEs.mResultHandler->attribute(
-              txXPathNodeUtils::getPrefix(attr), localName, nullptr,
+              prefix, localName, nullptr,
               txXPathNodeUtils::getNamespaceID(attr), nodeValue);
           NS_ENSURE_SUCCESS(rv, rv);
         } while (walker.moveToNextAttribute());
@@ -296,10 +298,10 @@ nsresult txCopy::execute(txExecutionState& aEs) {
       break;
     }
     case txXPathNodeType::ELEMENT_NODE: {
+      RefPtr<nsAtom> prefix = txXPathNodeUtils::getPrefix(node);
       RefPtr<nsAtom> localName = txXPathNodeUtils::getLocalName(node);
       rv = aEs.mResultHandler->startElement(
-          txXPathNodeUtils::getPrefix(node), localName, nullptr,
-          txXPathNodeUtils::getNamespaceID(node));
+          prefix, localName, nullptr, txXPathNodeUtils::getNamespaceID(node));
       NS_ENSURE_SUCCESS(rv, rv);
 
       // XXX copy namespace nodes once we have them
Loading diff…