From a4ce85f356b78401fe727a07b908a1e7b5a25198 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Wed, 3 Nov 2021 08:56:33 +0100 Subject: [PATCH] QDomDocument::setContent: Open device if necessary This restores the Qt 5 behavior in Qt 6, but prepares for disabling it in Qt 7. We want to deprecate the current behavior, as it makes it unclear who is responsible for calling close. Fixes: QTBUG-97747 Pick-to: 6.2 Change-Id: I2c99eb96667e784576d8850085068ca334d75b16 Reviewed-by: Fabian Kosmale Reviewed-by: Lars Knoll --- src/xml/dom/qdom.cpp | 16 ++++++++++++++++ tests/auto/xml/dom/qdom/tst_qdom.cpp | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 2ac4c69b7f1..603704f9163 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -6197,12 +6197,28 @@ bool QDomDocument::setContent(const QByteArray &data, bool namespaceProcessing, This function reads the XML document from the IO device \a dev, returning true if the content was successfully parsed; otherwise returns \c false. + + \note This method will try to open \a dev in read-only mode if it is not + already open. In that case, the caller is responsible for calling close. + This will change in Qt 7, which will no longer open \a dev. Applications + shoul therefore open the device themselves before calling setContent. */ bool QDomDocument::setContent(QIODevice* dev, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn) { if (!impl) impl = new QDomDocumentPrivate(); +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + if (!dev->isOpen()) { + qWarning("QDomDocument called with unopened QIODevice. " + "This will not be supported in future Qt versions"); + if (!dev->open(QIODevice::ReadOnly)) { + qWarning("QDomDocument::setContent: Failed to open device"); + return false; + } + } +#endif + QXmlStreamReader streamReader(dev); streamReader.setNamespaceProcessing(namespaceProcessing); return IMPL->setContent(&streamReader, namespaceProcessing, errorMsg, errorLine, errorColumn); diff --git a/tests/auto/xml/dom/qdom/tst_qdom.cpp b/tests/auto/xml/dom/qdom/tst_qdom.cpp index c44626e1612..b1c9b2e9c9e 100644 --- a/tests/auto/xml/dom/qdom/tst_qdom.cpp +++ b/tests/auto/xml/dom/qdom/tst_qdom.cpp @@ -111,6 +111,7 @@ private slots: void checkIntOverflow() const; void setContentWhitespace() const; void setContentWhitespace_data() const; + void setContentUnopenedQIODevice() const; void taskQTBUG4595_dontAssertWhenDocumentSpecifiesUnknownEncoding() const; void cloneDTD_QTBUG8398() const; @@ -1919,6 +1920,23 @@ void tst_QDom::setContentWhitespace_data() const QTest::newRow("data25") << QString::fromLatin1("\t\t\t\t") << false; } +void tst_QDom::setContentUnopenedQIODevice() const +{ + QByteArray data("bar"); + QBuffer buffer(&data); + + QDomDocument doc; + + QTest::ignoreMessage(QtWarningMsg, + "QDomDocument called with unopened QIODevice. " + "This will not be supported in future Qt versions"); + + // Note: the check below is expected to fail in Qt 7. + // Fix the test and remove the obsolete code from setContent(). + QVERIFY(doc.setContent(&buffer, true)); + QCOMPARE(doc.toString().trimmed(), data); +} + void tst_QDom::taskQTBUG4595_dontAssertWhenDocumentSpecifiesUnknownEncoding() const { QString xmlWithUnknownEncoding(""