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 <fabian.kosmale@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Fabian Kosmale 2021-11-03 08:56:33 +01:00 committed by Sona Kurazyan
parent c677b3b8af
commit a4ce85f356
2 changed files with 34 additions and 0 deletions

View File

@ -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 This function reads the XML document from the IO device \a dev, returning
true if the content was successfully parsed; otherwise returns \c false. 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) bool QDomDocument::setContent(QIODevice* dev, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
{ {
if (!impl) if (!impl)
impl = new QDomDocumentPrivate(); 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); QXmlStreamReader streamReader(dev);
streamReader.setNamespaceProcessing(namespaceProcessing); streamReader.setNamespaceProcessing(namespaceProcessing);
return IMPL->setContent(&streamReader, namespaceProcessing, errorMsg, errorLine, errorColumn); return IMPL->setContent(&streamReader, namespaceProcessing, errorMsg, errorLine, errorColumn);

View File

@ -111,6 +111,7 @@ private slots:
void checkIntOverflow() const; void checkIntOverflow() const;
void setContentWhitespace() const; void setContentWhitespace() const;
void setContentWhitespace_data() const; void setContentWhitespace_data() const;
void setContentUnopenedQIODevice() const;
void taskQTBUG4595_dontAssertWhenDocumentSpecifiesUnknownEncoding() const; void taskQTBUG4595_dontAssertWhenDocumentSpecifiesUnknownEncoding() const;
void cloneDTD_QTBUG8398() const; void cloneDTD_QTBUG8398() const;
@ -1919,6 +1920,23 @@ void tst_QDom::setContentWhitespace_data() const
QTest::newRow("data25") << QString::fromLatin1("\t\t\t\t<?xml version='1.0' ?><e/>") << false; QTest::newRow("data25") << QString::fromLatin1("\t\t\t\t<?xml version='1.0' ?><e/>") << false;
} }
void tst_QDom::setContentUnopenedQIODevice() const
{
QByteArray data("<foo>bar</foo>");
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 void tst_QDom::taskQTBUG4595_dontAssertWhenDocumentSpecifiesUnknownEncoding() const
{ {
QString xmlWithUnknownEncoding("<?xml version='1.0' encoding='unknown-encoding'?>" QString xmlWithUnknownEncoding("<?xml version='1.0' encoding='unknown-encoding'?>"