1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtXml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QXML_P_H
41 #define QXML_P_H
42 
43 #include <qstack.h>
44 #include <qmap.h>
45 #include <qxml.h>
46 
47 #include <stack>
48 
49 #if QT_DEPRECATED_SINCE(5, 15)
50 
51 QT_BEGIN_NAMESPACE
52 
53 //
54 //  W A R N I N G
55 //  -------------
56 //
57 // This file is not part of the Qt API. It exists for the convenience of
58 // qxml.cpp and qdom.cpp. This header file may change from version to version without
59 // notice, or even be removed.
60 //
61 // We mean it.
62 //
63 
64 QT_WARNING_PUSH
65 QT_WARNING_DISABLE_DEPRECATED
66 
67 class QXmlSimpleReaderPrivate
68 {
69 public:
70     ~QXmlSimpleReaderPrivate();
71 private:
72     // functions
73     QXmlSimpleReaderPrivate(QXmlSimpleReader *reader);
74     void initIncrementalParsing();
75 
76     // used to determine if elements are correctly nested
77     std::stack<QString, QStringList> tags;
78 
79     // used by parseReference() and parsePEReference()
80     enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };
81 
82     // used for entity declarations
83     struct ExternParameterEntity
84     {
ExternParameterEntityExternParameterEntity85         ExternParameterEntity() {}
ExternParameterEntityExternParameterEntity86         ExternParameterEntity(const QString &p, const QString &s)
87             : publicId(p), systemId(s) {}
88         QString publicId;
89         QString systemId;
90 
91         Q_DUMMY_COMPARISON_OPERATOR(ExternParameterEntity)
92     };
93     friend class QTypeInfo<ExternParameterEntity>;
94 
95     struct ExternEntity
96     {
ExternEntityExternEntity97         ExternEntity() {}
ExternEntityExternEntity98         ExternEntity(const QString &p, const QString &s, const QString &n)
99             : publicId(p), systemId(s), notation(n) {}
100         QString publicId;
101         QString systemId;
102         QString notation;
103         Q_DUMMY_COMPARISON_OPERATOR(ExternEntity)
104     };
105     friend class QTypeInfo<ExternEntity>;
106 
107     QMap<QString,ExternParameterEntity> externParameterEntities;
108     QMap<QString,QString> parameterEntities;
109     QMap<QString,ExternEntity> externEntities;
110     QMap<QString,QString> entities;
111 
112     // used for parsing of entity references
113     struct XmlRef {
XmlRefXmlRef114         XmlRef()
115             : index(0) {}
XmlRefXmlRef116         XmlRef(const QString &_name, const QString &_value)
117             : name(_name), value(_value), index(0) {}
isEmptyXmlRef118         bool isEmpty() const { return index == value.length(); }
nextXmlRef119         QChar next() { return value.at(index++); }
120         QString name;
121         QString value;
122         int index;
123     };
124     friend class QTypeInfo<XmlRef>;
125     QStack<XmlRef> xmlRefStack;
126 
127     // used for standalone declaration
128     enum Standalone { Yes, No, Unknown };
129 
130     QString doctype; // only used for the doctype
131     QString xmlVersion; // only used to store the version information
132     QString encoding; // only used to store the encoding
133     Standalone standalone; // used to store the value of the standalone declaration
134 
135     QString publicId; // used by parseExternalID() to store the public ID
136     QString systemId; // used by parseExternalID() to store the system ID
137 
138     // Since publicId/systemId is used as temporary variables by parseExternalID(), it
139     // might overwrite the PUBLIC/SYSTEM for the document we're parsing. In effect, we would
140     // possibly send off an QXmlParseException that has the PUBLIC/SYSTEM of a entity declaration
141     // instead of those of the current document.
142     // Hence we have these two variables for storing the document's data.
143     QString thisPublicId;
144     QString thisSystemId;
145 
146     QString attDeclEName; // use by parseAttlistDecl()
147     QString attDeclAName; // use by parseAttlistDecl()
148 
149     // flags for some features support
150     bool useNamespaces;
151     bool useNamespacePrefixes;
152     bool reportWhitespaceCharData;
153     bool reportEntities;
154 
155     // used to build the attribute list
156     QXmlAttributes attList;
157 
158     // used in QXmlSimpleReader::parseContent() to decide whether character
159     // data was read
160     bool contentCharDataRead;
161     // Hack for letting QDom know where the skipped entity occurred
162     bool skipped_entity_in_content;
163 
164     // helper classes
165     QScopedPointer<QXmlLocator> locator;
166     QXmlNamespaceSupport namespaceSupport;
167 
168     // error string
169     QString error;
170 
171     // arguments for parse functions (this is needed to allow incremental
172     // parsing)
173     bool parsePI_xmldecl;
174     bool parseName_useRef;
175     bool parseReference_charDataRead;
176     EntityRecognitionContext parseReference_context;
177     bool parseExternalID_allowPublicID;
178     EntityRecognitionContext parsePEReference_context;
179     QString parseString_s;
180 
181     // for incremental parsing
182     struct ParseState {
183         typedef bool (QXmlSimpleReaderPrivate::*ParseFunction)();
184         ParseFunction function;
185         int state;
186     };
187     friend class QTypeInfo<ParseState>;
188     QStack<ParseState> *parseStack;
189 
190     // used in parseProlog()
191     bool xmldecl_possible;
192     bool doctype_read;
193 
194     // used in parseDoctype()
195     bool startDTDwasReported;
196 
197     // used in parseString()
198     signed char Done;
199 
200 
201     // variables
202     QXmlContentHandler *contentHnd;
203     QXmlErrorHandler   *errorHnd;
204     QXmlDTDHandler     *dtdHnd;
205     QXmlEntityResolver *entityRes;
206     QXmlLexicalHandler *lexicalHnd;
207     QXmlDeclHandler    *declHnd;
208 
209     QXmlInputSource *inputSource;
210 
211     QChar c; // the character at reading position
212     int   lineNr; // number of line
213     int   columnNr; // position in line
214 
215     QChar   nameArray[256]; // only used for names
216     QString nameValue; // only used for names
217     int     nameArrayPos;
218     int     nameValueLen;
219     QChar   refArray[256]; // only used for references
220     QString refValue; // only used for references
221     int     refArrayPos;
222     int     refValueLen;
223     QChar   stringArray[256]; // used for any other strings that are parsed
224     QString stringValue; // used for any other strings that are parsed
225     int     stringArrayPos;
226     int     stringValueLen;
227     QString emptyStr;
228 
229     QHash<QString, int> literalEntitySizes;
230     // The entity at (QMap<QString,) referenced the entities at (QMap<QString,) (int>) times.
231     QHash<QString, QHash<QString, int> > referencesToOtherEntities;
232     QHash<QString, int> expandedSizes;
233     // The limit to the amount of times the DTD parsing functions can be called
234     // for the DTD currently being parsed.
235     static const int dtdRecursionLimit = 2;
236     // The maximum amount of characters an entity value may contain, after expansion.
237     static const int entityCharacterLimit = 4096;
238 
239     const QString &string();
240     void stringClear();
241     void stringAddC(QChar);
stringAddC()242     inline void stringAddC() { stringAddC(c); }
243     const QString &name();
244     void nameClear();
245     void nameAddC(QChar);
nameAddC()246     inline void nameAddC() { nameAddC(c); }
247     const QString &ref();
248     void refClear();
249     void refAddC(QChar);
refAddC()250     inline void refAddC() { refAddC(c); }
251 
252     // private functions
253     bool eat_ws();
254     bool next_eat_ws();
255 
256     void QT_FASTCALL next();
257     bool atEnd();
258 
259     void init(const QXmlInputSource* i);
260     void initData();
261 
262     bool entityExist(const QString&) const;
263 
264     bool parseBeginOrContinue(int state, bool incremental);
265 
266     bool parseProlog();
267     bool parseElement();
268     bool processElementEmptyTag();
269     bool processElementETagBegin2();
270     bool processElementAttribute();
271     bool parseMisc();
272     bool parseContent();
273 
274     bool parsePI();
275     bool parseDoctype();
276     bool parseComment();
277 
278     bool parseName();
279     bool parseNmtoken();
280     bool parseAttribute();
281     bool parseReference();
282     bool processReference();
283 
284     bool parseExternalID();
285     bool parsePEReference();
286     bool parseMarkupdecl();
287     bool parseAttlistDecl();
288     bool parseAttType();
289     bool parseAttValue();
290     bool parseElementDecl();
291     bool parseNotationDecl();
292     bool parseChoiceSeq();
293     bool parseEntityDecl();
294     bool parseEntityValue();
295 
296     bool parseString();
297 
298     bool insertXmlRef(const QString&, const QString&, bool);
299 
300     bool reportEndEntities();
301     void reportParseError(const QString& error);
302 
303     typedef bool (QXmlSimpleReaderPrivate::*ParseFunction) ();
304     void unexpectedEof(ParseFunction where, int state);
305     void parseFailed(ParseFunction where, int state);
306     void pushParseState(ParseFunction function, int state);
307 
308     bool isExpandedEntityValueTooLarge(QString *errorMessage);
309 
310     Q_DECLARE_PUBLIC(QXmlSimpleReader)
311     QXmlSimpleReader *q_ptr;
312 
313     friend class QXmlSimpleReaderLocator;
314     friend class QDomHandler;
315 };
316 Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ParseState, Q_PRIMITIVE_TYPE);
317 Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::XmlRef, Q_MOVABLE_TYPE);
318 Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ExternParameterEntity, Q_MOVABLE_TYPE);
319 Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ExternEntity, Q_MOVABLE_TYPE);
320 
321 QT_WARNING_POP
322 
323 QT_END_NAMESPACE
324 
325 #endif // QT_DEPRECATED_SINCE(5, 15)
326 
327 #endif // QXML_P_H
328