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