summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSami Rosendahl <ext-sami.1.rosendahl@nokia.com>2012-01-19 10:14:05 +0200
committerThiago Macieira <thiago.macieira@intel.com>2012-04-05 15:43:00 +0200
commited2a887e21a09b1eb6890ac246efca19f7c6a19d (patch)
treef969864f24af986e31ccf7ff3bc051488d986113
parenta41219484a5ab064ca919871a0b7469d0be41419 (diff)
Fix memory leak in QDomDocument DTD notation declaration handler
The created notation node's reference count needs to be decremented to 0 before it is added as a child, because appendChild will increment the reference count to correct value of 1. Also added autotest DTDNotationDecl to tst_qdom to expose the leak when executed under valgrind memcheck. There was no previous test coverage for the notation declarations in DTD. Task-number: QTBUG-22588 Change-Id: Id211567a5eb9f5552e03756394f994866729dcff (cherry picked from commit fb38e3801724471a9fb0ea3b412e631223250c44) Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/xml/dom/qdom.cpp2
-rw-r--r--tests/auto/qdom/tst_qdom.cpp24
2 files changed, 26 insertions, 0 deletions
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index 7c7cafc1a0..c0bfda7d4c 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -7557,6 +7557,8 @@ bool QDomHandler::externalEntityDecl(const QString &name, const QString &publicI
bool QDomHandler::notationDecl(const QString & name, const QString & publicId, const QString & systemId)
{
QDomNotationPrivate* n = new QDomNotationPrivate(doc, 0, name, publicId, systemId);
+ // keep the refcount balanced: appendChild() does a ref anyway.
+ n->ref.deref();
doc->doctype()->appendChild(n);
return true;
}
diff --git a/tests/auto/qdom/tst_qdom.cpp b/tests/auto/qdom/tst_qdom.cpp
index f30d3bc533..684e704b30 100644
--- a/tests/auto/qdom/tst_qdom.cpp
+++ b/tests/auto/qdom/tst_qdom.cpp
@@ -132,6 +132,7 @@ private slots:
void taskQTBUG4595_dontAssertWhenDocumentSpecifiesUnknownEncoding() const;
void cloneDTD_QTBUG8398() const;
+ void DTDNotationDecl();
void cleanupTestCase() const;
@@ -1934,5 +1935,28 @@ void tst_QDom::cloneDTD_QTBUG8398() const
domDocument2.save(stream, 0);
QCOMPARE(output, expected);
}
+
+void tst_QDom::DTDNotationDecl()
+{
+ QString dtd("<?xml version='1.0' encoding='UTF-8'?>\n"
+ "<!DOCTYPE first [\n"
+ "<!NOTATION gif SYSTEM 'image/gif'>\n"
+ "<!NOTATION jpeg SYSTEM 'image/jpeg'>\n"
+ "]>\n"
+ "<first/>\n");
+
+ QDomDocument domDocument;
+ QVERIFY(domDocument.setContent(dtd));
+
+ const QDomDocumentType doctype = domDocument.doctype();
+ QCOMPARE(doctype.notations().size(), 2);
+
+ QVERIFY(doctype.namedItem(QString("gif")).isNotation());
+ QCOMPARE(doctype.namedItem(QString("gif")).toNotation().systemId(), QString("image/gif"));
+
+ QVERIFY(doctype.namedItem(QString("jpeg")).isNotation());
+ QCOMPARE(doctype.namedItem(QString("jpeg")).toNotation().systemId(), QString("image/jpeg"));
+}
+
QTEST_MAIN(tst_QDom)
#include "tst_qdom.moc"