1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:data-parser
4
5#ifndef QXMLSTREAM_H
6#define QXMLSTREAM_H
7
8#include <QtCore/qiodevice.h>
9
10#if QT_CONFIG(xmlstream)
11
12#include <QtCore/qcompare.h>
13#include <QtCore/qlist.h>
14#include <QtCore/qscopedpointer.h>
15#include <QtCore/qstring.h>
16
17#include <memory>
18
19QT_BEGIN_NAMESPACE
20
21namespace QtPrivate {
22
23class QXmlString {
24 QStringPrivate m_string;
25public:
26 QXmlString(QStringPrivate &&d) : m_string(std::move(d)) {}
27 QXmlString(const QString &s) : m_string(s.data_ptr()) {}
28 QXmlString & operator=(const QString &s) { m_string = s.data_ptr(); return *this; }
29 QXmlString & operator=(QString &&s) { m_string.swap(other&: s.data_ptr()); return *this; }
30 inline constexpr QXmlString() {}
31
32 void swap(QXmlString &other) noexcept
33 {
34 m_string.swap(other&: other.m_string);
35 }
36
37 operator QStringView() const noexcept { return QStringView(m_string.data(), m_string.size); }
38 qsizetype size() const noexcept { return m_string.size; }
39 bool isNull() const noexcept { return m_string.isNull(); }
40
41private:
42 friend bool comparesEqual(const QXmlString &lhs, const QXmlString &rhs) noexcept
43 {
44 return QStringView(lhs) == QStringView(rhs);
45 }
46 Q_DECLARE_EQUALITY_COMPARABLE(QXmlString)
47};
48
49}
50Q_DECLARE_SHARED_NS_EXT(QtPrivate, QXmlString)
51
52
53class QXmlStreamReaderPrivate;
54class QXmlStreamAttributes;
55class Q_CORE_EXPORT QXmlStreamAttribute {
56 QtPrivate::QXmlString m_name, m_namespaceUri, m_qualifiedName, m_value;
57 uint m_isDefault : 1;
58 friend class QXmlStreamReaderPrivate;
59 friend class QXmlStreamAttributes;
60public:
61 QXmlStreamAttribute();
62 QXmlStreamAttribute(const QString &qualifiedName, const QString &value);
63 QXmlStreamAttribute(const QString &namespaceUri, const QString &name, const QString &value);
64
65 inline QStringView namespaceUri() const { return m_namespaceUri; }
66 inline QStringView name() const { return m_name; }
67 inline QStringView qualifiedName() const { return m_qualifiedName; }
68 inline QStringView prefix() const {
69 return QStringView(m_qualifiedName).left(n: qMax(a: 0, b: m_qualifiedName.size() - m_name.size() - 1));
70 }
71 inline QStringView value() const { return m_value; }
72 inline bool isDefault() const { return m_isDefault; }
73#if QT_CORE_REMOVED_SINCE(6, 8)
74 inline bool operator==(const QXmlStreamAttribute &other) const
75 { return comparesEqual(*this, other); }
76 inline bool operator!=(const QXmlStreamAttribute &other) const
77 { return !operator==(other); }
78#endif
79
80private:
81 friend bool comparesEqual(const QXmlStreamAttribute &lhs,
82 const QXmlStreamAttribute &rhs) noexcept
83 {
84 if (lhs.m_value != rhs.m_value)
85 return false;
86 if (lhs.m_namespaceUri.isNull())
87 return lhs.m_qualifiedName == rhs.m_qualifiedName;
88 return lhs.m_namespaceUri == rhs.m_namespaceUri
89 && lhs.m_name == rhs.m_name;
90 }
91 Q_DECLARE_EQUALITY_COMPARABLE(QXmlStreamAttribute)
92};
93
94Q_DECLARE_TYPEINFO(QXmlStreamAttribute, Q_RELOCATABLE_TYPE);
95
96// We export each out-of-line method individually to prevent MSVC from
97// exporting the whole QList class.
98class QXmlStreamAttributes : public QList<QXmlStreamAttribute>
99{
100public:
101 inline QXmlStreamAttributes() {}
102#if QT_CORE_REMOVED_SINCE(6, 6)
103 Q_CORE_EXPORT QStringView value(const QString &namespaceUri, const QString &name) const;
104 Q_CORE_EXPORT QStringView value(const QString &namespaceUri, QLatin1StringView name) const;
105 Q_CORE_EXPORT QStringView value(QLatin1StringView namespaceUri, QLatin1StringView name) const;
106 Q_CORE_EXPORT QStringView value(const QString &qualifiedName) const;
107 Q_CORE_EXPORT QStringView value(QLatin1StringView qualifiedName) const;
108#endif
109 Q_CORE_EXPORT QStringView value(QAnyStringView namespaceUri, QAnyStringView name) const noexcept;
110 Q_CORE_EXPORT QStringView value(QAnyStringView qualifiedName) const noexcept;
111
112 Q_CORE_EXPORT void append(const QString &namespaceUri, const QString &name, const QString &value);
113 Q_CORE_EXPORT void append(const QString &qualifiedName, const QString &value);
114
115 bool hasAttribute(QAnyStringView qualifiedName) const
116 {
117 return !value(qualifiedName).isNull();
118 }
119
120 bool hasAttribute(QAnyStringView namespaceUri, QAnyStringView name) const
121 {
122 return !value(namespaceUri, name).isNull();
123 }
124
125 using QList<QXmlStreamAttribute>::append;
126};
127
128class Q_CORE_EXPORT QXmlStreamNamespaceDeclaration {
129 QtPrivate::QXmlString m_prefix, m_namespaceUri;
130
131 friend class QXmlStreamReaderPrivate;
132public:
133 QXmlStreamNamespaceDeclaration();
134 QXmlStreamNamespaceDeclaration(const QString &prefix, const QString &namespaceUri);
135
136 inline QStringView prefix() const { return m_prefix; }
137 inline QStringView namespaceUri() const { return m_namespaceUri; }
138#if QT_CORE_REMOVED_SINCE(6, 8)
139 inline bool operator==(const QXmlStreamNamespaceDeclaration &other) const
140 { return comparesEqual(*this, other); }
141 inline bool operator!=(const QXmlStreamNamespaceDeclaration &other) const
142 { return !operator==(other); }
143#endif
144private:
145 friend bool comparesEqual(const QXmlStreamNamespaceDeclaration &lhs,
146 const QXmlStreamNamespaceDeclaration &rhs) noexcept
147 {
148 return lhs.m_prefix == rhs.m_prefix
149 && lhs.m_namespaceUri == rhs.m_namespaceUri;
150 }
151 Q_DECLARE_EQUALITY_COMPARABLE(QXmlStreamNamespaceDeclaration)
152};
153
154Q_DECLARE_TYPEINFO(QXmlStreamNamespaceDeclaration, Q_RELOCATABLE_TYPE);
155typedef QList<QXmlStreamNamespaceDeclaration> QXmlStreamNamespaceDeclarations;
156
157class Q_CORE_EXPORT QXmlStreamNotationDeclaration {
158 QtPrivate::QXmlString m_name, m_systemId, m_publicId;
159
160 friend class QXmlStreamReaderPrivate;
161public:
162 QXmlStreamNotationDeclaration();
163
164 inline QStringView name() const { return m_name; }
165 inline QStringView systemId() const { return m_systemId; }
166 inline QStringView publicId() const { return m_publicId; }
167#if QT_CORE_REMOVED_SINCE(6, 8)
168 inline bool operator==(const QXmlStreamNotationDeclaration &other) const
169 { return comparesEqual(*this, other); }
170 inline bool operator!=(const QXmlStreamNotationDeclaration &other) const
171 { return !operator==(other); }
172#endif
173private:
174 friend bool comparesEqual(const QXmlStreamNotationDeclaration &lhs,
175 const QXmlStreamNotationDeclaration &rhs) noexcept
176 {
177 return lhs.m_name == rhs.m_name && lhs.m_systemId == rhs.m_systemId
178 && lhs.m_publicId == rhs.m_publicId;
179 }
180 Q_DECLARE_EQUALITY_COMPARABLE(QXmlStreamNotationDeclaration)
181};
182
183Q_DECLARE_TYPEINFO(QXmlStreamNotationDeclaration, Q_RELOCATABLE_TYPE);
184typedef QList<QXmlStreamNotationDeclaration> QXmlStreamNotationDeclarations;
185
186class Q_CORE_EXPORT QXmlStreamEntityDeclaration {
187 QtPrivate::QXmlString m_name, m_notationName, m_systemId, m_publicId, m_value;
188
189 friend class QXmlStreamReaderPrivate;
190public:
191 QXmlStreamEntityDeclaration();
192
193 inline QStringView name() const { return m_name; }
194 inline QStringView notationName() const { return m_notationName; }
195 inline QStringView systemId() const { return m_systemId; }
196 inline QStringView publicId() const { return m_publicId; }
197 inline QStringView value() const { return m_value; }
198#if QT_CORE_REMOVED_SINCE(6, 8)
199 inline bool operator==(const QXmlStreamEntityDeclaration &other) const
200 { return comparesEqual(*this, other); }
201 inline bool operator!=(const QXmlStreamEntityDeclaration &other) const
202 { return !operator==(other); }
203#endif
204
205private:
206 friend bool comparesEqual(const QXmlStreamEntityDeclaration &lhs,
207 const QXmlStreamEntityDeclaration &rhs) noexcept
208 {
209 return lhs.m_name == rhs.m_name
210 && lhs.m_notationName == rhs.m_notationName
211 && lhs.m_systemId == rhs.m_systemId
212 && lhs.m_publicId == rhs.m_publicId
213 && lhs.m_value == rhs.m_value;
214 }
215 Q_DECLARE_EQUALITY_COMPARABLE(QXmlStreamEntityDeclaration)
216};
217
218Q_DECLARE_TYPEINFO(QXmlStreamEntityDeclaration, Q_RELOCATABLE_TYPE);
219typedef QList<QXmlStreamEntityDeclaration> QXmlStreamEntityDeclarations;
220
221class Q_CORE_EXPORT QXmlStreamEntityResolver
222{
223 Q_DISABLE_COPY_MOVE(QXmlStreamEntityResolver)
224public:
225 QXmlStreamEntityResolver() = default;
226 virtual ~QXmlStreamEntityResolver();
227 virtual QString resolveEntity(const QString& publicId, const QString& systemId);
228 virtual QString resolveUndeclaredEntity(const QString &name);
229};
230
231#if QT_CONFIG(xmlstreamreader)
232class Q_CORE_EXPORT QXmlStreamReader
233{
234 QDOC_PROPERTY(bool namespaceProcessing READ namespaceProcessing WRITE setNamespaceProcessing)
235public:
236 enum TokenType {
237 NoToken = 0,
238 Invalid,
239 StartDocument,
240 EndDocument,
241 StartElement,
242 EndElement,
243 Characters,
244 Comment,
245 DTD,
246 EntityReference,
247 ProcessingInstruction
248 };
249
250
251 QXmlStreamReader();
252 explicit QXmlStreamReader(QIODevice *device);
253#if QT_CORE_REMOVED_SINCE(6, 5)
254 explicit QXmlStreamReader(const QByteArray &data);
255 explicit QXmlStreamReader(const QString &data);
256 explicit QXmlStreamReader(const char * data);
257#endif // QT_CORE_REMOVED_SINCE(6, 5)
258 Q_WEAK_OVERLOAD
259 explicit QXmlStreamReader(const QByteArray &data)
260 : QXmlStreamReader(data, PrivateConstructorTag{}) { }
261 explicit QXmlStreamReader(QAnyStringView data);
262 ~QXmlStreamReader();
263
264 void setDevice(QIODevice *device);
265 QIODevice *device() const;
266#if QT_CORE_REMOVED_SINCE(6, 5)
267 void addData(const QByteArray &data);
268 void addData(const QString &data);
269 void addData(const char *data);
270#endif // QT_CORE_REMOVED_SINCE(6, 5)
271 Q_WEAK_OVERLOAD
272 void addData(const QByteArray &data) { addDataImpl(data); }
273 void addData(QAnyStringView data);
274 void clear();
275
276
277 bool atEnd() const;
278 TokenType readNext();
279
280 bool readNextStartElement();
281 void skipCurrentElement();
282 QString readRawInnerData();
283
284 TokenType tokenType() const;
285 QString tokenString() const;
286
287 void setNamespaceProcessing(bool);
288 bool namespaceProcessing() const;
289
290 inline bool isStartDocument() const { return tokenType() == StartDocument; }
291 inline bool isEndDocument() const { return tokenType() == EndDocument; }
292 inline bool isStartElement() const { return tokenType() == StartElement; }
293 inline bool isEndElement() const { return tokenType() == EndElement; }
294 inline bool isCharacters() const { return tokenType() == Characters; }
295 bool isWhitespace() const;
296 bool isCDATA() const;
297 inline bool isComment() const { return tokenType() == Comment; }
298 inline bool isDTD() const { return tokenType() == DTD; }
299 inline bool isEntityReference() const { return tokenType() == EntityReference; }
300 inline bool isProcessingInstruction() const { return tokenType() == ProcessingInstruction; }
301
302 bool isStandaloneDocument() const;
303 bool hasStandaloneDeclaration() const;
304 QStringView documentVersion() const;
305 QStringView documentEncoding() const;
306
307 qint64 lineNumber() const;
308 qint64 columnNumber() const;
309 qint64 characterOffset() const;
310
311 QXmlStreamAttributes attributes() const;
312
313 enum ReadElementTextBehaviour {
314 ErrorOnUnexpectedElement,
315 IncludeChildElements,
316 SkipChildElements
317 };
318 QString readElementText(ReadElementTextBehaviour behaviour = ErrorOnUnexpectedElement);
319
320 QStringView name() const;
321 QStringView namespaceUri() const;
322 QStringView qualifiedName() const;
323 QStringView prefix() const;
324
325 QStringView processingInstructionTarget() const;
326 QStringView processingInstructionData() const;
327
328 QStringView text() const;
329
330 QXmlStreamNamespaceDeclarations namespaceDeclarations() const;
331 void addExtraNamespaceDeclaration(const QXmlStreamNamespaceDeclaration &extraNamespaceDeclaraction);
332 void addExtraNamespaceDeclarations(const QXmlStreamNamespaceDeclarations &extraNamespaceDeclaractions);
333 QXmlStreamNotationDeclarations notationDeclarations() const;
334 QXmlStreamEntityDeclarations entityDeclarations() const;
335 QStringView dtdName() const;
336 QStringView dtdPublicId() const;
337 QStringView dtdSystemId() const;
338
339 int entityExpansionLimit() const;
340 void setEntityExpansionLimit(int limit);
341
342 enum Error {
343 NoError,
344 UnexpectedElementError,
345 CustomError,
346 NotWellFormedError,
347 PrematureEndOfDocumentError
348 };
349 void raiseError(const QString& message = QString());
350 QString errorString() const;
351 Error error() const;
352
353 inline bool hasError() const
354 {
355 return error() != NoError;
356 }
357
358 void setEntityResolver(QXmlStreamEntityResolver *resolver);
359 QXmlStreamEntityResolver *entityResolver() const;
360
361private:
362 struct PrivateConstructorTag { };
363 QXmlStreamReader(const QByteArray &data, PrivateConstructorTag);
364 void addDataImpl(const QByteArray &data);
365
366 Q_DISABLE_COPY(QXmlStreamReader)
367 Q_DECLARE_PRIVATE(QXmlStreamReader)
368 std::unique_ptr<QXmlStreamReaderPrivate> d_ptr;
369
370};
371#endif // feature xmlstreamreader
372
373#if QT_CONFIG(xmlstreamwriter)
374
375class QXmlStreamWriterPrivate;
376
377class Q_CORE_EXPORT QXmlStreamWriter
378{
379 QDOC_PROPERTY(bool autoFormatting READ autoFormatting WRITE setAutoFormatting)
380 QDOC_PROPERTY(int autoFormattingIndent READ autoFormattingIndent WRITE setAutoFormattingIndent)
381 QDOC_PROPERTY(bool stopWritingOnError READ stopWritingOnError WRITE setStopWritingOnError)
382public:
383 QXmlStreamWriter();
384 explicit QXmlStreamWriter(QIODevice *device);
385 explicit QXmlStreamWriter(QByteArray *array);
386 explicit QXmlStreamWriter(QString *string);
387 ~QXmlStreamWriter();
388
389 void setDevice(QIODevice *device);
390 QIODevice *device() const;
391
392 void setAutoFormatting(bool);
393 bool autoFormatting() const;
394
395 void setAutoFormattingIndent(int spacesOrTabs);
396 int autoFormattingIndent() const;
397
398 void setStopWritingOnError(bool stop);
399 bool stopWritingOnError() const;
400
401#if QT_CORE_REMOVED_SINCE(6,5)
402 void writeAttribute(const QString &qualifiedName, const QString &value);
403 void writeAttribute(const QString &namespaceUri, const QString &name, const QString &value);
404#endif
405 void writeAttribute(QAnyStringView qualifiedName, QAnyStringView value);
406 void writeAttribute(QAnyStringView namespaceUri, QAnyStringView name, QAnyStringView value);
407
408 void writeAttribute(const QXmlStreamAttribute& attribute);
409 void writeAttributes(const QXmlStreamAttributes& attributes);
410
411#if QT_CORE_REMOVED_SINCE(6,5)
412 void writeCDATA(const QString &text);
413 void writeCharacters(const QString &text);
414 void writeComment(const QString &text);
415
416 void writeDTD(const QString &dtd);
417
418 void writeEmptyElement(const QString &qualifiedName);
419 void writeEmptyElement(const QString &namespaceUri, const QString &name);
420
421 void writeTextElement(const QString &qualifiedName, const QString &text);
422 void writeTextElement(const QString &namespaceUri, const QString &name, const QString &text);
423#endif
424 void writeCDATA(QAnyStringView text);
425 void writeCharacters(QAnyStringView text);
426 void writeComment(QAnyStringView text);
427
428 void writeDTD(QAnyStringView dtd);
429
430 void writeEmptyElement(QAnyStringView qualifiedName);
431 void writeEmptyElement(QAnyStringView namespaceUri, QAnyStringView name);
432
433 void writeTextElement(QAnyStringView qualifiedName, QAnyStringView text);
434 void writeTextElement(QAnyStringView namespaceUri, QAnyStringView name, QAnyStringView text);
435
436
437 void writeEndDocument();
438 void writeEndElement();
439
440#if QT_CORE_REMOVED_SINCE(6,5)
441 void writeEntityReference(const QString &name);
442 void writeNamespace(const QString &namespaceUri, const QString &prefix);
443 void writeDefaultNamespace(const QString &namespaceUri);
444 void writeProcessingInstruction(const QString &target, const QString &data);
445#endif
446 void writeEntityReference(QAnyStringView name);
447 void writeNamespace(QAnyStringView namespaceUri, QAnyStringView prefix = {});
448 void writeDefaultNamespace(QAnyStringView namespaceUri);
449 void writeProcessingInstruction(QAnyStringView target, QAnyStringView data = {});
450
451 void writeStartDocument();
452#if QT_CORE_REMOVED_SINCE(6,5)
453 void writeStartDocument(const QString &version);
454 void writeStartDocument(const QString &version, bool standalone);
455 void writeStartElement(const QString &qualifiedName);
456 void writeStartElement(const QString &namespaceUri, const QString &name);
457#endif
458 void writeStartDocument(QAnyStringView version);
459 void writeStartDocument(QAnyStringView version, bool standalone);
460 void writeStartElement(QAnyStringView qualifiedName);
461 void writeStartElement(QAnyStringView namespaceUri, QAnyStringView name);
462
463#if QT_CONFIG(xmlstreamreader)
464 void writeCurrentToken(const QXmlStreamReader &reader);
465#endif
466
467 enum class Error {
468 None,
469 IO,
470 Encoding,
471 InvalidCharacter,
472 Custom,
473 };
474
475 void raiseError(QAnyStringView message);
476 QString errorString() const;
477 Error error() const;
478 bool hasError() const;
479
480private:
481 Q_DISABLE_COPY(QXmlStreamWriter)
482 Q_DECLARE_PRIVATE(QXmlStreamWriter)
483 std::unique_ptr<QXmlStreamWriterPrivate> d_ptr;
484};
485#endif // feature xmlstreamwriter
486
487QT_END_NAMESPACE
488
489#endif // feature xmlstream
490
491#endif // QXMLSTREAM_H
492

source code of qtbase/src/corelib/serialization/qxmlstream.h