diff options
author | Magdalena Stojek <[email protected]> | 2025-03-12 14:23:53 +0100 |
---|---|---|
committer | Magdalena Stojek <[email protected]> | 2025-03-18 11:49:56 +0100 |
commit | 8c991345847e4b050d746a3efc28ddfa7115a130 (patch) | |
tree | 41d80c6087afba642e475fdfa95fa5a0fd6ca195 | |
parent | 1b9cf551170a54f813f7067f7948f0378cac2deb (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.cpp | 10 | ||||
-rw-r--r-- | tests/auto/xml/dom/qdom/tst_qdom.cpp | 28 |
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/'>" |