summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagdalena Stojek <[email protected]>2025-03-12 14:23:53 +0100
committerMagdalena Stojek <[email protected]>2025-03-18 11:49:56 +0100
commit8c991345847e4b050d746a3efc28ddfa7115a130 (patch)
tree41d80c6087afba642e475fdfa95fa5a0fd6ca195
parent1b9cf551170a54f813f7067f7948f0378cac2deb (diff)
QDom: Fix setAttributeNode() to properly replace existing attributes
This fix ensures that QDomElement::setAttributeNode() correctly replaces an existing attribute with the same name. Previously, calling setAttributeNode() with a new attribute of the same name resulted in both the old and new attributes being present, violating the expected behavior described in the documentation. Fixes: QTBUG-15125 Pick-to: 6.9 6.8 6.5 Change-Id: Ibdda37a65f6e754d9f7e68e725d3438bbb2d9e0c Reviewed-by: Mate Barany <[email protected]>
-rw-r--r--src/xml/dom/qdom.cpp10
-rw-r--r--tests/auto/xml/dom/qdom/tst_qdom.cpp28
2 files changed, 35 insertions, 3 deletions
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index 9daf13f377c..7bfe6cd5cc7 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -4123,14 +4123,18 @@ QDomAttrPrivate* QDomElementPrivate::attributeNodeNS(const QString& nsURI, const
QDomAttrPrivate* QDomElementPrivate::setAttributeNode(QDomAttrPrivate* newAttr)
{
- QDomNodePrivate* n = m_attr->namedItem(newAttr->nodeName());
+ if (!newAttr)
+ return nullptr;
+
+ QDomNodePrivate* foundAttr = m_attr->namedItem(newAttr->nodeName());
+ if (foundAttr)
+ m_attr->removeNamedItem(newAttr->nodeName());
// Referencing is done by the maps
m_attr->setNamedItem(newAttr);
-
newAttr->setParent(this);
- return static_cast<QDomAttrPrivate *>(n);
+ return static_cast<QDomAttrPrivate *>(foundAttr);
}
QDomAttrPrivate* QDomElementPrivate::setAttributeNodeNS(QDomAttrPrivate* newAttr)
diff --git a/tests/auto/xml/dom/qdom/tst_qdom.cpp b/tests/auto/xml/dom/qdom/tst_qdom.cpp
index 8138de1fce3..2c62e6fa1a8 100644
--- a/tests/auto/xml/dom/qdom/tst_qdom.cpp
+++ b/tests/auto/xml/dom/qdom/tst_qdom.cpp
@@ -89,6 +89,7 @@ private slots:
void normalizeAttributes() const;
void serializeWeirdEOL() const;
void reparentAttribute() const;
+ void replaceAttribute() const;
void serializeNamespaces() const;
void flagInvalidNamespaces() const;
void flagUndeclaredNamespace() const;
@@ -1999,6 +2000,33 @@ void tst_QDom::reparentAttribute() const
QVERIFY(attr.parentNode() == ele);
}
+void tst_QDom::replaceAttribute() const
+{
+ QDomImplementation impl;
+ QDomDocument doc(impl.createDocument("", "docName", QDomDocumentType()));
+
+ QDomElement root = doc.createElement("root");
+ doc.appendChild(root);
+
+ QDomAttr attr1 = doc.createAttribute("firstAttribute");
+ attr1.setValue("true");
+ auto nullAttr = root.setAttributeNode(attr1);
+ QVERIFY(nullAttr.isNull());
+ QVERIFY(root.hasAttribute("firstAttribute"));
+ QCOMPARE(root.attributeNode("firstAttribute").value(), "true");
+
+ QDomAttr attr2 = doc.createAttribute("firstAttribute");
+ attr2.setValue("false");
+ root.setAttributeNode(attr2);
+ QCOMPARE(root.attributeNode("firstAttribute").value(), "false");
+
+ QDomAttr attr3 = doc.createAttribute("secondAttribute");
+ attr3.setValue("123");
+ root.setAttributeNode(attr3);
+ QVERIFY(root.hasAttribute("secondAttribute"));
+ QCOMPARE(root.attributeNode("secondAttribute").value(), "123");
+}
+
void tst_QDom::serializeNamespaces() const
{
const char *const input = "<doc xmlns:b='http://example.com/'>"