diff options
| author | Magdalena Stojek <magdalena.stojek@qt.io> | 2025-03-13 13:38:30 +0100 |
|---|---|---|
| committer | Magdalena Stojek <magdalena.stojek@qt.io> | 2025-03-19 07:31:15 +0100 |
| commit | c3295bd59cb1c3b858b6a858aba4481adeea209b (patch) | |
| tree | 2a03796b2a81b820b660922db3f074c1f65903a2 /src/corelib/serialization/qxmlstream.cpp | |
| parent | d359035c804021f59da70a75d962bfeafd320a71 (diff) | |
QXmlStreamWriter: Ensure correct newline handling with auto-formatting
Previously, QXmlStreamWriter would incorrectly insert a newline before
the first token when writeStartDocument() was not used, while
auto-formatting was enabled.
This fix ensures that the first token is written inline without an extra
leading newline, while preserving expected formatting for subsequent
tokens.
To achieve this, two new flags have been introduced:
- didWriteStartDocument: Tracks whether writeStartDocument() was called.
- didWriteAnyToken: Ensures that at least one token has been written
before allowing newlines.
Fixes: QTBUG-28721
Pick-to: 6.9 6.8
Change-Id: I8be7e8fc6ac0e63304359d24c6c8372e5ba42bb4
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/serialization/qxmlstream.cpp')
| -rw-r--r-- | src/corelib/serialization/qxmlstream.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index 9dcdf490412..50f87900161 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -2913,6 +2913,8 @@ public: uint hasIoError :1; uint hasEncodingError :1; uint autoFormatting :1; + uint didWriteStartDocument :1; + uint didWriteAnyToken :1; std::string autoFormattingIndent; NamespaceDeclaration emptyNamespace; qsizetype lastNamespaceDeclaration; @@ -2946,6 +2948,8 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q) lastNamespaceDeclaration = 1; autoFormatting = false; namespacePrefixCount = 0; + didWriteStartDocument = false; + didWriteAnyToken = false; } void QXmlStreamWriterPrivate::write(QAnyStringView s) @@ -3065,6 +3069,7 @@ void QXmlStreamWriterPrivate::writeNamespaceDeclaration(const NamespaceDeclarati write(namespaceDeclaration.namespaceUri); write("\""); } + didWriteAnyToken = true; } bool QXmlStreamWriterPrivate::finishStartElement(bool contents) @@ -3084,6 +3089,7 @@ bool QXmlStreamWriterPrivate::finishStartElement(bool contents) } inStartElement = inEmptyElement = false; lastNamespaceDeclaration = namespaceDeclarations.size(); + didWriteAnyToken = true; return hadSomethingWritten; } @@ -3149,7 +3155,8 @@ QXmlStreamPrivateTagStack::NamespaceDeclaration &QXmlStreamWriterPrivate::findNa void QXmlStreamWriterPrivate::indent(int level) { - write("\n"); + if (didWriteStartDocument || didWriteAnyToken) + write("\n"); for (int i = 0; i < level; ++i) write(autoFormattingIndent); } @@ -3375,6 +3382,7 @@ void QXmlStreamWriter::writeAttribute(QAnyStringView qualifiedName, QAnyStringVi d->write("=\""); d->writeEscaped(value, true); d->write("\""); + d->didWriteAnyToken = true; } /*! Writes an attribute with \a name and \a value, prefixed for @@ -3403,6 +3411,7 @@ void QXmlStreamWriter::writeAttribute(QAnyStringView namespaceUri, QAnyStringVie d->write("=\""); d->writeEscaped(value, true); d->write("\""); + d->didWriteAnyToken = true; } /*! @@ -3610,7 +3619,8 @@ void QXmlStreamWriter::writeEndDocument() Q_D(QXmlStreamWriter); while (d->tagStack.size()) writeEndElement(); - d->write("\n"); + if (d->didWriteStartDocument || d->didWriteAnyToken) + d->write("\n"); } /*! @@ -3621,6 +3631,7 @@ void QXmlStreamWriter::writeEndDocument() void QXmlStreamWriter::writeEndElement() { Q_D(QXmlStreamWriter); + Q_ASSERT(d->didWriteAnyToken); if (d->tagStack.isEmpty()) return; @@ -3744,6 +3755,7 @@ void QXmlStreamWriter::writeProcessingInstruction(QAnyStringView target, QAnyStr d->write(data); } d->write("?>"); + d->didWriteAnyToken = true; } @@ -3778,6 +3790,7 @@ void QXmlStreamWriter::writeStartDocument(QAnyStringView version) if (d->device) // stringDevice does not get any encoding d->write("\" encoding=\"UTF-8"); d->write("\"?>"); + d->didWriteStartDocument = true; } /*! Writes a document start with the XML version number \a version @@ -3801,6 +3814,7 @@ void QXmlStreamWriter::writeStartDocument(QAnyStringView version, bool standalon d->write("\" standalone=\"yes\"?>"); else d->write("\" standalone=\"no\"?>"); + d->didWriteStartDocument = true; } @@ -3862,6 +3876,7 @@ void QXmlStreamWriterPrivate::writeStartElement(QAnyStringView namespaceUri, QAn writeNamespaceDeclaration(namespaceDeclarations[i]); } tag.namespaceDeclarationsSize = lastNamespaceDeclaration; + didWriteAnyToken = true; } /*! Writes the current state of the \a reader. All possible valid |
