1// Copyright (C) 2020 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// ### TODO: inline this file into qxml.cpp
5
6#ifndef QXML_P_H
7#define QXML_P_H
8
9#include <qstack.h>
10#include <qmap.h>
11#include <qhash.h>
12#include <qxml.h>
13#include <private/qglobal_p.h>
14
15#include <stack>
16
17QT_BEGIN_NAMESPACE
18
19//
20// W A R N I N G
21// -------------
22//
23// This file is not part of the Qt API. It exists for the convenience of
24// qxml.cpp. This header file may change from version to version without
25// notice, or even be removed.
26//
27// We mean it.
28//
29
30class QXmlSimpleReaderPrivate
31{
32public:
33 ~QXmlSimpleReaderPrivate();
34private:
35 // functions
36 QXmlSimpleReaderPrivate(QXmlSimpleReader *reader);
37 void initIncrementalParsing();
38
39 // used to determine if elements are correctly nested
40 std::stack<QString, QStringList> tags;
41
42 // used by parseReference() and parsePEReference()
43 enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };
44
45 // used for entity declarations
46 struct ExternParameterEntity
47 {
48 ExternParameterEntity() {}
49 ExternParameterEntity(const QString &p, const QString &s)
50 : publicId(p), systemId(s) {}
51 QString publicId;
52 QString systemId;
53 };
54 friend class QTypeInfo<ExternParameterEntity>;
55
56 struct ExternEntity
57 {
58 ExternEntity() {}
59 ExternEntity(const QString &p, const QString &s, const QString &n)
60 : publicId(p), systemId(s), notation(n) {}
61 QString publicId;
62 QString systemId;
63 QString notation;
64 };
65 friend class QTypeInfo<ExternEntity>;
66
67 QMap<QString,ExternParameterEntity> externParameterEntities;
68 QMap<QString,QString> parameterEntities;
69 QMap<QString,ExternEntity> externEntities;
70 QMap<QString,QString> entities;
71
72 // used for parsing of entity references
73 struct XmlRef {
74 XmlRef()
75 : index(0) {}
76 XmlRef(const QString &_name, const QString &_value)
77 : name(_name), value(_value), index(0) {}
78 bool isEmpty() const { return index == value.size(); }
79 QChar next() { return value.at(i: index++); }
80 QString name;
81 QString value;
82 int index;
83 };
84 friend class QTypeInfo<XmlRef>;
85 QStack<XmlRef> xmlRefStack;
86
87 // used for standalone declaration
88 enum Standalone { Yes, No, Unknown };
89
90 QString doctype; // only used for the doctype
91 QString xmlVersion; // only used to store the version information
92 QString encoding; // only used to store the encoding
93 Standalone standalone; // used to store the value of the standalone declaration
94
95 QString publicId; // used by parseExternalID() to store the public ID
96 QString systemId; // used by parseExternalID() to store the system ID
97
98 // Since publicId/systemId is used as temporary variables by parseExternalID(), it
99 // might overwrite the PUBLIC/SYSTEM for the document we're parsing. In effect, we would
100 // possibly send off an QXmlParseException that has the PUBLIC/SYSTEM of a entity declaration
101 // instead of those of the current document.
102 // Hence we have these two variables for storing the document's data.
103 QString thisPublicId;
104 QString thisSystemId;
105
106 QString attDeclEName; // use by parseAttlistDecl()
107 QString attDeclAName; // use by parseAttlistDecl()
108
109 // flags for some features support
110 bool useNamespaces;
111 bool useNamespacePrefixes;
112 bool reportWhitespaceCharData;
113 bool reportEntities;
114
115 // used to build the attribute list
116 QXmlAttributes attList;
117
118 // used in QXmlSimpleReader::parseContent() to decide whether character
119 // data was read
120 bool contentCharDataRead;
121 // Hack for letting QDom know where the skipped entity occurred
122 bool skipped_entity_in_content;
123
124 // helper classes
125 std::unique_ptr<QXmlLocator> locator;
126 QXmlNamespaceSupport namespaceSupport;
127
128 // error string
129 QString error;
130
131 // arguments for parse functions (this is needed to allow incremental
132 // parsing)
133 bool parsePI_xmldecl;
134 bool parseName_useRef;
135 bool parseReference_charDataRead;
136 EntityRecognitionContext parseReference_context;
137 bool parseExternalID_allowPublicID;
138 EntityRecognitionContext parsePEReference_context;
139 QString parseString_s;
140
141 // for incremental parsing
142 struct ParseState {
143 typedef bool (QXmlSimpleReaderPrivate::*ParseFunction)();
144 ParseFunction function;
145 int state;
146 };
147 friend class QTypeInfo<ParseState>;
148 QStack<ParseState> *parseStack;
149
150 // used in parseProlog()
151 bool xmldecl_possible;
152 bool doctype_read;
153
154 // used in parseDoctype()
155 bool startDTDwasReported;
156
157 // used in parseString()
158 signed char Done;
159
160 // variables
161 QXmlContentHandler *contentHnd;
162 QXmlErrorHandler *errorHnd;
163 QXmlDTDHandler *dtdHnd;
164 QXmlEntityResolver *entityRes;
165 QXmlLexicalHandler *lexicalHnd;
166 QXmlDeclHandler *declHnd;
167
168 QXmlInputSource *inputSource;
169
170 QChar c; // the character at reading position
171 int lineNr; // number of line
172 int columnNr; // position in line
173
174 QChar nameArray[256]; // only used for names
175 QString nameValue; // only used for names
176 int nameArrayPos;
177 int nameValueLen;
178 QChar refArray[256]; // only used for references
179 QString refValue; // only used for references
180 int refArrayPos;
181 int refValueLen;
182 QChar stringArray[256]; // used for any other strings that are parsed
183 QString stringValue; // used for any other strings that are parsed
184 int stringArrayPos;
185 int stringValueLen;
186 QString emptyStr;
187
188 QHash<QString, int> literalEntitySizes;
189 // The entity at (QMap<QString,) referenced the entities at (QMap<QString,) (int>) times.
190 QHash<QString, QHash<QString, int> > referencesToOtherEntities;
191 QHash<QString, int> expandedSizes;
192 // The limit to the amount of times the DTD parsing functions can be called
193 // for the DTD currently being parsed.
194 static const int dtdRecursionLimit = 2;
195 // The maximum amount of characters an entity value may contain, after expansion.
196 static const int entityCharacterLimit = 4096;
197
198 const QString &string();
199 void stringClear();
200 void stringAddC(QChar);
201 inline void stringAddC() { stringAddC(c); }
202 const QString &name();
203 void nameClear();
204 void nameAddC(QChar);
205 inline void nameAddC() { nameAddC(c); }
206 const QString &ref();
207 void refClear();
208 void refAddC(QChar);
209 inline void refAddC() { refAddC(c); }
210
211 // private functions
212 bool eat_ws();
213 bool next_eat_ws();
214
215 void QT_FASTCALL next();
216 bool atEnd();
217
218 void init(const QXmlInputSource* i);
219 void initData();
220
221 bool entityExist(const QString&) const;
222
223 bool parseBeginOrContinue(int state, bool incremental);
224
225 bool parseProlog();
226 bool parseElement();
227 bool processElementEmptyTag();
228 bool processElementETagBegin2();
229 bool processElementAttribute();
230 bool parseMisc();
231 bool parseContent();
232
233 bool parsePI();
234 bool parseDoctype();
235 bool parseComment();
236
237 bool parseName();
238 bool parseNmtoken();
239 bool parseAttribute();
240 bool parseReference();
241 bool processReference();
242
243 bool parseExternalID();
244 bool parsePEReference();
245 bool parseMarkupdecl();
246 bool parseAttlistDecl();
247 bool parseAttType();
248 bool parseAttValue();
249 bool parseElementDecl();
250 bool parseNotationDecl();
251 bool parseChoiceSeq();
252 bool parseEntityDecl();
253 bool parseEntityValue();
254
255 bool parseString();
256
257 bool insertXmlRef(const QString&, const QString&, bool);
258
259 bool reportEndEntities();
260 void reportParseError(const QString& error);
261
262 typedef bool (QXmlSimpleReaderPrivate::*ParseFunction) ();
263 void unexpectedEof(ParseFunction where, int state);
264 void parseFailed(ParseFunction where, int state);
265 void pushParseState(ParseFunction function, int state);
266
267 bool isExpandedEntityValueTooLarge(QString *errorMessage);
268
269 Q_DECLARE_PUBLIC(QXmlSimpleReader)
270 QXmlSimpleReader *q_ptr;
271
272 friend class QXmlSimpleReaderLocator;
273 friend class QDomHandler;
274};
275Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ParseState, Q_PRIMITIVE_TYPE);
276Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::XmlRef, Q_RELOCATABLE_TYPE);
277Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ExternParameterEntity, Q_RELOCATABLE_TYPE);
278Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ExternEntity, Q_RELOCATABLE_TYPE);
279
280QT_END_NAMESPACE
281
282#endif // QXML_P_H
283

source code of qt5compat/src/core5/sax/qxml_p.h