1*6777b538SAndroid Build Coastguard Worker /*
2*6777b538SAndroid Build Coastguard Worker * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
3*6777b538SAndroid Build Coastguard Worker * implemented on top of the SAX interfaces
4*6777b538SAndroid Build Coastguard Worker *
5*6777b538SAndroid Build Coastguard Worker * References:
6*6777b538SAndroid Build Coastguard Worker * The XML specification:
7*6777b538SAndroid Build Coastguard Worker * http://www.w3.org/TR/REC-xml
8*6777b538SAndroid Build Coastguard Worker * Original 1.0 version:
9*6777b538SAndroid Build Coastguard Worker * http://www.w3.org/TR/1998/REC-xml-19980210
10*6777b538SAndroid Build Coastguard Worker * XML second edition working draft
11*6777b538SAndroid Build Coastguard Worker * http://www.w3.org/TR/2000/WD-xml-2e-20000814
12*6777b538SAndroid Build Coastguard Worker *
13*6777b538SAndroid Build Coastguard Worker * Okay this is a big file, the parser core is around 7000 lines, then it
14*6777b538SAndroid Build Coastguard Worker * is followed by the progressive parser top routines, then the various
15*6777b538SAndroid Build Coastguard Worker * high level APIs to call the parser and a few miscellaneous functions.
16*6777b538SAndroid Build Coastguard Worker * A number of helper functions and deprecated ones have been moved to
17*6777b538SAndroid Build Coastguard Worker * parserInternals.c to reduce this file size.
18*6777b538SAndroid Build Coastguard Worker * As much as possible the functions are associated with their relative
19*6777b538SAndroid Build Coastguard Worker * production in the XML specification. A few productions defining the
20*6777b538SAndroid Build Coastguard Worker * different ranges of character are actually implanted either in
21*6777b538SAndroid Build Coastguard Worker * parserInternals.h or parserInternals.c
22*6777b538SAndroid Build Coastguard Worker * The DOM tree build is realized from the default SAX callbacks in
23*6777b538SAndroid Build Coastguard Worker * the module SAX.c.
24*6777b538SAndroid Build Coastguard Worker * The routines doing the validation checks are in valid.c and called either
25*6777b538SAndroid Build Coastguard Worker * from the SAX callbacks or as standalone functions using a preparsed
26*6777b538SAndroid Build Coastguard Worker * document.
27*6777b538SAndroid Build Coastguard Worker *
28*6777b538SAndroid Build Coastguard Worker * See Copyright for the status of this software.
29*6777b538SAndroid Build Coastguard Worker *
30*6777b538SAndroid Build Coastguard Worker * [email protected]
31*6777b538SAndroid Build Coastguard Worker */
32*6777b538SAndroid Build Coastguard Worker
33*6777b538SAndroid Build Coastguard Worker /* To avoid EBCDIC trouble when parsing on zOS */
34*6777b538SAndroid Build Coastguard Worker #if defined(__MVS__)
35*6777b538SAndroid Build Coastguard Worker #pragma convert("ISO8859-1")
36*6777b538SAndroid Build Coastguard Worker #endif
37*6777b538SAndroid Build Coastguard Worker
38*6777b538SAndroid Build Coastguard Worker #define IN_LIBXML
39*6777b538SAndroid Build Coastguard Worker #include "libxml.h"
40*6777b538SAndroid Build Coastguard Worker
41*6777b538SAndroid Build Coastguard Worker #if defined(_WIN32)
42*6777b538SAndroid Build Coastguard Worker #define XML_DIR_SEP '\\'
43*6777b538SAndroid Build Coastguard Worker #else
44*6777b538SAndroid Build Coastguard Worker #define XML_DIR_SEP '/'
45*6777b538SAndroid Build Coastguard Worker #endif
46*6777b538SAndroid Build Coastguard Worker
47*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
48*6777b538SAndroid Build Coastguard Worker #include <limits.h>
49*6777b538SAndroid Build Coastguard Worker #include <string.h>
50*6777b538SAndroid Build Coastguard Worker #include <stdarg.h>
51*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
52*6777b538SAndroid Build Coastguard Worker #include <ctype.h>
53*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
54*6777b538SAndroid Build Coastguard Worker #include <libxml/parser.h>
55*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlmemory.h>
56*6777b538SAndroid Build Coastguard Worker #include <libxml/tree.h>
57*6777b538SAndroid Build Coastguard Worker #include <libxml/parserInternals.h>
58*6777b538SAndroid Build Coastguard Worker #include <libxml/valid.h>
59*6777b538SAndroid Build Coastguard Worker #include <libxml/entities.h>
60*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlerror.h>
61*6777b538SAndroid Build Coastguard Worker #include <libxml/encoding.h>
62*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlIO.h>
63*6777b538SAndroid Build Coastguard Worker #include <libxml/uri.h>
64*6777b538SAndroid Build Coastguard Worker #include <libxml/SAX2.h>
65*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
66*6777b538SAndroid Build Coastguard Worker #include <libxml/catalog.h>
67*6777b538SAndroid Build Coastguard Worker #endif
68*6777b538SAndroid Build Coastguard Worker
69*6777b538SAndroid Build Coastguard Worker #include "private/buf.h"
70*6777b538SAndroid Build Coastguard Worker #include "private/dict.h"
71*6777b538SAndroid Build Coastguard Worker #include "private/entities.h"
72*6777b538SAndroid Build Coastguard Worker #include "private/error.h"
73*6777b538SAndroid Build Coastguard Worker #include "private/html.h"
74*6777b538SAndroid Build Coastguard Worker #include "private/io.h"
75*6777b538SAndroid Build Coastguard Worker #include "private/parser.h"
76*6777b538SAndroid Build Coastguard Worker
77*6777b538SAndroid Build Coastguard Worker #define NS_INDEX_EMPTY INT_MAX
78*6777b538SAndroid Build Coastguard Worker #define NS_INDEX_XML (INT_MAX - 1)
79*6777b538SAndroid Build Coastguard Worker #define URI_HASH_EMPTY 0xD943A04E
80*6777b538SAndroid Build Coastguard Worker #define URI_HASH_XML 0xF0451F02
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker struct _xmlStartTag {
83*6777b538SAndroid Build Coastguard Worker const xmlChar *prefix;
84*6777b538SAndroid Build Coastguard Worker const xmlChar *URI;
85*6777b538SAndroid Build Coastguard Worker int line;
86*6777b538SAndroid Build Coastguard Worker int nsNr;
87*6777b538SAndroid Build Coastguard Worker };
88*6777b538SAndroid Build Coastguard Worker
89*6777b538SAndroid Build Coastguard Worker typedef struct {
90*6777b538SAndroid Build Coastguard Worker void *saxData;
91*6777b538SAndroid Build Coastguard Worker unsigned prefixHashValue;
92*6777b538SAndroid Build Coastguard Worker unsigned uriHashValue;
93*6777b538SAndroid Build Coastguard Worker unsigned elementId;
94*6777b538SAndroid Build Coastguard Worker int oldIndex;
95*6777b538SAndroid Build Coastguard Worker } xmlParserNsExtra;
96*6777b538SAndroid Build Coastguard Worker
97*6777b538SAndroid Build Coastguard Worker typedef struct {
98*6777b538SAndroid Build Coastguard Worker unsigned hashValue;
99*6777b538SAndroid Build Coastguard Worker int index;
100*6777b538SAndroid Build Coastguard Worker } xmlParserNsBucket;
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Worker struct _xmlParserNsData {
103*6777b538SAndroid Build Coastguard Worker xmlParserNsExtra *extra;
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker unsigned hashSize;
106*6777b538SAndroid Build Coastguard Worker unsigned hashElems;
107*6777b538SAndroid Build Coastguard Worker xmlParserNsBucket *hash;
108*6777b538SAndroid Build Coastguard Worker
109*6777b538SAndroid Build Coastguard Worker unsigned elementId;
110*6777b538SAndroid Build Coastguard Worker int defaultNsIndex;
111*6777b538SAndroid Build Coastguard Worker int minNsIndex;
112*6777b538SAndroid Build Coastguard Worker };
113*6777b538SAndroid Build Coastguard Worker
114*6777b538SAndroid Build Coastguard Worker struct _xmlAttrHashBucket {
115*6777b538SAndroid Build Coastguard Worker int index;
116*6777b538SAndroid Build Coastguard Worker };
117*6777b538SAndroid Build Coastguard Worker
118*6777b538SAndroid Build Coastguard Worker static int
119*6777b538SAndroid Build Coastguard Worker xmlParseElementStart(xmlParserCtxtPtr ctxt);
120*6777b538SAndroid Build Coastguard Worker
121*6777b538SAndroid Build Coastguard Worker static void
122*6777b538SAndroid Build Coastguard Worker xmlParseElementEnd(xmlParserCtxtPtr ctxt);
123*6777b538SAndroid Build Coastguard Worker
124*6777b538SAndroid Build Coastguard Worker static xmlEntityPtr
125*6777b538SAndroid Build Coastguard Worker xmlLookupGeneralEntity(xmlParserCtxtPtr ctxt, const xmlChar *name, int inAttr);
126*6777b538SAndroid Build Coastguard Worker
127*6777b538SAndroid Build Coastguard Worker static const xmlChar *
128*6777b538SAndroid Build Coastguard Worker xmlParseEntityRefInternal(xmlParserCtxtPtr ctxt);
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard Worker /************************************************************************
131*6777b538SAndroid Build Coastguard Worker * *
132*6777b538SAndroid Build Coastguard Worker * Arbitrary limits set in the parser. See XML_PARSE_HUGE *
133*6777b538SAndroid Build Coastguard Worker * *
134*6777b538SAndroid Build Coastguard Worker ************************************************************************/
135*6777b538SAndroid Build Coastguard Worker
136*6777b538SAndroid Build Coastguard Worker #define XML_PARSER_BIG_ENTITY 1000
137*6777b538SAndroid Build Coastguard Worker #define XML_PARSER_LOT_ENTITY 5000
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard Worker /*
140*6777b538SAndroid Build Coastguard Worker * Constants for protection against abusive entity expansion
141*6777b538SAndroid Build Coastguard Worker * ("billion laughs").
142*6777b538SAndroid Build Coastguard Worker */
143*6777b538SAndroid Build Coastguard Worker
144*6777b538SAndroid Build Coastguard Worker /*
145*6777b538SAndroid Build Coastguard Worker * A certain amount of entity expansion which is always allowed.
146*6777b538SAndroid Build Coastguard Worker */
147*6777b538SAndroid Build Coastguard Worker #define XML_PARSER_ALLOWED_EXPANSION 1000000
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker /*
150*6777b538SAndroid Build Coastguard Worker * Fixed cost for each entity reference. This crudely models processing time
151*6777b538SAndroid Build Coastguard Worker * as well to protect, for example, against exponential expansion of empty
152*6777b538SAndroid Build Coastguard Worker * or very short entities.
153*6777b538SAndroid Build Coastguard Worker */
154*6777b538SAndroid Build Coastguard Worker #define XML_ENT_FIXED_COST 20
155*6777b538SAndroid Build Coastguard Worker
156*6777b538SAndroid Build Coastguard Worker /**
157*6777b538SAndroid Build Coastguard Worker * xmlParserMaxDepth:
158*6777b538SAndroid Build Coastguard Worker *
159*6777b538SAndroid Build Coastguard Worker * arbitrary depth limit for the XML documents that we allow to
160*6777b538SAndroid Build Coastguard Worker * process. This is not a limitation of the parser but a safety
161*6777b538SAndroid Build Coastguard Worker * boundary feature. It can be disabled with the XML_PARSE_HUGE
162*6777b538SAndroid Build Coastguard Worker * parser option.
163*6777b538SAndroid Build Coastguard Worker */
164*6777b538SAndroid Build Coastguard Worker const unsigned int xmlParserMaxDepth = 256;
165*6777b538SAndroid Build Coastguard Worker
166*6777b538SAndroid Build Coastguard Worker
167*6777b538SAndroid Build Coastguard Worker
168*6777b538SAndroid Build Coastguard Worker #define XML_PARSER_BIG_BUFFER_SIZE 300
169*6777b538SAndroid Build Coastguard Worker #define XML_PARSER_BUFFER_SIZE 100
170*6777b538SAndroid Build Coastguard Worker #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
171*6777b538SAndroid Build Coastguard Worker
172*6777b538SAndroid Build Coastguard Worker /**
173*6777b538SAndroid Build Coastguard Worker * XML_PARSER_CHUNK_SIZE
174*6777b538SAndroid Build Coastguard Worker *
175*6777b538SAndroid Build Coastguard Worker * When calling GROW that's the minimal amount of data
176*6777b538SAndroid Build Coastguard Worker * the parser expected to have received. It is not a hard
177*6777b538SAndroid Build Coastguard Worker * limit but an optimization when reading strings like Names
178*6777b538SAndroid Build Coastguard Worker * It is not strictly needed as long as inputs available characters
179*6777b538SAndroid Build Coastguard Worker * are followed by 0, which should be provided by the I/O level
180*6777b538SAndroid Build Coastguard Worker */
181*6777b538SAndroid Build Coastguard Worker #define XML_PARSER_CHUNK_SIZE 100
182*6777b538SAndroid Build Coastguard Worker
183*6777b538SAndroid Build Coastguard Worker /**
184*6777b538SAndroid Build Coastguard Worker * xmlParserVersion:
185*6777b538SAndroid Build Coastguard Worker *
186*6777b538SAndroid Build Coastguard Worker * Constant string describing the internal version of the library
187*6777b538SAndroid Build Coastguard Worker */
188*6777b538SAndroid Build Coastguard Worker const char *const
189*6777b538SAndroid Build Coastguard Worker xmlParserVersion = LIBXML_VERSION_STRING LIBXML_VERSION_EXTRA;
190*6777b538SAndroid Build Coastguard Worker
191*6777b538SAndroid Build Coastguard Worker /*
192*6777b538SAndroid Build Coastguard Worker * List of XML prefixed PI allowed by W3C specs
193*6777b538SAndroid Build Coastguard Worker */
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker static const char* const xmlW3CPIs[] = {
196*6777b538SAndroid Build Coastguard Worker "xml-stylesheet",
197*6777b538SAndroid Build Coastguard Worker "xml-model",
198*6777b538SAndroid Build Coastguard Worker NULL
199*6777b538SAndroid Build Coastguard Worker };
200*6777b538SAndroid Build Coastguard Worker
201*6777b538SAndroid Build Coastguard Worker
202*6777b538SAndroid Build Coastguard Worker /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
203*6777b538SAndroid Build Coastguard Worker static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
204*6777b538SAndroid Build Coastguard Worker const xmlChar **str);
205*6777b538SAndroid Build Coastguard Worker
206*6777b538SAndroid Build Coastguard Worker static void
207*6777b538SAndroid Build Coastguard Worker xmlCtxtParseEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr ent);
208*6777b538SAndroid Build Coastguard Worker
209*6777b538SAndroid Build Coastguard Worker static int
210*6777b538SAndroid Build Coastguard Worker xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
211*6777b538SAndroid Build Coastguard Worker
212*6777b538SAndroid Build Coastguard Worker /************************************************************************
213*6777b538SAndroid Build Coastguard Worker * *
214*6777b538SAndroid Build Coastguard Worker * Some factorized error routines *
215*6777b538SAndroid Build Coastguard Worker * *
216*6777b538SAndroid Build Coastguard Worker ************************************************************************/
217*6777b538SAndroid Build Coastguard Worker
218*6777b538SAndroid Build Coastguard Worker static void
xmlErrMemory(xmlParserCtxtPtr ctxt)219*6777b538SAndroid Build Coastguard Worker xmlErrMemory(xmlParserCtxtPtr ctxt) {
220*6777b538SAndroid Build Coastguard Worker xmlCtxtErrMemory(ctxt);
221*6777b538SAndroid Build Coastguard Worker }
222*6777b538SAndroid Build Coastguard Worker
223*6777b538SAndroid Build Coastguard Worker /**
224*6777b538SAndroid Build Coastguard Worker * xmlErrAttributeDup:
225*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
226*6777b538SAndroid Build Coastguard Worker * @prefix: the attribute prefix
227*6777b538SAndroid Build Coastguard Worker * @localname: the attribute localname
228*6777b538SAndroid Build Coastguard Worker *
229*6777b538SAndroid Build Coastguard Worker * Handle a redefinition of attribute error
230*6777b538SAndroid Build Coastguard Worker */
231*6777b538SAndroid Build Coastguard Worker static void
xmlErrAttributeDup(xmlParserCtxtPtr ctxt,const xmlChar * prefix,const xmlChar * localname)232*6777b538SAndroid Build Coastguard Worker xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
233*6777b538SAndroid Build Coastguard Worker const xmlChar * localname)
234*6777b538SAndroid Build Coastguard Worker {
235*6777b538SAndroid Build Coastguard Worker if (prefix == NULL)
236*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, XML_ERR_ATTRIBUTE_REDEFINED,
237*6777b538SAndroid Build Coastguard Worker XML_ERR_FATAL, localname, NULL, NULL, 0,
238*6777b538SAndroid Build Coastguard Worker "Attribute %s redefined\n", localname);
239*6777b538SAndroid Build Coastguard Worker else
240*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, XML_ERR_ATTRIBUTE_REDEFINED,
241*6777b538SAndroid Build Coastguard Worker XML_ERR_FATAL, prefix, localname, NULL, 0,
242*6777b538SAndroid Build Coastguard Worker "Attribute %s:%s redefined\n", prefix, localname);
243*6777b538SAndroid Build Coastguard Worker }
244*6777b538SAndroid Build Coastguard Worker
245*6777b538SAndroid Build Coastguard Worker /**
246*6777b538SAndroid Build Coastguard Worker * xmlFatalErrMsg:
247*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
248*6777b538SAndroid Build Coastguard Worker * @error: the error number
249*6777b538SAndroid Build Coastguard Worker * @msg: the error message
250*6777b538SAndroid Build Coastguard Worker *
251*6777b538SAndroid Build Coastguard Worker * Handle a fatal parser error, i.e. violating Well-Formedness constraints
252*6777b538SAndroid Build Coastguard Worker */
253*6777b538SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(3,0)
xmlFatalErrMsg(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg)254*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
255*6777b538SAndroid Build Coastguard Worker const char *msg)
256*6777b538SAndroid Build Coastguard Worker {
257*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
258*6777b538SAndroid Build Coastguard Worker NULL, NULL, NULL, 0, "%s", msg);
259*6777b538SAndroid Build Coastguard Worker }
260*6777b538SAndroid Build Coastguard Worker
261*6777b538SAndroid Build Coastguard Worker /**
262*6777b538SAndroid Build Coastguard Worker * xmlWarningMsg:
263*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
264*6777b538SAndroid Build Coastguard Worker * @error: the error number
265*6777b538SAndroid Build Coastguard Worker * @msg: the error message
266*6777b538SAndroid Build Coastguard Worker * @str1: extra data
267*6777b538SAndroid Build Coastguard Worker * @str2: extra data
268*6777b538SAndroid Build Coastguard Worker *
269*6777b538SAndroid Build Coastguard Worker * Handle a warning.
270*6777b538SAndroid Build Coastguard Worker */
271*6777b538SAndroid Build Coastguard Worker void LIBXML_ATTR_FORMAT(3,0)
xmlWarningMsg(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg,const xmlChar * str1,const xmlChar * str2)272*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
273*6777b538SAndroid Build Coastguard Worker const char *msg, const xmlChar *str1, const xmlChar *str2)
274*6777b538SAndroid Build Coastguard Worker {
275*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_WARNING,
276*6777b538SAndroid Build Coastguard Worker str1, str2, NULL, 0, msg, str1, str2);
277*6777b538SAndroid Build Coastguard Worker }
278*6777b538SAndroid Build Coastguard Worker
279*6777b538SAndroid Build Coastguard Worker /**
280*6777b538SAndroid Build Coastguard Worker * xmlValidityError:
281*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
282*6777b538SAndroid Build Coastguard Worker * @error: the error number
283*6777b538SAndroid Build Coastguard Worker * @msg: the error message
284*6777b538SAndroid Build Coastguard Worker * @str1: extra data
285*6777b538SAndroid Build Coastguard Worker *
286*6777b538SAndroid Build Coastguard Worker * Handle a validity error.
287*6777b538SAndroid Build Coastguard Worker */
288*6777b538SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(3,0)
xmlValidityError(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg,const xmlChar * str1,const xmlChar * str2)289*6777b538SAndroid Build Coastguard Worker xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
290*6777b538SAndroid Build Coastguard Worker const char *msg, const xmlChar *str1, const xmlChar *str2)
291*6777b538SAndroid Build Coastguard Worker {
292*6777b538SAndroid Build Coastguard Worker ctxt->valid = 0;
293*6777b538SAndroid Build Coastguard Worker
294*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_DTD, error, XML_ERR_ERROR,
295*6777b538SAndroid Build Coastguard Worker str1, str2, NULL, 0, msg, str1, str2);
296*6777b538SAndroid Build Coastguard Worker }
297*6777b538SAndroid Build Coastguard Worker
298*6777b538SAndroid Build Coastguard Worker /**
299*6777b538SAndroid Build Coastguard Worker * xmlFatalErrMsgInt:
300*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
301*6777b538SAndroid Build Coastguard Worker * @error: the error number
302*6777b538SAndroid Build Coastguard Worker * @msg: the error message
303*6777b538SAndroid Build Coastguard Worker * @val: an integer value
304*6777b538SAndroid Build Coastguard Worker *
305*6777b538SAndroid Build Coastguard Worker * Handle a fatal parser error, i.e. violating Well-Formedness constraints
306*6777b538SAndroid Build Coastguard Worker */
307*6777b538SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(3,0)
xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg,int val)308*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
309*6777b538SAndroid Build Coastguard Worker const char *msg, int val)
310*6777b538SAndroid Build Coastguard Worker {
311*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
312*6777b538SAndroid Build Coastguard Worker NULL, NULL, NULL, val, msg, val);
313*6777b538SAndroid Build Coastguard Worker }
314*6777b538SAndroid Build Coastguard Worker
315*6777b538SAndroid Build Coastguard Worker /**
316*6777b538SAndroid Build Coastguard Worker * xmlFatalErrMsgStrIntStr:
317*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
318*6777b538SAndroid Build Coastguard Worker * @error: the error number
319*6777b538SAndroid Build Coastguard Worker * @msg: the error message
320*6777b538SAndroid Build Coastguard Worker * @str1: an string info
321*6777b538SAndroid Build Coastguard Worker * @val: an integer value
322*6777b538SAndroid Build Coastguard Worker * @str2: an string info
323*6777b538SAndroid Build Coastguard Worker *
324*6777b538SAndroid Build Coastguard Worker * Handle a fatal parser error, i.e. violating Well-Formedness constraints
325*6777b538SAndroid Build Coastguard Worker */
326*6777b538SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(3,0)
xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg,const xmlChar * str1,int val,const xmlChar * str2)327*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
328*6777b538SAndroid Build Coastguard Worker const char *msg, const xmlChar *str1, int val,
329*6777b538SAndroid Build Coastguard Worker const xmlChar *str2)
330*6777b538SAndroid Build Coastguard Worker {
331*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
332*6777b538SAndroid Build Coastguard Worker str1, str2, NULL, val, msg, str1, val, str2);
333*6777b538SAndroid Build Coastguard Worker }
334*6777b538SAndroid Build Coastguard Worker
335*6777b538SAndroid Build Coastguard Worker /**
336*6777b538SAndroid Build Coastguard Worker * xmlFatalErrMsgStr:
337*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
338*6777b538SAndroid Build Coastguard Worker * @error: the error number
339*6777b538SAndroid Build Coastguard Worker * @msg: the error message
340*6777b538SAndroid Build Coastguard Worker * @val: a string value
341*6777b538SAndroid Build Coastguard Worker *
342*6777b538SAndroid Build Coastguard Worker * Handle a fatal parser error, i.e. violating Well-Formedness constraints
343*6777b538SAndroid Build Coastguard Worker */
344*6777b538SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(3,0)
xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg,const xmlChar * val)345*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
346*6777b538SAndroid Build Coastguard Worker const char *msg, const xmlChar * val)
347*6777b538SAndroid Build Coastguard Worker {
348*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
349*6777b538SAndroid Build Coastguard Worker val, NULL, NULL, 0, msg, val);
350*6777b538SAndroid Build Coastguard Worker }
351*6777b538SAndroid Build Coastguard Worker
352*6777b538SAndroid Build Coastguard Worker /**
353*6777b538SAndroid Build Coastguard Worker * xmlErrMsgStr:
354*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
355*6777b538SAndroid Build Coastguard Worker * @error: the error number
356*6777b538SAndroid Build Coastguard Worker * @msg: the error message
357*6777b538SAndroid Build Coastguard Worker * @val: a string value
358*6777b538SAndroid Build Coastguard Worker *
359*6777b538SAndroid Build Coastguard Worker * Handle a non fatal parser error
360*6777b538SAndroid Build Coastguard Worker */
361*6777b538SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(3,0)
xmlErrMsgStr(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg,const xmlChar * val)362*6777b538SAndroid Build Coastguard Worker xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
363*6777b538SAndroid Build Coastguard Worker const char *msg, const xmlChar * val)
364*6777b538SAndroid Build Coastguard Worker {
365*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_ERROR,
366*6777b538SAndroid Build Coastguard Worker val, NULL, NULL, 0, msg, val);
367*6777b538SAndroid Build Coastguard Worker }
368*6777b538SAndroid Build Coastguard Worker
369*6777b538SAndroid Build Coastguard Worker /**
370*6777b538SAndroid Build Coastguard Worker * xmlNsErr:
371*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
372*6777b538SAndroid Build Coastguard Worker * @error: the error number
373*6777b538SAndroid Build Coastguard Worker * @msg: the message
374*6777b538SAndroid Build Coastguard Worker * @info1: extra information string
375*6777b538SAndroid Build Coastguard Worker * @info2: extra information string
376*6777b538SAndroid Build Coastguard Worker *
377*6777b538SAndroid Build Coastguard Worker * Handle a fatal parser error, i.e. violating Well-Formedness constraints
378*6777b538SAndroid Build Coastguard Worker */
379*6777b538SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(3,0)
xmlNsErr(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg,const xmlChar * info1,const xmlChar * info2,const xmlChar * info3)380*6777b538SAndroid Build Coastguard Worker xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
381*6777b538SAndroid Build Coastguard Worker const char *msg,
382*6777b538SAndroid Build Coastguard Worker const xmlChar * info1, const xmlChar * info2,
383*6777b538SAndroid Build Coastguard Worker const xmlChar * info3)
384*6777b538SAndroid Build Coastguard Worker {
385*6777b538SAndroid Build Coastguard Worker ctxt->nsWellFormed = 0;
386*6777b538SAndroid Build Coastguard Worker
387*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_NAMESPACE, error, XML_ERR_ERROR,
388*6777b538SAndroid Build Coastguard Worker info1, info2, info3, 0, msg, info1, info2, info3);
389*6777b538SAndroid Build Coastguard Worker }
390*6777b538SAndroid Build Coastguard Worker
391*6777b538SAndroid Build Coastguard Worker /**
392*6777b538SAndroid Build Coastguard Worker * xmlNsWarn
393*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
394*6777b538SAndroid Build Coastguard Worker * @error: the error number
395*6777b538SAndroid Build Coastguard Worker * @msg: the message
396*6777b538SAndroid Build Coastguard Worker * @info1: extra information string
397*6777b538SAndroid Build Coastguard Worker * @info2: extra information string
398*6777b538SAndroid Build Coastguard Worker *
399*6777b538SAndroid Build Coastguard Worker * Handle a namespace warning error
400*6777b538SAndroid Build Coastguard Worker */
401*6777b538SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(3,0)
xmlNsWarn(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg,const xmlChar * info1,const xmlChar * info2,const xmlChar * info3)402*6777b538SAndroid Build Coastguard Worker xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
403*6777b538SAndroid Build Coastguard Worker const char *msg,
404*6777b538SAndroid Build Coastguard Worker const xmlChar * info1, const xmlChar * info2,
405*6777b538SAndroid Build Coastguard Worker const xmlChar * info3)
406*6777b538SAndroid Build Coastguard Worker {
407*6777b538SAndroid Build Coastguard Worker xmlCtxtErr(ctxt, NULL, XML_FROM_NAMESPACE, error, XML_ERR_WARNING,
408*6777b538SAndroid Build Coastguard Worker info1, info2, info3, 0, msg, info1, info2, info3);
409*6777b538SAndroid Build Coastguard Worker }
410*6777b538SAndroid Build Coastguard Worker
411*6777b538SAndroid Build Coastguard Worker static void
xmlSaturatedAdd(unsigned long * dst,unsigned long val)412*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(unsigned long *dst, unsigned long val) {
413*6777b538SAndroid Build Coastguard Worker if (val > ULONG_MAX - *dst)
414*6777b538SAndroid Build Coastguard Worker *dst = ULONG_MAX;
415*6777b538SAndroid Build Coastguard Worker else
416*6777b538SAndroid Build Coastguard Worker *dst += val;
417*6777b538SAndroid Build Coastguard Worker }
418*6777b538SAndroid Build Coastguard Worker
419*6777b538SAndroid Build Coastguard Worker static void
xmlSaturatedAddSizeT(unsigned long * dst,unsigned long val)420*6777b538SAndroid Build Coastguard Worker xmlSaturatedAddSizeT(unsigned long *dst, unsigned long val) {
421*6777b538SAndroid Build Coastguard Worker if (val > ULONG_MAX - *dst)
422*6777b538SAndroid Build Coastguard Worker *dst = ULONG_MAX;
423*6777b538SAndroid Build Coastguard Worker else
424*6777b538SAndroid Build Coastguard Worker *dst += val;
425*6777b538SAndroid Build Coastguard Worker }
426*6777b538SAndroid Build Coastguard Worker
427*6777b538SAndroid Build Coastguard Worker /**
428*6777b538SAndroid Build Coastguard Worker * xmlParserEntityCheck:
429*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
430*6777b538SAndroid Build Coastguard Worker * @extra: sum of unexpanded entity sizes
431*6777b538SAndroid Build Coastguard Worker *
432*6777b538SAndroid Build Coastguard Worker * Check for non-linear entity expansion behaviour.
433*6777b538SAndroid Build Coastguard Worker *
434*6777b538SAndroid Build Coastguard Worker * In some cases like xmlExpandEntityInAttValue, this function is called
435*6777b538SAndroid Build Coastguard Worker * for each, possibly nested entity and its unexpanded content length.
436*6777b538SAndroid Build Coastguard Worker *
437*6777b538SAndroid Build Coastguard Worker * In other cases like xmlParseReference, it's only called for each
438*6777b538SAndroid Build Coastguard Worker * top-level entity with its unexpanded content length plus the sum of
439*6777b538SAndroid Build Coastguard Worker * the unexpanded content lengths (plus fixed cost) of all nested
440*6777b538SAndroid Build Coastguard Worker * entities.
441*6777b538SAndroid Build Coastguard Worker *
442*6777b538SAndroid Build Coastguard Worker * Summing the unexpanded lengths also adds the length of the reference.
443*6777b538SAndroid Build Coastguard Worker * This is by design. Taking the length of the entity name into account
444*6777b538SAndroid Build Coastguard Worker * discourages attacks that try to waste CPU time with abusively long
445*6777b538SAndroid Build Coastguard Worker * entity names. See test/recurse/lol6.xml for example. Each call also
446*6777b538SAndroid Build Coastguard Worker * adds some fixed cost XML_ENT_FIXED_COST to discourage attacks with
447*6777b538SAndroid Build Coastguard Worker * short entities.
448*6777b538SAndroid Build Coastguard Worker *
449*6777b538SAndroid Build Coastguard Worker * Returns 1 on error, 0 on success.
450*6777b538SAndroid Build Coastguard Worker */
451*6777b538SAndroid Build Coastguard Worker static int
xmlParserEntityCheck(xmlParserCtxtPtr ctxt,unsigned long extra)452*6777b538SAndroid Build Coastguard Worker xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long extra)
453*6777b538SAndroid Build Coastguard Worker {
454*6777b538SAndroid Build Coastguard Worker unsigned long consumed;
455*6777b538SAndroid Build Coastguard Worker unsigned long *expandedSize;
456*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input = ctxt->input;
457*6777b538SAndroid Build Coastguard Worker xmlEntityPtr entity = input->entity;
458*6777b538SAndroid Build Coastguard Worker
459*6777b538SAndroid Build Coastguard Worker if ((entity) && (entity->flags & XML_ENT_CHECKED))
460*6777b538SAndroid Build Coastguard Worker return(0);
461*6777b538SAndroid Build Coastguard Worker
462*6777b538SAndroid Build Coastguard Worker /*
463*6777b538SAndroid Build Coastguard Worker * Compute total consumed bytes so far, including input streams of
464*6777b538SAndroid Build Coastguard Worker * external entities.
465*6777b538SAndroid Build Coastguard Worker */
466*6777b538SAndroid Build Coastguard Worker consumed = input->consumed;
467*6777b538SAndroid Build Coastguard Worker xmlSaturatedAddSizeT(&consumed, input->cur - input->base);
468*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(&consumed, ctxt->sizeentities);
469*6777b538SAndroid Build Coastguard Worker
470*6777b538SAndroid Build Coastguard Worker if (entity)
471*6777b538SAndroid Build Coastguard Worker expandedSize = &entity->expandedSize;
472*6777b538SAndroid Build Coastguard Worker else
473*6777b538SAndroid Build Coastguard Worker expandedSize = &ctxt->sizeentcopy;
474*6777b538SAndroid Build Coastguard Worker
475*6777b538SAndroid Build Coastguard Worker /*
476*6777b538SAndroid Build Coastguard Worker * Add extra cost and some fixed cost.
477*6777b538SAndroid Build Coastguard Worker */
478*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(expandedSize, extra);
479*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(expandedSize, XML_ENT_FIXED_COST);
480*6777b538SAndroid Build Coastguard Worker
481*6777b538SAndroid Build Coastguard Worker /*
482*6777b538SAndroid Build Coastguard Worker * It's important to always use saturation arithmetic when tracking
483*6777b538SAndroid Build Coastguard Worker * entity sizes to make the size checks reliable. If "sizeentcopy"
484*6777b538SAndroid Build Coastguard Worker * overflows, we have to abort.
485*6777b538SAndroid Build Coastguard Worker */
486*6777b538SAndroid Build Coastguard Worker if ((*expandedSize > XML_PARSER_ALLOWED_EXPANSION) &&
487*6777b538SAndroid Build Coastguard Worker ((*expandedSize >= ULONG_MAX) ||
488*6777b538SAndroid Build Coastguard Worker (*expandedSize / ctxt->maxAmpl > consumed))) {
489*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT,
490*6777b538SAndroid Build Coastguard Worker "Maximum entity amplification factor exceeded, see "
491*6777b538SAndroid Build Coastguard Worker "xmlCtxtSetMaxAmplification.\n");
492*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
493*6777b538SAndroid Build Coastguard Worker return(1);
494*6777b538SAndroid Build Coastguard Worker }
495*6777b538SAndroid Build Coastguard Worker
496*6777b538SAndroid Build Coastguard Worker return(0);
497*6777b538SAndroid Build Coastguard Worker }
498*6777b538SAndroid Build Coastguard Worker
499*6777b538SAndroid Build Coastguard Worker /************************************************************************
500*6777b538SAndroid Build Coastguard Worker * *
501*6777b538SAndroid Build Coastguard Worker * Library wide options *
502*6777b538SAndroid Build Coastguard Worker * *
503*6777b538SAndroid Build Coastguard Worker ************************************************************************/
504*6777b538SAndroid Build Coastguard Worker
505*6777b538SAndroid Build Coastguard Worker /**
506*6777b538SAndroid Build Coastguard Worker * xmlHasFeature:
507*6777b538SAndroid Build Coastguard Worker * @feature: the feature to be examined
508*6777b538SAndroid Build Coastguard Worker *
509*6777b538SAndroid Build Coastguard Worker * Examines if the library has been compiled with a given feature.
510*6777b538SAndroid Build Coastguard Worker *
511*6777b538SAndroid Build Coastguard Worker * Returns a non-zero value if the feature exist, otherwise zero.
512*6777b538SAndroid Build Coastguard Worker * Returns zero (0) if the feature does not exist or an unknown
513*6777b538SAndroid Build Coastguard Worker * unknown feature is requested, non-zero otherwise.
514*6777b538SAndroid Build Coastguard Worker */
515*6777b538SAndroid Build Coastguard Worker int
xmlHasFeature(xmlFeature feature)516*6777b538SAndroid Build Coastguard Worker xmlHasFeature(xmlFeature feature)
517*6777b538SAndroid Build Coastguard Worker {
518*6777b538SAndroid Build Coastguard Worker switch (feature) {
519*6777b538SAndroid Build Coastguard Worker case XML_WITH_THREAD:
520*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_THREAD_ENABLED
521*6777b538SAndroid Build Coastguard Worker return(1);
522*6777b538SAndroid Build Coastguard Worker #else
523*6777b538SAndroid Build Coastguard Worker return(0);
524*6777b538SAndroid Build Coastguard Worker #endif
525*6777b538SAndroid Build Coastguard Worker case XML_WITH_TREE:
526*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_TREE_ENABLED
527*6777b538SAndroid Build Coastguard Worker return(1);
528*6777b538SAndroid Build Coastguard Worker #else
529*6777b538SAndroid Build Coastguard Worker return(0);
530*6777b538SAndroid Build Coastguard Worker #endif
531*6777b538SAndroid Build Coastguard Worker case XML_WITH_OUTPUT:
532*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
533*6777b538SAndroid Build Coastguard Worker return(1);
534*6777b538SAndroid Build Coastguard Worker #else
535*6777b538SAndroid Build Coastguard Worker return(0);
536*6777b538SAndroid Build Coastguard Worker #endif
537*6777b538SAndroid Build Coastguard Worker case XML_WITH_PUSH:
538*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_PUSH_ENABLED
539*6777b538SAndroid Build Coastguard Worker return(1);
540*6777b538SAndroid Build Coastguard Worker #else
541*6777b538SAndroid Build Coastguard Worker return(0);
542*6777b538SAndroid Build Coastguard Worker #endif
543*6777b538SAndroid Build Coastguard Worker case XML_WITH_READER:
544*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_READER_ENABLED
545*6777b538SAndroid Build Coastguard Worker return(1);
546*6777b538SAndroid Build Coastguard Worker #else
547*6777b538SAndroid Build Coastguard Worker return(0);
548*6777b538SAndroid Build Coastguard Worker #endif
549*6777b538SAndroid Build Coastguard Worker case XML_WITH_PATTERN:
550*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_PATTERN_ENABLED
551*6777b538SAndroid Build Coastguard Worker return(1);
552*6777b538SAndroid Build Coastguard Worker #else
553*6777b538SAndroid Build Coastguard Worker return(0);
554*6777b538SAndroid Build Coastguard Worker #endif
555*6777b538SAndroid Build Coastguard Worker case XML_WITH_WRITER:
556*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_WRITER_ENABLED
557*6777b538SAndroid Build Coastguard Worker return(1);
558*6777b538SAndroid Build Coastguard Worker #else
559*6777b538SAndroid Build Coastguard Worker return(0);
560*6777b538SAndroid Build Coastguard Worker #endif
561*6777b538SAndroid Build Coastguard Worker case XML_WITH_SAX1:
562*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
563*6777b538SAndroid Build Coastguard Worker return(1);
564*6777b538SAndroid Build Coastguard Worker #else
565*6777b538SAndroid Build Coastguard Worker return(0);
566*6777b538SAndroid Build Coastguard Worker #endif
567*6777b538SAndroid Build Coastguard Worker case XML_WITH_FTP:
568*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_FTP_ENABLED
569*6777b538SAndroid Build Coastguard Worker return(1);
570*6777b538SAndroid Build Coastguard Worker #else
571*6777b538SAndroid Build Coastguard Worker return(0);
572*6777b538SAndroid Build Coastguard Worker #endif
573*6777b538SAndroid Build Coastguard Worker case XML_WITH_HTTP:
574*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_HTTP_ENABLED
575*6777b538SAndroid Build Coastguard Worker return(1);
576*6777b538SAndroid Build Coastguard Worker #else
577*6777b538SAndroid Build Coastguard Worker return(0);
578*6777b538SAndroid Build Coastguard Worker #endif
579*6777b538SAndroid Build Coastguard Worker case XML_WITH_VALID:
580*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_VALID_ENABLED
581*6777b538SAndroid Build Coastguard Worker return(1);
582*6777b538SAndroid Build Coastguard Worker #else
583*6777b538SAndroid Build Coastguard Worker return(0);
584*6777b538SAndroid Build Coastguard Worker #endif
585*6777b538SAndroid Build Coastguard Worker case XML_WITH_HTML:
586*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
587*6777b538SAndroid Build Coastguard Worker return(1);
588*6777b538SAndroid Build Coastguard Worker #else
589*6777b538SAndroid Build Coastguard Worker return(0);
590*6777b538SAndroid Build Coastguard Worker #endif
591*6777b538SAndroid Build Coastguard Worker case XML_WITH_LEGACY:
592*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_LEGACY_ENABLED
593*6777b538SAndroid Build Coastguard Worker return(1);
594*6777b538SAndroid Build Coastguard Worker #else
595*6777b538SAndroid Build Coastguard Worker return(0);
596*6777b538SAndroid Build Coastguard Worker #endif
597*6777b538SAndroid Build Coastguard Worker case XML_WITH_C14N:
598*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_C14N_ENABLED
599*6777b538SAndroid Build Coastguard Worker return(1);
600*6777b538SAndroid Build Coastguard Worker #else
601*6777b538SAndroid Build Coastguard Worker return(0);
602*6777b538SAndroid Build Coastguard Worker #endif
603*6777b538SAndroid Build Coastguard Worker case XML_WITH_CATALOG:
604*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
605*6777b538SAndroid Build Coastguard Worker return(1);
606*6777b538SAndroid Build Coastguard Worker #else
607*6777b538SAndroid Build Coastguard Worker return(0);
608*6777b538SAndroid Build Coastguard Worker #endif
609*6777b538SAndroid Build Coastguard Worker case XML_WITH_XPATH:
610*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_XPATH_ENABLED
611*6777b538SAndroid Build Coastguard Worker return(1);
612*6777b538SAndroid Build Coastguard Worker #else
613*6777b538SAndroid Build Coastguard Worker return(0);
614*6777b538SAndroid Build Coastguard Worker #endif
615*6777b538SAndroid Build Coastguard Worker case XML_WITH_XPTR:
616*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_XPTR_ENABLED
617*6777b538SAndroid Build Coastguard Worker return(1);
618*6777b538SAndroid Build Coastguard Worker #else
619*6777b538SAndroid Build Coastguard Worker return(0);
620*6777b538SAndroid Build Coastguard Worker #endif
621*6777b538SAndroid Build Coastguard Worker case XML_WITH_XINCLUDE:
622*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_XINCLUDE_ENABLED
623*6777b538SAndroid Build Coastguard Worker return(1);
624*6777b538SAndroid Build Coastguard Worker #else
625*6777b538SAndroid Build Coastguard Worker return(0);
626*6777b538SAndroid Build Coastguard Worker #endif
627*6777b538SAndroid Build Coastguard Worker case XML_WITH_ICONV:
628*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_ICONV_ENABLED
629*6777b538SAndroid Build Coastguard Worker return(1);
630*6777b538SAndroid Build Coastguard Worker #else
631*6777b538SAndroid Build Coastguard Worker return(0);
632*6777b538SAndroid Build Coastguard Worker #endif
633*6777b538SAndroid Build Coastguard Worker case XML_WITH_ISO8859X:
634*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_ISO8859X_ENABLED
635*6777b538SAndroid Build Coastguard Worker return(1);
636*6777b538SAndroid Build Coastguard Worker #else
637*6777b538SAndroid Build Coastguard Worker return(0);
638*6777b538SAndroid Build Coastguard Worker #endif
639*6777b538SAndroid Build Coastguard Worker case XML_WITH_UNICODE:
640*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_UNICODE_ENABLED
641*6777b538SAndroid Build Coastguard Worker return(1);
642*6777b538SAndroid Build Coastguard Worker #else
643*6777b538SAndroid Build Coastguard Worker return(0);
644*6777b538SAndroid Build Coastguard Worker #endif
645*6777b538SAndroid Build Coastguard Worker case XML_WITH_REGEXP:
646*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_REGEXP_ENABLED
647*6777b538SAndroid Build Coastguard Worker return(1);
648*6777b538SAndroid Build Coastguard Worker #else
649*6777b538SAndroid Build Coastguard Worker return(0);
650*6777b538SAndroid Build Coastguard Worker #endif
651*6777b538SAndroid Build Coastguard Worker case XML_WITH_AUTOMATA:
652*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_AUTOMATA_ENABLED
653*6777b538SAndroid Build Coastguard Worker return(1);
654*6777b538SAndroid Build Coastguard Worker #else
655*6777b538SAndroid Build Coastguard Worker return(0);
656*6777b538SAndroid Build Coastguard Worker #endif
657*6777b538SAndroid Build Coastguard Worker case XML_WITH_EXPR:
658*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_EXPR_ENABLED
659*6777b538SAndroid Build Coastguard Worker return(1);
660*6777b538SAndroid Build Coastguard Worker #else
661*6777b538SAndroid Build Coastguard Worker return(0);
662*6777b538SAndroid Build Coastguard Worker #endif
663*6777b538SAndroid Build Coastguard Worker case XML_WITH_SCHEMAS:
664*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SCHEMAS_ENABLED
665*6777b538SAndroid Build Coastguard Worker return(1);
666*6777b538SAndroid Build Coastguard Worker #else
667*6777b538SAndroid Build Coastguard Worker return(0);
668*6777b538SAndroid Build Coastguard Worker #endif
669*6777b538SAndroid Build Coastguard Worker case XML_WITH_SCHEMATRON:
670*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SCHEMATRON_ENABLED
671*6777b538SAndroid Build Coastguard Worker return(1);
672*6777b538SAndroid Build Coastguard Worker #else
673*6777b538SAndroid Build Coastguard Worker return(0);
674*6777b538SAndroid Build Coastguard Worker #endif
675*6777b538SAndroid Build Coastguard Worker case XML_WITH_MODULES:
676*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_MODULES_ENABLED
677*6777b538SAndroid Build Coastguard Worker return(1);
678*6777b538SAndroid Build Coastguard Worker #else
679*6777b538SAndroid Build Coastguard Worker return(0);
680*6777b538SAndroid Build Coastguard Worker #endif
681*6777b538SAndroid Build Coastguard Worker case XML_WITH_DEBUG:
682*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_DEBUG_ENABLED
683*6777b538SAndroid Build Coastguard Worker return(1);
684*6777b538SAndroid Build Coastguard Worker #else
685*6777b538SAndroid Build Coastguard Worker return(0);
686*6777b538SAndroid Build Coastguard Worker #endif
687*6777b538SAndroid Build Coastguard Worker case XML_WITH_DEBUG_MEM:
688*6777b538SAndroid Build Coastguard Worker #ifdef DEBUG_MEMORY_LOCATION
689*6777b538SAndroid Build Coastguard Worker return(1);
690*6777b538SAndroid Build Coastguard Worker #else
691*6777b538SAndroid Build Coastguard Worker return(0);
692*6777b538SAndroid Build Coastguard Worker #endif
693*6777b538SAndroid Build Coastguard Worker case XML_WITH_ZLIB:
694*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_ZLIB_ENABLED
695*6777b538SAndroid Build Coastguard Worker return(1);
696*6777b538SAndroid Build Coastguard Worker #else
697*6777b538SAndroid Build Coastguard Worker return(0);
698*6777b538SAndroid Build Coastguard Worker #endif
699*6777b538SAndroid Build Coastguard Worker case XML_WITH_LZMA:
700*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_LZMA_ENABLED
701*6777b538SAndroid Build Coastguard Worker return(1);
702*6777b538SAndroid Build Coastguard Worker #else
703*6777b538SAndroid Build Coastguard Worker return(0);
704*6777b538SAndroid Build Coastguard Worker #endif
705*6777b538SAndroid Build Coastguard Worker case XML_WITH_ICU:
706*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_ICU_ENABLED
707*6777b538SAndroid Build Coastguard Worker return(1);
708*6777b538SAndroid Build Coastguard Worker #else
709*6777b538SAndroid Build Coastguard Worker return(0);
710*6777b538SAndroid Build Coastguard Worker #endif
711*6777b538SAndroid Build Coastguard Worker default:
712*6777b538SAndroid Build Coastguard Worker break;
713*6777b538SAndroid Build Coastguard Worker }
714*6777b538SAndroid Build Coastguard Worker return(0);
715*6777b538SAndroid Build Coastguard Worker }
716*6777b538SAndroid Build Coastguard Worker
717*6777b538SAndroid Build Coastguard Worker /************************************************************************
718*6777b538SAndroid Build Coastguard Worker * *
719*6777b538SAndroid Build Coastguard Worker * Simple string buffer *
720*6777b538SAndroid Build Coastguard Worker * *
721*6777b538SAndroid Build Coastguard Worker ************************************************************************/
722*6777b538SAndroid Build Coastguard Worker
723*6777b538SAndroid Build Coastguard Worker typedef struct {
724*6777b538SAndroid Build Coastguard Worker xmlChar *mem;
725*6777b538SAndroid Build Coastguard Worker unsigned size;
726*6777b538SAndroid Build Coastguard Worker unsigned cap; /* size < cap */
727*6777b538SAndroid Build Coastguard Worker unsigned max; /* size <= max */
728*6777b538SAndroid Build Coastguard Worker xmlParserErrors code;
729*6777b538SAndroid Build Coastguard Worker } xmlSBuf;
730*6777b538SAndroid Build Coastguard Worker
731*6777b538SAndroid Build Coastguard Worker static void
xmlSBufInit(xmlSBuf * buf,unsigned max)732*6777b538SAndroid Build Coastguard Worker xmlSBufInit(xmlSBuf *buf, unsigned max) {
733*6777b538SAndroid Build Coastguard Worker buf->mem = NULL;
734*6777b538SAndroid Build Coastguard Worker buf->size = 0;
735*6777b538SAndroid Build Coastguard Worker buf->cap = 0;
736*6777b538SAndroid Build Coastguard Worker buf->max = max;
737*6777b538SAndroid Build Coastguard Worker buf->code = XML_ERR_OK;
738*6777b538SAndroid Build Coastguard Worker }
739*6777b538SAndroid Build Coastguard Worker
740*6777b538SAndroid Build Coastguard Worker static int
xmlSBufGrow(xmlSBuf * buf,unsigned len)741*6777b538SAndroid Build Coastguard Worker xmlSBufGrow(xmlSBuf *buf, unsigned len) {
742*6777b538SAndroid Build Coastguard Worker xmlChar *mem;
743*6777b538SAndroid Build Coastguard Worker unsigned cap;
744*6777b538SAndroid Build Coastguard Worker
745*6777b538SAndroid Build Coastguard Worker if (len >= UINT_MAX / 2 - buf->size) {
746*6777b538SAndroid Build Coastguard Worker buf->code = XML_ERR_RESOURCE_LIMIT;
747*6777b538SAndroid Build Coastguard Worker return(-1);
748*6777b538SAndroid Build Coastguard Worker }
749*6777b538SAndroid Build Coastguard Worker
750*6777b538SAndroid Build Coastguard Worker cap = (buf->size + len) * 2;
751*6777b538SAndroid Build Coastguard Worker if (cap < 240)
752*6777b538SAndroid Build Coastguard Worker cap = 240;
753*6777b538SAndroid Build Coastguard Worker
754*6777b538SAndroid Build Coastguard Worker mem = xmlRealloc(buf->mem, cap);
755*6777b538SAndroid Build Coastguard Worker if (mem == NULL) {
756*6777b538SAndroid Build Coastguard Worker buf->code = XML_ERR_NO_MEMORY;
757*6777b538SAndroid Build Coastguard Worker return(-1);
758*6777b538SAndroid Build Coastguard Worker }
759*6777b538SAndroid Build Coastguard Worker
760*6777b538SAndroid Build Coastguard Worker buf->mem = mem;
761*6777b538SAndroid Build Coastguard Worker buf->cap = cap;
762*6777b538SAndroid Build Coastguard Worker
763*6777b538SAndroid Build Coastguard Worker return(0);
764*6777b538SAndroid Build Coastguard Worker }
765*6777b538SAndroid Build Coastguard Worker
766*6777b538SAndroid Build Coastguard Worker static void
xmlSBufAddString(xmlSBuf * buf,const xmlChar * str,unsigned len)767*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(xmlSBuf *buf, const xmlChar *str, unsigned len) {
768*6777b538SAndroid Build Coastguard Worker if (buf->max - buf->size < len) {
769*6777b538SAndroid Build Coastguard Worker buf->code = XML_ERR_RESOURCE_LIMIT;
770*6777b538SAndroid Build Coastguard Worker return;
771*6777b538SAndroid Build Coastguard Worker }
772*6777b538SAndroid Build Coastguard Worker
773*6777b538SAndroid Build Coastguard Worker if (buf->cap - buf->size <= len) {
774*6777b538SAndroid Build Coastguard Worker if (xmlSBufGrow(buf, len) < 0)
775*6777b538SAndroid Build Coastguard Worker return;
776*6777b538SAndroid Build Coastguard Worker }
777*6777b538SAndroid Build Coastguard Worker
778*6777b538SAndroid Build Coastguard Worker if (len > 0)
779*6777b538SAndroid Build Coastguard Worker memcpy(buf->mem + buf->size, str, len);
780*6777b538SAndroid Build Coastguard Worker buf->size += len;
781*6777b538SAndroid Build Coastguard Worker }
782*6777b538SAndroid Build Coastguard Worker
783*6777b538SAndroid Build Coastguard Worker static void
xmlSBufAddCString(xmlSBuf * buf,const char * str,unsigned len)784*6777b538SAndroid Build Coastguard Worker xmlSBufAddCString(xmlSBuf *buf, const char *str, unsigned len) {
785*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, (const xmlChar *) str, len);
786*6777b538SAndroid Build Coastguard Worker }
787*6777b538SAndroid Build Coastguard Worker
788*6777b538SAndroid Build Coastguard Worker static void
xmlSBufAddChar(xmlSBuf * buf,int c)789*6777b538SAndroid Build Coastguard Worker xmlSBufAddChar(xmlSBuf *buf, int c) {
790*6777b538SAndroid Build Coastguard Worker xmlChar *end;
791*6777b538SAndroid Build Coastguard Worker
792*6777b538SAndroid Build Coastguard Worker if (buf->max - buf->size < 4) {
793*6777b538SAndroid Build Coastguard Worker buf->code = XML_ERR_RESOURCE_LIMIT;
794*6777b538SAndroid Build Coastguard Worker return;
795*6777b538SAndroid Build Coastguard Worker }
796*6777b538SAndroid Build Coastguard Worker
797*6777b538SAndroid Build Coastguard Worker if (buf->cap - buf->size <= 4) {
798*6777b538SAndroid Build Coastguard Worker if (xmlSBufGrow(buf, 4) < 0)
799*6777b538SAndroid Build Coastguard Worker return;
800*6777b538SAndroid Build Coastguard Worker }
801*6777b538SAndroid Build Coastguard Worker
802*6777b538SAndroid Build Coastguard Worker end = buf->mem + buf->size;
803*6777b538SAndroid Build Coastguard Worker
804*6777b538SAndroid Build Coastguard Worker if (c < 0x80) {
805*6777b538SAndroid Build Coastguard Worker *end = (xmlChar) c;
806*6777b538SAndroid Build Coastguard Worker buf->size += 1;
807*6777b538SAndroid Build Coastguard Worker } else {
808*6777b538SAndroid Build Coastguard Worker buf->size += xmlCopyCharMultiByte(end, c);
809*6777b538SAndroid Build Coastguard Worker }
810*6777b538SAndroid Build Coastguard Worker }
811*6777b538SAndroid Build Coastguard Worker
812*6777b538SAndroid Build Coastguard Worker static void
xmlSBufAddReplChar(xmlSBuf * buf)813*6777b538SAndroid Build Coastguard Worker xmlSBufAddReplChar(xmlSBuf *buf) {
814*6777b538SAndroid Build Coastguard Worker xmlSBufAddCString(buf, "\xEF\xBF\xBD", 3);
815*6777b538SAndroid Build Coastguard Worker }
816*6777b538SAndroid Build Coastguard Worker
817*6777b538SAndroid Build Coastguard Worker static void
xmlSBufReportError(xmlSBuf * buf,xmlParserCtxtPtr ctxt,const char * errMsg)818*6777b538SAndroid Build Coastguard Worker xmlSBufReportError(xmlSBuf *buf, xmlParserCtxtPtr ctxt, const char *errMsg) {
819*6777b538SAndroid Build Coastguard Worker if (buf->code == XML_ERR_NO_MEMORY)
820*6777b538SAndroid Build Coastguard Worker xmlCtxtErrMemory(ctxt);
821*6777b538SAndroid Build Coastguard Worker else
822*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, buf->code, errMsg);
823*6777b538SAndroid Build Coastguard Worker }
824*6777b538SAndroid Build Coastguard Worker
825*6777b538SAndroid Build Coastguard Worker static xmlChar *
xmlSBufFinish(xmlSBuf * buf,int * sizeOut,xmlParserCtxtPtr ctxt,const char * errMsg)826*6777b538SAndroid Build Coastguard Worker xmlSBufFinish(xmlSBuf *buf, int *sizeOut, xmlParserCtxtPtr ctxt,
827*6777b538SAndroid Build Coastguard Worker const char *errMsg) {
828*6777b538SAndroid Build Coastguard Worker if (buf->mem == NULL) {
829*6777b538SAndroid Build Coastguard Worker buf->mem = xmlMalloc(1);
830*6777b538SAndroid Build Coastguard Worker if (buf->mem == NULL) {
831*6777b538SAndroid Build Coastguard Worker buf->code = XML_ERR_NO_MEMORY;
832*6777b538SAndroid Build Coastguard Worker } else {
833*6777b538SAndroid Build Coastguard Worker buf->mem[0] = 0;
834*6777b538SAndroid Build Coastguard Worker }
835*6777b538SAndroid Build Coastguard Worker } else {
836*6777b538SAndroid Build Coastguard Worker buf->mem[buf->size] = 0;
837*6777b538SAndroid Build Coastguard Worker }
838*6777b538SAndroid Build Coastguard Worker
839*6777b538SAndroid Build Coastguard Worker if (buf->code == XML_ERR_OK) {
840*6777b538SAndroid Build Coastguard Worker if (sizeOut != NULL)
841*6777b538SAndroid Build Coastguard Worker *sizeOut = buf->size;
842*6777b538SAndroid Build Coastguard Worker return(buf->mem);
843*6777b538SAndroid Build Coastguard Worker }
844*6777b538SAndroid Build Coastguard Worker
845*6777b538SAndroid Build Coastguard Worker xmlSBufReportError(buf, ctxt, errMsg);
846*6777b538SAndroid Build Coastguard Worker
847*6777b538SAndroid Build Coastguard Worker xmlFree(buf->mem);
848*6777b538SAndroid Build Coastguard Worker
849*6777b538SAndroid Build Coastguard Worker if (sizeOut != NULL)
850*6777b538SAndroid Build Coastguard Worker *sizeOut = 0;
851*6777b538SAndroid Build Coastguard Worker return(NULL);
852*6777b538SAndroid Build Coastguard Worker }
853*6777b538SAndroid Build Coastguard Worker
854*6777b538SAndroid Build Coastguard Worker static void
xmlSBufCleanup(xmlSBuf * buf,xmlParserCtxtPtr ctxt,const char * errMsg)855*6777b538SAndroid Build Coastguard Worker xmlSBufCleanup(xmlSBuf *buf, xmlParserCtxtPtr ctxt, const char *errMsg) {
856*6777b538SAndroid Build Coastguard Worker if (buf->code != XML_ERR_OK)
857*6777b538SAndroid Build Coastguard Worker xmlSBufReportError(buf, ctxt, errMsg);
858*6777b538SAndroid Build Coastguard Worker
859*6777b538SAndroid Build Coastguard Worker xmlFree(buf->mem);
860*6777b538SAndroid Build Coastguard Worker }
861*6777b538SAndroid Build Coastguard Worker
862*6777b538SAndroid Build Coastguard Worker static int
xmlUTF8MultibyteLen(xmlParserCtxtPtr ctxt,const xmlChar * str,const char * errMsg)863*6777b538SAndroid Build Coastguard Worker xmlUTF8MultibyteLen(xmlParserCtxtPtr ctxt, const xmlChar *str,
864*6777b538SAndroid Build Coastguard Worker const char *errMsg) {
865*6777b538SAndroid Build Coastguard Worker int c = str[0];
866*6777b538SAndroid Build Coastguard Worker int c1 = str[1];
867*6777b538SAndroid Build Coastguard Worker
868*6777b538SAndroid Build Coastguard Worker if ((c1 & 0xC0) != 0x80)
869*6777b538SAndroid Build Coastguard Worker goto encoding_error;
870*6777b538SAndroid Build Coastguard Worker
871*6777b538SAndroid Build Coastguard Worker if (c < 0xE0) {
872*6777b538SAndroid Build Coastguard Worker /* 2-byte sequence */
873*6777b538SAndroid Build Coastguard Worker if (c < 0xC2)
874*6777b538SAndroid Build Coastguard Worker goto encoding_error;
875*6777b538SAndroid Build Coastguard Worker
876*6777b538SAndroid Build Coastguard Worker return(2);
877*6777b538SAndroid Build Coastguard Worker } else {
878*6777b538SAndroid Build Coastguard Worker int c2 = str[2];
879*6777b538SAndroid Build Coastguard Worker
880*6777b538SAndroid Build Coastguard Worker if ((c2 & 0xC0) != 0x80)
881*6777b538SAndroid Build Coastguard Worker goto encoding_error;
882*6777b538SAndroid Build Coastguard Worker
883*6777b538SAndroid Build Coastguard Worker if (c < 0xF0) {
884*6777b538SAndroid Build Coastguard Worker /* 3-byte sequence */
885*6777b538SAndroid Build Coastguard Worker if (c == 0xE0) {
886*6777b538SAndroid Build Coastguard Worker /* overlong */
887*6777b538SAndroid Build Coastguard Worker if (c1 < 0xA0)
888*6777b538SAndroid Build Coastguard Worker goto encoding_error;
889*6777b538SAndroid Build Coastguard Worker } else if (c == 0xED) {
890*6777b538SAndroid Build Coastguard Worker /* surrogate */
891*6777b538SAndroid Build Coastguard Worker if (c1 >= 0xA0)
892*6777b538SAndroid Build Coastguard Worker goto encoding_error;
893*6777b538SAndroid Build Coastguard Worker } else if (c == 0xEF) {
894*6777b538SAndroid Build Coastguard Worker /* U+FFFE and U+FFFF are invalid Chars */
895*6777b538SAndroid Build Coastguard Worker if ((c1 == 0xBF) && (c2 >= 0xBE))
896*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR, errMsg);
897*6777b538SAndroid Build Coastguard Worker }
898*6777b538SAndroid Build Coastguard Worker
899*6777b538SAndroid Build Coastguard Worker return(3);
900*6777b538SAndroid Build Coastguard Worker } else {
901*6777b538SAndroid Build Coastguard Worker /* 4-byte sequence */
902*6777b538SAndroid Build Coastguard Worker if ((str[3] & 0xC0) != 0x80)
903*6777b538SAndroid Build Coastguard Worker goto encoding_error;
904*6777b538SAndroid Build Coastguard Worker if (c == 0xF0) {
905*6777b538SAndroid Build Coastguard Worker /* overlong */
906*6777b538SAndroid Build Coastguard Worker if (c1 < 0x90)
907*6777b538SAndroid Build Coastguard Worker goto encoding_error;
908*6777b538SAndroid Build Coastguard Worker } else if (c >= 0xF4) {
909*6777b538SAndroid Build Coastguard Worker /* greater than 0x10FFFF */
910*6777b538SAndroid Build Coastguard Worker if ((c > 0xF4) || (c1 >= 0x90))
911*6777b538SAndroid Build Coastguard Worker goto encoding_error;
912*6777b538SAndroid Build Coastguard Worker }
913*6777b538SAndroid Build Coastguard Worker
914*6777b538SAndroid Build Coastguard Worker return(4);
915*6777b538SAndroid Build Coastguard Worker }
916*6777b538SAndroid Build Coastguard Worker }
917*6777b538SAndroid Build Coastguard Worker
918*6777b538SAndroid Build Coastguard Worker encoding_error:
919*6777b538SAndroid Build Coastguard Worker /* Only report the first error */
920*6777b538SAndroid Build Coastguard Worker if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
921*6777b538SAndroid Build Coastguard Worker xmlCtxtErrIO(ctxt, XML_ERR_INVALID_ENCODING, NULL);
922*6777b538SAndroid Build Coastguard Worker ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
923*6777b538SAndroid Build Coastguard Worker }
924*6777b538SAndroid Build Coastguard Worker
925*6777b538SAndroid Build Coastguard Worker return(0);
926*6777b538SAndroid Build Coastguard Worker }
927*6777b538SAndroid Build Coastguard Worker
928*6777b538SAndroid Build Coastguard Worker /************************************************************************
929*6777b538SAndroid Build Coastguard Worker * *
930*6777b538SAndroid Build Coastguard Worker * SAX2 defaulted attributes handling *
931*6777b538SAndroid Build Coastguard Worker * *
932*6777b538SAndroid Build Coastguard Worker ************************************************************************/
933*6777b538SAndroid Build Coastguard Worker
934*6777b538SAndroid Build Coastguard Worker /**
935*6777b538SAndroid Build Coastguard Worker * xmlCtxtInitializeLate:
936*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
937*6777b538SAndroid Build Coastguard Worker *
938*6777b538SAndroid Build Coastguard Worker * Final initialization of the parser context before starting to parse.
939*6777b538SAndroid Build Coastguard Worker *
940*6777b538SAndroid Build Coastguard Worker * This accounts for users modifying struct members of parser context
941*6777b538SAndroid Build Coastguard Worker * directly.
942*6777b538SAndroid Build Coastguard Worker */
943*6777b538SAndroid Build Coastguard Worker static void
xmlCtxtInitializeLate(xmlParserCtxtPtr ctxt)944*6777b538SAndroid Build Coastguard Worker xmlCtxtInitializeLate(xmlParserCtxtPtr ctxt) {
945*6777b538SAndroid Build Coastguard Worker xmlSAXHandlerPtr sax;
946*6777b538SAndroid Build Coastguard Worker
947*6777b538SAndroid Build Coastguard Worker /* Avoid unused variable warning if features are disabled. */
948*6777b538SAndroid Build Coastguard Worker (void) sax;
949*6777b538SAndroid Build Coastguard Worker
950*6777b538SAndroid Build Coastguard Worker /*
951*6777b538SAndroid Build Coastguard Worker * Changing the SAX struct directly is still widespread practice
952*6777b538SAndroid Build Coastguard Worker * in internal and external code.
953*6777b538SAndroid Build Coastguard Worker */
954*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL) return;
955*6777b538SAndroid Build Coastguard Worker sax = ctxt->sax;
956*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
957*6777b538SAndroid Build Coastguard Worker /*
958*6777b538SAndroid Build Coastguard Worker * Only enable SAX2 if there SAX2 element handlers, except when there
959*6777b538SAndroid Build Coastguard Worker * are no element handlers at all.
960*6777b538SAndroid Build Coastguard Worker */
961*6777b538SAndroid Build Coastguard Worker if (((ctxt->options & XML_PARSE_SAX1) == 0) &&
962*6777b538SAndroid Build Coastguard Worker (sax) &&
963*6777b538SAndroid Build Coastguard Worker (sax->initialized == XML_SAX2_MAGIC) &&
964*6777b538SAndroid Build Coastguard Worker ((sax->startElementNs != NULL) ||
965*6777b538SAndroid Build Coastguard Worker (sax->endElementNs != NULL) ||
966*6777b538SAndroid Build Coastguard Worker ((sax->startElement == NULL) && (sax->endElement == NULL))))
967*6777b538SAndroid Build Coastguard Worker ctxt->sax2 = 1;
968*6777b538SAndroid Build Coastguard Worker #else
969*6777b538SAndroid Build Coastguard Worker ctxt->sax2 = 1;
970*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
971*6777b538SAndroid Build Coastguard Worker
972*6777b538SAndroid Build Coastguard Worker /*
973*6777b538SAndroid Build Coastguard Worker * Some users replace the dictionary directly in the context struct.
974*6777b538SAndroid Build Coastguard Worker * We really need an API function to do that cleanly.
975*6777b538SAndroid Build Coastguard Worker */
976*6777b538SAndroid Build Coastguard Worker ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
977*6777b538SAndroid Build Coastguard Worker ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
978*6777b538SAndroid Build Coastguard Worker ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
979*6777b538SAndroid Build Coastguard Worker if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
980*6777b538SAndroid Build Coastguard Worker (ctxt->str_xml_ns == NULL)) {
981*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
982*6777b538SAndroid Build Coastguard Worker }
983*6777b538SAndroid Build Coastguard Worker }
984*6777b538SAndroid Build Coastguard Worker
985*6777b538SAndroid Build Coastguard Worker typedef struct {
986*6777b538SAndroid Build Coastguard Worker xmlHashedString prefix;
987*6777b538SAndroid Build Coastguard Worker xmlHashedString name;
988*6777b538SAndroid Build Coastguard Worker xmlHashedString value;
989*6777b538SAndroid Build Coastguard Worker const xmlChar *valueEnd;
990*6777b538SAndroid Build Coastguard Worker int external;
991*6777b538SAndroid Build Coastguard Worker int expandedSize;
992*6777b538SAndroid Build Coastguard Worker } xmlDefAttr;
993*6777b538SAndroid Build Coastguard Worker
994*6777b538SAndroid Build Coastguard Worker typedef struct _xmlDefAttrs xmlDefAttrs;
995*6777b538SAndroid Build Coastguard Worker typedef xmlDefAttrs *xmlDefAttrsPtr;
996*6777b538SAndroid Build Coastguard Worker struct _xmlDefAttrs {
997*6777b538SAndroid Build Coastguard Worker int nbAttrs; /* number of defaulted attributes on that element */
998*6777b538SAndroid Build Coastguard Worker int maxAttrs; /* the size of the array */
999*6777b538SAndroid Build Coastguard Worker #if __STDC_VERSION__ >= 199901L
1000*6777b538SAndroid Build Coastguard Worker /* Using a C99 flexible array member avoids UBSan errors. */
1001*6777b538SAndroid Build Coastguard Worker xmlDefAttr attrs[]; /* array of localname/prefix/values/external */
1002*6777b538SAndroid Build Coastguard Worker #else
1003*6777b538SAndroid Build Coastguard Worker xmlDefAttr attrs[1];
1004*6777b538SAndroid Build Coastguard Worker #endif
1005*6777b538SAndroid Build Coastguard Worker };
1006*6777b538SAndroid Build Coastguard Worker
1007*6777b538SAndroid Build Coastguard Worker /**
1008*6777b538SAndroid Build Coastguard Worker * xmlAttrNormalizeSpace:
1009*6777b538SAndroid Build Coastguard Worker * @src: the source string
1010*6777b538SAndroid Build Coastguard Worker * @dst: the target string
1011*6777b538SAndroid Build Coastguard Worker *
1012*6777b538SAndroid Build Coastguard Worker * Normalize the space in non CDATA attribute values:
1013*6777b538SAndroid Build Coastguard Worker * If the attribute type is not CDATA, then the XML processor MUST further
1014*6777b538SAndroid Build Coastguard Worker * process the normalized attribute value by discarding any leading and
1015*6777b538SAndroid Build Coastguard Worker * trailing space (#x20) characters, and by replacing sequences of space
1016*6777b538SAndroid Build Coastguard Worker * (#x20) characters by a single space (#x20) character.
1017*6777b538SAndroid Build Coastguard Worker * Note that the size of dst need to be at least src, and if one doesn't need
1018*6777b538SAndroid Build Coastguard Worker * to preserve dst (and it doesn't come from a dictionary or read-only) then
1019*6777b538SAndroid Build Coastguard Worker * passing src as dst is just fine.
1020*6777b538SAndroid Build Coastguard Worker *
1021*6777b538SAndroid Build Coastguard Worker * Returns a pointer to the normalized value (dst) or NULL if no conversion
1022*6777b538SAndroid Build Coastguard Worker * is needed.
1023*6777b538SAndroid Build Coastguard Worker */
1024*6777b538SAndroid Build Coastguard Worker static xmlChar *
xmlAttrNormalizeSpace(const xmlChar * src,xmlChar * dst)1025*6777b538SAndroid Build Coastguard Worker xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
1026*6777b538SAndroid Build Coastguard Worker {
1027*6777b538SAndroid Build Coastguard Worker if ((src == NULL) || (dst == NULL))
1028*6777b538SAndroid Build Coastguard Worker return(NULL);
1029*6777b538SAndroid Build Coastguard Worker
1030*6777b538SAndroid Build Coastguard Worker while (*src == 0x20) src++;
1031*6777b538SAndroid Build Coastguard Worker while (*src != 0) {
1032*6777b538SAndroid Build Coastguard Worker if (*src == 0x20) {
1033*6777b538SAndroid Build Coastguard Worker while (*src == 0x20) src++;
1034*6777b538SAndroid Build Coastguard Worker if (*src != 0)
1035*6777b538SAndroid Build Coastguard Worker *dst++ = 0x20;
1036*6777b538SAndroid Build Coastguard Worker } else {
1037*6777b538SAndroid Build Coastguard Worker *dst++ = *src++;
1038*6777b538SAndroid Build Coastguard Worker }
1039*6777b538SAndroid Build Coastguard Worker }
1040*6777b538SAndroid Build Coastguard Worker *dst = 0;
1041*6777b538SAndroid Build Coastguard Worker if (dst == src)
1042*6777b538SAndroid Build Coastguard Worker return(NULL);
1043*6777b538SAndroid Build Coastguard Worker return(dst);
1044*6777b538SAndroid Build Coastguard Worker }
1045*6777b538SAndroid Build Coastguard Worker
1046*6777b538SAndroid Build Coastguard Worker /**
1047*6777b538SAndroid Build Coastguard Worker * xmlAddDefAttrs:
1048*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
1049*6777b538SAndroid Build Coastguard Worker * @fullname: the element fullname
1050*6777b538SAndroid Build Coastguard Worker * @fullattr: the attribute fullname
1051*6777b538SAndroid Build Coastguard Worker * @value: the attribute value
1052*6777b538SAndroid Build Coastguard Worker *
1053*6777b538SAndroid Build Coastguard Worker * Add a defaulted attribute for an element
1054*6777b538SAndroid Build Coastguard Worker */
1055*6777b538SAndroid Build Coastguard Worker static void
xmlAddDefAttrs(xmlParserCtxtPtr ctxt,const xmlChar * fullname,const xmlChar * fullattr,const xmlChar * value)1056*6777b538SAndroid Build Coastguard Worker xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
1057*6777b538SAndroid Build Coastguard Worker const xmlChar *fullname,
1058*6777b538SAndroid Build Coastguard Worker const xmlChar *fullattr,
1059*6777b538SAndroid Build Coastguard Worker const xmlChar *value) {
1060*6777b538SAndroid Build Coastguard Worker xmlDefAttrsPtr defaults;
1061*6777b538SAndroid Build Coastguard Worker xmlDefAttr *attr;
1062*6777b538SAndroid Build Coastguard Worker int len, expandedSize;
1063*6777b538SAndroid Build Coastguard Worker xmlHashedString name;
1064*6777b538SAndroid Build Coastguard Worker xmlHashedString prefix;
1065*6777b538SAndroid Build Coastguard Worker xmlHashedString hvalue;
1066*6777b538SAndroid Build Coastguard Worker const xmlChar *localname;
1067*6777b538SAndroid Build Coastguard Worker
1068*6777b538SAndroid Build Coastguard Worker /*
1069*6777b538SAndroid Build Coastguard Worker * Allows to detect attribute redefinitions
1070*6777b538SAndroid Build Coastguard Worker */
1071*6777b538SAndroid Build Coastguard Worker if (ctxt->attsSpecial != NULL) {
1072*6777b538SAndroid Build Coastguard Worker if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1073*6777b538SAndroid Build Coastguard Worker return;
1074*6777b538SAndroid Build Coastguard Worker }
1075*6777b538SAndroid Build Coastguard Worker
1076*6777b538SAndroid Build Coastguard Worker if (ctxt->attsDefault == NULL) {
1077*6777b538SAndroid Build Coastguard Worker ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
1078*6777b538SAndroid Build Coastguard Worker if (ctxt->attsDefault == NULL)
1079*6777b538SAndroid Build Coastguard Worker goto mem_error;
1080*6777b538SAndroid Build Coastguard Worker }
1081*6777b538SAndroid Build Coastguard Worker
1082*6777b538SAndroid Build Coastguard Worker /*
1083*6777b538SAndroid Build Coastguard Worker * split the element name into prefix:localname , the string found
1084*6777b538SAndroid Build Coastguard Worker * are within the DTD and then not associated to namespace names.
1085*6777b538SAndroid Build Coastguard Worker */
1086*6777b538SAndroid Build Coastguard Worker localname = xmlSplitQName3(fullname, &len);
1087*6777b538SAndroid Build Coastguard Worker if (localname == NULL) {
1088*6777b538SAndroid Build Coastguard Worker name = xmlDictLookupHashed(ctxt->dict, fullname, -1);
1089*6777b538SAndroid Build Coastguard Worker prefix.name = NULL;
1090*6777b538SAndroid Build Coastguard Worker } else {
1091*6777b538SAndroid Build Coastguard Worker name = xmlDictLookupHashed(ctxt->dict, localname, -1);
1092*6777b538SAndroid Build Coastguard Worker prefix = xmlDictLookupHashed(ctxt->dict, fullname, len);
1093*6777b538SAndroid Build Coastguard Worker if (prefix.name == NULL)
1094*6777b538SAndroid Build Coastguard Worker goto mem_error;
1095*6777b538SAndroid Build Coastguard Worker }
1096*6777b538SAndroid Build Coastguard Worker if (name.name == NULL)
1097*6777b538SAndroid Build Coastguard Worker goto mem_error;
1098*6777b538SAndroid Build Coastguard Worker
1099*6777b538SAndroid Build Coastguard Worker /*
1100*6777b538SAndroid Build Coastguard Worker * make sure there is some storage
1101*6777b538SAndroid Build Coastguard Worker */
1102*6777b538SAndroid Build Coastguard Worker defaults = xmlHashLookup2(ctxt->attsDefault, name.name, prefix.name);
1103*6777b538SAndroid Build Coastguard Worker if ((defaults == NULL) ||
1104*6777b538SAndroid Build Coastguard Worker (defaults->nbAttrs >= defaults->maxAttrs)) {
1105*6777b538SAndroid Build Coastguard Worker xmlDefAttrsPtr temp;
1106*6777b538SAndroid Build Coastguard Worker int newSize;
1107*6777b538SAndroid Build Coastguard Worker
1108*6777b538SAndroid Build Coastguard Worker newSize = (defaults != NULL) ? 2 * defaults->maxAttrs : 4;
1109*6777b538SAndroid Build Coastguard Worker temp = xmlRealloc(defaults,
1110*6777b538SAndroid Build Coastguard Worker sizeof(*defaults) + newSize * sizeof(xmlDefAttr));
1111*6777b538SAndroid Build Coastguard Worker if (temp == NULL)
1112*6777b538SAndroid Build Coastguard Worker goto mem_error;
1113*6777b538SAndroid Build Coastguard Worker if (defaults == NULL)
1114*6777b538SAndroid Build Coastguard Worker temp->nbAttrs = 0;
1115*6777b538SAndroid Build Coastguard Worker temp->maxAttrs = newSize;
1116*6777b538SAndroid Build Coastguard Worker defaults = temp;
1117*6777b538SAndroid Build Coastguard Worker if (xmlHashUpdateEntry2(ctxt->attsDefault, name.name, prefix.name,
1118*6777b538SAndroid Build Coastguard Worker defaults, NULL) < 0) {
1119*6777b538SAndroid Build Coastguard Worker xmlFree(defaults);
1120*6777b538SAndroid Build Coastguard Worker goto mem_error;
1121*6777b538SAndroid Build Coastguard Worker }
1122*6777b538SAndroid Build Coastguard Worker }
1123*6777b538SAndroid Build Coastguard Worker
1124*6777b538SAndroid Build Coastguard Worker /*
1125*6777b538SAndroid Build Coastguard Worker * Split the attribute name into prefix:localname , the string found
1126*6777b538SAndroid Build Coastguard Worker * are within the DTD and hen not associated to namespace names.
1127*6777b538SAndroid Build Coastguard Worker */
1128*6777b538SAndroid Build Coastguard Worker localname = xmlSplitQName3(fullattr, &len);
1129*6777b538SAndroid Build Coastguard Worker if (localname == NULL) {
1130*6777b538SAndroid Build Coastguard Worker name = xmlDictLookupHashed(ctxt->dict, fullattr, -1);
1131*6777b538SAndroid Build Coastguard Worker prefix.name = NULL;
1132*6777b538SAndroid Build Coastguard Worker } else {
1133*6777b538SAndroid Build Coastguard Worker name = xmlDictLookupHashed(ctxt->dict, localname, -1);
1134*6777b538SAndroid Build Coastguard Worker prefix = xmlDictLookupHashed(ctxt->dict, fullattr, len);
1135*6777b538SAndroid Build Coastguard Worker if (prefix.name == NULL)
1136*6777b538SAndroid Build Coastguard Worker goto mem_error;
1137*6777b538SAndroid Build Coastguard Worker }
1138*6777b538SAndroid Build Coastguard Worker if (name.name == NULL)
1139*6777b538SAndroid Build Coastguard Worker goto mem_error;
1140*6777b538SAndroid Build Coastguard Worker
1141*6777b538SAndroid Build Coastguard Worker /* intern the string and precompute the end */
1142*6777b538SAndroid Build Coastguard Worker len = strlen((const char *) value);
1143*6777b538SAndroid Build Coastguard Worker hvalue = xmlDictLookupHashed(ctxt->dict, value, len);
1144*6777b538SAndroid Build Coastguard Worker if (hvalue.name == NULL)
1145*6777b538SAndroid Build Coastguard Worker goto mem_error;
1146*6777b538SAndroid Build Coastguard Worker
1147*6777b538SAndroid Build Coastguard Worker expandedSize = strlen((const char *) name.name);
1148*6777b538SAndroid Build Coastguard Worker if (prefix.name != NULL)
1149*6777b538SAndroid Build Coastguard Worker expandedSize += strlen((const char *) prefix.name);
1150*6777b538SAndroid Build Coastguard Worker expandedSize += len;
1151*6777b538SAndroid Build Coastguard Worker
1152*6777b538SAndroid Build Coastguard Worker attr = &defaults->attrs[defaults->nbAttrs++];
1153*6777b538SAndroid Build Coastguard Worker attr->name = name;
1154*6777b538SAndroid Build Coastguard Worker attr->prefix = prefix;
1155*6777b538SAndroid Build Coastguard Worker attr->value = hvalue;
1156*6777b538SAndroid Build Coastguard Worker attr->valueEnd = hvalue.name + len;
1157*6777b538SAndroid Build Coastguard Worker attr->external = PARSER_EXTERNAL(ctxt);
1158*6777b538SAndroid Build Coastguard Worker attr->expandedSize = expandedSize;
1159*6777b538SAndroid Build Coastguard Worker
1160*6777b538SAndroid Build Coastguard Worker return;
1161*6777b538SAndroid Build Coastguard Worker
1162*6777b538SAndroid Build Coastguard Worker mem_error:
1163*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
1164*6777b538SAndroid Build Coastguard Worker return;
1165*6777b538SAndroid Build Coastguard Worker }
1166*6777b538SAndroid Build Coastguard Worker
1167*6777b538SAndroid Build Coastguard Worker /**
1168*6777b538SAndroid Build Coastguard Worker * xmlAddSpecialAttr:
1169*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
1170*6777b538SAndroid Build Coastguard Worker * @fullname: the element fullname
1171*6777b538SAndroid Build Coastguard Worker * @fullattr: the attribute fullname
1172*6777b538SAndroid Build Coastguard Worker * @type: the attribute type
1173*6777b538SAndroid Build Coastguard Worker *
1174*6777b538SAndroid Build Coastguard Worker * Register this attribute type
1175*6777b538SAndroid Build Coastguard Worker */
1176*6777b538SAndroid Build Coastguard Worker static void
xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,const xmlChar * fullname,const xmlChar * fullattr,int type)1177*6777b538SAndroid Build Coastguard Worker xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
1178*6777b538SAndroid Build Coastguard Worker const xmlChar *fullname,
1179*6777b538SAndroid Build Coastguard Worker const xmlChar *fullattr,
1180*6777b538SAndroid Build Coastguard Worker int type)
1181*6777b538SAndroid Build Coastguard Worker {
1182*6777b538SAndroid Build Coastguard Worker if (ctxt->attsSpecial == NULL) {
1183*6777b538SAndroid Build Coastguard Worker ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
1184*6777b538SAndroid Build Coastguard Worker if (ctxt->attsSpecial == NULL)
1185*6777b538SAndroid Build Coastguard Worker goto mem_error;
1186*6777b538SAndroid Build Coastguard Worker }
1187*6777b538SAndroid Build Coastguard Worker
1188*6777b538SAndroid Build Coastguard Worker if (xmlHashAdd2(ctxt->attsSpecial, fullname, fullattr,
1189*6777b538SAndroid Build Coastguard Worker (void *) (ptrdiff_t) type) < 0)
1190*6777b538SAndroid Build Coastguard Worker goto mem_error;
1191*6777b538SAndroid Build Coastguard Worker return;
1192*6777b538SAndroid Build Coastguard Worker
1193*6777b538SAndroid Build Coastguard Worker mem_error:
1194*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
1195*6777b538SAndroid Build Coastguard Worker return;
1196*6777b538SAndroid Build Coastguard Worker }
1197*6777b538SAndroid Build Coastguard Worker
1198*6777b538SAndroid Build Coastguard Worker /**
1199*6777b538SAndroid Build Coastguard Worker * xmlCleanSpecialAttrCallback:
1200*6777b538SAndroid Build Coastguard Worker *
1201*6777b538SAndroid Build Coastguard Worker * Removes CDATA attributes from the special attribute table
1202*6777b538SAndroid Build Coastguard Worker */
1203*6777b538SAndroid Build Coastguard Worker static void
xmlCleanSpecialAttrCallback(void * payload,void * data,const xmlChar * fullname,const xmlChar * fullattr,const xmlChar * unused ATTRIBUTE_UNUSED)1204*6777b538SAndroid Build Coastguard Worker xmlCleanSpecialAttrCallback(void *payload, void *data,
1205*6777b538SAndroid Build Coastguard Worker const xmlChar *fullname, const xmlChar *fullattr,
1206*6777b538SAndroid Build Coastguard Worker const xmlChar *unused ATTRIBUTE_UNUSED) {
1207*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
1208*6777b538SAndroid Build Coastguard Worker
1209*6777b538SAndroid Build Coastguard Worker if (((ptrdiff_t) payload) == XML_ATTRIBUTE_CDATA) {
1210*6777b538SAndroid Build Coastguard Worker xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
1211*6777b538SAndroid Build Coastguard Worker }
1212*6777b538SAndroid Build Coastguard Worker }
1213*6777b538SAndroid Build Coastguard Worker
1214*6777b538SAndroid Build Coastguard Worker /**
1215*6777b538SAndroid Build Coastguard Worker * xmlCleanSpecialAttr:
1216*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
1217*6777b538SAndroid Build Coastguard Worker *
1218*6777b538SAndroid Build Coastguard Worker * Trim the list of attributes defined to remove all those of type
1219*6777b538SAndroid Build Coastguard Worker * CDATA as they are not special. This call should be done when finishing
1220*6777b538SAndroid Build Coastguard Worker * to parse the DTD and before starting to parse the document root.
1221*6777b538SAndroid Build Coastguard Worker */
1222*6777b538SAndroid Build Coastguard Worker static void
xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)1223*6777b538SAndroid Build Coastguard Worker xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
1224*6777b538SAndroid Build Coastguard Worker {
1225*6777b538SAndroid Build Coastguard Worker if (ctxt->attsSpecial == NULL)
1226*6777b538SAndroid Build Coastguard Worker return;
1227*6777b538SAndroid Build Coastguard Worker
1228*6777b538SAndroid Build Coastguard Worker xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
1229*6777b538SAndroid Build Coastguard Worker
1230*6777b538SAndroid Build Coastguard Worker if (xmlHashSize(ctxt->attsSpecial) == 0) {
1231*6777b538SAndroid Build Coastguard Worker xmlHashFree(ctxt->attsSpecial, NULL);
1232*6777b538SAndroid Build Coastguard Worker ctxt->attsSpecial = NULL;
1233*6777b538SAndroid Build Coastguard Worker }
1234*6777b538SAndroid Build Coastguard Worker return;
1235*6777b538SAndroid Build Coastguard Worker }
1236*6777b538SAndroid Build Coastguard Worker
1237*6777b538SAndroid Build Coastguard Worker /**
1238*6777b538SAndroid Build Coastguard Worker * xmlCheckLanguageID:
1239*6777b538SAndroid Build Coastguard Worker * @lang: pointer to the string value
1240*6777b538SAndroid Build Coastguard Worker *
1241*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, do not use.
1242*6777b538SAndroid Build Coastguard Worker *
1243*6777b538SAndroid Build Coastguard Worker * Checks that the value conforms to the LanguageID production:
1244*6777b538SAndroid Build Coastguard Worker *
1245*6777b538SAndroid Build Coastguard Worker * NOTE: this is somewhat deprecated, those productions were removed from
1246*6777b538SAndroid Build Coastguard Worker * the XML Second edition.
1247*6777b538SAndroid Build Coastguard Worker *
1248*6777b538SAndroid Build Coastguard Worker * [33] LanguageID ::= Langcode ('-' Subcode)*
1249*6777b538SAndroid Build Coastguard Worker * [34] Langcode ::= ISO639Code | IanaCode | UserCode
1250*6777b538SAndroid Build Coastguard Worker * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
1251*6777b538SAndroid Build Coastguard Worker * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
1252*6777b538SAndroid Build Coastguard Worker * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
1253*6777b538SAndroid Build Coastguard Worker * [38] Subcode ::= ([a-z] | [A-Z])+
1254*6777b538SAndroid Build Coastguard Worker *
1255*6777b538SAndroid Build Coastguard Worker * The current REC reference the successors of RFC 1766, currently 5646
1256*6777b538SAndroid Build Coastguard Worker *
1257*6777b538SAndroid Build Coastguard Worker * http://www.rfc-editor.org/rfc/rfc5646.txt
1258*6777b538SAndroid Build Coastguard Worker * langtag = language
1259*6777b538SAndroid Build Coastguard Worker * ["-" script]
1260*6777b538SAndroid Build Coastguard Worker * ["-" region]
1261*6777b538SAndroid Build Coastguard Worker * *("-" variant)
1262*6777b538SAndroid Build Coastguard Worker * *("-" extension)
1263*6777b538SAndroid Build Coastguard Worker * ["-" privateuse]
1264*6777b538SAndroid Build Coastguard Worker * language = 2*3ALPHA ; shortest ISO 639 code
1265*6777b538SAndroid Build Coastguard Worker * ["-" extlang] ; sometimes followed by
1266*6777b538SAndroid Build Coastguard Worker * ; extended language subtags
1267*6777b538SAndroid Build Coastguard Worker * / 4ALPHA ; or reserved for future use
1268*6777b538SAndroid Build Coastguard Worker * / 5*8ALPHA ; or registered language subtag
1269*6777b538SAndroid Build Coastguard Worker *
1270*6777b538SAndroid Build Coastguard Worker * extlang = 3ALPHA ; selected ISO 639 codes
1271*6777b538SAndroid Build Coastguard Worker * *2("-" 3ALPHA) ; permanently reserved
1272*6777b538SAndroid Build Coastguard Worker *
1273*6777b538SAndroid Build Coastguard Worker * script = 4ALPHA ; ISO 15924 code
1274*6777b538SAndroid Build Coastguard Worker *
1275*6777b538SAndroid Build Coastguard Worker * region = 2ALPHA ; ISO 3166-1 code
1276*6777b538SAndroid Build Coastguard Worker * / 3DIGIT ; UN M.49 code
1277*6777b538SAndroid Build Coastguard Worker *
1278*6777b538SAndroid Build Coastguard Worker * variant = 5*8alphanum ; registered variants
1279*6777b538SAndroid Build Coastguard Worker * / (DIGIT 3alphanum)
1280*6777b538SAndroid Build Coastguard Worker *
1281*6777b538SAndroid Build Coastguard Worker * extension = singleton 1*("-" (2*8alphanum))
1282*6777b538SAndroid Build Coastguard Worker *
1283*6777b538SAndroid Build Coastguard Worker * ; Single alphanumerics
1284*6777b538SAndroid Build Coastguard Worker * ; "x" reserved for private use
1285*6777b538SAndroid Build Coastguard Worker * singleton = DIGIT ; 0 - 9
1286*6777b538SAndroid Build Coastguard Worker * / %x41-57 ; A - W
1287*6777b538SAndroid Build Coastguard Worker * / %x59-5A ; Y - Z
1288*6777b538SAndroid Build Coastguard Worker * / %x61-77 ; a - w
1289*6777b538SAndroid Build Coastguard Worker * / %x79-7A ; y - z
1290*6777b538SAndroid Build Coastguard Worker *
1291*6777b538SAndroid Build Coastguard Worker * it sounds right to still allow Irregular i-xxx IANA and user codes too
1292*6777b538SAndroid Build Coastguard Worker * The parser below doesn't try to cope with extension or privateuse
1293*6777b538SAndroid Build Coastguard Worker * that could be added but that's not interoperable anyway
1294*6777b538SAndroid Build Coastguard Worker *
1295*6777b538SAndroid Build Coastguard Worker * Returns 1 if correct 0 otherwise
1296*6777b538SAndroid Build Coastguard Worker **/
1297*6777b538SAndroid Build Coastguard Worker int
xmlCheckLanguageID(const xmlChar * lang)1298*6777b538SAndroid Build Coastguard Worker xmlCheckLanguageID(const xmlChar * lang)
1299*6777b538SAndroid Build Coastguard Worker {
1300*6777b538SAndroid Build Coastguard Worker const xmlChar *cur = lang, *nxt;
1301*6777b538SAndroid Build Coastguard Worker
1302*6777b538SAndroid Build Coastguard Worker if (cur == NULL)
1303*6777b538SAndroid Build Coastguard Worker return (0);
1304*6777b538SAndroid Build Coastguard Worker if (((cur[0] == 'i') && (cur[1] == '-')) ||
1305*6777b538SAndroid Build Coastguard Worker ((cur[0] == 'I') && (cur[1] == '-')) ||
1306*6777b538SAndroid Build Coastguard Worker ((cur[0] == 'x') && (cur[1] == '-')) ||
1307*6777b538SAndroid Build Coastguard Worker ((cur[0] == 'X') && (cur[1] == '-'))) {
1308*6777b538SAndroid Build Coastguard Worker /*
1309*6777b538SAndroid Build Coastguard Worker * Still allow IANA code and user code which were coming
1310*6777b538SAndroid Build Coastguard Worker * from the previous version of the XML-1.0 specification
1311*6777b538SAndroid Build Coastguard Worker * it's deprecated but we should not fail
1312*6777b538SAndroid Build Coastguard Worker */
1313*6777b538SAndroid Build Coastguard Worker cur += 2;
1314*6777b538SAndroid Build Coastguard Worker while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1315*6777b538SAndroid Build Coastguard Worker ((cur[0] >= 'a') && (cur[0] <= 'z')))
1316*6777b538SAndroid Build Coastguard Worker cur++;
1317*6777b538SAndroid Build Coastguard Worker return(cur[0] == 0);
1318*6777b538SAndroid Build Coastguard Worker }
1319*6777b538SAndroid Build Coastguard Worker nxt = cur;
1320*6777b538SAndroid Build Coastguard Worker while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1321*6777b538SAndroid Build Coastguard Worker ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1322*6777b538SAndroid Build Coastguard Worker nxt++;
1323*6777b538SAndroid Build Coastguard Worker if (nxt - cur >= 4) {
1324*6777b538SAndroid Build Coastguard Worker /*
1325*6777b538SAndroid Build Coastguard Worker * Reserved
1326*6777b538SAndroid Build Coastguard Worker */
1327*6777b538SAndroid Build Coastguard Worker if ((nxt - cur > 8) || (nxt[0] != 0))
1328*6777b538SAndroid Build Coastguard Worker return(0);
1329*6777b538SAndroid Build Coastguard Worker return(1);
1330*6777b538SAndroid Build Coastguard Worker }
1331*6777b538SAndroid Build Coastguard Worker if (nxt - cur < 2)
1332*6777b538SAndroid Build Coastguard Worker return(0);
1333*6777b538SAndroid Build Coastguard Worker /* we got an ISO 639 code */
1334*6777b538SAndroid Build Coastguard Worker if (nxt[0] == 0)
1335*6777b538SAndroid Build Coastguard Worker return(1);
1336*6777b538SAndroid Build Coastguard Worker if (nxt[0] != '-')
1337*6777b538SAndroid Build Coastguard Worker return(0);
1338*6777b538SAndroid Build Coastguard Worker
1339*6777b538SAndroid Build Coastguard Worker nxt++;
1340*6777b538SAndroid Build Coastguard Worker cur = nxt;
1341*6777b538SAndroid Build Coastguard Worker /* now we can have extlang or script or region or variant */
1342*6777b538SAndroid Build Coastguard Worker if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1343*6777b538SAndroid Build Coastguard Worker goto region_m49;
1344*6777b538SAndroid Build Coastguard Worker
1345*6777b538SAndroid Build Coastguard Worker while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1346*6777b538SAndroid Build Coastguard Worker ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1347*6777b538SAndroid Build Coastguard Worker nxt++;
1348*6777b538SAndroid Build Coastguard Worker if (nxt - cur == 4)
1349*6777b538SAndroid Build Coastguard Worker goto script;
1350*6777b538SAndroid Build Coastguard Worker if (nxt - cur == 2)
1351*6777b538SAndroid Build Coastguard Worker goto region;
1352*6777b538SAndroid Build Coastguard Worker if ((nxt - cur >= 5) && (nxt - cur <= 8))
1353*6777b538SAndroid Build Coastguard Worker goto variant;
1354*6777b538SAndroid Build Coastguard Worker if (nxt - cur != 3)
1355*6777b538SAndroid Build Coastguard Worker return(0);
1356*6777b538SAndroid Build Coastguard Worker /* we parsed an extlang */
1357*6777b538SAndroid Build Coastguard Worker if (nxt[0] == 0)
1358*6777b538SAndroid Build Coastguard Worker return(1);
1359*6777b538SAndroid Build Coastguard Worker if (nxt[0] != '-')
1360*6777b538SAndroid Build Coastguard Worker return(0);
1361*6777b538SAndroid Build Coastguard Worker
1362*6777b538SAndroid Build Coastguard Worker nxt++;
1363*6777b538SAndroid Build Coastguard Worker cur = nxt;
1364*6777b538SAndroid Build Coastguard Worker /* now we can have script or region or variant */
1365*6777b538SAndroid Build Coastguard Worker if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1366*6777b538SAndroid Build Coastguard Worker goto region_m49;
1367*6777b538SAndroid Build Coastguard Worker
1368*6777b538SAndroid Build Coastguard Worker while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1369*6777b538SAndroid Build Coastguard Worker ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1370*6777b538SAndroid Build Coastguard Worker nxt++;
1371*6777b538SAndroid Build Coastguard Worker if (nxt - cur == 2)
1372*6777b538SAndroid Build Coastguard Worker goto region;
1373*6777b538SAndroid Build Coastguard Worker if ((nxt - cur >= 5) && (nxt - cur <= 8))
1374*6777b538SAndroid Build Coastguard Worker goto variant;
1375*6777b538SAndroid Build Coastguard Worker if (nxt - cur != 4)
1376*6777b538SAndroid Build Coastguard Worker return(0);
1377*6777b538SAndroid Build Coastguard Worker /* we parsed a script */
1378*6777b538SAndroid Build Coastguard Worker script:
1379*6777b538SAndroid Build Coastguard Worker if (nxt[0] == 0)
1380*6777b538SAndroid Build Coastguard Worker return(1);
1381*6777b538SAndroid Build Coastguard Worker if (nxt[0] != '-')
1382*6777b538SAndroid Build Coastguard Worker return(0);
1383*6777b538SAndroid Build Coastguard Worker
1384*6777b538SAndroid Build Coastguard Worker nxt++;
1385*6777b538SAndroid Build Coastguard Worker cur = nxt;
1386*6777b538SAndroid Build Coastguard Worker /* now we can have region or variant */
1387*6777b538SAndroid Build Coastguard Worker if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1388*6777b538SAndroid Build Coastguard Worker goto region_m49;
1389*6777b538SAndroid Build Coastguard Worker
1390*6777b538SAndroid Build Coastguard Worker while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1391*6777b538SAndroid Build Coastguard Worker ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1392*6777b538SAndroid Build Coastguard Worker nxt++;
1393*6777b538SAndroid Build Coastguard Worker
1394*6777b538SAndroid Build Coastguard Worker if ((nxt - cur >= 5) && (nxt - cur <= 8))
1395*6777b538SAndroid Build Coastguard Worker goto variant;
1396*6777b538SAndroid Build Coastguard Worker if (nxt - cur != 2)
1397*6777b538SAndroid Build Coastguard Worker return(0);
1398*6777b538SAndroid Build Coastguard Worker /* we parsed a region */
1399*6777b538SAndroid Build Coastguard Worker region:
1400*6777b538SAndroid Build Coastguard Worker if (nxt[0] == 0)
1401*6777b538SAndroid Build Coastguard Worker return(1);
1402*6777b538SAndroid Build Coastguard Worker if (nxt[0] != '-')
1403*6777b538SAndroid Build Coastguard Worker return(0);
1404*6777b538SAndroid Build Coastguard Worker
1405*6777b538SAndroid Build Coastguard Worker nxt++;
1406*6777b538SAndroid Build Coastguard Worker cur = nxt;
1407*6777b538SAndroid Build Coastguard Worker /* now we can just have a variant */
1408*6777b538SAndroid Build Coastguard Worker while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1409*6777b538SAndroid Build Coastguard Worker ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1410*6777b538SAndroid Build Coastguard Worker nxt++;
1411*6777b538SAndroid Build Coastguard Worker
1412*6777b538SAndroid Build Coastguard Worker if ((nxt - cur < 5) || (nxt - cur > 8))
1413*6777b538SAndroid Build Coastguard Worker return(0);
1414*6777b538SAndroid Build Coastguard Worker
1415*6777b538SAndroid Build Coastguard Worker /* we parsed a variant */
1416*6777b538SAndroid Build Coastguard Worker variant:
1417*6777b538SAndroid Build Coastguard Worker if (nxt[0] == 0)
1418*6777b538SAndroid Build Coastguard Worker return(1);
1419*6777b538SAndroid Build Coastguard Worker if (nxt[0] != '-')
1420*6777b538SAndroid Build Coastguard Worker return(0);
1421*6777b538SAndroid Build Coastguard Worker /* extensions and private use subtags not checked */
1422*6777b538SAndroid Build Coastguard Worker return (1);
1423*6777b538SAndroid Build Coastguard Worker
1424*6777b538SAndroid Build Coastguard Worker region_m49:
1425*6777b538SAndroid Build Coastguard Worker if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
1426*6777b538SAndroid Build Coastguard Worker ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
1427*6777b538SAndroid Build Coastguard Worker nxt += 3;
1428*6777b538SAndroid Build Coastguard Worker goto region;
1429*6777b538SAndroid Build Coastguard Worker }
1430*6777b538SAndroid Build Coastguard Worker return(0);
1431*6777b538SAndroid Build Coastguard Worker }
1432*6777b538SAndroid Build Coastguard Worker
1433*6777b538SAndroid Build Coastguard Worker /************************************************************************
1434*6777b538SAndroid Build Coastguard Worker * *
1435*6777b538SAndroid Build Coastguard Worker * Parser stacks related functions and macros *
1436*6777b538SAndroid Build Coastguard Worker * *
1437*6777b538SAndroid Build Coastguard Worker ************************************************************************/
1438*6777b538SAndroid Build Coastguard Worker
1439*6777b538SAndroid Build Coastguard Worker static xmlChar *
1440*6777b538SAndroid Build Coastguard Worker xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar **str);
1441*6777b538SAndroid Build Coastguard Worker
1442*6777b538SAndroid Build Coastguard Worker /**
1443*6777b538SAndroid Build Coastguard Worker * xmlParserNsCreate:
1444*6777b538SAndroid Build Coastguard Worker *
1445*6777b538SAndroid Build Coastguard Worker * Create a new namespace database.
1446*6777b538SAndroid Build Coastguard Worker *
1447*6777b538SAndroid Build Coastguard Worker * Returns the new obejct.
1448*6777b538SAndroid Build Coastguard Worker */
1449*6777b538SAndroid Build Coastguard Worker xmlParserNsData *
xmlParserNsCreate(void)1450*6777b538SAndroid Build Coastguard Worker xmlParserNsCreate(void) {
1451*6777b538SAndroid Build Coastguard Worker xmlParserNsData *nsdb = xmlMalloc(sizeof(*nsdb));
1452*6777b538SAndroid Build Coastguard Worker
1453*6777b538SAndroid Build Coastguard Worker if (nsdb == NULL)
1454*6777b538SAndroid Build Coastguard Worker return(NULL);
1455*6777b538SAndroid Build Coastguard Worker memset(nsdb, 0, sizeof(*nsdb));
1456*6777b538SAndroid Build Coastguard Worker nsdb->defaultNsIndex = INT_MAX;
1457*6777b538SAndroid Build Coastguard Worker
1458*6777b538SAndroid Build Coastguard Worker return(nsdb);
1459*6777b538SAndroid Build Coastguard Worker }
1460*6777b538SAndroid Build Coastguard Worker
1461*6777b538SAndroid Build Coastguard Worker /**
1462*6777b538SAndroid Build Coastguard Worker * xmlParserNsFree:
1463*6777b538SAndroid Build Coastguard Worker * @nsdb: namespace database
1464*6777b538SAndroid Build Coastguard Worker *
1465*6777b538SAndroid Build Coastguard Worker * Free a namespace database.
1466*6777b538SAndroid Build Coastguard Worker */
1467*6777b538SAndroid Build Coastguard Worker void
xmlParserNsFree(xmlParserNsData * nsdb)1468*6777b538SAndroid Build Coastguard Worker xmlParserNsFree(xmlParserNsData *nsdb) {
1469*6777b538SAndroid Build Coastguard Worker if (nsdb == NULL)
1470*6777b538SAndroid Build Coastguard Worker return;
1471*6777b538SAndroid Build Coastguard Worker
1472*6777b538SAndroid Build Coastguard Worker xmlFree(nsdb->extra);
1473*6777b538SAndroid Build Coastguard Worker xmlFree(nsdb->hash);
1474*6777b538SAndroid Build Coastguard Worker xmlFree(nsdb);
1475*6777b538SAndroid Build Coastguard Worker }
1476*6777b538SAndroid Build Coastguard Worker
1477*6777b538SAndroid Build Coastguard Worker /**
1478*6777b538SAndroid Build Coastguard Worker * xmlParserNsReset:
1479*6777b538SAndroid Build Coastguard Worker * @nsdb: namespace database
1480*6777b538SAndroid Build Coastguard Worker *
1481*6777b538SAndroid Build Coastguard Worker * Reset a namespace database.
1482*6777b538SAndroid Build Coastguard Worker */
1483*6777b538SAndroid Build Coastguard Worker static void
xmlParserNsReset(xmlParserNsData * nsdb)1484*6777b538SAndroid Build Coastguard Worker xmlParserNsReset(xmlParserNsData *nsdb) {
1485*6777b538SAndroid Build Coastguard Worker if (nsdb == NULL)
1486*6777b538SAndroid Build Coastguard Worker return;
1487*6777b538SAndroid Build Coastguard Worker
1488*6777b538SAndroid Build Coastguard Worker nsdb->hashElems = 0;
1489*6777b538SAndroid Build Coastguard Worker nsdb->elementId = 0;
1490*6777b538SAndroid Build Coastguard Worker nsdb->defaultNsIndex = INT_MAX;
1491*6777b538SAndroid Build Coastguard Worker
1492*6777b538SAndroid Build Coastguard Worker if (nsdb->hash)
1493*6777b538SAndroid Build Coastguard Worker memset(nsdb->hash, 0, nsdb->hashSize * sizeof(nsdb->hash[0]));
1494*6777b538SAndroid Build Coastguard Worker }
1495*6777b538SAndroid Build Coastguard Worker
1496*6777b538SAndroid Build Coastguard Worker /**
1497*6777b538SAndroid Build Coastguard Worker * xmlParserStartElement:
1498*6777b538SAndroid Build Coastguard Worker * @nsdb: namespace database
1499*6777b538SAndroid Build Coastguard Worker *
1500*6777b538SAndroid Build Coastguard Worker * Signal that a new element has started.
1501*6777b538SAndroid Build Coastguard Worker *
1502*6777b538SAndroid Build Coastguard Worker * Returns 0 on success, -1 if the element counter overflowed.
1503*6777b538SAndroid Build Coastguard Worker */
1504*6777b538SAndroid Build Coastguard Worker static int
xmlParserNsStartElement(xmlParserNsData * nsdb)1505*6777b538SAndroid Build Coastguard Worker xmlParserNsStartElement(xmlParserNsData *nsdb) {
1506*6777b538SAndroid Build Coastguard Worker if (nsdb->elementId == UINT_MAX)
1507*6777b538SAndroid Build Coastguard Worker return(-1);
1508*6777b538SAndroid Build Coastguard Worker nsdb->elementId++;
1509*6777b538SAndroid Build Coastguard Worker
1510*6777b538SAndroid Build Coastguard Worker return(0);
1511*6777b538SAndroid Build Coastguard Worker }
1512*6777b538SAndroid Build Coastguard Worker
1513*6777b538SAndroid Build Coastguard Worker /**
1514*6777b538SAndroid Build Coastguard Worker * xmlParserNsLookup:
1515*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
1516*6777b538SAndroid Build Coastguard Worker * @prefix: namespace prefix
1517*6777b538SAndroid Build Coastguard Worker * @bucketPtr: optional bucket (return value)
1518*6777b538SAndroid Build Coastguard Worker *
1519*6777b538SAndroid Build Coastguard Worker * Lookup namespace with given prefix. If @bucketPtr is non-NULL, it will
1520*6777b538SAndroid Build Coastguard Worker * be set to the matching bucket, or the first empty bucket if no match
1521*6777b538SAndroid Build Coastguard Worker * was found.
1522*6777b538SAndroid Build Coastguard Worker *
1523*6777b538SAndroid Build Coastguard Worker * Returns the namespace index on success, INT_MAX if no namespace was
1524*6777b538SAndroid Build Coastguard Worker * found.
1525*6777b538SAndroid Build Coastguard Worker */
1526*6777b538SAndroid Build Coastguard Worker static int
xmlParserNsLookup(xmlParserCtxtPtr ctxt,const xmlHashedString * prefix,xmlParserNsBucket ** bucketPtr)1527*6777b538SAndroid Build Coastguard Worker xmlParserNsLookup(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix,
1528*6777b538SAndroid Build Coastguard Worker xmlParserNsBucket **bucketPtr) {
1529*6777b538SAndroid Build Coastguard Worker xmlParserNsBucket *bucket;
1530*6777b538SAndroid Build Coastguard Worker unsigned index, hashValue;
1531*6777b538SAndroid Build Coastguard Worker
1532*6777b538SAndroid Build Coastguard Worker if (prefix->name == NULL)
1533*6777b538SAndroid Build Coastguard Worker return(ctxt->nsdb->defaultNsIndex);
1534*6777b538SAndroid Build Coastguard Worker
1535*6777b538SAndroid Build Coastguard Worker if (ctxt->nsdb->hashSize == 0)
1536*6777b538SAndroid Build Coastguard Worker return(INT_MAX);
1537*6777b538SAndroid Build Coastguard Worker
1538*6777b538SAndroid Build Coastguard Worker hashValue = prefix->hashValue;
1539*6777b538SAndroid Build Coastguard Worker index = hashValue & (ctxt->nsdb->hashSize - 1);
1540*6777b538SAndroid Build Coastguard Worker bucket = &ctxt->nsdb->hash[index];
1541*6777b538SAndroid Build Coastguard Worker
1542*6777b538SAndroid Build Coastguard Worker while (bucket->hashValue) {
1543*6777b538SAndroid Build Coastguard Worker if ((bucket->hashValue == hashValue) &&
1544*6777b538SAndroid Build Coastguard Worker (bucket->index != INT_MAX)) {
1545*6777b538SAndroid Build Coastguard Worker if (ctxt->nsTab[bucket->index * 2] == prefix->name) {
1546*6777b538SAndroid Build Coastguard Worker if (bucketPtr != NULL)
1547*6777b538SAndroid Build Coastguard Worker *bucketPtr = bucket;
1548*6777b538SAndroid Build Coastguard Worker return(bucket->index);
1549*6777b538SAndroid Build Coastguard Worker }
1550*6777b538SAndroid Build Coastguard Worker }
1551*6777b538SAndroid Build Coastguard Worker
1552*6777b538SAndroid Build Coastguard Worker index++;
1553*6777b538SAndroid Build Coastguard Worker bucket++;
1554*6777b538SAndroid Build Coastguard Worker if (index == ctxt->nsdb->hashSize) {
1555*6777b538SAndroid Build Coastguard Worker index = 0;
1556*6777b538SAndroid Build Coastguard Worker bucket = ctxt->nsdb->hash;
1557*6777b538SAndroid Build Coastguard Worker }
1558*6777b538SAndroid Build Coastguard Worker }
1559*6777b538SAndroid Build Coastguard Worker
1560*6777b538SAndroid Build Coastguard Worker if (bucketPtr != NULL)
1561*6777b538SAndroid Build Coastguard Worker *bucketPtr = bucket;
1562*6777b538SAndroid Build Coastguard Worker return(INT_MAX);
1563*6777b538SAndroid Build Coastguard Worker }
1564*6777b538SAndroid Build Coastguard Worker
1565*6777b538SAndroid Build Coastguard Worker /**
1566*6777b538SAndroid Build Coastguard Worker * xmlParserNsLookupUri:
1567*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
1568*6777b538SAndroid Build Coastguard Worker * @prefix: namespace prefix
1569*6777b538SAndroid Build Coastguard Worker *
1570*6777b538SAndroid Build Coastguard Worker * Lookup namespace URI with given prefix.
1571*6777b538SAndroid Build Coastguard Worker *
1572*6777b538SAndroid Build Coastguard Worker * Returns the namespace URI on success, NULL if no namespace was found.
1573*6777b538SAndroid Build Coastguard Worker */
1574*6777b538SAndroid Build Coastguard Worker static const xmlChar *
xmlParserNsLookupUri(xmlParserCtxtPtr ctxt,const xmlHashedString * prefix)1575*6777b538SAndroid Build Coastguard Worker xmlParserNsLookupUri(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix) {
1576*6777b538SAndroid Build Coastguard Worker const xmlChar *ret;
1577*6777b538SAndroid Build Coastguard Worker int nsIndex;
1578*6777b538SAndroid Build Coastguard Worker
1579*6777b538SAndroid Build Coastguard Worker if (prefix->name == ctxt->str_xml)
1580*6777b538SAndroid Build Coastguard Worker return(ctxt->str_xml_ns);
1581*6777b538SAndroid Build Coastguard Worker
1582*6777b538SAndroid Build Coastguard Worker /*
1583*6777b538SAndroid Build Coastguard Worker * minNsIndex is used when building an entity tree. We must
1584*6777b538SAndroid Build Coastguard Worker * ignore namespaces declared outside the entity.
1585*6777b538SAndroid Build Coastguard Worker */
1586*6777b538SAndroid Build Coastguard Worker nsIndex = xmlParserNsLookup(ctxt, prefix, NULL);
1587*6777b538SAndroid Build Coastguard Worker if ((nsIndex == INT_MAX) || (nsIndex < ctxt->nsdb->minNsIndex))
1588*6777b538SAndroid Build Coastguard Worker return(NULL);
1589*6777b538SAndroid Build Coastguard Worker
1590*6777b538SAndroid Build Coastguard Worker ret = ctxt->nsTab[nsIndex * 2 + 1];
1591*6777b538SAndroid Build Coastguard Worker if (ret[0] == 0)
1592*6777b538SAndroid Build Coastguard Worker ret = NULL;
1593*6777b538SAndroid Build Coastguard Worker return(ret);
1594*6777b538SAndroid Build Coastguard Worker }
1595*6777b538SAndroid Build Coastguard Worker
1596*6777b538SAndroid Build Coastguard Worker /**
1597*6777b538SAndroid Build Coastguard Worker * xmlParserNsLookupSax:
1598*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
1599*6777b538SAndroid Build Coastguard Worker * @prefix: namespace prefix
1600*6777b538SAndroid Build Coastguard Worker *
1601*6777b538SAndroid Build Coastguard Worker * Lookup extra data for the given prefix. This returns data stored
1602*6777b538SAndroid Build Coastguard Worker * with xmlParserNsUdpateSax.
1603*6777b538SAndroid Build Coastguard Worker *
1604*6777b538SAndroid Build Coastguard Worker * Returns the data on success, NULL if no namespace was found.
1605*6777b538SAndroid Build Coastguard Worker */
1606*6777b538SAndroid Build Coastguard Worker void *
xmlParserNsLookupSax(xmlParserCtxtPtr ctxt,const xmlChar * prefix)1607*6777b538SAndroid Build Coastguard Worker xmlParserNsLookupSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
1608*6777b538SAndroid Build Coastguard Worker xmlHashedString hprefix;
1609*6777b538SAndroid Build Coastguard Worker int nsIndex;
1610*6777b538SAndroid Build Coastguard Worker
1611*6777b538SAndroid Build Coastguard Worker if (prefix == ctxt->str_xml)
1612*6777b538SAndroid Build Coastguard Worker return(NULL);
1613*6777b538SAndroid Build Coastguard Worker
1614*6777b538SAndroid Build Coastguard Worker hprefix.name = prefix;
1615*6777b538SAndroid Build Coastguard Worker if (prefix != NULL)
1616*6777b538SAndroid Build Coastguard Worker hprefix.hashValue = xmlDictComputeHash(ctxt->dict, prefix);
1617*6777b538SAndroid Build Coastguard Worker else
1618*6777b538SAndroid Build Coastguard Worker hprefix.hashValue = 0;
1619*6777b538SAndroid Build Coastguard Worker nsIndex = xmlParserNsLookup(ctxt, &hprefix, NULL);
1620*6777b538SAndroid Build Coastguard Worker if ((nsIndex == INT_MAX) || (nsIndex < ctxt->nsdb->minNsIndex))
1621*6777b538SAndroid Build Coastguard Worker return(NULL);
1622*6777b538SAndroid Build Coastguard Worker
1623*6777b538SAndroid Build Coastguard Worker return(ctxt->nsdb->extra[nsIndex].saxData);
1624*6777b538SAndroid Build Coastguard Worker }
1625*6777b538SAndroid Build Coastguard Worker
1626*6777b538SAndroid Build Coastguard Worker /**
1627*6777b538SAndroid Build Coastguard Worker * xmlParserNsUpdateSax:
1628*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
1629*6777b538SAndroid Build Coastguard Worker * @prefix: namespace prefix
1630*6777b538SAndroid Build Coastguard Worker * @saxData: extra data for SAX handler
1631*6777b538SAndroid Build Coastguard Worker *
1632*6777b538SAndroid Build Coastguard Worker * Sets or updates extra data for the given prefix. This value will be
1633*6777b538SAndroid Build Coastguard Worker * returned by xmlParserNsLookupSax as long as the namespace with the
1634*6777b538SAndroid Build Coastguard Worker * given prefix is in scope.
1635*6777b538SAndroid Build Coastguard Worker *
1636*6777b538SAndroid Build Coastguard Worker * Returns the data on success, NULL if no namespace was found.
1637*6777b538SAndroid Build Coastguard Worker */
1638*6777b538SAndroid Build Coastguard Worker int
xmlParserNsUpdateSax(xmlParserCtxtPtr ctxt,const xmlChar * prefix,void * saxData)1639*6777b538SAndroid Build Coastguard Worker xmlParserNsUpdateSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
1640*6777b538SAndroid Build Coastguard Worker void *saxData) {
1641*6777b538SAndroid Build Coastguard Worker xmlHashedString hprefix;
1642*6777b538SAndroid Build Coastguard Worker int nsIndex;
1643*6777b538SAndroid Build Coastguard Worker
1644*6777b538SAndroid Build Coastguard Worker if (prefix == ctxt->str_xml)
1645*6777b538SAndroid Build Coastguard Worker return(-1);
1646*6777b538SAndroid Build Coastguard Worker
1647*6777b538SAndroid Build Coastguard Worker hprefix.name = prefix;
1648*6777b538SAndroid Build Coastguard Worker if (prefix != NULL)
1649*6777b538SAndroid Build Coastguard Worker hprefix.hashValue = xmlDictComputeHash(ctxt->dict, prefix);
1650*6777b538SAndroid Build Coastguard Worker else
1651*6777b538SAndroid Build Coastguard Worker hprefix.hashValue = 0;
1652*6777b538SAndroid Build Coastguard Worker nsIndex = xmlParserNsLookup(ctxt, &hprefix, NULL);
1653*6777b538SAndroid Build Coastguard Worker if ((nsIndex == INT_MAX) || (nsIndex < ctxt->nsdb->minNsIndex))
1654*6777b538SAndroid Build Coastguard Worker return(-1);
1655*6777b538SAndroid Build Coastguard Worker
1656*6777b538SAndroid Build Coastguard Worker ctxt->nsdb->extra[nsIndex].saxData = saxData;
1657*6777b538SAndroid Build Coastguard Worker return(0);
1658*6777b538SAndroid Build Coastguard Worker }
1659*6777b538SAndroid Build Coastguard Worker
1660*6777b538SAndroid Build Coastguard Worker /**
1661*6777b538SAndroid Build Coastguard Worker * xmlParserNsGrow:
1662*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
1663*6777b538SAndroid Build Coastguard Worker *
1664*6777b538SAndroid Build Coastguard Worker * Grows the namespace tables.
1665*6777b538SAndroid Build Coastguard Worker *
1666*6777b538SAndroid Build Coastguard Worker * Returns 0 on success, -1 if a memory allocation failed.
1667*6777b538SAndroid Build Coastguard Worker */
1668*6777b538SAndroid Build Coastguard Worker static int
xmlParserNsGrow(xmlParserCtxtPtr ctxt)1669*6777b538SAndroid Build Coastguard Worker xmlParserNsGrow(xmlParserCtxtPtr ctxt) {
1670*6777b538SAndroid Build Coastguard Worker const xmlChar **table;
1671*6777b538SAndroid Build Coastguard Worker xmlParserNsExtra *extra;
1672*6777b538SAndroid Build Coastguard Worker int newSize;
1673*6777b538SAndroid Build Coastguard Worker
1674*6777b538SAndroid Build Coastguard Worker if (ctxt->nsMax > INT_MAX / 2)
1675*6777b538SAndroid Build Coastguard Worker goto error;
1676*6777b538SAndroid Build Coastguard Worker newSize = ctxt->nsMax ? ctxt->nsMax * 2 : 16;
1677*6777b538SAndroid Build Coastguard Worker
1678*6777b538SAndroid Build Coastguard Worker table = xmlRealloc(ctxt->nsTab, 2 * newSize * sizeof(table[0]));
1679*6777b538SAndroid Build Coastguard Worker if (table == NULL)
1680*6777b538SAndroid Build Coastguard Worker goto error;
1681*6777b538SAndroid Build Coastguard Worker ctxt->nsTab = table;
1682*6777b538SAndroid Build Coastguard Worker
1683*6777b538SAndroid Build Coastguard Worker extra = xmlRealloc(ctxt->nsdb->extra, newSize * sizeof(extra[0]));
1684*6777b538SAndroid Build Coastguard Worker if (extra == NULL)
1685*6777b538SAndroid Build Coastguard Worker goto error;
1686*6777b538SAndroid Build Coastguard Worker ctxt->nsdb->extra = extra;
1687*6777b538SAndroid Build Coastguard Worker
1688*6777b538SAndroid Build Coastguard Worker ctxt->nsMax = newSize;
1689*6777b538SAndroid Build Coastguard Worker return(0);
1690*6777b538SAndroid Build Coastguard Worker
1691*6777b538SAndroid Build Coastguard Worker error:
1692*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
1693*6777b538SAndroid Build Coastguard Worker return(-1);
1694*6777b538SAndroid Build Coastguard Worker }
1695*6777b538SAndroid Build Coastguard Worker
1696*6777b538SAndroid Build Coastguard Worker /**
1697*6777b538SAndroid Build Coastguard Worker * xmlParserNsPush:
1698*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
1699*6777b538SAndroid Build Coastguard Worker * @prefix: prefix with hash value
1700*6777b538SAndroid Build Coastguard Worker * @uri: uri with hash value
1701*6777b538SAndroid Build Coastguard Worker * @saxData: extra data for SAX handler
1702*6777b538SAndroid Build Coastguard Worker * @defAttr: whether the namespace comes from a default attribute
1703*6777b538SAndroid Build Coastguard Worker *
1704*6777b538SAndroid Build Coastguard Worker * Push a new namespace on the table.
1705*6777b538SAndroid Build Coastguard Worker *
1706*6777b538SAndroid Build Coastguard Worker * Returns 1 if the namespace was pushed, 0 if the namespace was ignored,
1707*6777b538SAndroid Build Coastguard Worker * -1 if a memory allocation failed.
1708*6777b538SAndroid Build Coastguard Worker */
1709*6777b538SAndroid Build Coastguard Worker static int
xmlParserNsPush(xmlParserCtxtPtr ctxt,const xmlHashedString * prefix,const xmlHashedString * uri,void * saxData,int defAttr)1710*6777b538SAndroid Build Coastguard Worker xmlParserNsPush(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix,
1711*6777b538SAndroid Build Coastguard Worker const xmlHashedString *uri, void *saxData, int defAttr) {
1712*6777b538SAndroid Build Coastguard Worker xmlParserNsBucket *bucket = NULL;
1713*6777b538SAndroid Build Coastguard Worker xmlParserNsExtra *extra;
1714*6777b538SAndroid Build Coastguard Worker const xmlChar **ns;
1715*6777b538SAndroid Build Coastguard Worker unsigned hashValue, nsIndex, oldIndex;
1716*6777b538SAndroid Build Coastguard Worker
1717*6777b538SAndroid Build Coastguard Worker if ((prefix != NULL) && (prefix->name == ctxt->str_xml))
1718*6777b538SAndroid Build Coastguard Worker return(0);
1719*6777b538SAndroid Build Coastguard Worker
1720*6777b538SAndroid Build Coastguard Worker if ((ctxt->nsNr >= ctxt->nsMax) && (xmlParserNsGrow(ctxt) < 0)) {
1721*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
1722*6777b538SAndroid Build Coastguard Worker return(-1);
1723*6777b538SAndroid Build Coastguard Worker }
1724*6777b538SAndroid Build Coastguard Worker
1725*6777b538SAndroid Build Coastguard Worker /*
1726*6777b538SAndroid Build Coastguard Worker * Default namespace and 'xml' namespace
1727*6777b538SAndroid Build Coastguard Worker */
1728*6777b538SAndroid Build Coastguard Worker if ((prefix == NULL) || (prefix->name == NULL)) {
1729*6777b538SAndroid Build Coastguard Worker oldIndex = ctxt->nsdb->defaultNsIndex;
1730*6777b538SAndroid Build Coastguard Worker
1731*6777b538SAndroid Build Coastguard Worker if (oldIndex != INT_MAX) {
1732*6777b538SAndroid Build Coastguard Worker extra = &ctxt->nsdb->extra[oldIndex];
1733*6777b538SAndroid Build Coastguard Worker
1734*6777b538SAndroid Build Coastguard Worker if (extra->elementId == ctxt->nsdb->elementId) {
1735*6777b538SAndroid Build Coastguard Worker if (defAttr == 0)
1736*6777b538SAndroid Build Coastguard Worker xmlErrAttributeDup(ctxt, NULL, BAD_CAST "xmlns");
1737*6777b538SAndroid Build Coastguard Worker return(0);
1738*6777b538SAndroid Build Coastguard Worker }
1739*6777b538SAndroid Build Coastguard Worker
1740*6777b538SAndroid Build Coastguard Worker if ((ctxt->options & XML_PARSE_NSCLEAN) &&
1741*6777b538SAndroid Build Coastguard Worker (uri->name == ctxt->nsTab[oldIndex * 2 + 1]))
1742*6777b538SAndroid Build Coastguard Worker return(0);
1743*6777b538SAndroid Build Coastguard Worker }
1744*6777b538SAndroid Build Coastguard Worker
1745*6777b538SAndroid Build Coastguard Worker ctxt->nsdb->defaultNsIndex = ctxt->nsNr;
1746*6777b538SAndroid Build Coastguard Worker goto populate_entry;
1747*6777b538SAndroid Build Coastguard Worker }
1748*6777b538SAndroid Build Coastguard Worker
1749*6777b538SAndroid Build Coastguard Worker /*
1750*6777b538SAndroid Build Coastguard Worker * Hash table lookup
1751*6777b538SAndroid Build Coastguard Worker */
1752*6777b538SAndroid Build Coastguard Worker oldIndex = xmlParserNsLookup(ctxt, prefix, &bucket);
1753*6777b538SAndroid Build Coastguard Worker if (oldIndex != INT_MAX) {
1754*6777b538SAndroid Build Coastguard Worker extra = &ctxt->nsdb->extra[oldIndex];
1755*6777b538SAndroid Build Coastguard Worker
1756*6777b538SAndroid Build Coastguard Worker /*
1757*6777b538SAndroid Build Coastguard Worker * Check for duplicate definitions on the same element.
1758*6777b538SAndroid Build Coastguard Worker */
1759*6777b538SAndroid Build Coastguard Worker if (extra->elementId == ctxt->nsdb->elementId) {
1760*6777b538SAndroid Build Coastguard Worker if (defAttr == 0)
1761*6777b538SAndroid Build Coastguard Worker xmlErrAttributeDup(ctxt, BAD_CAST "xmlns", prefix->name);
1762*6777b538SAndroid Build Coastguard Worker return(0);
1763*6777b538SAndroid Build Coastguard Worker }
1764*6777b538SAndroid Build Coastguard Worker
1765*6777b538SAndroid Build Coastguard Worker if ((ctxt->options & XML_PARSE_NSCLEAN) &&
1766*6777b538SAndroid Build Coastguard Worker (uri->name == ctxt->nsTab[bucket->index * 2 + 1]))
1767*6777b538SAndroid Build Coastguard Worker return(0);
1768*6777b538SAndroid Build Coastguard Worker
1769*6777b538SAndroid Build Coastguard Worker bucket->index = ctxt->nsNr;
1770*6777b538SAndroid Build Coastguard Worker goto populate_entry;
1771*6777b538SAndroid Build Coastguard Worker }
1772*6777b538SAndroid Build Coastguard Worker
1773*6777b538SAndroid Build Coastguard Worker /*
1774*6777b538SAndroid Build Coastguard Worker * Insert new bucket
1775*6777b538SAndroid Build Coastguard Worker */
1776*6777b538SAndroid Build Coastguard Worker
1777*6777b538SAndroid Build Coastguard Worker hashValue = prefix->hashValue;
1778*6777b538SAndroid Build Coastguard Worker
1779*6777b538SAndroid Build Coastguard Worker /*
1780*6777b538SAndroid Build Coastguard Worker * Grow hash table, 50% fill factor
1781*6777b538SAndroid Build Coastguard Worker */
1782*6777b538SAndroid Build Coastguard Worker if (ctxt->nsdb->hashElems + 1 > ctxt->nsdb->hashSize / 2) {
1783*6777b538SAndroid Build Coastguard Worker xmlParserNsBucket *newHash;
1784*6777b538SAndroid Build Coastguard Worker unsigned newSize, i, index;
1785*6777b538SAndroid Build Coastguard Worker
1786*6777b538SAndroid Build Coastguard Worker if (ctxt->nsdb->hashSize > UINT_MAX / 2) {
1787*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
1788*6777b538SAndroid Build Coastguard Worker return(-1);
1789*6777b538SAndroid Build Coastguard Worker }
1790*6777b538SAndroid Build Coastguard Worker newSize = ctxt->nsdb->hashSize ? ctxt->nsdb->hashSize * 2 : 16;
1791*6777b538SAndroid Build Coastguard Worker newHash = xmlMalloc(newSize * sizeof(newHash[0]));
1792*6777b538SAndroid Build Coastguard Worker if (newHash == NULL) {
1793*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
1794*6777b538SAndroid Build Coastguard Worker return(-1);
1795*6777b538SAndroid Build Coastguard Worker }
1796*6777b538SAndroid Build Coastguard Worker memset(newHash, 0, newSize * sizeof(newHash[0]));
1797*6777b538SAndroid Build Coastguard Worker
1798*6777b538SAndroid Build Coastguard Worker for (i = 0; i < ctxt->nsdb->hashSize; i++) {
1799*6777b538SAndroid Build Coastguard Worker unsigned hv = ctxt->nsdb->hash[i].hashValue;
1800*6777b538SAndroid Build Coastguard Worker unsigned newIndex;
1801*6777b538SAndroid Build Coastguard Worker
1802*6777b538SAndroid Build Coastguard Worker if (hv == 0)
1803*6777b538SAndroid Build Coastguard Worker continue;
1804*6777b538SAndroid Build Coastguard Worker newIndex = hv & (newSize - 1);
1805*6777b538SAndroid Build Coastguard Worker
1806*6777b538SAndroid Build Coastguard Worker while (newHash[newIndex].hashValue != 0) {
1807*6777b538SAndroid Build Coastguard Worker newIndex++;
1808*6777b538SAndroid Build Coastguard Worker if (newIndex == newSize)
1809*6777b538SAndroid Build Coastguard Worker newIndex = 0;
1810*6777b538SAndroid Build Coastguard Worker }
1811*6777b538SAndroid Build Coastguard Worker
1812*6777b538SAndroid Build Coastguard Worker newHash[newIndex] = ctxt->nsdb->hash[i];
1813*6777b538SAndroid Build Coastguard Worker }
1814*6777b538SAndroid Build Coastguard Worker
1815*6777b538SAndroid Build Coastguard Worker xmlFree(ctxt->nsdb->hash);
1816*6777b538SAndroid Build Coastguard Worker ctxt->nsdb->hash = newHash;
1817*6777b538SAndroid Build Coastguard Worker ctxt->nsdb->hashSize = newSize;
1818*6777b538SAndroid Build Coastguard Worker
1819*6777b538SAndroid Build Coastguard Worker /*
1820*6777b538SAndroid Build Coastguard Worker * Relookup
1821*6777b538SAndroid Build Coastguard Worker */
1822*6777b538SAndroid Build Coastguard Worker index = hashValue & (newSize - 1);
1823*6777b538SAndroid Build Coastguard Worker
1824*6777b538SAndroid Build Coastguard Worker while (newHash[index].hashValue != 0) {
1825*6777b538SAndroid Build Coastguard Worker index++;
1826*6777b538SAndroid Build Coastguard Worker if (index == newSize)
1827*6777b538SAndroid Build Coastguard Worker index = 0;
1828*6777b538SAndroid Build Coastguard Worker }
1829*6777b538SAndroid Build Coastguard Worker
1830*6777b538SAndroid Build Coastguard Worker bucket = &newHash[index];
1831*6777b538SAndroid Build Coastguard Worker }
1832*6777b538SAndroid Build Coastguard Worker
1833*6777b538SAndroid Build Coastguard Worker bucket->hashValue = hashValue;
1834*6777b538SAndroid Build Coastguard Worker bucket->index = ctxt->nsNr;
1835*6777b538SAndroid Build Coastguard Worker ctxt->nsdb->hashElems++;
1836*6777b538SAndroid Build Coastguard Worker oldIndex = INT_MAX;
1837*6777b538SAndroid Build Coastguard Worker
1838*6777b538SAndroid Build Coastguard Worker populate_entry:
1839*6777b538SAndroid Build Coastguard Worker nsIndex = ctxt->nsNr;
1840*6777b538SAndroid Build Coastguard Worker
1841*6777b538SAndroid Build Coastguard Worker ns = &ctxt->nsTab[nsIndex * 2];
1842*6777b538SAndroid Build Coastguard Worker ns[0] = prefix ? prefix->name : NULL;
1843*6777b538SAndroid Build Coastguard Worker ns[1] = uri->name;
1844*6777b538SAndroid Build Coastguard Worker
1845*6777b538SAndroid Build Coastguard Worker extra = &ctxt->nsdb->extra[nsIndex];
1846*6777b538SAndroid Build Coastguard Worker extra->saxData = saxData;
1847*6777b538SAndroid Build Coastguard Worker extra->prefixHashValue = prefix ? prefix->hashValue : 0;
1848*6777b538SAndroid Build Coastguard Worker extra->uriHashValue = uri->hashValue;
1849*6777b538SAndroid Build Coastguard Worker extra->elementId = ctxt->nsdb->elementId;
1850*6777b538SAndroid Build Coastguard Worker extra->oldIndex = oldIndex;
1851*6777b538SAndroid Build Coastguard Worker
1852*6777b538SAndroid Build Coastguard Worker ctxt->nsNr++;
1853*6777b538SAndroid Build Coastguard Worker
1854*6777b538SAndroid Build Coastguard Worker return(1);
1855*6777b538SAndroid Build Coastguard Worker }
1856*6777b538SAndroid Build Coastguard Worker
1857*6777b538SAndroid Build Coastguard Worker /**
1858*6777b538SAndroid Build Coastguard Worker * xmlParserNsPop:
1859*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
1860*6777b538SAndroid Build Coastguard Worker * @nr: the number to pop
1861*6777b538SAndroid Build Coastguard Worker *
1862*6777b538SAndroid Build Coastguard Worker * Pops the top @nr namespaces and restores the hash table.
1863*6777b538SAndroid Build Coastguard Worker *
1864*6777b538SAndroid Build Coastguard Worker * Returns the number of namespaces popped.
1865*6777b538SAndroid Build Coastguard Worker */
1866*6777b538SAndroid Build Coastguard Worker static int
xmlParserNsPop(xmlParserCtxtPtr ctxt,int nr)1867*6777b538SAndroid Build Coastguard Worker xmlParserNsPop(xmlParserCtxtPtr ctxt, int nr)
1868*6777b538SAndroid Build Coastguard Worker {
1869*6777b538SAndroid Build Coastguard Worker int i;
1870*6777b538SAndroid Build Coastguard Worker
1871*6777b538SAndroid Build Coastguard Worker /* assert(nr <= ctxt->nsNr); */
1872*6777b538SAndroid Build Coastguard Worker
1873*6777b538SAndroid Build Coastguard Worker for (i = ctxt->nsNr - 1; i >= ctxt->nsNr - nr; i--) {
1874*6777b538SAndroid Build Coastguard Worker const xmlChar *prefix = ctxt->nsTab[i * 2];
1875*6777b538SAndroid Build Coastguard Worker xmlParserNsExtra *extra = &ctxt->nsdb->extra[i];
1876*6777b538SAndroid Build Coastguard Worker
1877*6777b538SAndroid Build Coastguard Worker if (prefix == NULL) {
1878*6777b538SAndroid Build Coastguard Worker ctxt->nsdb->defaultNsIndex = extra->oldIndex;
1879*6777b538SAndroid Build Coastguard Worker } else {
1880*6777b538SAndroid Build Coastguard Worker xmlHashedString hprefix;
1881*6777b538SAndroid Build Coastguard Worker xmlParserNsBucket *bucket = NULL;
1882*6777b538SAndroid Build Coastguard Worker
1883*6777b538SAndroid Build Coastguard Worker hprefix.name = prefix;
1884*6777b538SAndroid Build Coastguard Worker hprefix.hashValue = extra->prefixHashValue;
1885*6777b538SAndroid Build Coastguard Worker xmlParserNsLookup(ctxt, &hprefix, &bucket);
1886*6777b538SAndroid Build Coastguard Worker /* assert(bucket && bucket->hashValue); */
1887*6777b538SAndroid Build Coastguard Worker bucket->index = extra->oldIndex;
1888*6777b538SAndroid Build Coastguard Worker }
1889*6777b538SAndroid Build Coastguard Worker }
1890*6777b538SAndroid Build Coastguard Worker
1891*6777b538SAndroid Build Coastguard Worker ctxt->nsNr -= nr;
1892*6777b538SAndroid Build Coastguard Worker return(nr);
1893*6777b538SAndroid Build Coastguard Worker }
1894*6777b538SAndroid Build Coastguard Worker
1895*6777b538SAndroid Build Coastguard Worker static int
xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt,int nr)1896*6777b538SAndroid Build Coastguard Worker xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
1897*6777b538SAndroid Build Coastguard Worker const xmlChar **atts;
1898*6777b538SAndroid Build Coastguard Worker unsigned *attallocs;
1899*6777b538SAndroid Build Coastguard Worker int maxatts;
1900*6777b538SAndroid Build Coastguard Worker
1901*6777b538SAndroid Build Coastguard Worker if (nr + 5 > ctxt->maxatts) {
1902*6777b538SAndroid Build Coastguard Worker maxatts = ctxt->maxatts == 0 ? 55 : (nr + 5) * 2;
1903*6777b538SAndroid Build Coastguard Worker atts = (const xmlChar **) xmlMalloc(
1904*6777b538SAndroid Build Coastguard Worker maxatts * sizeof(const xmlChar *));
1905*6777b538SAndroid Build Coastguard Worker if (atts == NULL) goto mem_error;
1906*6777b538SAndroid Build Coastguard Worker attallocs = xmlRealloc(ctxt->attallocs,
1907*6777b538SAndroid Build Coastguard Worker (maxatts / 5) * sizeof(attallocs[0]));
1908*6777b538SAndroid Build Coastguard Worker if (attallocs == NULL) {
1909*6777b538SAndroid Build Coastguard Worker xmlFree(atts);
1910*6777b538SAndroid Build Coastguard Worker goto mem_error;
1911*6777b538SAndroid Build Coastguard Worker }
1912*6777b538SAndroid Build Coastguard Worker if (ctxt->maxatts > 0)
1913*6777b538SAndroid Build Coastguard Worker memcpy(atts, ctxt->atts, ctxt->maxatts * sizeof(const xmlChar *));
1914*6777b538SAndroid Build Coastguard Worker xmlFree(ctxt->atts);
1915*6777b538SAndroid Build Coastguard Worker ctxt->atts = atts;
1916*6777b538SAndroid Build Coastguard Worker ctxt->attallocs = attallocs;
1917*6777b538SAndroid Build Coastguard Worker ctxt->maxatts = maxatts;
1918*6777b538SAndroid Build Coastguard Worker }
1919*6777b538SAndroid Build Coastguard Worker return(ctxt->maxatts);
1920*6777b538SAndroid Build Coastguard Worker mem_error:
1921*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
1922*6777b538SAndroid Build Coastguard Worker return(-1);
1923*6777b538SAndroid Build Coastguard Worker }
1924*6777b538SAndroid Build Coastguard Worker
1925*6777b538SAndroid Build Coastguard Worker /**
1926*6777b538SAndroid Build Coastguard Worker * inputPush:
1927*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
1928*6777b538SAndroid Build Coastguard Worker * @value: the parser input
1929*6777b538SAndroid Build Coastguard Worker *
1930*6777b538SAndroid Build Coastguard Worker * Pushes a new parser input on top of the input stack
1931*6777b538SAndroid Build Coastguard Worker *
1932*6777b538SAndroid Build Coastguard Worker * Returns -1 in case of error, the index in the stack otherwise
1933*6777b538SAndroid Build Coastguard Worker */
1934*6777b538SAndroid Build Coastguard Worker int
inputPush(xmlParserCtxtPtr ctxt,xmlParserInputPtr value)1935*6777b538SAndroid Build Coastguard Worker inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
1936*6777b538SAndroid Build Coastguard Worker {
1937*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (value == NULL))
1938*6777b538SAndroid Build Coastguard Worker return(-1);
1939*6777b538SAndroid Build Coastguard Worker if (ctxt->inputNr >= ctxt->inputMax) {
1940*6777b538SAndroid Build Coastguard Worker size_t newSize = ctxt->inputMax * 2;
1941*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr *tmp;
1942*6777b538SAndroid Build Coastguard Worker
1943*6777b538SAndroid Build Coastguard Worker tmp = (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
1944*6777b538SAndroid Build Coastguard Worker newSize * sizeof(*tmp));
1945*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
1946*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
1947*6777b538SAndroid Build Coastguard Worker return (-1);
1948*6777b538SAndroid Build Coastguard Worker }
1949*6777b538SAndroid Build Coastguard Worker ctxt->inputTab = tmp;
1950*6777b538SAndroid Build Coastguard Worker ctxt->inputMax = newSize;
1951*6777b538SAndroid Build Coastguard Worker }
1952*6777b538SAndroid Build Coastguard Worker ctxt->inputTab[ctxt->inputNr] = value;
1953*6777b538SAndroid Build Coastguard Worker ctxt->input = value;
1954*6777b538SAndroid Build Coastguard Worker return (ctxt->inputNr++);
1955*6777b538SAndroid Build Coastguard Worker }
1956*6777b538SAndroid Build Coastguard Worker /**
1957*6777b538SAndroid Build Coastguard Worker * inputPop:
1958*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
1959*6777b538SAndroid Build Coastguard Worker *
1960*6777b538SAndroid Build Coastguard Worker * Pops the top parser input from the input stack
1961*6777b538SAndroid Build Coastguard Worker *
1962*6777b538SAndroid Build Coastguard Worker * Returns the input just removed
1963*6777b538SAndroid Build Coastguard Worker */
1964*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr
inputPop(xmlParserCtxtPtr ctxt)1965*6777b538SAndroid Build Coastguard Worker inputPop(xmlParserCtxtPtr ctxt)
1966*6777b538SAndroid Build Coastguard Worker {
1967*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr ret;
1968*6777b538SAndroid Build Coastguard Worker
1969*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
1970*6777b538SAndroid Build Coastguard Worker return(NULL);
1971*6777b538SAndroid Build Coastguard Worker if (ctxt->inputNr <= 0)
1972*6777b538SAndroid Build Coastguard Worker return (NULL);
1973*6777b538SAndroid Build Coastguard Worker ctxt->inputNr--;
1974*6777b538SAndroid Build Coastguard Worker if (ctxt->inputNr > 0)
1975*6777b538SAndroid Build Coastguard Worker ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
1976*6777b538SAndroid Build Coastguard Worker else
1977*6777b538SAndroid Build Coastguard Worker ctxt->input = NULL;
1978*6777b538SAndroid Build Coastguard Worker ret = ctxt->inputTab[ctxt->inputNr];
1979*6777b538SAndroid Build Coastguard Worker ctxt->inputTab[ctxt->inputNr] = NULL;
1980*6777b538SAndroid Build Coastguard Worker return (ret);
1981*6777b538SAndroid Build Coastguard Worker }
1982*6777b538SAndroid Build Coastguard Worker /**
1983*6777b538SAndroid Build Coastguard Worker * nodePush:
1984*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
1985*6777b538SAndroid Build Coastguard Worker * @value: the element node
1986*6777b538SAndroid Build Coastguard Worker *
1987*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, do not use.
1988*6777b538SAndroid Build Coastguard Worker *
1989*6777b538SAndroid Build Coastguard Worker * Pushes a new element node on top of the node stack
1990*6777b538SAndroid Build Coastguard Worker *
1991*6777b538SAndroid Build Coastguard Worker * Returns -1 in case of error, the index in the stack otherwise
1992*6777b538SAndroid Build Coastguard Worker */
1993*6777b538SAndroid Build Coastguard Worker int
nodePush(xmlParserCtxtPtr ctxt,xmlNodePtr value)1994*6777b538SAndroid Build Coastguard Worker nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
1995*6777b538SAndroid Build Coastguard Worker {
1996*6777b538SAndroid Build Coastguard Worker int maxDepth;
1997*6777b538SAndroid Build Coastguard Worker
1998*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
1999*6777b538SAndroid Build Coastguard Worker return(0);
2000*6777b538SAndroid Build Coastguard Worker
2001*6777b538SAndroid Build Coastguard Worker maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 2048 : 256;
2002*6777b538SAndroid Build Coastguard Worker if (ctxt->nodeNr > maxDepth) {
2003*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_RESOURCE_LIMIT,
2004*6777b538SAndroid Build Coastguard Worker "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
2005*6777b538SAndroid Build Coastguard Worker ctxt->nodeNr);
2006*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
2007*6777b538SAndroid Build Coastguard Worker return(-1);
2008*6777b538SAndroid Build Coastguard Worker }
2009*6777b538SAndroid Build Coastguard Worker if (ctxt->nodeNr >= ctxt->nodeMax) {
2010*6777b538SAndroid Build Coastguard Worker xmlNodePtr *tmp;
2011*6777b538SAndroid Build Coastguard Worker
2012*6777b538SAndroid Build Coastguard Worker tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
2013*6777b538SAndroid Build Coastguard Worker ctxt->nodeMax * 2 *
2014*6777b538SAndroid Build Coastguard Worker sizeof(ctxt->nodeTab[0]));
2015*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
2016*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
2017*6777b538SAndroid Build Coastguard Worker return (-1);
2018*6777b538SAndroid Build Coastguard Worker }
2019*6777b538SAndroid Build Coastguard Worker ctxt->nodeTab = tmp;
2020*6777b538SAndroid Build Coastguard Worker ctxt->nodeMax *= 2;
2021*6777b538SAndroid Build Coastguard Worker }
2022*6777b538SAndroid Build Coastguard Worker ctxt->nodeTab[ctxt->nodeNr] = value;
2023*6777b538SAndroid Build Coastguard Worker ctxt->node = value;
2024*6777b538SAndroid Build Coastguard Worker return (ctxt->nodeNr++);
2025*6777b538SAndroid Build Coastguard Worker }
2026*6777b538SAndroid Build Coastguard Worker
2027*6777b538SAndroid Build Coastguard Worker /**
2028*6777b538SAndroid Build Coastguard Worker * nodePop:
2029*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2030*6777b538SAndroid Build Coastguard Worker *
2031*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, do not use.
2032*6777b538SAndroid Build Coastguard Worker *
2033*6777b538SAndroid Build Coastguard Worker * Pops the top element node from the node stack
2034*6777b538SAndroid Build Coastguard Worker *
2035*6777b538SAndroid Build Coastguard Worker * Returns the node just removed
2036*6777b538SAndroid Build Coastguard Worker */
2037*6777b538SAndroid Build Coastguard Worker xmlNodePtr
nodePop(xmlParserCtxtPtr ctxt)2038*6777b538SAndroid Build Coastguard Worker nodePop(xmlParserCtxtPtr ctxt)
2039*6777b538SAndroid Build Coastguard Worker {
2040*6777b538SAndroid Build Coastguard Worker xmlNodePtr ret;
2041*6777b538SAndroid Build Coastguard Worker
2042*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL) return(NULL);
2043*6777b538SAndroid Build Coastguard Worker if (ctxt->nodeNr <= 0)
2044*6777b538SAndroid Build Coastguard Worker return (NULL);
2045*6777b538SAndroid Build Coastguard Worker ctxt->nodeNr--;
2046*6777b538SAndroid Build Coastguard Worker if (ctxt->nodeNr > 0)
2047*6777b538SAndroid Build Coastguard Worker ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
2048*6777b538SAndroid Build Coastguard Worker else
2049*6777b538SAndroid Build Coastguard Worker ctxt->node = NULL;
2050*6777b538SAndroid Build Coastguard Worker ret = ctxt->nodeTab[ctxt->nodeNr];
2051*6777b538SAndroid Build Coastguard Worker ctxt->nodeTab[ctxt->nodeNr] = NULL;
2052*6777b538SAndroid Build Coastguard Worker return (ret);
2053*6777b538SAndroid Build Coastguard Worker }
2054*6777b538SAndroid Build Coastguard Worker
2055*6777b538SAndroid Build Coastguard Worker /**
2056*6777b538SAndroid Build Coastguard Worker * nameNsPush:
2057*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2058*6777b538SAndroid Build Coastguard Worker * @value: the element name
2059*6777b538SAndroid Build Coastguard Worker * @prefix: the element prefix
2060*6777b538SAndroid Build Coastguard Worker * @URI: the element namespace name
2061*6777b538SAndroid Build Coastguard Worker * @line: the current line number for error messages
2062*6777b538SAndroid Build Coastguard Worker * @nsNr: the number of namespaces pushed on the namespace table
2063*6777b538SAndroid Build Coastguard Worker *
2064*6777b538SAndroid Build Coastguard Worker * Pushes a new element name/prefix/URL on top of the name stack
2065*6777b538SAndroid Build Coastguard Worker *
2066*6777b538SAndroid Build Coastguard Worker * Returns -1 in case of error, the index in the stack otherwise
2067*6777b538SAndroid Build Coastguard Worker */
2068*6777b538SAndroid Build Coastguard Worker static int
nameNsPush(xmlParserCtxtPtr ctxt,const xmlChar * value,const xmlChar * prefix,const xmlChar * URI,int line,int nsNr)2069*6777b538SAndroid Build Coastguard Worker nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
2070*6777b538SAndroid Build Coastguard Worker const xmlChar *prefix, const xmlChar *URI, int line, int nsNr)
2071*6777b538SAndroid Build Coastguard Worker {
2072*6777b538SAndroid Build Coastguard Worker xmlStartTag *tag;
2073*6777b538SAndroid Build Coastguard Worker
2074*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr >= ctxt->nameMax) {
2075*6777b538SAndroid Build Coastguard Worker const xmlChar * *tmp;
2076*6777b538SAndroid Build Coastguard Worker xmlStartTag *tmp2;
2077*6777b538SAndroid Build Coastguard Worker ctxt->nameMax *= 2;
2078*6777b538SAndroid Build Coastguard Worker tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
2079*6777b538SAndroid Build Coastguard Worker ctxt->nameMax *
2080*6777b538SAndroid Build Coastguard Worker sizeof(ctxt->nameTab[0]));
2081*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
2082*6777b538SAndroid Build Coastguard Worker ctxt->nameMax /= 2;
2083*6777b538SAndroid Build Coastguard Worker goto mem_error;
2084*6777b538SAndroid Build Coastguard Worker }
2085*6777b538SAndroid Build Coastguard Worker ctxt->nameTab = tmp;
2086*6777b538SAndroid Build Coastguard Worker tmp2 = (xmlStartTag *) xmlRealloc((void * *)ctxt->pushTab,
2087*6777b538SAndroid Build Coastguard Worker ctxt->nameMax *
2088*6777b538SAndroid Build Coastguard Worker sizeof(ctxt->pushTab[0]));
2089*6777b538SAndroid Build Coastguard Worker if (tmp2 == NULL) {
2090*6777b538SAndroid Build Coastguard Worker ctxt->nameMax /= 2;
2091*6777b538SAndroid Build Coastguard Worker goto mem_error;
2092*6777b538SAndroid Build Coastguard Worker }
2093*6777b538SAndroid Build Coastguard Worker ctxt->pushTab = tmp2;
2094*6777b538SAndroid Build Coastguard Worker } else if (ctxt->pushTab == NULL) {
2095*6777b538SAndroid Build Coastguard Worker ctxt->pushTab = (xmlStartTag *) xmlMalloc(ctxt->nameMax *
2096*6777b538SAndroid Build Coastguard Worker sizeof(ctxt->pushTab[0]));
2097*6777b538SAndroid Build Coastguard Worker if (ctxt->pushTab == NULL)
2098*6777b538SAndroid Build Coastguard Worker goto mem_error;
2099*6777b538SAndroid Build Coastguard Worker }
2100*6777b538SAndroid Build Coastguard Worker ctxt->nameTab[ctxt->nameNr] = value;
2101*6777b538SAndroid Build Coastguard Worker ctxt->name = value;
2102*6777b538SAndroid Build Coastguard Worker tag = &ctxt->pushTab[ctxt->nameNr];
2103*6777b538SAndroid Build Coastguard Worker tag->prefix = prefix;
2104*6777b538SAndroid Build Coastguard Worker tag->URI = URI;
2105*6777b538SAndroid Build Coastguard Worker tag->line = line;
2106*6777b538SAndroid Build Coastguard Worker tag->nsNr = nsNr;
2107*6777b538SAndroid Build Coastguard Worker return (ctxt->nameNr++);
2108*6777b538SAndroid Build Coastguard Worker mem_error:
2109*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
2110*6777b538SAndroid Build Coastguard Worker return (-1);
2111*6777b538SAndroid Build Coastguard Worker }
2112*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_PUSH_ENABLED
2113*6777b538SAndroid Build Coastguard Worker /**
2114*6777b538SAndroid Build Coastguard Worker * nameNsPop:
2115*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2116*6777b538SAndroid Build Coastguard Worker *
2117*6777b538SAndroid Build Coastguard Worker * Pops the top element/prefix/URI name from the name stack
2118*6777b538SAndroid Build Coastguard Worker *
2119*6777b538SAndroid Build Coastguard Worker * Returns the name just removed
2120*6777b538SAndroid Build Coastguard Worker */
2121*6777b538SAndroid Build Coastguard Worker static const xmlChar *
nameNsPop(xmlParserCtxtPtr ctxt)2122*6777b538SAndroid Build Coastguard Worker nameNsPop(xmlParserCtxtPtr ctxt)
2123*6777b538SAndroid Build Coastguard Worker {
2124*6777b538SAndroid Build Coastguard Worker const xmlChar *ret;
2125*6777b538SAndroid Build Coastguard Worker
2126*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr <= 0)
2127*6777b538SAndroid Build Coastguard Worker return (NULL);
2128*6777b538SAndroid Build Coastguard Worker ctxt->nameNr--;
2129*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr > 0)
2130*6777b538SAndroid Build Coastguard Worker ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
2131*6777b538SAndroid Build Coastguard Worker else
2132*6777b538SAndroid Build Coastguard Worker ctxt->name = NULL;
2133*6777b538SAndroid Build Coastguard Worker ret = ctxt->nameTab[ctxt->nameNr];
2134*6777b538SAndroid Build Coastguard Worker ctxt->nameTab[ctxt->nameNr] = NULL;
2135*6777b538SAndroid Build Coastguard Worker return (ret);
2136*6777b538SAndroid Build Coastguard Worker }
2137*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_PUSH_ENABLED */
2138*6777b538SAndroid Build Coastguard Worker
2139*6777b538SAndroid Build Coastguard Worker /**
2140*6777b538SAndroid Build Coastguard Worker * namePush:
2141*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2142*6777b538SAndroid Build Coastguard Worker * @value: the element name
2143*6777b538SAndroid Build Coastguard Worker *
2144*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, do not use.
2145*6777b538SAndroid Build Coastguard Worker *
2146*6777b538SAndroid Build Coastguard Worker * Pushes a new element name on top of the name stack
2147*6777b538SAndroid Build Coastguard Worker *
2148*6777b538SAndroid Build Coastguard Worker * Returns -1 in case of error, the index in the stack otherwise
2149*6777b538SAndroid Build Coastguard Worker */
2150*6777b538SAndroid Build Coastguard Worker int
namePush(xmlParserCtxtPtr ctxt,const xmlChar * value)2151*6777b538SAndroid Build Coastguard Worker namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
2152*6777b538SAndroid Build Coastguard Worker {
2153*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL) return (-1);
2154*6777b538SAndroid Build Coastguard Worker
2155*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr >= ctxt->nameMax) {
2156*6777b538SAndroid Build Coastguard Worker const xmlChar * *tmp;
2157*6777b538SAndroid Build Coastguard Worker tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
2158*6777b538SAndroid Build Coastguard Worker ctxt->nameMax * 2 *
2159*6777b538SAndroid Build Coastguard Worker sizeof(ctxt->nameTab[0]));
2160*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
2161*6777b538SAndroid Build Coastguard Worker goto mem_error;
2162*6777b538SAndroid Build Coastguard Worker }
2163*6777b538SAndroid Build Coastguard Worker ctxt->nameTab = tmp;
2164*6777b538SAndroid Build Coastguard Worker ctxt->nameMax *= 2;
2165*6777b538SAndroid Build Coastguard Worker }
2166*6777b538SAndroid Build Coastguard Worker ctxt->nameTab[ctxt->nameNr] = value;
2167*6777b538SAndroid Build Coastguard Worker ctxt->name = value;
2168*6777b538SAndroid Build Coastguard Worker return (ctxt->nameNr++);
2169*6777b538SAndroid Build Coastguard Worker mem_error:
2170*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
2171*6777b538SAndroid Build Coastguard Worker return (-1);
2172*6777b538SAndroid Build Coastguard Worker }
2173*6777b538SAndroid Build Coastguard Worker
2174*6777b538SAndroid Build Coastguard Worker /**
2175*6777b538SAndroid Build Coastguard Worker * namePop:
2176*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2177*6777b538SAndroid Build Coastguard Worker *
2178*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, do not use.
2179*6777b538SAndroid Build Coastguard Worker *
2180*6777b538SAndroid Build Coastguard Worker * Pops the top element name from the name stack
2181*6777b538SAndroid Build Coastguard Worker *
2182*6777b538SAndroid Build Coastguard Worker * Returns the name just removed
2183*6777b538SAndroid Build Coastguard Worker */
2184*6777b538SAndroid Build Coastguard Worker const xmlChar *
namePop(xmlParserCtxtPtr ctxt)2185*6777b538SAndroid Build Coastguard Worker namePop(xmlParserCtxtPtr ctxt)
2186*6777b538SAndroid Build Coastguard Worker {
2187*6777b538SAndroid Build Coastguard Worker const xmlChar *ret;
2188*6777b538SAndroid Build Coastguard Worker
2189*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->nameNr <= 0))
2190*6777b538SAndroid Build Coastguard Worker return (NULL);
2191*6777b538SAndroid Build Coastguard Worker ctxt->nameNr--;
2192*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr > 0)
2193*6777b538SAndroid Build Coastguard Worker ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
2194*6777b538SAndroid Build Coastguard Worker else
2195*6777b538SAndroid Build Coastguard Worker ctxt->name = NULL;
2196*6777b538SAndroid Build Coastguard Worker ret = ctxt->nameTab[ctxt->nameNr];
2197*6777b538SAndroid Build Coastguard Worker ctxt->nameTab[ctxt->nameNr] = NULL;
2198*6777b538SAndroid Build Coastguard Worker return (ret);
2199*6777b538SAndroid Build Coastguard Worker }
2200*6777b538SAndroid Build Coastguard Worker
spacePush(xmlParserCtxtPtr ctxt,int val)2201*6777b538SAndroid Build Coastguard Worker static int spacePush(xmlParserCtxtPtr ctxt, int val) {
2202*6777b538SAndroid Build Coastguard Worker if (ctxt->spaceNr >= ctxt->spaceMax) {
2203*6777b538SAndroid Build Coastguard Worker int *tmp;
2204*6777b538SAndroid Build Coastguard Worker
2205*6777b538SAndroid Build Coastguard Worker ctxt->spaceMax *= 2;
2206*6777b538SAndroid Build Coastguard Worker tmp = (int *) xmlRealloc(ctxt->spaceTab,
2207*6777b538SAndroid Build Coastguard Worker ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
2208*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
2209*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
2210*6777b538SAndroid Build Coastguard Worker ctxt->spaceMax /=2;
2211*6777b538SAndroid Build Coastguard Worker return(-1);
2212*6777b538SAndroid Build Coastguard Worker }
2213*6777b538SAndroid Build Coastguard Worker ctxt->spaceTab = tmp;
2214*6777b538SAndroid Build Coastguard Worker }
2215*6777b538SAndroid Build Coastguard Worker ctxt->spaceTab[ctxt->spaceNr] = val;
2216*6777b538SAndroid Build Coastguard Worker ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
2217*6777b538SAndroid Build Coastguard Worker return(ctxt->spaceNr++);
2218*6777b538SAndroid Build Coastguard Worker }
2219*6777b538SAndroid Build Coastguard Worker
spacePop(xmlParserCtxtPtr ctxt)2220*6777b538SAndroid Build Coastguard Worker static int spacePop(xmlParserCtxtPtr ctxt) {
2221*6777b538SAndroid Build Coastguard Worker int ret;
2222*6777b538SAndroid Build Coastguard Worker if (ctxt->spaceNr <= 0) return(0);
2223*6777b538SAndroid Build Coastguard Worker ctxt->spaceNr--;
2224*6777b538SAndroid Build Coastguard Worker if (ctxt->spaceNr > 0)
2225*6777b538SAndroid Build Coastguard Worker ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
2226*6777b538SAndroid Build Coastguard Worker else
2227*6777b538SAndroid Build Coastguard Worker ctxt->space = &ctxt->spaceTab[0];
2228*6777b538SAndroid Build Coastguard Worker ret = ctxt->spaceTab[ctxt->spaceNr];
2229*6777b538SAndroid Build Coastguard Worker ctxt->spaceTab[ctxt->spaceNr] = -1;
2230*6777b538SAndroid Build Coastguard Worker return(ret);
2231*6777b538SAndroid Build Coastguard Worker }
2232*6777b538SAndroid Build Coastguard Worker
2233*6777b538SAndroid Build Coastguard Worker /*
2234*6777b538SAndroid Build Coastguard Worker * Macros for accessing the content. Those should be used only by the parser,
2235*6777b538SAndroid Build Coastguard Worker * and not exported.
2236*6777b538SAndroid Build Coastguard Worker *
2237*6777b538SAndroid Build Coastguard Worker * Dirty macros, i.e. one often need to make assumption on the context to
2238*6777b538SAndroid Build Coastguard Worker * use them
2239*6777b538SAndroid Build Coastguard Worker *
2240*6777b538SAndroid Build Coastguard Worker * CUR_PTR return the current pointer to the xmlChar to be parsed.
2241*6777b538SAndroid Build Coastguard Worker * To be used with extreme caution since operations consuming
2242*6777b538SAndroid Build Coastguard Worker * characters may move the input buffer to a different location !
2243*6777b538SAndroid Build Coastguard Worker * CUR returns the current xmlChar value, i.e. a 8 bit value if compiled
2244*6777b538SAndroid Build Coastguard Worker * This should be used internally by the parser
2245*6777b538SAndroid Build Coastguard Worker * only to compare to ASCII values otherwise it would break when
2246*6777b538SAndroid Build Coastguard Worker * running with UTF-8 encoding.
2247*6777b538SAndroid Build Coastguard Worker * RAW same as CUR but in the input buffer, bypass any token
2248*6777b538SAndroid Build Coastguard Worker * extraction that may have been done
2249*6777b538SAndroid Build Coastguard Worker * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
2250*6777b538SAndroid Build Coastguard Worker * to compare on ASCII based substring.
2251*6777b538SAndroid Build Coastguard Worker * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
2252*6777b538SAndroid Build Coastguard Worker * strings without newlines within the parser.
2253*6777b538SAndroid Build Coastguard Worker * NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII
2254*6777b538SAndroid Build Coastguard Worker * defined char within the parser.
2255*6777b538SAndroid Build Coastguard Worker * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
2256*6777b538SAndroid Build Coastguard Worker *
2257*6777b538SAndroid Build Coastguard Worker * NEXT Skip to the next character, this does the proper decoding
2258*6777b538SAndroid Build Coastguard Worker * in UTF-8 mode. It also pop-up unfinished entities on the fly.
2259*6777b538SAndroid Build Coastguard Worker * NEXTL(l) Skip the current unicode character of l xmlChars long.
2260*6777b538SAndroid Build Coastguard Worker * CUR_CHAR(l) returns the current unicode character (int), set l
2261*6777b538SAndroid Build Coastguard Worker * to the number of xmlChars used for the encoding [0-5].
2262*6777b538SAndroid Build Coastguard Worker * CUR_SCHAR same but operate on a string instead of the context
2263*6777b538SAndroid Build Coastguard Worker * COPY_BUF copy the current unicode char to the target buffer, increment
2264*6777b538SAndroid Build Coastguard Worker * the index
2265*6777b538SAndroid Build Coastguard Worker * GROW, SHRINK handling of input buffers
2266*6777b538SAndroid Build Coastguard Worker */
2267*6777b538SAndroid Build Coastguard Worker
2268*6777b538SAndroid Build Coastguard Worker #define RAW (*ctxt->input->cur)
2269*6777b538SAndroid Build Coastguard Worker #define CUR (*ctxt->input->cur)
2270*6777b538SAndroid Build Coastguard Worker #define NXT(val) ctxt->input->cur[(val)]
2271*6777b538SAndroid Build Coastguard Worker #define CUR_PTR ctxt->input->cur
2272*6777b538SAndroid Build Coastguard Worker #define BASE_PTR ctxt->input->base
2273*6777b538SAndroid Build Coastguard Worker
2274*6777b538SAndroid Build Coastguard Worker #define CMP4( s, c1, c2, c3, c4 ) \
2275*6777b538SAndroid Build Coastguard Worker ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
2276*6777b538SAndroid Build Coastguard Worker ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
2277*6777b538SAndroid Build Coastguard Worker #define CMP5( s, c1, c2, c3, c4, c5 ) \
2278*6777b538SAndroid Build Coastguard Worker ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
2279*6777b538SAndroid Build Coastguard Worker #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
2280*6777b538SAndroid Build Coastguard Worker ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
2281*6777b538SAndroid Build Coastguard Worker #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
2282*6777b538SAndroid Build Coastguard Worker ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
2283*6777b538SAndroid Build Coastguard Worker #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
2284*6777b538SAndroid Build Coastguard Worker ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
2285*6777b538SAndroid Build Coastguard Worker #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
2286*6777b538SAndroid Build Coastguard Worker ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
2287*6777b538SAndroid Build Coastguard Worker ((unsigned char *) s)[ 8 ] == c9 )
2288*6777b538SAndroid Build Coastguard Worker #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
2289*6777b538SAndroid Build Coastguard Worker ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
2290*6777b538SAndroid Build Coastguard Worker ((unsigned char *) s)[ 9 ] == c10 )
2291*6777b538SAndroid Build Coastguard Worker
2292*6777b538SAndroid Build Coastguard Worker #define SKIP(val) do { \
2293*6777b538SAndroid Build Coastguard Worker ctxt->input->cur += (val),ctxt->input->col+=(val); \
2294*6777b538SAndroid Build Coastguard Worker if (*ctxt->input->cur == 0) \
2295*6777b538SAndroid Build Coastguard Worker xmlParserGrow(ctxt); \
2296*6777b538SAndroid Build Coastguard Worker } while (0)
2297*6777b538SAndroid Build Coastguard Worker
2298*6777b538SAndroid Build Coastguard Worker #define SKIPL(val) do { \
2299*6777b538SAndroid Build Coastguard Worker int skipl; \
2300*6777b538SAndroid Build Coastguard Worker for(skipl=0; skipl<val; skipl++) { \
2301*6777b538SAndroid Build Coastguard Worker if (*(ctxt->input->cur) == '\n') { \
2302*6777b538SAndroid Build Coastguard Worker ctxt->input->line++; ctxt->input->col = 1; \
2303*6777b538SAndroid Build Coastguard Worker } else ctxt->input->col++; \
2304*6777b538SAndroid Build Coastguard Worker ctxt->input->cur++; \
2305*6777b538SAndroid Build Coastguard Worker } \
2306*6777b538SAndroid Build Coastguard Worker if (*ctxt->input->cur == 0) \
2307*6777b538SAndroid Build Coastguard Worker xmlParserGrow(ctxt); \
2308*6777b538SAndroid Build Coastguard Worker } while (0)
2309*6777b538SAndroid Build Coastguard Worker
2310*6777b538SAndroid Build Coastguard Worker #define SHRINK \
2311*6777b538SAndroid Build Coastguard Worker if ((!PARSER_PROGRESSIVE(ctxt)) && \
2312*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
2313*6777b538SAndroid Build Coastguard Worker (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
2314*6777b538SAndroid Build Coastguard Worker xmlParserShrink(ctxt);
2315*6777b538SAndroid Build Coastguard Worker
2316*6777b538SAndroid Build Coastguard Worker #define GROW \
2317*6777b538SAndroid Build Coastguard Worker if ((!PARSER_PROGRESSIVE(ctxt)) && \
2318*6777b538SAndroid Build Coastguard Worker (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \
2319*6777b538SAndroid Build Coastguard Worker xmlParserGrow(ctxt);
2320*6777b538SAndroid Build Coastguard Worker
2321*6777b538SAndroid Build Coastguard Worker #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
2322*6777b538SAndroid Build Coastguard Worker
2323*6777b538SAndroid Build Coastguard Worker #define SKIP_BLANKS_PE xmlSkipBlankCharsPE(ctxt)
2324*6777b538SAndroid Build Coastguard Worker
2325*6777b538SAndroid Build Coastguard Worker #define NEXT xmlNextChar(ctxt)
2326*6777b538SAndroid Build Coastguard Worker
2327*6777b538SAndroid Build Coastguard Worker #define NEXT1 { \
2328*6777b538SAndroid Build Coastguard Worker ctxt->input->col++; \
2329*6777b538SAndroid Build Coastguard Worker ctxt->input->cur++; \
2330*6777b538SAndroid Build Coastguard Worker if (*ctxt->input->cur == 0) \
2331*6777b538SAndroid Build Coastguard Worker xmlParserGrow(ctxt); \
2332*6777b538SAndroid Build Coastguard Worker }
2333*6777b538SAndroid Build Coastguard Worker
2334*6777b538SAndroid Build Coastguard Worker #define NEXTL(l) do { \
2335*6777b538SAndroid Build Coastguard Worker if (*(ctxt->input->cur) == '\n') { \
2336*6777b538SAndroid Build Coastguard Worker ctxt->input->line++; ctxt->input->col = 1; \
2337*6777b538SAndroid Build Coastguard Worker } else ctxt->input->col++; \
2338*6777b538SAndroid Build Coastguard Worker ctxt->input->cur += l; \
2339*6777b538SAndroid Build Coastguard Worker } while (0)
2340*6777b538SAndroid Build Coastguard Worker
2341*6777b538SAndroid Build Coastguard Worker #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
2342*6777b538SAndroid Build Coastguard Worker #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
2343*6777b538SAndroid Build Coastguard Worker
2344*6777b538SAndroid Build Coastguard Worker #define COPY_BUF(b, i, v) \
2345*6777b538SAndroid Build Coastguard Worker if (v < 0x80) b[i++] = v; \
2346*6777b538SAndroid Build Coastguard Worker else i += xmlCopyCharMultiByte(&b[i],v)
2347*6777b538SAndroid Build Coastguard Worker
2348*6777b538SAndroid Build Coastguard Worker /**
2349*6777b538SAndroid Build Coastguard Worker * xmlSkipBlankChars:
2350*6777b538SAndroid Build Coastguard Worker * @ctxt: the XML parser context
2351*6777b538SAndroid Build Coastguard Worker *
2352*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, do not use.
2353*6777b538SAndroid Build Coastguard Worker *
2354*6777b538SAndroid Build Coastguard Worker * Skip whitespace in the input stream.
2355*6777b538SAndroid Build Coastguard Worker *
2356*6777b538SAndroid Build Coastguard Worker * Returns the number of space chars skipped
2357*6777b538SAndroid Build Coastguard Worker */
2358*6777b538SAndroid Build Coastguard Worker int
xmlSkipBlankChars(xmlParserCtxtPtr ctxt)2359*6777b538SAndroid Build Coastguard Worker xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
2360*6777b538SAndroid Build Coastguard Worker const xmlChar *cur;
2361*6777b538SAndroid Build Coastguard Worker int res = 0;
2362*6777b538SAndroid Build Coastguard Worker
2363*6777b538SAndroid Build Coastguard Worker /*
2364*6777b538SAndroid Build Coastguard Worker * It's Okay to use CUR/NEXT here since all the blanks are on
2365*6777b538SAndroid Build Coastguard Worker * the ASCII range.
2366*6777b538SAndroid Build Coastguard Worker */
2367*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur;
2368*6777b538SAndroid Build Coastguard Worker while (IS_BLANK_CH(*cur)) {
2369*6777b538SAndroid Build Coastguard Worker if (*cur == '\n') {
2370*6777b538SAndroid Build Coastguard Worker ctxt->input->line++; ctxt->input->col = 1;
2371*6777b538SAndroid Build Coastguard Worker } else {
2372*6777b538SAndroid Build Coastguard Worker ctxt->input->col++;
2373*6777b538SAndroid Build Coastguard Worker }
2374*6777b538SAndroid Build Coastguard Worker cur++;
2375*6777b538SAndroid Build Coastguard Worker if (res < INT_MAX)
2376*6777b538SAndroid Build Coastguard Worker res++;
2377*6777b538SAndroid Build Coastguard Worker if (*cur == 0) {
2378*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = cur;
2379*6777b538SAndroid Build Coastguard Worker xmlParserGrow(ctxt);
2380*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur;
2381*6777b538SAndroid Build Coastguard Worker }
2382*6777b538SAndroid Build Coastguard Worker }
2383*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = cur;
2384*6777b538SAndroid Build Coastguard Worker
2385*6777b538SAndroid Build Coastguard Worker return(res);
2386*6777b538SAndroid Build Coastguard Worker }
2387*6777b538SAndroid Build Coastguard Worker
2388*6777b538SAndroid Build Coastguard Worker static void
xmlPopPE(xmlParserCtxtPtr ctxt)2389*6777b538SAndroid Build Coastguard Worker xmlPopPE(xmlParserCtxtPtr ctxt) {
2390*6777b538SAndroid Build Coastguard Worker unsigned long consumed;
2391*6777b538SAndroid Build Coastguard Worker xmlEntityPtr ent;
2392*6777b538SAndroid Build Coastguard Worker
2393*6777b538SAndroid Build Coastguard Worker ent = ctxt->input->entity;
2394*6777b538SAndroid Build Coastguard Worker
2395*6777b538SAndroid Build Coastguard Worker ent->flags &= ~XML_ENT_EXPANDING;
2396*6777b538SAndroid Build Coastguard Worker
2397*6777b538SAndroid Build Coastguard Worker if ((ent->flags & XML_ENT_CHECKED) == 0) {
2398*6777b538SAndroid Build Coastguard Worker int result;
2399*6777b538SAndroid Build Coastguard Worker
2400*6777b538SAndroid Build Coastguard Worker /*
2401*6777b538SAndroid Build Coastguard Worker * Read the rest of the stream in case of errors. We want
2402*6777b538SAndroid Build Coastguard Worker * to account for the whole entity size.
2403*6777b538SAndroid Build Coastguard Worker */
2404*6777b538SAndroid Build Coastguard Worker do {
2405*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = ctxt->input->end;
2406*6777b538SAndroid Build Coastguard Worker xmlParserShrink(ctxt);
2407*6777b538SAndroid Build Coastguard Worker result = xmlParserGrow(ctxt);
2408*6777b538SAndroid Build Coastguard Worker } while (result > 0);
2409*6777b538SAndroid Build Coastguard Worker
2410*6777b538SAndroid Build Coastguard Worker consumed = ctxt->input->consumed;
2411*6777b538SAndroid Build Coastguard Worker xmlSaturatedAddSizeT(&consumed,
2412*6777b538SAndroid Build Coastguard Worker ctxt->input->end - ctxt->input->base);
2413*6777b538SAndroid Build Coastguard Worker
2414*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(&ent->expandedSize, consumed);
2415*6777b538SAndroid Build Coastguard Worker
2416*6777b538SAndroid Build Coastguard Worker /*
2417*6777b538SAndroid Build Coastguard Worker * Add to sizeentities when parsing an external entity
2418*6777b538SAndroid Build Coastguard Worker * for the first time.
2419*6777b538SAndroid Build Coastguard Worker */
2420*6777b538SAndroid Build Coastguard Worker if (ent->etype == XML_EXTERNAL_PARAMETER_ENTITY) {
2421*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(&ctxt->sizeentities, consumed);
2422*6777b538SAndroid Build Coastguard Worker }
2423*6777b538SAndroid Build Coastguard Worker
2424*6777b538SAndroid Build Coastguard Worker ent->flags |= XML_ENT_CHECKED;
2425*6777b538SAndroid Build Coastguard Worker }
2426*6777b538SAndroid Build Coastguard Worker
2427*6777b538SAndroid Build Coastguard Worker xmlPopInput(ctxt);
2428*6777b538SAndroid Build Coastguard Worker
2429*6777b538SAndroid Build Coastguard Worker xmlParserEntityCheck(ctxt, ent->expandedSize);
2430*6777b538SAndroid Build Coastguard Worker }
2431*6777b538SAndroid Build Coastguard Worker
2432*6777b538SAndroid Build Coastguard Worker /**
2433*6777b538SAndroid Build Coastguard Worker * xmlSkipBlankCharsPE:
2434*6777b538SAndroid Build Coastguard Worker * @ctxt: the XML parser context
2435*6777b538SAndroid Build Coastguard Worker *
2436*6777b538SAndroid Build Coastguard Worker * Skip whitespace in the input stream, also handling parameter
2437*6777b538SAndroid Build Coastguard Worker * entities.
2438*6777b538SAndroid Build Coastguard Worker *
2439*6777b538SAndroid Build Coastguard Worker * Returns the number of space chars skipped
2440*6777b538SAndroid Build Coastguard Worker */
2441*6777b538SAndroid Build Coastguard Worker static int
xmlSkipBlankCharsPE(xmlParserCtxtPtr ctxt)2442*6777b538SAndroid Build Coastguard Worker xmlSkipBlankCharsPE(xmlParserCtxtPtr ctxt) {
2443*6777b538SAndroid Build Coastguard Worker int res = 0;
2444*6777b538SAndroid Build Coastguard Worker int inParam;
2445*6777b538SAndroid Build Coastguard Worker int expandParam;
2446*6777b538SAndroid Build Coastguard Worker
2447*6777b538SAndroid Build Coastguard Worker inParam = PARSER_IN_PE(ctxt);
2448*6777b538SAndroid Build Coastguard Worker expandParam = PARSER_EXTERNAL(ctxt);
2449*6777b538SAndroid Build Coastguard Worker
2450*6777b538SAndroid Build Coastguard Worker if (!inParam && !expandParam)
2451*6777b538SAndroid Build Coastguard Worker return(xmlSkipBlankChars(ctxt));
2452*6777b538SAndroid Build Coastguard Worker
2453*6777b538SAndroid Build Coastguard Worker while (PARSER_STOPPED(ctxt) == 0) {
2454*6777b538SAndroid Build Coastguard Worker if (IS_BLANK_CH(CUR)) { /* CHECKED tstblanks.xml */
2455*6777b538SAndroid Build Coastguard Worker NEXT;
2456*6777b538SAndroid Build Coastguard Worker } else if (CUR == '%') {
2457*6777b538SAndroid Build Coastguard Worker if ((expandParam == 0) ||
2458*6777b538SAndroid Build Coastguard Worker (IS_BLANK_CH(NXT(1))) || (NXT(1) == 0))
2459*6777b538SAndroid Build Coastguard Worker break;
2460*6777b538SAndroid Build Coastguard Worker
2461*6777b538SAndroid Build Coastguard Worker /*
2462*6777b538SAndroid Build Coastguard Worker * Expand parameter entity. We continue to consume
2463*6777b538SAndroid Build Coastguard Worker * whitespace at the start of the entity and possible
2464*6777b538SAndroid Build Coastguard Worker * even consume the whole entity and pop it. We might
2465*6777b538SAndroid Build Coastguard Worker * even pop multiple PEs in this loop.
2466*6777b538SAndroid Build Coastguard Worker */
2467*6777b538SAndroid Build Coastguard Worker xmlParsePEReference(ctxt);
2468*6777b538SAndroid Build Coastguard Worker
2469*6777b538SAndroid Build Coastguard Worker inParam = PARSER_IN_PE(ctxt);
2470*6777b538SAndroid Build Coastguard Worker expandParam = PARSER_EXTERNAL(ctxt);
2471*6777b538SAndroid Build Coastguard Worker } else if (CUR == 0) {
2472*6777b538SAndroid Build Coastguard Worker if (inParam == 0)
2473*6777b538SAndroid Build Coastguard Worker break;
2474*6777b538SAndroid Build Coastguard Worker
2475*6777b538SAndroid Build Coastguard Worker xmlPopPE(ctxt);
2476*6777b538SAndroid Build Coastguard Worker
2477*6777b538SAndroid Build Coastguard Worker inParam = PARSER_IN_PE(ctxt);
2478*6777b538SAndroid Build Coastguard Worker expandParam = PARSER_EXTERNAL(ctxt);
2479*6777b538SAndroid Build Coastguard Worker } else {
2480*6777b538SAndroid Build Coastguard Worker break;
2481*6777b538SAndroid Build Coastguard Worker }
2482*6777b538SAndroid Build Coastguard Worker
2483*6777b538SAndroid Build Coastguard Worker /*
2484*6777b538SAndroid Build Coastguard Worker * Also increase the counter when entering or exiting a PERef.
2485*6777b538SAndroid Build Coastguard Worker * The spec says: "When a parameter-entity reference is recognized
2486*6777b538SAndroid Build Coastguard Worker * in the DTD and included, its replacement text MUST be enlarged
2487*6777b538SAndroid Build Coastguard Worker * by the attachment of one leading and one following space (#x20)
2488*6777b538SAndroid Build Coastguard Worker * character."
2489*6777b538SAndroid Build Coastguard Worker */
2490*6777b538SAndroid Build Coastguard Worker if (res < INT_MAX)
2491*6777b538SAndroid Build Coastguard Worker res++;
2492*6777b538SAndroid Build Coastguard Worker }
2493*6777b538SAndroid Build Coastguard Worker
2494*6777b538SAndroid Build Coastguard Worker return(res);
2495*6777b538SAndroid Build Coastguard Worker }
2496*6777b538SAndroid Build Coastguard Worker
2497*6777b538SAndroid Build Coastguard Worker /************************************************************************
2498*6777b538SAndroid Build Coastguard Worker * *
2499*6777b538SAndroid Build Coastguard Worker * Commodity functions to handle entities *
2500*6777b538SAndroid Build Coastguard Worker * *
2501*6777b538SAndroid Build Coastguard Worker ************************************************************************/
2502*6777b538SAndroid Build Coastguard Worker
2503*6777b538SAndroid Build Coastguard Worker /**
2504*6777b538SAndroid Build Coastguard Worker * xmlPopInput:
2505*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2506*6777b538SAndroid Build Coastguard Worker *
2507*6777b538SAndroid Build Coastguard Worker * xmlPopInput: the current input pointed by ctxt->input came to an end
2508*6777b538SAndroid Build Coastguard Worker * pop it and return the next char.
2509*6777b538SAndroid Build Coastguard Worker *
2510*6777b538SAndroid Build Coastguard Worker * Returns the current xmlChar in the parser context
2511*6777b538SAndroid Build Coastguard Worker */
2512*6777b538SAndroid Build Coastguard Worker xmlChar
xmlPopInput(xmlParserCtxtPtr ctxt)2513*6777b538SAndroid Build Coastguard Worker xmlPopInput(xmlParserCtxtPtr ctxt) {
2514*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
2515*6777b538SAndroid Build Coastguard Worker
2516*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
2517*6777b538SAndroid Build Coastguard Worker input = inputPop(ctxt);
2518*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(input);
2519*6777b538SAndroid Build Coastguard Worker if (*ctxt->input->cur == 0)
2520*6777b538SAndroid Build Coastguard Worker xmlParserGrow(ctxt);
2521*6777b538SAndroid Build Coastguard Worker return(CUR);
2522*6777b538SAndroid Build Coastguard Worker }
2523*6777b538SAndroid Build Coastguard Worker
2524*6777b538SAndroid Build Coastguard Worker /**
2525*6777b538SAndroid Build Coastguard Worker * xmlPushInput:
2526*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2527*6777b538SAndroid Build Coastguard Worker * @input: an XML parser input fragment (entity, XML fragment ...).
2528*6777b538SAndroid Build Coastguard Worker *
2529*6777b538SAndroid Build Coastguard Worker * Push an input stream onto the stack.
2530*6777b538SAndroid Build Coastguard Worker *
2531*6777b538SAndroid Build Coastguard Worker * This makes the parser use an input returned from advanced functions
2532*6777b538SAndroid Build Coastguard Worker * like xmlNewInputURL or xmlNewInputMemory.
2533*6777b538SAndroid Build Coastguard Worker *
2534*6777b538SAndroid Build Coastguard Worker * Returns -1 in case of error or the index in the input stack
2535*6777b538SAndroid Build Coastguard Worker */
2536*6777b538SAndroid Build Coastguard Worker int
xmlPushInput(xmlParserCtxtPtr ctxt,xmlParserInputPtr input)2537*6777b538SAndroid Build Coastguard Worker xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
2538*6777b538SAndroid Build Coastguard Worker int maxDepth;
2539*6777b538SAndroid Build Coastguard Worker int ret;
2540*6777b538SAndroid Build Coastguard Worker
2541*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (input == NULL))
2542*6777b538SAndroid Build Coastguard Worker return(-1);
2543*6777b538SAndroid Build Coastguard Worker
2544*6777b538SAndroid Build Coastguard Worker maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 40 : 20;
2545*6777b538SAndroid Build Coastguard Worker if (ctxt->inputNr > maxDepth) {
2546*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT,
2547*6777b538SAndroid Build Coastguard Worker "Maximum entity nesting depth exceeded");
2548*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
2549*6777b538SAndroid Build Coastguard Worker return(-1);
2550*6777b538SAndroid Build Coastguard Worker }
2551*6777b538SAndroid Build Coastguard Worker ret = inputPush(ctxt, input);
2552*6777b538SAndroid Build Coastguard Worker GROW;
2553*6777b538SAndroid Build Coastguard Worker return(ret);
2554*6777b538SAndroid Build Coastguard Worker }
2555*6777b538SAndroid Build Coastguard Worker
2556*6777b538SAndroid Build Coastguard Worker /**
2557*6777b538SAndroid Build Coastguard Worker * xmlParseCharRef:
2558*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2559*6777b538SAndroid Build Coastguard Worker *
2560*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
2561*6777b538SAndroid Build Coastguard Worker *
2562*6777b538SAndroid Build Coastguard Worker * Parse a numeric character reference. Always consumes '&'.
2563*6777b538SAndroid Build Coastguard Worker *
2564*6777b538SAndroid Build Coastguard Worker * [66] CharRef ::= '&#' [0-9]+ ';' |
2565*6777b538SAndroid Build Coastguard Worker * '&#x' [0-9a-fA-F]+ ';'
2566*6777b538SAndroid Build Coastguard Worker *
2567*6777b538SAndroid Build Coastguard Worker * [ WFC: Legal Character ]
2568*6777b538SAndroid Build Coastguard Worker * Characters referred to using character references must match the
2569*6777b538SAndroid Build Coastguard Worker * production for Char.
2570*6777b538SAndroid Build Coastguard Worker *
2571*6777b538SAndroid Build Coastguard Worker * Returns the value parsed (as an int), 0 in case of error
2572*6777b538SAndroid Build Coastguard Worker */
2573*6777b538SAndroid Build Coastguard Worker int
xmlParseCharRef(xmlParserCtxtPtr ctxt)2574*6777b538SAndroid Build Coastguard Worker xmlParseCharRef(xmlParserCtxtPtr ctxt) {
2575*6777b538SAndroid Build Coastguard Worker int val = 0;
2576*6777b538SAndroid Build Coastguard Worker int count = 0;
2577*6777b538SAndroid Build Coastguard Worker
2578*6777b538SAndroid Build Coastguard Worker /*
2579*6777b538SAndroid Build Coastguard Worker * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
2580*6777b538SAndroid Build Coastguard Worker */
2581*6777b538SAndroid Build Coastguard Worker if ((RAW == '&') && (NXT(1) == '#') &&
2582*6777b538SAndroid Build Coastguard Worker (NXT(2) == 'x')) {
2583*6777b538SAndroid Build Coastguard Worker SKIP(3);
2584*6777b538SAndroid Build Coastguard Worker GROW;
2585*6777b538SAndroid Build Coastguard Worker while ((RAW != ';') && (PARSER_STOPPED(ctxt) == 0)) {
2586*6777b538SAndroid Build Coastguard Worker if (count++ > 20) {
2587*6777b538SAndroid Build Coastguard Worker count = 0;
2588*6777b538SAndroid Build Coastguard Worker GROW;
2589*6777b538SAndroid Build Coastguard Worker }
2590*6777b538SAndroid Build Coastguard Worker if ((RAW >= '0') && (RAW <= '9'))
2591*6777b538SAndroid Build Coastguard Worker val = val * 16 + (CUR - '0');
2592*6777b538SAndroid Build Coastguard Worker else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
2593*6777b538SAndroid Build Coastguard Worker val = val * 16 + (CUR - 'a') + 10;
2594*6777b538SAndroid Build Coastguard Worker else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
2595*6777b538SAndroid Build Coastguard Worker val = val * 16 + (CUR - 'A') + 10;
2596*6777b538SAndroid Build Coastguard Worker else {
2597*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2598*6777b538SAndroid Build Coastguard Worker val = 0;
2599*6777b538SAndroid Build Coastguard Worker break;
2600*6777b538SAndroid Build Coastguard Worker }
2601*6777b538SAndroid Build Coastguard Worker if (val > 0x110000)
2602*6777b538SAndroid Build Coastguard Worker val = 0x110000;
2603*6777b538SAndroid Build Coastguard Worker
2604*6777b538SAndroid Build Coastguard Worker NEXT;
2605*6777b538SAndroid Build Coastguard Worker count++;
2606*6777b538SAndroid Build Coastguard Worker }
2607*6777b538SAndroid Build Coastguard Worker if (RAW == ';') {
2608*6777b538SAndroid Build Coastguard Worker /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2609*6777b538SAndroid Build Coastguard Worker ctxt->input->col++;
2610*6777b538SAndroid Build Coastguard Worker ctxt->input->cur++;
2611*6777b538SAndroid Build Coastguard Worker }
2612*6777b538SAndroid Build Coastguard Worker } else if ((RAW == '&') && (NXT(1) == '#')) {
2613*6777b538SAndroid Build Coastguard Worker SKIP(2);
2614*6777b538SAndroid Build Coastguard Worker GROW;
2615*6777b538SAndroid Build Coastguard Worker while (RAW != ';') { /* loop blocked by count */
2616*6777b538SAndroid Build Coastguard Worker if (count++ > 20) {
2617*6777b538SAndroid Build Coastguard Worker count = 0;
2618*6777b538SAndroid Build Coastguard Worker GROW;
2619*6777b538SAndroid Build Coastguard Worker }
2620*6777b538SAndroid Build Coastguard Worker if ((RAW >= '0') && (RAW <= '9'))
2621*6777b538SAndroid Build Coastguard Worker val = val * 10 + (CUR - '0');
2622*6777b538SAndroid Build Coastguard Worker else {
2623*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2624*6777b538SAndroid Build Coastguard Worker val = 0;
2625*6777b538SAndroid Build Coastguard Worker break;
2626*6777b538SAndroid Build Coastguard Worker }
2627*6777b538SAndroid Build Coastguard Worker if (val > 0x110000)
2628*6777b538SAndroid Build Coastguard Worker val = 0x110000;
2629*6777b538SAndroid Build Coastguard Worker
2630*6777b538SAndroid Build Coastguard Worker NEXT;
2631*6777b538SAndroid Build Coastguard Worker count++;
2632*6777b538SAndroid Build Coastguard Worker }
2633*6777b538SAndroid Build Coastguard Worker if (RAW == ';') {
2634*6777b538SAndroid Build Coastguard Worker /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2635*6777b538SAndroid Build Coastguard Worker ctxt->input->col++;
2636*6777b538SAndroid Build Coastguard Worker ctxt->input->cur++;
2637*6777b538SAndroid Build Coastguard Worker }
2638*6777b538SAndroid Build Coastguard Worker } else {
2639*6777b538SAndroid Build Coastguard Worker if (RAW == '&')
2640*6777b538SAndroid Build Coastguard Worker SKIP(1);
2641*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2642*6777b538SAndroid Build Coastguard Worker }
2643*6777b538SAndroid Build Coastguard Worker
2644*6777b538SAndroid Build Coastguard Worker /*
2645*6777b538SAndroid Build Coastguard Worker * [ WFC: Legal Character ]
2646*6777b538SAndroid Build Coastguard Worker * Characters referred to using character references must match the
2647*6777b538SAndroid Build Coastguard Worker * production for Char.
2648*6777b538SAndroid Build Coastguard Worker */
2649*6777b538SAndroid Build Coastguard Worker if (val >= 0x110000) {
2650*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2651*6777b538SAndroid Build Coastguard Worker "xmlParseCharRef: character reference out of bounds\n",
2652*6777b538SAndroid Build Coastguard Worker val);
2653*6777b538SAndroid Build Coastguard Worker } else if (IS_CHAR(val)) {
2654*6777b538SAndroid Build Coastguard Worker return(val);
2655*6777b538SAndroid Build Coastguard Worker } else {
2656*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2657*6777b538SAndroid Build Coastguard Worker "xmlParseCharRef: invalid xmlChar value %d\n",
2658*6777b538SAndroid Build Coastguard Worker val);
2659*6777b538SAndroid Build Coastguard Worker }
2660*6777b538SAndroid Build Coastguard Worker return(0);
2661*6777b538SAndroid Build Coastguard Worker }
2662*6777b538SAndroid Build Coastguard Worker
2663*6777b538SAndroid Build Coastguard Worker /**
2664*6777b538SAndroid Build Coastguard Worker * xmlParseStringCharRef:
2665*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2666*6777b538SAndroid Build Coastguard Worker * @str: a pointer to an index in the string
2667*6777b538SAndroid Build Coastguard Worker *
2668*6777b538SAndroid Build Coastguard Worker * parse Reference declarations, variant parsing from a string rather
2669*6777b538SAndroid Build Coastguard Worker * than an an input flow.
2670*6777b538SAndroid Build Coastguard Worker *
2671*6777b538SAndroid Build Coastguard Worker * [66] CharRef ::= '&#' [0-9]+ ';' |
2672*6777b538SAndroid Build Coastguard Worker * '&#x' [0-9a-fA-F]+ ';'
2673*6777b538SAndroid Build Coastguard Worker *
2674*6777b538SAndroid Build Coastguard Worker * [ WFC: Legal Character ]
2675*6777b538SAndroid Build Coastguard Worker * Characters referred to using character references must match the
2676*6777b538SAndroid Build Coastguard Worker * production for Char.
2677*6777b538SAndroid Build Coastguard Worker *
2678*6777b538SAndroid Build Coastguard Worker * Returns the value parsed (as an int), 0 in case of error, str will be
2679*6777b538SAndroid Build Coastguard Worker * updated to the current value of the index
2680*6777b538SAndroid Build Coastguard Worker */
2681*6777b538SAndroid Build Coastguard Worker static int
xmlParseStringCharRef(xmlParserCtxtPtr ctxt,const xmlChar ** str)2682*6777b538SAndroid Build Coastguard Worker xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
2683*6777b538SAndroid Build Coastguard Worker const xmlChar *ptr;
2684*6777b538SAndroid Build Coastguard Worker xmlChar cur;
2685*6777b538SAndroid Build Coastguard Worker int val = 0;
2686*6777b538SAndroid Build Coastguard Worker
2687*6777b538SAndroid Build Coastguard Worker if ((str == NULL) || (*str == NULL)) return(0);
2688*6777b538SAndroid Build Coastguard Worker ptr = *str;
2689*6777b538SAndroid Build Coastguard Worker cur = *ptr;
2690*6777b538SAndroid Build Coastguard Worker if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
2691*6777b538SAndroid Build Coastguard Worker ptr += 3;
2692*6777b538SAndroid Build Coastguard Worker cur = *ptr;
2693*6777b538SAndroid Build Coastguard Worker while (cur != ';') { /* Non input consuming loop */
2694*6777b538SAndroid Build Coastguard Worker if ((cur >= '0') && (cur <= '9'))
2695*6777b538SAndroid Build Coastguard Worker val = val * 16 + (cur - '0');
2696*6777b538SAndroid Build Coastguard Worker else if ((cur >= 'a') && (cur <= 'f'))
2697*6777b538SAndroid Build Coastguard Worker val = val * 16 + (cur - 'a') + 10;
2698*6777b538SAndroid Build Coastguard Worker else if ((cur >= 'A') && (cur <= 'F'))
2699*6777b538SAndroid Build Coastguard Worker val = val * 16 + (cur - 'A') + 10;
2700*6777b538SAndroid Build Coastguard Worker else {
2701*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2702*6777b538SAndroid Build Coastguard Worker val = 0;
2703*6777b538SAndroid Build Coastguard Worker break;
2704*6777b538SAndroid Build Coastguard Worker }
2705*6777b538SAndroid Build Coastguard Worker if (val > 0x110000)
2706*6777b538SAndroid Build Coastguard Worker val = 0x110000;
2707*6777b538SAndroid Build Coastguard Worker
2708*6777b538SAndroid Build Coastguard Worker ptr++;
2709*6777b538SAndroid Build Coastguard Worker cur = *ptr;
2710*6777b538SAndroid Build Coastguard Worker }
2711*6777b538SAndroid Build Coastguard Worker if (cur == ';')
2712*6777b538SAndroid Build Coastguard Worker ptr++;
2713*6777b538SAndroid Build Coastguard Worker } else if ((cur == '&') && (ptr[1] == '#')){
2714*6777b538SAndroid Build Coastguard Worker ptr += 2;
2715*6777b538SAndroid Build Coastguard Worker cur = *ptr;
2716*6777b538SAndroid Build Coastguard Worker while (cur != ';') { /* Non input consuming loops */
2717*6777b538SAndroid Build Coastguard Worker if ((cur >= '0') && (cur <= '9'))
2718*6777b538SAndroid Build Coastguard Worker val = val * 10 + (cur - '0');
2719*6777b538SAndroid Build Coastguard Worker else {
2720*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2721*6777b538SAndroid Build Coastguard Worker val = 0;
2722*6777b538SAndroid Build Coastguard Worker break;
2723*6777b538SAndroid Build Coastguard Worker }
2724*6777b538SAndroid Build Coastguard Worker if (val > 0x110000)
2725*6777b538SAndroid Build Coastguard Worker val = 0x110000;
2726*6777b538SAndroid Build Coastguard Worker
2727*6777b538SAndroid Build Coastguard Worker ptr++;
2728*6777b538SAndroid Build Coastguard Worker cur = *ptr;
2729*6777b538SAndroid Build Coastguard Worker }
2730*6777b538SAndroid Build Coastguard Worker if (cur == ';')
2731*6777b538SAndroid Build Coastguard Worker ptr++;
2732*6777b538SAndroid Build Coastguard Worker } else {
2733*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2734*6777b538SAndroid Build Coastguard Worker return(0);
2735*6777b538SAndroid Build Coastguard Worker }
2736*6777b538SAndroid Build Coastguard Worker *str = ptr;
2737*6777b538SAndroid Build Coastguard Worker
2738*6777b538SAndroid Build Coastguard Worker /*
2739*6777b538SAndroid Build Coastguard Worker * [ WFC: Legal Character ]
2740*6777b538SAndroid Build Coastguard Worker * Characters referred to using character references must match the
2741*6777b538SAndroid Build Coastguard Worker * production for Char.
2742*6777b538SAndroid Build Coastguard Worker */
2743*6777b538SAndroid Build Coastguard Worker if (val >= 0x110000) {
2744*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2745*6777b538SAndroid Build Coastguard Worker "xmlParseStringCharRef: character reference out of bounds\n",
2746*6777b538SAndroid Build Coastguard Worker val);
2747*6777b538SAndroid Build Coastguard Worker } else if (IS_CHAR(val)) {
2748*6777b538SAndroid Build Coastguard Worker return(val);
2749*6777b538SAndroid Build Coastguard Worker } else {
2750*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2751*6777b538SAndroid Build Coastguard Worker "xmlParseStringCharRef: invalid xmlChar value %d\n",
2752*6777b538SAndroid Build Coastguard Worker val);
2753*6777b538SAndroid Build Coastguard Worker }
2754*6777b538SAndroid Build Coastguard Worker return(0);
2755*6777b538SAndroid Build Coastguard Worker }
2756*6777b538SAndroid Build Coastguard Worker
2757*6777b538SAndroid Build Coastguard Worker /**
2758*6777b538SAndroid Build Coastguard Worker * xmlParserHandlePEReference:
2759*6777b538SAndroid Build Coastguard Worker * @ctxt: the parser context
2760*6777b538SAndroid Build Coastguard Worker *
2761*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, do not use.
2762*6777b538SAndroid Build Coastguard Worker *
2763*6777b538SAndroid Build Coastguard Worker * [69] PEReference ::= '%' Name ';'
2764*6777b538SAndroid Build Coastguard Worker *
2765*6777b538SAndroid Build Coastguard Worker * [ WFC: No Recursion ]
2766*6777b538SAndroid Build Coastguard Worker * A parsed entity must not contain a recursive
2767*6777b538SAndroid Build Coastguard Worker * reference to itself, either directly or indirectly.
2768*6777b538SAndroid Build Coastguard Worker *
2769*6777b538SAndroid Build Coastguard Worker * [ WFC: Entity Declared ]
2770*6777b538SAndroid Build Coastguard Worker * In a document without any DTD, a document with only an internal DTD
2771*6777b538SAndroid Build Coastguard Worker * subset which contains no parameter entity references, or a document
2772*6777b538SAndroid Build Coastguard Worker * with "standalone='yes'", ... ... The declaration of a parameter
2773*6777b538SAndroid Build Coastguard Worker * entity must precede any reference to it...
2774*6777b538SAndroid Build Coastguard Worker *
2775*6777b538SAndroid Build Coastguard Worker * [ VC: Entity Declared ]
2776*6777b538SAndroid Build Coastguard Worker * In a document with an external subset or external parameter entities
2777*6777b538SAndroid Build Coastguard Worker * with "standalone='no'", ... ... The declaration of a parameter entity
2778*6777b538SAndroid Build Coastguard Worker * must precede any reference to it...
2779*6777b538SAndroid Build Coastguard Worker *
2780*6777b538SAndroid Build Coastguard Worker * [ WFC: In DTD ]
2781*6777b538SAndroid Build Coastguard Worker * Parameter-entity references may only appear in the DTD.
2782*6777b538SAndroid Build Coastguard Worker * NOTE: misleading but this is handled.
2783*6777b538SAndroid Build Coastguard Worker *
2784*6777b538SAndroid Build Coastguard Worker * A PEReference may have been detected in the current input stream
2785*6777b538SAndroid Build Coastguard Worker * the handling is done accordingly to
2786*6777b538SAndroid Build Coastguard Worker * http://www.w3.org/TR/REC-xml#entproc
2787*6777b538SAndroid Build Coastguard Worker * i.e.
2788*6777b538SAndroid Build Coastguard Worker * - Included in literal in entity values
2789*6777b538SAndroid Build Coastguard Worker * - Included as Parameter Entity reference within DTDs
2790*6777b538SAndroid Build Coastguard Worker */
2791*6777b538SAndroid Build Coastguard Worker void
xmlParserHandlePEReference(xmlParserCtxtPtr ctxt)2792*6777b538SAndroid Build Coastguard Worker xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
2793*6777b538SAndroid Build Coastguard Worker xmlParsePEReference(ctxt);
2794*6777b538SAndroid Build Coastguard Worker }
2795*6777b538SAndroid Build Coastguard Worker
2796*6777b538SAndroid Build Coastguard Worker /**
2797*6777b538SAndroid Build Coastguard Worker * xmlStringLenDecodeEntities:
2798*6777b538SAndroid Build Coastguard Worker * @ctxt: the parser context
2799*6777b538SAndroid Build Coastguard Worker * @str: the input string
2800*6777b538SAndroid Build Coastguard Worker * @len: the string length
2801*6777b538SAndroid Build Coastguard Worker * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2802*6777b538SAndroid Build Coastguard Worker * @end: an end marker xmlChar, 0 if none
2803*6777b538SAndroid Build Coastguard Worker * @end2: an end marker xmlChar, 0 if none
2804*6777b538SAndroid Build Coastguard Worker * @end3: an end marker xmlChar, 0 if none
2805*6777b538SAndroid Build Coastguard Worker *
2806*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
2807*6777b538SAndroid Build Coastguard Worker *
2808*6777b538SAndroid Build Coastguard Worker * Returns A newly allocated string with the substitution done. The caller
2809*6777b538SAndroid Build Coastguard Worker * must deallocate it !
2810*6777b538SAndroid Build Coastguard Worker */
2811*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt,const xmlChar * str,int len,int what ATTRIBUTE_UNUSED,xmlChar end,xmlChar end2,xmlChar end3)2812*6777b538SAndroid Build Coastguard Worker xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2813*6777b538SAndroid Build Coastguard Worker int what ATTRIBUTE_UNUSED,
2814*6777b538SAndroid Build Coastguard Worker xmlChar end, xmlChar end2, xmlChar end3) {
2815*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (str == NULL) || (len < 0))
2816*6777b538SAndroid Build Coastguard Worker return(NULL);
2817*6777b538SAndroid Build Coastguard Worker
2818*6777b538SAndroid Build Coastguard Worker if ((str[len] != 0) ||
2819*6777b538SAndroid Build Coastguard Worker (end != 0) || (end2 != 0) || (end3 != 0))
2820*6777b538SAndroid Build Coastguard Worker return(NULL);
2821*6777b538SAndroid Build Coastguard Worker
2822*6777b538SAndroid Build Coastguard Worker return(xmlExpandEntitiesInAttValue(ctxt, str, 0));
2823*6777b538SAndroid Build Coastguard Worker }
2824*6777b538SAndroid Build Coastguard Worker
2825*6777b538SAndroid Build Coastguard Worker /**
2826*6777b538SAndroid Build Coastguard Worker * xmlStringDecodeEntities:
2827*6777b538SAndroid Build Coastguard Worker * @ctxt: the parser context
2828*6777b538SAndroid Build Coastguard Worker * @str: the input string
2829*6777b538SAndroid Build Coastguard Worker * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2830*6777b538SAndroid Build Coastguard Worker * @end: an end marker xmlChar, 0 if none
2831*6777b538SAndroid Build Coastguard Worker * @end2: an end marker xmlChar, 0 if none
2832*6777b538SAndroid Build Coastguard Worker * @end3: an end marker xmlChar, 0 if none
2833*6777b538SAndroid Build Coastguard Worker *
2834*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
2835*6777b538SAndroid Build Coastguard Worker *
2836*6777b538SAndroid Build Coastguard Worker * Returns A newly allocated string with the substitution done. The caller
2837*6777b538SAndroid Build Coastguard Worker * must deallocate it !
2838*6777b538SAndroid Build Coastguard Worker */
2839*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlStringDecodeEntities(xmlParserCtxtPtr ctxt,const xmlChar * str,int what ATTRIBUTE_UNUSED,xmlChar end,xmlChar end2,xmlChar end3)2840*6777b538SAndroid Build Coastguard Worker xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
2841*6777b538SAndroid Build Coastguard Worker int what ATTRIBUTE_UNUSED,
2842*6777b538SAndroid Build Coastguard Worker xmlChar end, xmlChar end2, xmlChar end3) {
2843*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (str == NULL))
2844*6777b538SAndroid Build Coastguard Worker return(NULL);
2845*6777b538SAndroid Build Coastguard Worker
2846*6777b538SAndroid Build Coastguard Worker if ((end != 0) || (end2 != 0) || (end3 != 0))
2847*6777b538SAndroid Build Coastguard Worker return(NULL);
2848*6777b538SAndroid Build Coastguard Worker
2849*6777b538SAndroid Build Coastguard Worker return(xmlExpandEntitiesInAttValue(ctxt, str, 0));
2850*6777b538SAndroid Build Coastguard Worker }
2851*6777b538SAndroid Build Coastguard Worker
2852*6777b538SAndroid Build Coastguard Worker /************************************************************************
2853*6777b538SAndroid Build Coastguard Worker * *
2854*6777b538SAndroid Build Coastguard Worker * Commodity functions, cleanup needed ? *
2855*6777b538SAndroid Build Coastguard Worker * *
2856*6777b538SAndroid Build Coastguard Worker ************************************************************************/
2857*6777b538SAndroid Build Coastguard Worker
2858*6777b538SAndroid Build Coastguard Worker /**
2859*6777b538SAndroid Build Coastguard Worker * areBlanks:
2860*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2861*6777b538SAndroid Build Coastguard Worker * @str: a xmlChar *
2862*6777b538SAndroid Build Coastguard Worker * @len: the size of @str
2863*6777b538SAndroid Build Coastguard Worker * @blank_chars: we know the chars are blanks
2864*6777b538SAndroid Build Coastguard Worker *
2865*6777b538SAndroid Build Coastguard Worker * Is this a sequence of blank chars that one can ignore ?
2866*6777b538SAndroid Build Coastguard Worker *
2867*6777b538SAndroid Build Coastguard Worker * Returns 1 if ignorable 0 otherwise.
2868*6777b538SAndroid Build Coastguard Worker */
2869*6777b538SAndroid Build Coastguard Worker
areBlanks(xmlParserCtxtPtr ctxt,const xmlChar * str,int len,int blank_chars)2870*6777b538SAndroid Build Coastguard Worker static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2871*6777b538SAndroid Build Coastguard Worker int blank_chars) {
2872*6777b538SAndroid Build Coastguard Worker int i;
2873*6777b538SAndroid Build Coastguard Worker xmlNodePtr lastChild;
2874*6777b538SAndroid Build Coastguard Worker
2875*6777b538SAndroid Build Coastguard Worker /*
2876*6777b538SAndroid Build Coastguard Worker * Don't spend time trying to differentiate them, the same callback is
2877*6777b538SAndroid Build Coastguard Worker * used !
2878*6777b538SAndroid Build Coastguard Worker */
2879*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
2880*6777b538SAndroid Build Coastguard Worker return(0);
2881*6777b538SAndroid Build Coastguard Worker
2882*6777b538SAndroid Build Coastguard Worker /*
2883*6777b538SAndroid Build Coastguard Worker * Check for xml:space value.
2884*6777b538SAndroid Build Coastguard Worker */
2885*6777b538SAndroid Build Coastguard Worker if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
2886*6777b538SAndroid Build Coastguard Worker (*(ctxt->space) == -2))
2887*6777b538SAndroid Build Coastguard Worker return(0);
2888*6777b538SAndroid Build Coastguard Worker
2889*6777b538SAndroid Build Coastguard Worker /*
2890*6777b538SAndroid Build Coastguard Worker * Check that the string is made of blanks
2891*6777b538SAndroid Build Coastguard Worker */
2892*6777b538SAndroid Build Coastguard Worker if (blank_chars == 0) {
2893*6777b538SAndroid Build Coastguard Worker for (i = 0;i < len;i++)
2894*6777b538SAndroid Build Coastguard Worker if (!(IS_BLANK_CH(str[i]))) return(0);
2895*6777b538SAndroid Build Coastguard Worker }
2896*6777b538SAndroid Build Coastguard Worker
2897*6777b538SAndroid Build Coastguard Worker /*
2898*6777b538SAndroid Build Coastguard Worker * Look if the element is mixed content in the DTD if available
2899*6777b538SAndroid Build Coastguard Worker */
2900*6777b538SAndroid Build Coastguard Worker if (ctxt->node == NULL) return(0);
2901*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc != NULL) {
2902*6777b538SAndroid Build Coastguard Worker xmlElementPtr elemDecl = NULL;
2903*6777b538SAndroid Build Coastguard Worker xmlDocPtr doc = ctxt->myDoc;
2904*6777b538SAndroid Build Coastguard Worker const xmlChar *prefix = NULL;
2905*6777b538SAndroid Build Coastguard Worker
2906*6777b538SAndroid Build Coastguard Worker if (ctxt->node->ns)
2907*6777b538SAndroid Build Coastguard Worker prefix = ctxt->node->ns->prefix;
2908*6777b538SAndroid Build Coastguard Worker if (doc->intSubset != NULL)
2909*6777b538SAndroid Build Coastguard Worker elemDecl = xmlHashLookup2(doc->intSubset->elements, ctxt->node->name,
2910*6777b538SAndroid Build Coastguard Worker prefix);
2911*6777b538SAndroid Build Coastguard Worker if ((elemDecl == NULL) && (doc->extSubset != NULL))
2912*6777b538SAndroid Build Coastguard Worker elemDecl = xmlHashLookup2(doc->extSubset->elements, ctxt->node->name,
2913*6777b538SAndroid Build Coastguard Worker prefix);
2914*6777b538SAndroid Build Coastguard Worker if (elemDecl != NULL) {
2915*6777b538SAndroid Build Coastguard Worker if (elemDecl->etype == XML_ELEMENT_TYPE_ELEMENT)
2916*6777b538SAndroid Build Coastguard Worker return(1);
2917*6777b538SAndroid Build Coastguard Worker if ((elemDecl->etype == XML_ELEMENT_TYPE_ANY) ||
2918*6777b538SAndroid Build Coastguard Worker (elemDecl->etype == XML_ELEMENT_TYPE_MIXED))
2919*6777b538SAndroid Build Coastguard Worker return(0);
2920*6777b538SAndroid Build Coastguard Worker }
2921*6777b538SAndroid Build Coastguard Worker }
2922*6777b538SAndroid Build Coastguard Worker
2923*6777b538SAndroid Build Coastguard Worker /*
2924*6777b538SAndroid Build Coastguard Worker * Otherwise, heuristic :-\
2925*6777b538SAndroid Build Coastguard Worker */
2926*6777b538SAndroid Build Coastguard Worker if ((RAW != '<') && (RAW != 0xD)) return(0);
2927*6777b538SAndroid Build Coastguard Worker if ((ctxt->node->children == NULL) &&
2928*6777b538SAndroid Build Coastguard Worker (RAW == '<') && (NXT(1) == '/')) return(0);
2929*6777b538SAndroid Build Coastguard Worker
2930*6777b538SAndroid Build Coastguard Worker lastChild = xmlGetLastChild(ctxt->node);
2931*6777b538SAndroid Build Coastguard Worker if (lastChild == NULL) {
2932*6777b538SAndroid Build Coastguard Worker if ((ctxt->node->type != XML_ELEMENT_NODE) &&
2933*6777b538SAndroid Build Coastguard Worker (ctxt->node->content != NULL)) return(0);
2934*6777b538SAndroid Build Coastguard Worker } else if (xmlNodeIsText(lastChild))
2935*6777b538SAndroid Build Coastguard Worker return(0);
2936*6777b538SAndroid Build Coastguard Worker else if ((ctxt->node->children != NULL) &&
2937*6777b538SAndroid Build Coastguard Worker (xmlNodeIsText(ctxt->node->children)))
2938*6777b538SAndroid Build Coastguard Worker return(0);
2939*6777b538SAndroid Build Coastguard Worker return(1);
2940*6777b538SAndroid Build Coastguard Worker }
2941*6777b538SAndroid Build Coastguard Worker
2942*6777b538SAndroid Build Coastguard Worker /************************************************************************
2943*6777b538SAndroid Build Coastguard Worker * *
2944*6777b538SAndroid Build Coastguard Worker * Extra stuff for namespace support *
2945*6777b538SAndroid Build Coastguard Worker * Relates to http://www.w3.org/TR/WD-xml-names *
2946*6777b538SAndroid Build Coastguard Worker * *
2947*6777b538SAndroid Build Coastguard Worker ************************************************************************/
2948*6777b538SAndroid Build Coastguard Worker
2949*6777b538SAndroid Build Coastguard Worker /**
2950*6777b538SAndroid Build Coastguard Worker * xmlSplitQName:
2951*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
2952*6777b538SAndroid Build Coastguard Worker * @name: an XML parser context
2953*6777b538SAndroid Build Coastguard Worker * @prefixOut: a xmlChar **
2954*6777b538SAndroid Build Coastguard Worker *
2955*6777b538SAndroid Build Coastguard Worker * parse an UTF8 encoded XML qualified name string
2956*6777b538SAndroid Build Coastguard Worker *
2957*6777b538SAndroid Build Coastguard Worker * [NS 5] QName ::= (Prefix ':')? LocalPart
2958*6777b538SAndroid Build Coastguard Worker *
2959*6777b538SAndroid Build Coastguard Worker * [NS 6] Prefix ::= NCName
2960*6777b538SAndroid Build Coastguard Worker *
2961*6777b538SAndroid Build Coastguard Worker * [NS 7] LocalPart ::= NCName
2962*6777b538SAndroid Build Coastguard Worker *
2963*6777b538SAndroid Build Coastguard Worker * Returns the local part, and prefix is updated
2964*6777b538SAndroid Build Coastguard Worker * to get the Prefix if any.
2965*6777b538SAndroid Build Coastguard Worker */
2966*6777b538SAndroid Build Coastguard Worker
2967*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlSplitQName(xmlParserCtxtPtr ctxt,const xmlChar * name,xmlChar ** prefixOut)2968*6777b538SAndroid Build Coastguard Worker xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefixOut) {
2969*6777b538SAndroid Build Coastguard Worker xmlChar buf[XML_MAX_NAMELEN + 5];
2970*6777b538SAndroid Build Coastguard Worker xmlChar *buffer = NULL;
2971*6777b538SAndroid Build Coastguard Worker int len = 0;
2972*6777b538SAndroid Build Coastguard Worker int max = XML_MAX_NAMELEN;
2973*6777b538SAndroid Build Coastguard Worker xmlChar *ret = NULL;
2974*6777b538SAndroid Build Coastguard Worker xmlChar *prefix;
2975*6777b538SAndroid Build Coastguard Worker const xmlChar *cur = name;
2976*6777b538SAndroid Build Coastguard Worker int c;
2977*6777b538SAndroid Build Coastguard Worker
2978*6777b538SAndroid Build Coastguard Worker if (prefixOut == NULL) return(NULL);
2979*6777b538SAndroid Build Coastguard Worker *prefixOut = NULL;
2980*6777b538SAndroid Build Coastguard Worker
2981*6777b538SAndroid Build Coastguard Worker if (cur == NULL) return(NULL);
2982*6777b538SAndroid Build Coastguard Worker
2983*6777b538SAndroid Build Coastguard Worker #ifndef XML_XML_NAMESPACE
2984*6777b538SAndroid Build Coastguard Worker /* xml: prefix is not really a namespace */
2985*6777b538SAndroid Build Coastguard Worker if ((cur[0] == 'x') && (cur[1] == 'm') &&
2986*6777b538SAndroid Build Coastguard Worker (cur[2] == 'l') && (cur[3] == ':'))
2987*6777b538SAndroid Build Coastguard Worker return(xmlStrdup(name));
2988*6777b538SAndroid Build Coastguard Worker #endif
2989*6777b538SAndroid Build Coastguard Worker
2990*6777b538SAndroid Build Coastguard Worker /* nasty but well=formed */
2991*6777b538SAndroid Build Coastguard Worker if (cur[0] == ':')
2992*6777b538SAndroid Build Coastguard Worker return(xmlStrdup(name));
2993*6777b538SAndroid Build Coastguard Worker
2994*6777b538SAndroid Build Coastguard Worker c = *cur++;
2995*6777b538SAndroid Build Coastguard Worker while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
2996*6777b538SAndroid Build Coastguard Worker buf[len++] = c;
2997*6777b538SAndroid Build Coastguard Worker c = *cur++;
2998*6777b538SAndroid Build Coastguard Worker }
2999*6777b538SAndroid Build Coastguard Worker if (len >= max) {
3000*6777b538SAndroid Build Coastguard Worker /*
3001*6777b538SAndroid Build Coastguard Worker * Okay someone managed to make a huge name, so he's ready to pay
3002*6777b538SAndroid Build Coastguard Worker * for the processing speed.
3003*6777b538SAndroid Build Coastguard Worker */
3004*6777b538SAndroid Build Coastguard Worker max = len * 2;
3005*6777b538SAndroid Build Coastguard Worker
3006*6777b538SAndroid Build Coastguard Worker buffer = (xmlChar *) xmlMallocAtomic(max);
3007*6777b538SAndroid Build Coastguard Worker if (buffer == NULL) {
3008*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3009*6777b538SAndroid Build Coastguard Worker return(NULL);
3010*6777b538SAndroid Build Coastguard Worker }
3011*6777b538SAndroid Build Coastguard Worker memcpy(buffer, buf, len);
3012*6777b538SAndroid Build Coastguard Worker while ((c != 0) && (c != ':')) { /* tested bigname.xml */
3013*6777b538SAndroid Build Coastguard Worker if (len + 10 > max) {
3014*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
3015*6777b538SAndroid Build Coastguard Worker
3016*6777b538SAndroid Build Coastguard Worker max *= 2;
3017*6777b538SAndroid Build Coastguard Worker tmp = (xmlChar *) xmlRealloc(buffer, max);
3018*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
3019*6777b538SAndroid Build Coastguard Worker xmlFree(buffer);
3020*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3021*6777b538SAndroid Build Coastguard Worker return(NULL);
3022*6777b538SAndroid Build Coastguard Worker }
3023*6777b538SAndroid Build Coastguard Worker buffer = tmp;
3024*6777b538SAndroid Build Coastguard Worker }
3025*6777b538SAndroid Build Coastguard Worker buffer[len++] = c;
3026*6777b538SAndroid Build Coastguard Worker c = *cur++;
3027*6777b538SAndroid Build Coastguard Worker }
3028*6777b538SAndroid Build Coastguard Worker buffer[len] = 0;
3029*6777b538SAndroid Build Coastguard Worker }
3030*6777b538SAndroid Build Coastguard Worker
3031*6777b538SAndroid Build Coastguard Worker if ((c == ':') && (*cur == 0)) {
3032*6777b538SAndroid Build Coastguard Worker if (buffer != NULL)
3033*6777b538SAndroid Build Coastguard Worker xmlFree(buffer);
3034*6777b538SAndroid Build Coastguard Worker return(xmlStrdup(name));
3035*6777b538SAndroid Build Coastguard Worker }
3036*6777b538SAndroid Build Coastguard Worker
3037*6777b538SAndroid Build Coastguard Worker if (buffer == NULL) {
3038*6777b538SAndroid Build Coastguard Worker ret = xmlStrndup(buf, len);
3039*6777b538SAndroid Build Coastguard Worker if (ret == NULL) {
3040*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3041*6777b538SAndroid Build Coastguard Worker return(NULL);
3042*6777b538SAndroid Build Coastguard Worker }
3043*6777b538SAndroid Build Coastguard Worker } else {
3044*6777b538SAndroid Build Coastguard Worker ret = buffer;
3045*6777b538SAndroid Build Coastguard Worker buffer = NULL;
3046*6777b538SAndroid Build Coastguard Worker max = XML_MAX_NAMELEN;
3047*6777b538SAndroid Build Coastguard Worker }
3048*6777b538SAndroid Build Coastguard Worker
3049*6777b538SAndroid Build Coastguard Worker
3050*6777b538SAndroid Build Coastguard Worker if (c == ':') {
3051*6777b538SAndroid Build Coastguard Worker c = *cur;
3052*6777b538SAndroid Build Coastguard Worker prefix = ret;
3053*6777b538SAndroid Build Coastguard Worker if (c == 0) {
3054*6777b538SAndroid Build Coastguard Worker ret = xmlStrndup(BAD_CAST "", 0);
3055*6777b538SAndroid Build Coastguard Worker if (ret == NULL) {
3056*6777b538SAndroid Build Coastguard Worker xmlFree(prefix);
3057*6777b538SAndroid Build Coastguard Worker return(NULL);
3058*6777b538SAndroid Build Coastguard Worker }
3059*6777b538SAndroid Build Coastguard Worker *prefixOut = prefix;
3060*6777b538SAndroid Build Coastguard Worker return(ret);
3061*6777b538SAndroid Build Coastguard Worker }
3062*6777b538SAndroid Build Coastguard Worker len = 0;
3063*6777b538SAndroid Build Coastguard Worker
3064*6777b538SAndroid Build Coastguard Worker /*
3065*6777b538SAndroid Build Coastguard Worker * Check that the first character is proper to start
3066*6777b538SAndroid Build Coastguard Worker * a new name
3067*6777b538SAndroid Build Coastguard Worker */
3068*6777b538SAndroid Build Coastguard Worker if (!(((c >= 0x61) && (c <= 0x7A)) ||
3069*6777b538SAndroid Build Coastguard Worker ((c >= 0x41) && (c <= 0x5A)) ||
3070*6777b538SAndroid Build Coastguard Worker (c == '_') || (c == ':'))) {
3071*6777b538SAndroid Build Coastguard Worker int l;
3072*6777b538SAndroid Build Coastguard Worker int first = CUR_SCHAR(cur, l);
3073*6777b538SAndroid Build Coastguard Worker
3074*6777b538SAndroid Build Coastguard Worker if (!IS_LETTER(first) && (first != '_')) {
3075*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
3076*6777b538SAndroid Build Coastguard Worker "Name %s is not XML Namespace compliant\n",
3077*6777b538SAndroid Build Coastguard Worker name);
3078*6777b538SAndroid Build Coastguard Worker }
3079*6777b538SAndroid Build Coastguard Worker }
3080*6777b538SAndroid Build Coastguard Worker cur++;
3081*6777b538SAndroid Build Coastguard Worker
3082*6777b538SAndroid Build Coastguard Worker while ((c != 0) && (len < max)) { /* tested bigname2.xml */
3083*6777b538SAndroid Build Coastguard Worker buf[len++] = c;
3084*6777b538SAndroid Build Coastguard Worker c = *cur++;
3085*6777b538SAndroid Build Coastguard Worker }
3086*6777b538SAndroid Build Coastguard Worker if (len >= max) {
3087*6777b538SAndroid Build Coastguard Worker /*
3088*6777b538SAndroid Build Coastguard Worker * Okay someone managed to make a huge name, so he's ready to pay
3089*6777b538SAndroid Build Coastguard Worker * for the processing speed.
3090*6777b538SAndroid Build Coastguard Worker */
3091*6777b538SAndroid Build Coastguard Worker max = len * 2;
3092*6777b538SAndroid Build Coastguard Worker
3093*6777b538SAndroid Build Coastguard Worker buffer = (xmlChar *) xmlMallocAtomic(max);
3094*6777b538SAndroid Build Coastguard Worker if (buffer == NULL) {
3095*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3096*6777b538SAndroid Build Coastguard Worker xmlFree(prefix);
3097*6777b538SAndroid Build Coastguard Worker return(NULL);
3098*6777b538SAndroid Build Coastguard Worker }
3099*6777b538SAndroid Build Coastguard Worker memcpy(buffer, buf, len);
3100*6777b538SAndroid Build Coastguard Worker while (c != 0) { /* tested bigname2.xml */
3101*6777b538SAndroid Build Coastguard Worker if (len + 10 > max) {
3102*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
3103*6777b538SAndroid Build Coastguard Worker
3104*6777b538SAndroid Build Coastguard Worker max *= 2;
3105*6777b538SAndroid Build Coastguard Worker tmp = (xmlChar *) xmlRealloc(buffer, max);
3106*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
3107*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3108*6777b538SAndroid Build Coastguard Worker xmlFree(prefix);
3109*6777b538SAndroid Build Coastguard Worker xmlFree(buffer);
3110*6777b538SAndroid Build Coastguard Worker return(NULL);
3111*6777b538SAndroid Build Coastguard Worker }
3112*6777b538SAndroid Build Coastguard Worker buffer = tmp;
3113*6777b538SAndroid Build Coastguard Worker }
3114*6777b538SAndroid Build Coastguard Worker buffer[len++] = c;
3115*6777b538SAndroid Build Coastguard Worker c = *cur++;
3116*6777b538SAndroid Build Coastguard Worker }
3117*6777b538SAndroid Build Coastguard Worker buffer[len] = 0;
3118*6777b538SAndroid Build Coastguard Worker }
3119*6777b538SAndroid Build Coastguard Worker
3120*6777b538SAndroid Build Coastguard Worker if (buffer == NULL) {
3121*6777b538SAndroid Build Coastguard Worker ret = xmlStrndup(buf, len);
3122*6777b538SAndroid Build Coastguard Worker if (ret == NULL) {
3123*6777b538SAndroid Build Coastguard Worker xmlFree(prefix);
3124*6777b538SAndroid Build Coastguard Worker return(NULL);
3125*6777b538SAndroid Build Coastguard Worker }
3126*6777b538SAndroid Build Coastguard Worker } else {
3127*6777b538SAndroid Build Coastguard Worker ret = buffer;
3128*6777b538SAndroid Build Coastguard Worker }
3129*6777b538SAndroid Build Coastguard Worker
3130*6777b538SAndroid Build Coastguard Worker *prefixOut = prefix;
3131*6777b538SAndroid Build Coastguard Worker }
3132*6777b538SAndroid Build Coastguard Worker
3133*6777b538SAndroid Build Coastguard Worker return(ret);
3134*6777b538SAndroid Build Coastguard Worker }
3135*6777b538SAndroid Build Coastguard Worker
3136*6777b538SAndroid Build Coastguard Worker /************************************************************************
3137*6777b538SAndroid Build Coastguard Worker * *
3138*6777b538SAndroid Build Coastguard Worker * The parser itself *
3139*6777b538SAndroid Build Coastguard Worker * Relates to http://www.w3.org/TR/REC-xml *
3140*6777b538SAndroid Build Coastguard Worker * *
3141*6777b538SAndroid Build Coastguard Worker ************************************************************************/
3142*6777b538SAndroid Build Coastguard Worker
3143*6777b538SAndroid Build Coastguard Worker /************************************************************************
3144*6777b538SAndroid Build Coastguard Worker * *
3145*6777b538SAndroid Build Coastguard Worker * Routines to parse Name, NCName and NmToken *
3146*6777b538SAndroid Build Coastguard Worker * *
3147*6777b538SAndroid Build Coastguard Worker ************************************************************************/
3148*6777b538SAndroid Build Coastguard Worker
3149*6777b538SAndroid Build Coastguard Worker /*
3150*6777b538SAndroid Build Coastguard Worker * The two following functions are related to the change of accepted
3151*6777b538SAndroid Build Coastguard Worker * characters for Name and NmToken in the Revision 5 of XML-1.0
3152*6777b538SAndroid Build Coastguard Worker * They correspond to the modified production [4] and the new production [4a]
3153*6777b538SAndroid Build Coastguard Worker * changes in that revision. Also note that the macros used for the
3154*6777b538SAndroid Build Coastguard Worker * productions Letter, Digit, CombiningChar and Extender are not needed
3155*6777b538SAndroid Build Coastguard Worker * anymore.
3156*6777b538SAndroid Build Coastguard Worker * We still keep compatibility to pre-revision5 parsing semantic if the
3157*6777b538SAndroid Build Coastguard Worker * new XML_PARSE_OLD10 option is given to the parser.
3158*6777b538SAndroid Build Coastguard Worker */
3159*6777b538SAndroid Build Coastguard Worker static int
xmlIsNameStartChar(xmlParserCtxtPtr ctxt,int c)3160*6777b538SAndroid Build Coastguard Worker xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
3161*6777b538SAndroid Build Coastguard Worker if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3162*6777b538SAndroid Build Coastguard Worker /*
3163*6777b538SAndroid Build Coastguard Worker * Use the new checks of production [4] [4a] amd [5] of the
3164*6777b538SAndroid Build Coastguard Worker * Update 5 of XML-1.0
3165*6777b538SAndroid Build Coastguard Worker */
3166*6777b538SAndroid Build Coastguard Worker if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3167*6777b538SAndroid Build Coastguard Worker (((c >= 'a') && (c <= 'z')) ||
3168*6777b538SAndroid Build Coastguard Worker ((c >= 'A') && (c <= 'Z')) ||
3169*6777b538SAndroid Build Coastguard Worker (c == '_') || (c == ':') ||
3170*6777b538SAndroid Build Coastguard Worker ((c >= 0xC0) && (c <= 0xD6)) ||
3171*6777b538SAndroid Build Coastguard Worker ((c >= 0xD8) && (c <= 0xF6)) ||
3172*6777b538SAndroid Build Coastguard Worker ((c >= 0xF8) && (c <= 0x2FF)) ||
3173*6777b538SAndroid Build Coastguard Worker ((c >= 0x370) && (c <= 0x37D)) ||
3174*6777b538SAndroid Build Coastguard Worker ((c >= 0x37F) && (c <= 0x1FFF)) ||
3175*6777b538SAndroid Build Coastguard Worker ((c >= 0x200C) && (c <= 0x200D)) ||
3176*6777b538SAndroid Build Coastguard Worker ((c >= 0x2070) && (c <= 0x218F)) ||
3177*6777b538SAndroid Build Coastguard Worker ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3178*6777b538SAndroid Build Coastguard Worker ((c >= 0x3001) && (c <= 0xD7FF)) ||
3179*6777b538SAndroid Build Coastguard Worker ((c >= 0xF900) && (c <= 0xFDCF)) ||
3180*6777b538SAndroid Build Coastguard Worker ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3181*6777b538SAndroid Build Coastguard Worker ((c >= 0x10000) && (c <= 0xEFFFF))))
3182*6777b538SAndroid Build Coastguard Worker return(1);
3183*6777b538SAndroid Build Coastguard Worker } else {
3184*6777b538SAndroid Build Coastguard Worker if (IS_LETTER(c) || (c == '_') || (c == ':'))
3185*6777b538SAndroid Build Coastguard Worker return(1);
3186*6777b538SAndroid Build Coastguard Worker }
3187*6777b538SAndroid Build Coastguard Worker return(0);
3188*6777b538SAndroid Build Coastguard Worker }
3189*6777b538SAndroid Build Coastguard Worker
3190*6777b538SAndroid Build Coastguard Worker static int
xmlIsNameChar(xmlParserCtxtPtr ctxt,int c)3191*6777b538SAndroid Build Coastguard Worker xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
3192*6777b538SAndroid Build Coastguard Worker if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3193*6777b538SAndroid Build Coastguard Worker /*
3194*6777b538SAndroid Build Coastguard Worker * Use the new checks of production [4] [4a] amd [5] of the
3195*6777b538SAndroid Build Coastguard Worker * Update 5 of XML-1.0
3196*6777b538SAndroid Build Coastguard Worker */
3197*6777b538SAndroid Build Coastguard Worker if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3198*6777b538SAndroid Build Coastguard Worker (((c >= 'a') && (c <= 'z')) ||
3199*6777b538SAndroid Build Coastguard Worker ((c >= 'A') && (c <= 'Z')) ||
3200*6777b538SAndroid Build Coastguard Worker ((c >= '0') && (c <= '9')) || /* !start */
3201*6777b538SAndroid Build Coastguard Worker (c == '_') || (c == ':') ||
3202*6777b538SAndroid Build Coastguard Worker (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3203*6777b538SAndroid Build Coastguard Worker ((c >= 0xC0) && (c <= 0xD6)) ||
3204*6777b538SAndroid Build Coastguard Worker ((c >= 0xD8) && (c <= 0xF6)) ||
3205*6777b538SAndroid Build Coastguard Worker ((c >= 0xF8) && (c <= 0x2FF)) ||
3206*6777b538SAndroid Build Coastguard Worker ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3207*6777b538SAndroid Build Coastguard Worker ((c >= 0x370) && (c <= 0x37D)) ||
3208*6777b538SAndroid Build Coastguard Worker ((c >= 0x37F) && (c <= 0x1FFF)) ||
3209*6777b538SAndroid Build Coastguard Worker ((c >= 0x200C) && (c <= 0x200D)) ||
3210*6777b538SAndroid Build Coastguard Worker ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3211*6777b538SAndroid Build Coastguard Worker ((c >= 0x2070) && (c <= 0x218F)) ||
3212*6777b538SAndroid Build Coastguard Worker ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3213*6777b538SAndroid Build Coastguard Worker ((c >= 0x3001) && (c <= 0xD7FF)) ||
3214*6777b538SAndroid Build Coastguard Worker ((c >= 0xF900) && (c <= 0xFDCF)) ||
3215*6777b538SAndroid Build Coastguard Worker ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3216*6777b538SAndroid Build Coastguard Worker ((c >= 0x10000) && (c <= 0xEFFFF))))
3217*6777b538SAndroid Build Coastguard Worker return(1);
3218*6777b538SAndroid Build Coastguard Worker } else {
3219*6777b538SAndroid Build Coastguard Worker if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3220*6777b538SAndroid Build Coastguard Worker (c == '.') || (c == '-') ||
3221*6777b538SAndroid Build Coastguard Worker (c == '_') || (c == ':') ||
3222*6777b538SAndroid Build Coastguard Worker (IS_COMBINING(c)) ||
3223*6777b538SAndroid Build Coastguard Worker (IS_EXTENDER(c)))
3224*6777b538SAndroid Build Coastguard Worker return(1);
3225*6777b538SAndroid Build Coastguard Worker }
3226*6777b538SAndroid Build Coastguard Worker return(0);
3227*6777b538SAndroid Build Coastguard Worker }
3228*6777b538SAndroid Build Coastguard Worker
3229*6777b538SAndroid Build Coastguard Worker static const xmlChar *
xmlParseNameComplex(xmlParserCtxtPtr ctxt)3230*6777b538SAndroid Build Coastguard Worker xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
3231*6777b538SAndroid Build Coastguard Worker const xmlChar *ret;
3232*6777b538SAndroid Build Coastguard Worker int len = 0, l;
3233*6777b538SAndroid Build Coastguard Worker int c;
3234*6777b538SAndroid Build Coastguard Worker int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3235*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH :
3236*6777b538SAndroid Build Coastguard Worker XML_MAX_NAME_LENGTH;
3237*6777b538SAndroid Build Coastguard Worker
3238*6777b538SAndroid Build Coastguard Worker /*
3239*6777b538SAndroid Build Coastguard Worker * Handler for more complex cases
3240*6777b538SAndroid Build Coastguard Worker */
3241*6777b538SAndroid Build Coastguard Worker c = CUR_CHAR(l);
3242*6777b538SAndroid Build Coastguard Worker if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3243*6777b538SAndroid Build Coastguard Worker /*
3244*6777b538SAndroid Build Coastguard Worker * Use the new checks of production [4] [4a] amd [5] of the
3245*6777b538SAndroid Build Coastguard Worker * Update 5 of XML-1.0
3246*6777b538SAndroid Build Coastguard Worker */
3247*6777b538SAndroid Build Coastguard Worker if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3248*6777b538SAndroid Build Coastguard Worker (!(((c >= 'a') && (c <= 'z')) ||
3249*6777b538SAndroid Build Coastguard Worker ((c >= 'A') && (c <= 'Z')) ||
3250*6777b538SAndroid Build Coastguard Worker (c == '_') || (c == ':') ||
3251*6777b538SAndroid Build Coastguard Worker ((c >= 0xC0) && (c <= 0xD6)) ||
3252*6777b538SAndroid Build Coastguard Worker ((c >= 0xD8) && (c <= 0xF6)) ||
3253*6777b538SAndroid Build Coastguard Worker ((c >= 0xF8) && (c <= 0x2FF)) ||
3254*6777b538SAndroid Build Coastguard Worker ((c >= 0x370) && (c <= 0x37D)) ||
3255*6777b538SAndroid Build Coastguard Worker ((c >= 0x37F) && (c <= 0x1FFF)) ||
3256*6777b538SAndroid Build Coastguard Worker ((c >= 0x200C) && (c <= 0x200D)) ||
3257*6777b538SAndroid Build Coastguard Worker ((c >= 0x2070) && (c <= 0x218F)) ||
3258*6777b538SAndroid Build Coastguard Worker ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3259*6777b538SAndroid Build Coastguard Worker ((c >= 0x3001) && (c <= 0xD7FF)) ||
3260*6777b538SAndroid Build Coastguard Worker ((c >= 0xF900) && (c <= 0xFDCF)) ||
3261*6777b538SAndroid Build Coastguard Worker ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3262*6777b538SAndroid Build Coastguard Worker ((c >= 0x10000) && (c <= 0xEFFFF))))) {
3263*6777b538SAndroid Build Coastguard Worker return(NULL);
3264*6777b538SAndroid Build Coastguard Worker }
3265*6777b538SAndroid Build Coastguard Worker len += l;
3266*6777b538SAndroid Build Coastguard Worker NEXTL(l);
3267*6777b538SAndroid Build Coastguard Worker c = CUR_CHAR(l);
3268*6777b538SAndroid Build Coastguard Worker while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3269*6777b538SAndroid Build Coastguard Worker (((c >= 'a') && (c <= 'z')) ||
3270*6777b538SAndroid Build Coastguard Worker ((c >= 'A') && (c <= 'Z')) ||
3271*6777b538SAndroid Build Coastguard Worker ((c >= '0') && (c <= '9')) || /* !start */
3272*6777b538SAndroid Build Coastguard Worker (c == '_') || (c == ':') ||
3273*6777b538SAndroid Build Coastguard Worker (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3274*6777b538SAndroid Build Coastguard Worker ((c >= 0xC0) && (c <= 0xD6)) ||
3275*6777b538SAndroid Build Coastguard Worker ((c >= 0xD8) && (c <= 0xF6)) ||
3276*6777b538SAndroid Build Coastguard Worker ((c >= 0xF8) && (c <= 0x2FF)) ||
3277*6777b538SAndroid Build Coastguard Worker ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3278*6777b538SAndroid Build Coastguard Worker ((c >= 0x370) && (c <= 0x37D)) ||
3279*6777b538SAndroid Build Coastguard Worker ((c >= 0x37F) && (c <= 0x1FFF)) ||
3280*6777b538SAndroid Build Coastguard Worker ((c >= 0x200C) && (c <= 0x200D)) ||
3281*6777b538SAndroid Build Coastguard Worker ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3282*6777b538SAndroid Build Coastguard Worker ((c >= 0x2070) && (c <= 0x218F)) ||
3283*6777b538SAndroid Build Coastguard Worker ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3284*6777b538SAndroid Build Coastguard Worker ((c >= 0x3001) && (c <= 0xD7FF)) ||
3285*6777b538SAndroid Build Coastguard Worker ((c >= 0xF900) && (c <= 0xFDCF)) ||
3286*6777b538SAndroid Build Coastguard Worker ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3287*6777b538SAndroid Build Coastguard Worker ((c >= 0x10000) && (c <= 0xEFFFF))
3288*6777b538SAndroid Build Coastguard Worker )) {
3289*6777b538SAndroid Build Coastguard Worker if (len <= INT_MAX - l)
3290*6777b538SAndroid Build Coastguard Worker len += l;
3291*6777b538SAndroid Build Coastguard Worker NEXTL(l);
3292*6777b538SAndroid Build Coastguard Worker c = CUR_CHAR(l);
3293*6777b538SAndroid Build Coastguard Worker }
3294*6777b538SAndroid Build Coastguard Worker } else {
3295*6777b538SAndroid Build Coastguard Worker if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3296*6777b538SAndroid Build Coastguard Worker (!IS_LETTER(c) && (c != '_') &&
3297*6777b538SAndroid Build Coastguard Worker (c != ':'))) {
3298*6777b538SAndroid Build Coastguard Worker return(NULL);
3299*6777b538SAndroid Build Coastguard Worker }
3300*6777b538SAndroid Build Coastguard Worker len += l;
3301*6777b538SAndroid Build Coastguard Worker NEXTL(l);
3302*6777b538SAndroid Build Coastguard Worker c = CUR_CHAR(l);
3303*6777b538SAndroid Build Coastguard Worker
3304*6777b538SAndroid Build Coastguard Worker while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3305*6777b538SAndroid Build Coastguard Worker ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3306*6777b538SAndroid Build Coastguard Worker (c == '.') || (c == '-') ||
3307*6777b538SAndroid Build Coastguard Worker (c == '_') || (c == ':') ||
3308*6777b538SAndroid Build Coastguard Worker (IS_COMBINING(c)) ||
3309*6777b538SAndroid Build Coastguard Worker (IS_EXTENDER(c)))) {
3310*6777b538SAndroid Build Coastguard Worker if (len <= INT_MAX - l)
3311*6777b538SAndroid Build Coastguard Worker len += l;
3312*6777b538SAndroid Build Coastguard Worker NEXTL(l);
3313*6777b538SAndroid Build Coastguard Worker c = CUR_CHAR(l);
3314*6777b538SAndroid Build Coastguard Worker }
3315*6777b538SAndroid Build Coastguard Worker }
3316*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
3317*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3318*6777b538SAndroid Build Coastguard Worker return(NULL);
3319*6777b538SAndroid Build Coastguard Worker }
3320*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur - ctxt->input->base < len) {
3321*6777b538SAndroid Build Coastguard Worker /*
3322*6777b538SAndroid Build Coastguard Worker * There were a couple of bugs where PERefs lead to to a change
3323*6777b538SAndroid Build Coastguard Worker * of the buffer. Check the buffer size to avoid passing an invalid
3324*6777b538SAndroid Build Coastguard Worker * pointer to xmlDictLookup.
3325*6777b538SAndroid Build Coastguard Worker */
3326*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
3327*6777b538SAndroid Build Coastguard Worker "unexpected change of input buffer");
3328*6777b538SAndroid Build Coastguard Worker return (NULL);
3329*6777b538SAndroid Build Coastguard Worker }
3330*6777b538SAndroid Build Coastguard Worker if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
3331*6777b538SAndroid Build Coastguard Worker ret = xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len);
3332*6777b538SAndroid Build Coastguard Worker else
3333*6777b538SAndroid Build Coastguard Worker ret = xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len);
3334*6777b538SAndroid Build Coastguard Worker if (ret == NULL)
3335*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3336*6777b538SAndroid Build Coastguard Worker return(ret);
3337*6777b538SAndroid Build Coastguard Worker }
3338*6777b538SAndroid Build Coastguard Worker
3339*6777b538SAndroid Build Coastguard Worker /**
3340*6777b538SAndroid Build Coastguard Worker * xmlParseName:
3341*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
3342*6777b538SAndroid Build Coastguard Worker *
3343*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
3344*6777b538SAndroid Build Coastguard Worker *
3345*6777b538SAndroid Build Coastguard Worker * parse an XML name.
3346*6777b538SAndroid Build Coastguard Worker *
3347*6777b538SAndroid Build Coastguard Worker * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3348*6777b538SAndroid Build Coastguard Worker * CombiningChar | Extender
3349*6777b538SAndroid Build Coastguard Worker *
3350*6777b538SAndroid Build Coastguard Worker * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3351*6777b538SAndroid Build Coastguard Worker *
3352*6777b538SAndroid Build Coastguard Worker * [6] Names ::= Name (#x20 Name)*
3353*6777b538SAndroid Build Coastguard Worker *
3354*6777b538SAndroid Build Coastguard Worker * Returns the Name parsed or NULL
3355*6777b538SAndroid Build Coastguard Worker */
3356*6777b538SAndroid Build Coastguard Worker
3357*6777b538SAndroid Build Coastguard Worker const xmlChar *
xmlParseName(xmlParserCtxtPtr ctxt)3358*6777b538SAndroid Build Coastguard Worker xmlParseName(xmlParserCtxtPtr ctxt) {
3359*6777b538SAndroid Build Coastguard Worker const xmlChar *in;
3360*6777b538SAndroid Build Coastguard Worker const xmlChar *ret;
3361*6777b538SAndroid Build Coastguard Worker size_t count = 0;
3362*6777b538SAndroid Build Coastguard Worker size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3363*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH :
3364*6777b538SAndroid Build Coastguard Worker XML_MAX_NAME_LENGTH;
3365*6777b538SAndroid Build Coastguard Worker
3366*6777b538SAndroid Build Coastguard Worker GROW;
3367*6777b538SAndroid Build Coastguard Worker
3368*6777b538SAndroid Build Coastguard Worker /*
3369*6777b538SAndroid Build Coastguard Worker * Accelerator for simple ASCII names
3370*6777b538SAndroid Build Coastguard Worker */
3371*6777b538SAndroid Build Coastguard Worker in = ctxt->input->cur;
3372*6777b538SAndroid Build Coastguard Worker if (((*in >= 0x61) && (*in <= 0x7A)) ||
3373*6777b538SAndroid Build Coastguard Worker ((*in >= 0x41) && (*in <= 0x5A)) ||
3374*6777b538SAndroid Build Coastguard Worker (*in == '_') || (*in == ':')) {
3375*6777b538SAndroid Build Coastguard Worker in++;
3376*6777b538SAndroid Build Coastguard Worker while (((*in >= 0x61) && (*in <= 0x7A)) ||
3377*6777b538SAndroid Build Coastguard Worker ((*in >= 0x41) && (*in <= 0x5A)) ||
3378*6777b538SAndroid Build Coastguard Worker ((*in >= 0x30) && (*in <= 0x39)) ||
3379*6777b538SAndroid Build Coastguard Worker (*in == '_') || (*in == '-') ||
3380*6777b538SAndroid Build Coastguard Worker (*in == ':') || (*in == '.'))
3381*6777b538SAndroid Build Coastguard Worker in++;
3382*6777b538SAndroid Build Coastguard Worker if ((*in > 0) && (*in < 0x80)) {
3383*6777b538SAndroid Build Coastguard Worker count = in - ctxt->input->cur;
3384*6777b538SAndroid Build Coastguard Worker if (count > maxLength) {
3385*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3386*6777b538SAndroid Build Coastguard Worker return(NULL);
3387*6777b538SAndroid Build Coastguard Worker }
3388*6777b538SAndroid Build Coastguard Worker ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3389*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in;
3390*6777b538SAndroid Build Coastguard Worker ctxt->input->col += count;
3391*6777b538SAndroid Build Coastguard Worker if (ret == NULL)
3392*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3393*6777b538SAndroid Build Coastguard Worker return(ret);
3394*6777b538SAndroid Build Coastguard Worker }
3395*6777b538SAndroid Build Coastguard Worker }
3396*6777b538SAndroid Build Coastguard Worker /* accelerator for special cases */
3397*6777b538SAndroid Build Coastguard Worker return(xmlParseNameComplex(ctxt));
3398*6777b538SAndroid Build Coastguard Worker }
3399*6777b538SAndroid Build Coastguard Worker
3400*6777b538SAndroid Build Coastguard Worker static xmlHashedString
xmlParseNCNameComplex(xmlParserCtxtPtr ctxt)3401*6777b538SAndroid Build Coastguard Worker xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
3402*6777b538SAndroid Build Coastguard Worker xmlHashedString ret;
3403*6777b538SAndroid Build Coastguard Worker int len = 0, l;
3404*6777b538SAndroid Build Coastguard Worker int c;
3405*6777b538SAndroid Build Coastguard Worker int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3406*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH :
3407*6777b538SAndroid Build Coastguard Worker XML_MAX_NAME_LENGTH;
3408*6777b538SAndroid Build Coastguard Worker size_t startPosition = 0;
3409*6777b538SAndroid Build Coastguard Worker
3410*6777b538SAndroid Build Coastguard Worker ret.name = NULL;
3411*6777b538SAndroid Build Coastguard Worker ret.hashValue = 0;
3412*6777b538SAndroid Build Coastguard Worker
3413*6777b538SAndroid Build Coastguard Worker /*
3414*6777b538SAndroid Build Coastguard Worker * Handler for more complex cases
3415*6777b538SAndroid Build Coastguard Worker */
3416*6777b538SAndroid Build Coastguard Worker startPosition = CUR_PTR - BASE_PTR;
3417*6777b538SAndroid Build Coastguard Worker c = CUR_CHAR(l);
3418*6777b538SAndroid Build Coastguard Worker if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3419*6777b538SAndroid Build Coastguard Worker (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
3420*6777b538SAndroid Build Coastguard Worker return(ret);
3421*6777b538SAndroid Build Coastguard Worker }
3422*6777b538SAndroid Build Coastguard Worker
3423*6777b538SAndroid Build Coastguard Worker while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3424*6777b538SAndroid Build Coastguard Worker (xmlIsNameChar(ctxt, c) && (c != ':'))) {
3425*6777b538SAndroid Build Coastguard Worker if (len <= INT_MAX - l)
3426*6777b538SAndroid Build Coastguard Worker len += l;
3427*6777b538SAndroid Build Coastguard Worker NEXTL(l);
3428*6777b538SAndroid Build Coastguard Worker c = CUR_CHAR(l);
3429*6777b538SAndroid Build Coastguard Worker }
3430*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
3431*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3432*6777b538SAndroid Build Coastguard Worker return(ret);
3433*6777b538SAndroid Build Coastguard Worker }
3434*6777b538SAndroid Build Coastguard Worker ret = xmlDictLookupHashed(ctxt->dict, (BASE_PTR + startPosition), len);
3435*6777b538SAndroid Build Coastguard Worker if (ret.name == NULL)
3436*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3437*6777b538SAndroid Build Coastguard Worker return(ret);
3438*6777b538SAndroid Build Coastguard Worker }
3439*6777b538SAndroid Build Coastguard Worker
3440*6777b538SAndroid Build Coastguard Worker /**
3441*6777b538SAndroid Build Coastguard Worker * xmlParseNCName:
3442*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
3443*6777b538SAndroid Build Coastguard Worker * @len: length of the string parsed
3444*6777b538SAndroid Build Coastguard Worker *
3445*6777b538SAndroid Build Coastguard Worker * parse an XML name.
3446*6777b538SAndroid Build Coastguard Worker *
3447*6777b538SAndroid Build Coastguard Worker * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
3448*6777b538SAndroid Build Coastguard Worker * CombiningChar | Extender
3449*6777b538SAndroid Build Coastguard Worker *
3450*6777b538SAndroid Build Coastguard Worker * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
3451*6777b538SAndroid Build Coastguard Worker *
3452*6777b538SAndroid Build Coastguard Worker * Returns the Name parsed or NULL
3453*6777b538SAndroid Build Coastguard Worker */
3454*6777b538SAndroid Build Coastguard Worker
3455*6777b538SAndroid Build Coastguard Worker static xmlHashedString
xmlParseNCName(xmlParserCtxtPtr ctxt)3456*6777b538SAndroid Build Coastguard Worker xmlParseNCName(xmlParserCtxtPtr ctxt) {
3457*6777b538SAndroid Build Coastguard Worker const xmlChar *in, *e;
3458*6777b538SAndroid Build Coastguard Worker xmlHashedString ret;
3459*6777b538SAndroid Build Coastguard Worker size_t count = 0;
3460*6777b538SAndroid Build Coastguard Worker size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3461*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH :
3462*6777b538SAndroid Build Coastguard Worker XML_MAX_NAME_LENGTH;
3463*6777b538SAndroid Build Coastguard Worker
3464*6777b538SAndroid Build Coastguard Worker ret.name = NULL;
3465*6777b538SAndroid Build Coastguard Worker
3466*6777b538SAndroid Build Coastguard Worker /*
3467*6777b538SAndroid Build Coastguard Worker * Accelerator for simple ASCII names
3468*6777b538SAndroid Build Coastguard Worker */
3469*6777b538SAndroid Build Coastguard Worker in = ctxt->input->cur;
3470*6777b538SAndroid Build Coastguard Worker e = ctxt->input->end;
3471*6777b538SAndroid Build Coastguard Worker if ((((*in >= 0x61) && (*in <= 0x7A)) ||
3472*6777b538SAndroid Build Coastguard Worker ((*in >= 0x41) && (*in <= 0x5A)) ||
3473*6777b538SAndroid Build Coastguard Worker (*in == '_')) && (in < e)) {
3474*6777b538SAndroid Build Coastguard Worker in++;
3475*6777b538SAndroid Build Coastguard Worker while ((((*in >= 0x61) && (*in <= 0x7A)) ||
3476*6777b538SAndroid Build Coastguard Worker ((*in >= 0x41) && (*in <= 0x5A)) ||
3477*6777b538SAndroid Build Coastguard Worker ((*in >= 0x30) && (*in <= 0x39)) ||
3478*6777b538SAndroid Build Coastguard Worker (*in == '_') || (*in == '-') ||
3479*6777b538SAndroid Build Coastguard Worker (*in == '.')) && (in < e))
3480*6777b538SAndroid Build Coastguard Worker in++;
3481*6777b538SAndroid Build Coastguard Worker if (in >= e)
3482*6777b538SAndroid Build Coastguard Worker goto complex;
3483*6777b538SAndroid Build Coastguard Worker if ((*in > 0) && (*in < 0x80)) {
3484*6777b538SAndroid Build Coastguard Worker count = in - ctxt->input->cur;
3485*6777b538SAndroid Build Coastguard Worker if (count > maxLength) {
3486*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3487*6777b538SAndroid Build Coastguard Worker return(ret);
3488*6777b538SAndroid Build Coastguard Worker }
3489*6777b538SAndroid Build Coastguard Worker ret = xmlDictLookupHashed(ctxt->dict, ctxt->input->cur, count);
3490*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in;
3491*6777b538SAndroid Build Coastguard Worker ctxt->input->col += count;
3492*6777b538SAndroid Build Coastguard Worker if (ret.name == NULL) {
3493*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3494*6777b538SAndroid Build Coastguard Worker }
3495*6777b538SAndroid Build Coastguard Worker return(ret);
3496*6777b538SAndroid Build Coastguard Worker }
3497*6777b538SAndroid Build Coastguard Worker }
3498*6777b538SAndroid Build Coastguard Worker complex:
3499*6777b538SAndroid Build Coastguard Worker return(xmlParseNCNameComplex(ctxt));
3500*6777b538SAndroid Build Coastguard Worker }
3501*6777b538SAndroid Build Coastguard Worker
3502*6777b538SAndroid Build Coastguard Worker /**
3503*6777b538SAndroid Build Coastguard Worker * xmlParseNameAndCompare:
3504*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
3505*6777b538SAndroid Build Coastguard Worker *
3506*6777b538SAndroid Build Coastguard Worker * parse an XML name and compares for match
3507*6777b538SAndroid Build Coastguard Worker * (specialized for endtag parsing)
3508*6777b538SAndroid Build Coastguard Worker *
3509*6777b538SAndroid Build Coastguard Worker * Returns NULL for an illegal name, (xmlChar*) 1 for success
3510*6777b538SAndroid Build Coastguard Worker * and the name for mismatch
3511*6777b538SAndroid Build Coastguard Worker */
3512*6777b538SAndroid Build Coastguard Worker
3513*6777b538SAndroid Build Coastguard Worker static const xmlChar *
xmlParseNameAndCompare(xmlParserCtxtPtr ctxt,xmlChar const * other)3514*6777b538SAndroid Build Coastguard Worker xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
3515*6777b538SAndroid Build Coastguard Worker register const xmlChar *cmp = other;
3516*6777b538SAndroid Build Coastguard Worker register const xmlChar *in;
3517*6777b538SAndroid Build Coastguard Worker const xmlChar *ret;
3518*6777b538SAndroid Build Coastguard Worker
3519*6777b538SAndroid Build Coastguard Worker GROW;
3520*6777b538SAndroid Build Coastguard Worker
3521*6777b538SAndroid Build Coastguard Worker in = ctxt->input->cur;
3522*6777b538SAndroid Build Coastguard Worker while (*in != 0 && *in == *cmp) {
3523*6777b538SAndroid Build Coastguard Worker ++in;
3524*6777b538SAndroid Build Coastguard Worker ++cmp;
3525*6777b538SAndroid Build Coastguard Worker }
3526*6777b538SAndroid Build Coastguard Worker if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
3527*6777b538SAndroid Build Coastguard Worker /* success */
3528*6777b538SAndroid Build Coastguard Worker ctxt->input->col += in - ctxt->input->cur;
3529*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in;
3530*6777b538SAndroid Build Coastguard Worker return (const xmlChar*) 1;
3531*6777b538SAndroid Build Coastguard Worker }
3532*6777b538SAndroid Build Coastguard Worker /* failure (or end of input buffer), check with full function */
3533*6777b538SAndroid Build Coastguard Worker ret = xmlParseName (ctxt);
3534*6777b538SAndroid Build Coastguard Worker /* strings coming from the dictionary direct compare possible */
3535*6777b538SAndroid Build Coastguard Worker if (ret == other) {
3536*6777b538SAndroid Build Coastguard Worker return (const xmlChar*) 1;
3537*6777b538SAndroid Build Coastguard Worker }
3538*6777b538SAndroid Build Coastguard Worker return ret;
3539*6777b538SAndroid Build Coastguard Worker }
3540*6777b538SAndroid Build Coastguard Worker
3541*6777b538SAndroid Build Coastguard Worker /**
3542*6777b538SAndroid Build Coastguard Worker * xmlParseStringName:
3543*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
3544*6777b538SAndroid Build Coastguard Worker * @str: a pointer to the string pointer (IN/OUT)
3545*6777b538SAndroid Build Coastguard Worker *
3546*6777b538SAndroid Build Coastguard Worker * parse an XML name.
3547*6777b538SAndroid Build Coastguard Worker *
3548*6777b538SAndroid Build Coastguard Worker * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3549*6777b538SAndroid Build Coastguard Worker * CombiningChar | Extender
3550*6777b538SAndroid Build Coastguard Worker *
3551*6777b538SAndroid Build Coastguard Worker * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3552*6777b538SAndroid Build Coastguard Worker *
3553*6777b538SAndroid Build Coastguard Worker * [6] Names ::= Name (#x20 Name)*
3554*6777b538SAndroid Build Coastguard Worker *
3555*6777b538SAndroid Build Coastguard Worker * Returns the Name parsed or NULL. The @str pointer
3556*6777b538SAndroid Build Coastguard Worker * is updated to the current location in the string.
3557*6777b538SAndroid Build Coastguard Worker */
3558*6777b538SAndroid Build Coastguard Worker
3559*6777b538SAndroid Build Coastguard Worker static xmlChar *
xmlParseStringName(xmlParserCtxtPtr ctxt,const xmlChar ** str)3560*6777b538SAndroid Build Coastguard Worker xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
3561*6777b538SAndroid Build Coastguard Worker xmlChar buf[XML_MAX_NAMELEN + 5];
3562*6777b538SAndroid Build Coastguard Worker xmlChar *ret;
3563*6777b538SAndroid Build Coastguard Worker const xmlChar *cur = *str;
3564*6777b538SAndroid Build Coastguard Worker int len = 0, l;
3565*6777b538SAndroid Build Coastguard Worker int c;
3566*6777b538SAndroid Build Coastguard Worker int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3567*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH :
3568*6777b538SAndroid Build Coastguard Worker XML_MAX_NAME_LENGTH;
3569*6777b538SAndroid Build Coastguard Worker
3570*6777b538SAndroid Build Coastguard Worker c = CUR_SCHAR(cur, l);
3571*6777b538SAndroid Build Coastguard Worker if (!xmlIsNameStartChar(ctxt, c)) {
3572*6777b538SAndroid Build Coastguard Worker return(NULL);
3573*6777b538SAndroid Build Coastguard Worker }
3574*6777b538SAndroid Build Coastguard Worker
3575*6777b538SAndroid Build Coastguard Worker COPY_BUF(buf, len, c);
3576*6777b538SAndroid Build Coastguard Worker cur += l;
3577*6777b538SAndroid Build Coastguard Worker c = CUR_SCHAR(cur, l);
3578*6777b538SAndroid Build Coastguard Worker while (xmlIsNameChar(ctxt, c)) {
3579*6777b538SAndroid Build Coastguard Worker COPY_BUF(buf, len, c);
3580*6777b538SAndroid Build Coastguard Worker cur += l;
3581*6777b538SAndroid Build Coastguard Worker c = CUR_SCHAR(cur, l);
3582*6777b538SAndroid Build Coastguard Worker if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
3583*6777b538SAndroid Build Coastguard Worker /*
3584*6777b538SAndroid Build Coastguard Worker * Okay someone managed to make a huge name, so he's ready to pay
3585*6777b538SAndroid Build Coastguard Worker * for the processing speed.
3586*6777b538SAndroid Build Coastguard Worker */
3587*6777b538SAndroid Build Coastguard Worker xmlChar *buffer;
3588*6777b538SAndroid Build Coastguard Worker int max = len * 2;
3589*6777b538SAndroid Build Coastguard Worker
3590*6777b538SAndroid Build Coastguard Worker buffer = (xmlChar *) xmlMallocAtomic(max);
3591*6777b538SAndroid Build Coastguard Worker if (buffer == NULL) {
3592*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3593*6777b538SAndroid Build Coastguard Worker return(NULL);
3594*6777b538SAndroid Build Coastguard Worker }
3595*6777b538SAndroid Build Coastguard Worker memcpy(buffer, buf, len);
3596*6777b538SAndroid Build Coastguard Worker while (xmlIsNameChar(ctxt, c)) {
3597*6777b538SAndroid Build Coastguard Worker if (len + 10 > max) {
3598*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
3599*6777b538SAndroid Build Coastguard Worker
3600*6777b538SAndroid Build Coastguard Worker max *= 2;
3601*6777b538SAndroid Build Coastguard Worker tmp = (xmlChar *) xmlRealloc(buffer, max);
3602*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
3603*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3604*6777b538SAndroid Build Coastguard Worker xmlFree(buffer);
3605*6777b538SAndroid Build Coastguard Worker return(NULL);
3606*6777b538SAndroid Build Coastguard Worker }
3607*6777b538SAndroid Build Coastguard Worker buffer = tmp;
3608*6777b538SAndroid Build Coastguard Worker }
3609*6777b538SAndroid Build Coastguard Worker COPY_BUF(buffer, len, c);
3610*6777b538SAndroid Build Coastguard Worker cur += l;
3611*6777b538SAndroid Build Coastguard Worker c = CUR_SCHAR(cur, l);
3612*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
3613*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3614*6777b538SAndroid Build Coastguard Worker xmlFree(buffer);
3615*6777b538SAndroid Build Coastguard Worker return(NULL);
3616*6777b538SAndroid Build Coastguard Worker }
3617*6777b538SAndroid Build Coastguard Worker }
3618*6777b538SAndroid Build Coastguard Worker buffer[len] = 0;
3619*6777b538SAndroid Build Coastguard Worker *str = cur;
3620*6777b538SAndroid Build Coastguard Worker return(buffer);
3621*6777b538SAndroid Build Coastguard Worker }
3622*6777b538SAndroid Build Coastguard Worker }
3623*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
3624*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3625*6777b538SAndroid Build Coastguard Worker return(NULL);
3626*6777b538SAndroid Build Coastguard Worker }
3627*6777b538SAndroid Build Coastguard Worker *str = cur;
3628*6777b538SAndroid Build Coastguard Worker ret = xmlStrndup(buf, len);
3629*6777b538SAndroid Build Coastguard Worker if (ret == NULL)
3630*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3631*6777b538SAndroid Build Coastguard Worker return(ret);
3632*6777b538SAndroid Build Coastguard Worker }
3633*6777b538SAndroid Build Coastguard Worker
3634*6777b538SAndroid Build Coastguard Worker /**
3635*6777b538SAndroid Build Coastguard Worker * xmlParseNmtoken:
3636*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
3637*6777b538SAndroid Build Coastguard Worker *
3638*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
3639*6777b538SAndroid Build Coastguard Worker *
3640*6777b538SAndroid Build Coastguard Worker * parse an XML Nmtoken.
3641*6777b538SAndroid Build Coastguard Worker *
3642*6777b538SAndroid Build Coastguard Worker * [7] Nmtoken ::= (NameChar)+
3643*6777b538SAndroid Build Coastguard Worker *
3644*6777b538SAndroid Build Coastguard Worker * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
3645*6777b538SAndroid Build Coastguard Worker *
3646*6777b538SAndroid Build Coastguard Worker * Returns the Nmtoken parsed or NULL
3647*6777b538SAndroid Build Coastguard Worker */
3648*6777b538SAndroid Build Coastguard Worker
3649*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlParseNmtoken(xmlParserCtxtPtr ctxt)3650*6777b538SAndroid Build Coastguard Worker xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
3651*6777b538SAndroid Build Coastguard Worker xmlChar buf[XML_MAX_NAMELEN + 5];
3652*6777b538SAndroid Build Coastguard Worker xmlChar *ret;
3653*6777b538SAndroid Build Coastguard Worker int len = 0, l;
3654*6777b538SAndroid Build Coastguard Worker int c;
3655*6777b538SAndroid Build Coastguard Worker int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3656*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH :
3657*6777b538SAndroid Build Coastguard Worker XML_MAX_NAME_LENGTH;
3658*6777b538SAndroid Build Coastguard Worker
3659*6777b538SAndroid Build Coastguard Worker c = CUR_CHAR(l);
3660*6777b538SAndroid Build Coastguard Worker
3661*6777b538SAndroid Build Coastguard Worker while (xmlIsNameChar(ctxt, c)) {
3662*6777b538SAndroid Build Coastguard Worker COPY_BUF(buf, len, c);
3663*6777b538SAndroid Build Coastguard Worker NEXTL(l);
3664*6777b538SAndroid Build Coastguard Worker c = CUR_CHAR(l);
3665*6777b538SAndroid Build Coastguard Worker if (len >= XML_MAX_NAMELEN) {
3666*6777b538SAndroid Build Coastguard Worker /*
3667*6777b538SAndroid Build Coastguard Worker * Okay someone managed to make a huge token, so he's ready to pay
3668*6777b538SAndroid Build Coastguard Worker * for the processing speed.
3669*6777b538SAndroid Build Coastguard Worker */
3670*6777b538SAndroid Build Coastguard Worker xmlChar *buffer;
3671*6777b538SAndroid Build Coastguard Worker int max = len * 2;
3672*6777b538SAndroid Build Coastguard Worker
3673*6777b538SAndroid Build Coastguard Worker buffer = (xmlChar *) xmlMallocAtomic(max);
3674*6777b538SAndroid Build Coastguard Worker if (buffer == NULL) {
3675*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3676*6777b538SAndroid Build Coastguard Worker return(NULL);
3677*6777b538SAndroid Build Coastguard Worker }
3678*6777b538SAndroid Build Coastguard Worker memcpy(buffer, buf, len);
3679*6777b538SAndroid Build Coastguard Worker while (xmlIsNameChar(ctxt, c)) {
3680*6777b538SAndroid Build Coastguard Worker if (len + 10 > max) {
3681*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
3682*6777b538SAndroid Build Coastguard Worker
3683*6777b538SAndroid Build Coastguard Worker max *= 2;
3684*6777b538SAndroid Build Coastguard Worker tmp = (xmlChar *) xmlRealloc(buffer, max);
3685*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
3686*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3687*6777b538SAndroid Build Coastguard Worker xmlFree(buffer);
3688*6777b538SAndroid Build Coastguard Worker return(NULL);
3689*6777b538SAndroid Build Coastguard Worker }
3690*6777b538SAndroid Build Coastguard Worker buffer = tmp;
3691*6777b538SAndroid Build Coastguard Worker }
3692*6777b538SAndroid Build Coastguard Worker COPY_BUF(buffer, len, c);
3693*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
3694*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3695*6777b538SAndroid Build Coastguard Worker xmlFree(buffer);
3696*6777b538SAndroid Build Coastguard Worker return(NULL);
3697*6777b538SAndroid Build Coastguard Worker }
3698*6777b538SAndroid Build Coastguard Worker NEXTL(l);
3699*6777b538SAndroid Build Coastguard Worker c = CUR_CHAR(l);
3700*6777b538SAndroid Build Coastguard Worker }
3701*6777b538SAndroid Build Coastguard Worker buffer[len] = 0;
3702*6777b538SAndroid Build Coastguard Worker return(buffer);
3703*6777b538SAndroid Build Coastguard Worker }
3704*6777b538SAndroid Build Coastguard Worker }
3705*6777b538SAndroid Build Coastguard Worker if (len == 0)
3706*6777b538SAndroid Build Coastguard Worker return(NULL);
3707*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
3708*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3709*6777b538SAndroid Build Coastguard Worker return(NULL);
3710*6777b538SAndroid Build Coastguard Worker }
3711*6777b538SAndroid Build Coastguard Worker ret = xmlStrndup(buf, len);
3712*6777b538SAndroid Build Coastguard Worker if (ret == NULL)
3713*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3714*6777b538SAndroid Build Coastguard Worker return(ret);
3715*6777b538SAndroid Build Coastguard Worker }
3716*6777b538SAndroid Build Coastguard Worker
3717*6777b538SAndroid Build Coastguard Worker /**
3718*6777b538SAndroid Build Coastguard Worker * xmlExpandPEsInEntityValue:
3719*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
3720*6777b538SAndroid Build Coastguard Worker * @buf: string buffer
3721*6777b538SAndroid Build Coastguard Worker * @str: entity value
3722*6777b538SAndroid Build Coastguard Worker * @length: size of entity value
3723*6777b538SAndroid Build Coastguard Worker * @depth: nesting depth
3724*6777b538SAndroid Build Coastguard Worker *
3725*6777b538SAndroid Build Coastguard Worker * Validate an entity value and expand parameter entities.
3726*6777b538SAndroid Build Coastguard Worker */
3727*6777b538SAndroid Build Coastguard Worker static void
xmlExpandPEsInEntityValue(xmlParserCtxtPtr ctxt,xmlSBuf * buf,const xmlChar * str,int length,int depth)3728*6777b538SAndroid Build Coastguard Worker xmlExpandPEsInEntityValue(xmlParserCtxtPtr ctxt, xmlSBuf *buf,
3729*6777b538SAndroid Build Coastguard Worker const xmlChar *str, int length, int depth) {
3730*6777b538SAndroid Build Coastguard Worker int maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 40 : 20;
3731*6777b538SAndroid Build Coastguard Worker const xmlChar *end, *chunk;
3732*6777b538SAndroid Build Coastguard Worker int c, l;
3733*6777b538SAndroid Build Coastguard Worker
3734*6777b538SAndroid Build Coastguard Worker if (str == NULL)
3735*6777b538SAndroid Build Coastguard Worker return;
3736*6777b538SAndroid Build Coastguard Worker
3737*6777b538SAndroid Build Coastguard Worker depth += 1;
3738*6777b538SAndroid Build Coastguard Worker if (depth > maxDepth) {
3739*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT,
3740*6777b538SAndroid Build Coastguard Worker "Maximum entity nesting depth exceeded");
3741*6777b538SAndroid Build Coastguard Worker return;
3742*6777b538SAndroid Build Coastguard Worker }
3743*6777b538SAndroid Build Coastguard Worker
3744*6777b538SAndroid Build Coastguard Worker end = str + length;
3745*6777b538SAndroid Build Coastguard Worker chunk = str;
3746*6777b538SAndroid Build Coastguard Worker
3747*6777b538SAndroid Build Coastguard Worker while ((str < end) && (!PARSER_STOPPED(ctxt))) {
3748*6777b538SAndroid Build Coastguard Worker c = *str;
3749*6777b538SAndroid Build Coastguard Worker
3750*6777b538SAndroid Build Coastguard Worker if (c >= 0x80) {
3751*6777b538SAndroid Build Coastguard Worker l = xmlUTF8MultibyteLen(ctxt, str,
3752*6777b538SAndroid Build Coastguard Worker "invalid character in entity value\n");
3753*6777b538SAndroid Build Coastguard Worker if (l == 0) {
3754*6777b538SAndroid Build Coastguard Worker if (chunk < str)
3755*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, chunk, str - chunk);
3756*6777b538SAndroid Build Coastguard Worker xmlSBufAddReplChar(buf);
3757*6777b538SAndroid Build Coastguard Worker str += 1;
3758*6777b538SAndroid Build Coastguard Worker chunk = str;
3759*6777b538SAndroid Build Coastguard Worker } else {
3760*6777b538SAndroid Build Coastguard Worker str += l;
3761*6777b538SAndroid Build Coastguard Worker }
3762*6777b538SAndroid Build Coastguard Worker } else if (c == '&') {
3763*6777b538SAndroid Build Coastguard Worker if (str[1] == '#') {
3764*6777b538SAndroid Build Coastguard Worker if (chunk < str)
3765*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, chunk, str - chunk);
3766*6777b538SAndroid Build Coastguard Worker
3767*6777b538SAndroid Build Coastguard Worker c = xmlParseStringCharRef(ctxt, &str);
3768*6777b538SAndroid Build Coastguard Worker if (c == 0)
3769*6777b538SAndroid Build Coastguard Worker return;
3770*6777b538SAndroid Build Coastguard Worker
3771*6777b538SAndroid Build Coastguard Worker xmlSBufAddChar(buf, c);
3772*6777b538SAndroid Build Coastguard Worker
3773*6777b538SAndroid Build Coastguard Worker chunk = str;
3774*6777b538SAndroid Build Coastguard Worker } else {
3775*6777b538SAndroid Build Coastguard Worker xmlChar *name;
3776*6777b538SAndroid Build Coastguard Worker
3777*6777b538SAndroid Build Coastguard Worker /*
3778*6777b538SAndroid Build Coastguard Worker * General entity references are checked for
3779*6777b538SAndroid Build Coastguard Worker * syntactic validity.
3780*6777b538SAndroid Build Coastguard Worker */
3781*6777b538SAndroid Build Coastguard Worker str++;
3782*6777b538SAndroid Build Coastguard Worker name = xmlParseStringName(ctxt, &str);
3783*6777b538SAndroid Build Coastguard Worker
3784*6777b538SAndroid Build Coastguard Worker if ((name == NULL) || (*str++ != ';')) {
3785*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
3786*6777b538SAndroid Build Coastguard Worker "EntityValue: '&' forbidden except for entities "
3787*6777b538SAndroid Build Coastguard Worker "references\n");
3788*6777b538SAndroid Build Coastguard Worker xmlFree(name);
3789*6777b538SAndroid Build Coastguard Worker return;
3790*6777b538SAndroid Build Coastguard Worker }
3791*6777b538SAndroid Build Coastguard Worker
3792*6777b538SAndroid Build Coastguard Worker xmlFree(name);
3793*6777b538SAndroid Build Coastguard Worker }
3794*6777b538SAndroid Build Coastguard Worker } else if (c == '%') {
3795*6777b538SAndroid Build Coastguard Worker xmlEntityPtr ent;
3796*6777b538SAndroid Build Coastguard Worker
3797*6777b538SAndroid Build Coastguard Worker if (chunk < str)
3798*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, chunk, str - chunk);
3799*6777b538SAndroid Build Coastguard Worker
3800*6777b538SAndroid Build Coastguard Worker ent = xmlParseStringPEReference(ctxt, &str);
3801*6777b538SAndroid Build Coastguard Worker if (ent == NULL)
3802*6777b538SAndroid Build Coastguard Worker return;
3803*6777b538SAndroid Build Coastguard Worker
3804*6777b538SAndroid Build Coastguard Worker if (!PARSER_EXTERNAL(ctxt)) {
3805*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
3806*6777b538SAndroid Build Coastguard Worker return;
3807*6777b538SAndroid Build Coastguard Worker }
3808*6777b538SAndroid Build Coastguard Worker
3809*6777b538SAndroid Build Coastguard Worker if (ent->content == NULL) {
3810*6777b538SAndroid Build Coastguard Worker /*
3811*6777b538SAndroid Build Coastguard Worker * Note: external parsed entities will not be loaded,
3812*6777b538SAndroid Build Coastguard Worker * it is not required for a non-validating parser to
3813*6777b538SAndroid Build Coastguard Worker * complete external PEReferences coming from the
3814*6777b538SAndroid Build Coastguard Worker * internal subset
3815*6777b538SAndroid Build Coastguard Worker */
3816*6777b538SAndroid Build Coastguard Worker if (((ctxt->options & XML_PARSE_NO_XXE) == 0) &&
3817*6777b538SAndroid Build Coastguard Worker ((ctxt->replaceEntities) ||
3818*6777b538SAndroid Build Coastguard Worker (ctxt->validate))) {
3819*6777b538SAndroid Build Coastguard Worker xmlLoadEntityContent(ctxt, ent);
3820*6777b538SAndroid Build Coastguard Worker } else {
3821*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
3822*6777b538SAndroid Build Coastguard Worker "not validating will not read content for "
3823*6777b538SAndroid Build Coastguard Worker "PE entity %s\n", ent->name, NULL);
3824*6777b538SAndroid Build Coastguard Worker }
3825*6777b538SAndroid Build Coastguard Worker }
3826*6777b538SAndroid Build Coastguard Worker
3827*6777b538SAndroid Build Coastguard Worker /*
3828*6777b538SAndroid Build Coastguard Worker * TODO: Skip if ent->content is still NULL.
3829*6777b538SAndroid Build Coastguard Worker */
3830*6777b538SAndroid Build Coastguard Worker
3831*6777b538SAndroid Build Coastguard Worker if (xmlParserEntityCheck(ctxt, ent->length))
3832*6777b538SAndroid Build Coastguard Worker return;
3833*6777b538SAndroid Build Coastguard Worker
3834*6777b538SAndroid Build Coastguard Worker if (ent->flags & XML_ENT_EXPANDING) {
3835*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
3836*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
3837*6777b538SAndroid Build Coastguard Worker return;
3838*6777b538SAndroid Build Coastguard Worker }
3839*6777b538SAndroid Build Coastguard Worker
3840*6777b538SAndroid Build Coastguard Worker ent->flags |= XML_ENT_EXPANDING;
3841*6777b538SAndroid Build Coastguard Worker xmlExpandPEsInEntityValue(ctxt, buf, ent->content, ent->length,
3842*6777b538SAndroid Build Coastguard Worker depth);
3843*6777b538SAndroid Build Coastguard Worker ent->flags &= ~XML_ENT_EXPANDING;
3844*6777b538SAndroid Build Coastguard Worker
3845*6777b538SAndroid Build Coastguard Worker chunk = str;
3846*6777b538SAndroid Build Coastguard Worker } else {
3847*6777b538SAndroid Build Coastguard Worker /* Normal ASCII char */
3848*6777b538SAndroid Build Coastguard Worker if (!IS_BYTE_CHAR(c)) {
3849*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
3850*6777b538SAndroid Build Coastguard Worker "invalid character in entity value\n");
3851*6777b538SAndroid Build Coastguard Worker if (chunk < str)
3852*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, chunk, str - chunk);
3853*6777b538SAndroid Build Coastguard Worker xmlSBufAddReplChar(buf);
3854*6777b538SAndroid Build Coastguard Worker str += 1;
3855*6777b538SAndroid Build Coastguard Worker chunk = str;
3856*6777b538SAndroid Build Coastguard Worker } else {
3857*6777b538SAndroid Build Coastguard Worker str += 1;
3858*6777b538SAndroid Build Coastguard Worker }
3859*6777b538SAndroid Build Coastguard Worker }
3860*6777b538SAndroid Build Coastguard Worker }
3861*6777b538SAndroid Build Coastguard Worker
3862*6777b538SAndroid Build Coastguard Worker if (chunk < str)
3863*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, chunk, str - chunk);
3864*6777b538SAndroid Build Coastguard Worker
3865*6777b538SAndroid Build Coastguard Worker return;
3866*6777b538SAndroid Build Coastguard Worker }
3867*6777b538SAndroid Build Coastguard Worker
3868*6777b538SAndroid Build Coastguard Worker /**
3869*6777b538SAndroid Build Coastguard Worker * xmlParseEntityValue:
3870*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
3871*6777b538SAndroid Build Coastguard Worker * @orig: if non-NULL store a copy of the original entity value
3872*6777b538SAndroid Build Coastguard Worker *
3873*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
3874*6777b538SAndroid Build Coastguard Worker *
3875*6777b538SAndroid Build Coastguard Worker * parse a value for ENTITY declarations
3876*6777b538SAndroid Build Coastguard Worker *
3877*6777b538SAndroid Build Coastguard Worker * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
3878*6777b538SAndroid Build Coastguard Worker * "'" ([^%&'] | PEReference | Reference)* "'"
3879*6777b538SAndroid Build Coastguard Worker *
3880*6777b538SAndroid Build Coastguard Worker * Returns the EntityValue parsed with reference substituted or NULL
3881*6777b538SAndroid Build Coastguard Worker */
3882*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlParseEntityValue(xmlParserCtxtPtr ctxt,xmlChar ** orig)3883*6777b538SAndroid Build Coastguard Worker xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
3884*6777b538SAndroid Build Coastguard Worker unsigned maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3885*6777b538SAndroid Build Coastguard Worker XML_MAX_HUGE_LENGTH :
3886*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH;
3887*6777b538SAndroid Build Coastguard Worker xmlSBuf buf;
3888*6777b538SAndroid Build Coastguard Worker const xmlChar *start;
3889*6777b538SAndroid Build Coastguard Worker int quote, length;
3890*6777b538SAndroid Build Coastguard Worker
3891*6777b538SAndroid Build Coastguard Worker xmlSBufInit(&buf, maxLength);
3892*6777b538SAndroid Build Coastguard Worker
3893*6777b538SAndroid Build Coastguard Worker GROW;
3894*6777b538SAndroid Build Coastguard Worker
3895*6777b538SAndroid Build Coastguard Worker quote = CUR;
3896*6777b538SAndroid Build Coastguard Worker if ((quote != '"') && (quote != '\'')) {
3897*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
3898*6777b538SAndroid Build Coastguard Worker return(NULL);
3899*6777b538SAndroid Build Coastguard Worker }
3900*6777b538SAndroid Build Coastguard Worker CUR_PTR++;
3901*6777b538SAndroid Build Coastguard Worker
3902*6777b538SAndroid Build Coastguard Worker length = 0;
3903*6777b538SAndroid Build Coastguard Worker
3904*6777b538SAndroid Build Coastguard Worker /*
3905*6777b538SAndroid Build Coastguard Worker * Copy raw content of the entity into a buffer
3906*6777b538SAndroid Build Coastguard Worker */
3907*6777b538SAndroid Build Coastguard Worker while (1) {
3908*6777b538SAndroid Build Coastguard Worker int c;
3909*6777b538SAndroid Build Coastguard Worker
3910*6777b538SAndroid Build Coastguard Worker if (PARSER_STOPPED(ctxt))
3911*6777b538SAndroid Build Coastguard Worker goto error;
3912*6777b538SAndroid Build Coastguard Worker
3913*6777b538SAndroid Build Coastguard Worker if (CUR_PTR >= ctxt->input->end) {
3914*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
3915*6777b538SAndroid Build Coastguard Worker goto error;
3916*6777b538SAndroid Build Coastguard Worker }
3917*6777b538SAndroid Build Coastguard Worker
3918*6777b538SAndroid Build Coastguard Worker c = CUR;
3919*6777b538SAndroid Build Coastguard Worker
3920*6777b538SAndroid Build Coastguard Worker if (c == 0) {
3921*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
3922*6777b538SAndroid Build Coastguard Worker "invalid character in entity value\n");
3923*6777b538SAndroid Build Coastguard Worker goto error;
3924*6777b538SAndroid Build Coastguard Worker }
3925*6777b538SAndroid Build Coastguard Worker if (c == quote)
3926*6777b538SAndroid Build Coastguard Worker break;
3927*6777b538SAndroid Build Coastguard Worker NEXTL(1);
3928*6777b538SAndroid Build Coastguard Worker length += 1;
3929*6777b538SAndroid Build Coastguard Worker
3930*6777b538SAndroid Build Coastguard Worker /*
3931*6777b538SAndroid Build Coastguard Worker * TODO: Check growth threshold
3932*6777b538SAndroid Build Coastguard Worker */
3933*6777b538SAndroid Build Coastguard Worker if (ctxt->input->end - CUR_PTR < 10)
3934*6777b538SAndroid Build Coastguard Worker GROW;
3935*6777b538SAndroid Build Coastguard Worker }
3936*6777b538SAndroid Build Coastguard Worker
3937*6777b538SAndroid Build Coastguard Worker start = CUR_PTR - length;
3938*6777b538SAndroid Build Coastguard Worker
3939*6777b538SAndroid Build Coastguard Worker if (orig != NULL) {
3940*6777b538SAndroid Build Coastguard Worker *orig = xmlStrndup(start, length);
3941*6777b538SAndroid Build Coastguard Worker if (*orig == NULL)
3942*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
3943*6777b538SAndroid Build Coastguard Worker }
3944*6777b538SAndroid Build Coastguard Worker
3945*6777b538SAndroid Build Coastguard Worker xmlExpandPEsInEntityValue(ctxt, &buf, start, length, ctxt->inputNr);
3946*6777b538SAndroid Build Coastguard Worker
3947*6777b538SAndroid Build Coastguard Worker NEXTL(1);
3948*6777b538SAndroid Build Coastguard Worker
3949*6777b538SAndroid Build Coastguard Worker return(xmlSBufFinish(&buf, NULL, ctxt, "entity length too long"));
3950*6777b538SAndroid Build Coastguard Worker
3951*6777b538SAndroid Build Coastguard Worker error:
3952*6777b538SAndroid Build Coastguard Worker xmlSBufCleanup(&buf, ctxt, "entity length too long");
3953*6777b538SAndroid Build Coastguard Worker return(NULL);
3954*6777b538SAndroid Build Coastguard Worker }
3955*6777b538SAndroid Build Coastguard Worker
3956*6777b538SAndroid Build Coastguard Worker /**
3957*6777b538SAndroid Build Coastguard Worker * xmlCheckEntityInAttValue:
3958*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
3959*6777b538SAndroid Build Coastguard Worker * @pent: entity
3960*6777b538SAndroid Build Coastguard Worker * @depth: nesting depth
3961*6777b538SAndroid Build Coastguard Worker *
3962*6777b538SAndroid Build Coastguard Worker * Check an entity reference in an attribute value for validity
3963*6777b538SAndroid Build Coastguard Worker * without expanding it.
3964*6777b538SAndroid Build Coastguard Worker */
3965*6777b538SAndroid Build Coastguard Worker static void
xmlCheckEntityInAttValue(xmlParserCtxtPtr ctxt,xmlEntityPtr pent,int depth)3966*6777b538SAndroid Build Coastguard Worker xmlCheckEntityInAttValue(xmlParserCtxtPtr ctxt, xmlEntityPtr pent, int depth) {
3967*6777b538SAndroid Build Coastguard Worker int maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 40 : 20;
3968*6777b538SAndroid Build Coastguard Worker const xmlChar *str;
3969*6777b538SAndroid Build Coastguard Worker unsigned long expandedSize = pent->length;
3970*6777b538SAndroid Build Coastguard Worker int c, flags;
3971*6777b538SAndroid Build Coastguard Worker
3972*6777b538SAndroid Build Coastguard Worker depth += 1;
3973*6777b538SAndroid Build Coastguard Worker if (depth > maxDepth) {
3974*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT,
3975*6777b538SAndroid Build Coastguard Worker "Maximum entity nesting depth exceeded");
3976*6777b538SAndroid Build Coastguard Worker return;
3977*6777b538SAndroid Build Coastguard Worker }
3978*6777b538SAndroid Build Coastguard Worker
3979*6777b538SAndroid Build Coastguard Worker if (pent->flags & XML_ENT_EXPANDING) {
3980*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
3981*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
3982*6777b538SAndroid Build Coastguard Worker return;
3983*6777b538SAndroid Build Coastguard Worker }
3984*6777b538SAndroid Build Coastguard Worker
3985*6777b538SAndroid Build Coastguard Worker /*
3986*6777b538SAndroid Build Coastguard Worker * If we're parsing a default attribute value in DTD content,
3987*6777b538SAndroid Build Coastguard Worker * the entity might reference other entities which weren't
3988*6777b538SAndroid Build Coastguard Worker * defined yet, so the check isn't reliable.
3989*6777b538SAndroid Build Coastguard Worker */
3990*6777b538SAndroid Build Coastguard Worker if (ctxt->inSubset == 0)
3991*6777b538SAndroid Build Coastguard Worker flags = XML_ENT_CHECKED | XML_ENT_VALIDATED;
3992*6777b538SAndroid Build Coastguard Worker else
3993*6777b538SAndroid Build Coastguard Worker flags = XML_ENT_VALIDATED;
3994*6777b538SAndroid Build Coastguard Worker
3995*6777b538SAndroid Build Coastguard Worker str = pent->content;
3996*6777b538SAndroid Build Coastguard Worker if (str == NULL)
3997*6777b538SAndroid Build Coastguard Worker goto done;
3998*6777b538SAndroid Build Coastguard Worker
3999*6777b538SAndroid Build Coastguard Worker /*
4000*6777b538SAndroid Build Coastguard Worker * Note that entity values are already validated. We only check
4001*6777b538SAndroid Build Coastguard Worker * for illegal less-than signs and compute the expanded size
4002*6777b538SAndroid Build Coastguard Worker * of the entity. No special handling for multi-byte characters
4003*6777b538SAndroid Build Coastguard Worker * is needed.
4004*6777b538SAndroid Build Coastguard Worker */
4005*6777b538SAndroid Build Coastguard Worker while (!PARSER_STOPPED(ctxt)) {
4006*6777b538SAndroid Build Coastguard Worker c = *str;
4007*6777b538SAndroid Build Coastguard Worker
4008*6777b538SAndroid Build Coastguard Worker if (c != '&') {
4009*6777b538SAndroid Build Coastguard Worker if (c == 0)
4010*6777b538SAndroid Build Coastguard Worker break;
4011*6777b538SAndroid Build Coastguard Worker
4012*6777b538SAndroid Build Coastguard Worker if (c == '<')
4013*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
4014*6777b538SAndroid Build Coastguard Worker "'<' in entity '%s' is not allowed in attributes "
4015*6777b538SAndroid Build Coastguard Worker "values\n", pent->name);
4016*6777b538SAndroid Build Coastguard Worker
4017*6777b538SAndroid Build Coastguard Worker str += 1;
4018*6777b538SAndroid Build Coastguard Worker } else if (str[1] == '#') {
4019*6777b538SAndroid Build Coastguard Worker int val;
4020*6777b538SAndroid Build Coastguard Worker
4021*6777b538SAndroid Build Coastguard Worker val = xmlParseStringCharRef(ctxt, &str);
4022*6777b538SAndroid Build Coastguard Worker if (val == 0) {
4023*6777b538SAndroid Build Coastguard Worker pent->content[0] = 0;
4024*6777b538SAndroid Build Coastguard Worker break;
4025*6777b538SAndroid Build Coastguard Worker }
4026*6777b538SAndroid Build Coastguard Worker } else {
4027*6777b538SAndroid Build Coastguard Worker xmlChar *name;
4028*6777b538SAndroid Build Coastguard Worker xmlEntityPtr ent;
4029*6777b538SAndroid Build Coastguard Worker
4030*6777b538SAndroid Build Coastguard Worker name = xmlParseStringEntityRef(ctxt, &str);
4031*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
4032*6777b538SAndroid Build Coastguard Worker pent->content[0] = 0;
4033*6777b538SAndroid Build Coastguard Worker break;
4034*6777b538SAndroid Build Coastguard Worker }
4035*6777b538SAndroid Build Coastguard Worker
4036*6777b538SAndroid Build Coastguard Worker ent = xmlLookupGeneralEntity(ctxt, name, /* inAttr */ 1);
4037*6777b538SAndroid Build Coastguard Worker xmlFree(name);
4038*6777b538SAndroid Build Coastguard Worker
4039*6777b538SAndroid Build Coastguard Worker if ((ent != NULL) &&
4040*6777b538SAndroid Build Coastguard Worker (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
4041*6777b538SAndroid Build Coastguard Worker if ((ent->flags & flags) != flags) {
4042*6777b538SAndroid Build Coastguard Worker pent->flags |= XML_ENT_EXPANDING;
4043*6777b538SAndroid Build Coastguard Worker xmlCheckEntityInAttValue(ctxt, ent, depth);
4044*6777b538SAndroid Build Coastguard Worker pent->flags &= ~XML_ENT_EXPANDING;
4045*6777b538SAndroid Build Coastguard Worker }
4046*6777b538SAndroid Build Coastguard Worker
4047*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(&expandedSize, ent->expandedSize);
4048*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(&expandedSize, XML_ENT_FIXED_COST);
4049*6777b538SAndroid Build Coastguard Worker }
4050*6777b538SAndroid Build Coastguard Worker }
4051*6777b538SAndroid Build Coastguard Worker }
4052*6777b538SAndroid Build Coastguard Worker
4053*6777b538SAndroid Build Coastguard Worker done:
4054*6777b538SAndroid Build Coastguard Worker if (ctxt->inSubset == 0)
4055*6777b538SAndroid Build Coastguard Worker pent->expandedSize = expandedSize;
4056*6777b538SAndroid Build Coastguard Worker
4057*6777b538SAndroid Build Coastguard Worker pent->flags |= flags;
4058*6777b538SAndroid Build Coastguard Worker }
4059*6777b538SAndroid Build Coastguard Worker
4060*6777b538SAndroid Build Coastguard Worker /**
4061*6777b538SAndroid Build Coastguard Worker * xmlExpandEntityInAttValue:
4062*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
4063*6777b538SAndroid Build Coastguard Worker * @buf: string buffer
4064*6777b538SAndroid Build Coastguard Worker * @str: entity or attribute value
4065*6777b538SAndroid Build Coastguard Worker * @pent: entity for entity value, NULL for attribute values
4066*6777b538SAndroid Build Coastguard Worker * @normalize: whether to collapse whitespace
4067*6777b538SAndroid Build Coastguard Worker * @inSpace: whitespace state
4068*6777b538SAndroid Build Coastguard Worker * @depth: nesting depth
4069*6777b538SAndroid Build Coastguard Worker * @check: whether to check for amplification
4070*6777b538SAndroid Build Coastguard Worker *
4071*6777b538SAndroid Build Coastguard Worker * Expand general entity references in an entity or attribute value.
4072*6777b538SAndroid Build Coastguard Worker * Perform attribute value normalization.
4073*6777b538SAndroid Build Coastguard Worker */
4074*6777b538SAndroid Build Coastguard Worker static void
xmlExpandEntityInAttValue(xmlParserCtxtPtr ctxt,xmlSBuf * buf,const xmlChar * str,xmlEntityPtr pent,int normalize,int * inSpace,int depth,int check)4075*6777b538SAndroid Build Coastguard Worker xmlExpandEntityInAttValue(xmlParserCtxtPtr ctxt, xmlSBuf *buf,
4076*6777b538SAndroid Build Coastguard Worker const xmlChar *str, xmlEntityPtr pent, int normalize,
4077*6777b538SAndroid Build Coastguard Worker int *inSpace, int depth, int check) {
4078*6777b538SAndroid Build Coastguard Worker int maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 40 : 20;
4079*6777b538SAndroid Build Coastguard Worker int c, chunkSize;
4080*6777b538SAndroid Build Coastguard Worker
4081*6777b538SAndroid Build Coastguard Worker if (str == NULL)
4082*6777b538SAndroid Build Coastguard Worker return;
4083*6777b538SAndroid Build Coastguard Worker
4084*6777b538SAndroid Build Coastguard Worker depth += 1;
4085*6777b538SAndroid Build Coastguard Worker if (depth > maxDepth) {
4086*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT,
4087*6777b538SAndroid Build Coastguard Worker "Maximum entity nesting depth exceeded");
4088*6777b538SAndroid Build Coastguard Worker return;
4089*6777b538SAndroid Build Coastguard Worker }
4090*6777b538SAndroid Build Coastguard Worker
4091*6777b538SAndroid Build Coastguard Worker if (pent != NULL) {
4092*6777b538SAndroid Build Coastguard Worker if (pent->flags & XML_ENT_EXPANDING) {
4093*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
4094*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
4095*6777b538SAndroid Build Coastguard Worker return;
4096*6777b538SAndroid Build Coastguard Worker }
4097*6777b538SAndroid Build Coastguard Worker
4098*6777b538SAndroid Build Coastguard Worker if (check) {
4099*6777b538SAndroid Build Coastguard Worker if (xmlParserEntityCheck(ctxt, pent->length))
4100*6777b538SAndroid Build Coastguard Worker return;
4101*6777b538SAndroid Build Coastguard Worker }
4102*6777b538SAndroid Build Coastguard Worker }
4103*6777b538SAndroid Build Coastguard Worker
4104*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4105*6777b538SAndroid Build Coastguard Worker
4106*6777b538SAndroid Build Coastguard Worker /*
4107*6777b538SAndroid Build Coastguard Worker * Note that entity values are already validated. No special
4108*6777b538SAndroid Build Coastguard Worker * handling for multi-byte characters is needed.
4109*6777b538SAndroid Build Coastguard Worker */
4110*6777b538SAndroid Build Coastguard Worker while (!PARSER_STOPPED(ctxt)) {
4111*6777b538SAndroid Build Coastguard Worker c = *str;
4112*6777b538SAndroid Build Coastguard Worker
4113*6777b538SAndroid Build Coastguard Worker if (c != '&') {
4114*6777b538SAndroid Build Coastguard Worker if (c == 0)
4115*6777b538SAndroid Build Coastguard Worker break;
4116*6777b538SAndroid Build Coastguard Worker
4117*6777b538SAndroid Build Coastguard Worker /*
4118*6777b538SAndroid Build Coastguard Worker * If this function is called without an entity, it is used to
4119*6777b538SAndroid Build Coastguard Worker * expand entities in an attribute content where less-than was
4120*6777b538SAndroid Build Coastguard Worker * already unscaped and is allowed.
4121*6777b538SAndroid Build Coastguard Worker */
4122*6777b538SAndroid Build Coastguard Worker if ((pent != NULL) && (c == '<')) {
4123*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
4124*6777b538SAndroid Build Coastguard Worker "'<' in entity '%s' is not allowed in attributes "
4125*6777b538SAndroid Build Coastguard Worker "values\n", pent->name);
4126*6777b538SAndroid Build Coastguard Worker break;
4127*6777b538SAndroid Build Coastguard Worker }
4128*6777b538SAndroid Build Coastguard Worker
4129*6777b538SAndroid Build Coastguard Worker if (c <= 0x20) {
4130*6777b538SAndroid Build Coastguard Worker if ((normalize) && (*inSpace)) {
4131*6777b538SAndroid Build Coastguard Worker /* Skip char */
4132*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0) {
4133*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, str - chunkSize, chunkSize);
4134*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4135*6777b538SAndroid Build Coastguard Worker }
4136*6777b538SAndroid Build Coastguard Worker } else if (c < 0x20) {
4137*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0) {
4138*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, str - chunkSize, chunkSize);
4139*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4140*6777b538SAndroid Build Coastguard Worker }
4141*6777b538SAndroid Build Coastguard Worker
4142*6777b538SAndroid Build Coastguard Worker xmlSBufAddCString(buf, " ", 1);
4143*6777b538SAndroid Build Coastguard Worker } else {
4144*6777b538SAndroid Build Coastguard Worker chunkSize += 1;
4145*6777b538SAndroid Build Coastguard Worker }
4146*6777b538SAndroid Build Coastguard Worker
4147*6777b538SAndroid Build Coastguard Worker *inSpace = 1;
4148*6777b538SAndroid Build Coastguard Worker } else {
4149*6777b538SAndroid Build Coastguard Worker chunkSize += 1;
4150*6777b538SAndroid Build Coastguard Worker *inSpace = 0;
4151*6777b538SAndroid Build Coastguard Worker }
4152*6777b538SAndroid Build Coastguard Worker
4153*6777b538SAndroid Build Coastguard Worker str += 1;
4154*6777b538SAndroid Build Coastguard Worker } else if (str[1] == '#') {
4155*6777b538SAndroid Build Coastguard Worker int val;
4156*6777b538SAndroid Build Coastguard Worker
4157*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0) {
4158*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, str - chunkSize, chunkSize);
4159*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4160*6777b538SAndroid Build Coastguard Worker }
4161*6777b538SAndroid Build Coastguard Worker
4162*6777b538SAndroid Build Coastguard Worker val = xmlParseStringCharRef(ctxt, &str);
4163*6777b538SAndroid Build Coastguard Worker if (val == 0) {
4164*6777b538SAndroid Build Coastguard Worker if (pent != NULL)
4165*6777b538SAndroid Build Coastguard Worker pent->content[0] = 0;
4166*6777b538SAndroid Build Coastguard Worker break;
4167*6777b538SAndroid Build Coastguard Worker }
4168*6777b538SAndroid Build Coastguard Worker
4169*6777b538SAndroid Build Coastguard Worker if (val == ' ') {
4170*6777b538SAndroid Build Coastguard Worker if ((!normalize) || (!*inSpace))
4171*6777b538SAndroid Build Coastguard Worker xmlSBufAddCString(buf, " ", 1);
4172*6777b538SAndroid Build Coastguard Worker *inSpace = 1;
4173*6777b538SAndroid Build Coastguard Worker } else {
4174*6777b538SAndroid Build Coastguard Worker xmlSBufAddChar(buf, val);
4175*6777b538SAndroid Build Coastguard Worker *inSpace = 0;
4176*6777b538SAndroid Build Coastguard Worker }
4177*6777b538SAndroid Build Coastguard Worker } else {
4178*6777b538SAndroid Build Coastguard Worker xmlChar *name;
4179*6777b538SAndroid Build Coastguard Worker xmlEntityPtr ent;
4180*6777b538SAndroid Build Coastguard Worker
4181*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0) {
4182*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, str - chunkSize, chunkSize);
4183*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4184*6777b538SAndroid Build Coastguard Worker }
4185*6777b538SAndroid Build Coastguard Worker
4186*6777b538SAndroid Build Coastguard Worker name = xmlParseStringEntityRef(ctxt, &str);
4187*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
4188*6777b538SAndroid Build Coastguard Worker if (pent != NULL)
4189*6777b538SAndroid Build Coastguard Worker pent->content[0] = 0;
4190*6777b538SAndroid Build Coastguard Worker break;
4191*6777b538SAndroid Build Coastguard Worker }
4192*6777b538SAndroid Build Coastguard Worker
4193*6777b538SAndroid Build Coastguard Worker ent = xmlLookupGeneralEntity(ctxt, name, /* inAttr */ 1);
4194*6777b538SAndroid Build Coastguard Worker xmlFree(name);
4195*6777b538SAndroid Build Coastguard Worker
4196*6777b538SAndroid Build Coastguard Worker if ((ent != NULL) &&
4197*6777b538SAndroid Build Coastguard Worker (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
4198*6777b538SAndroid Build Coastguard Worker if (ent->content == NULL) {
4199*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
4200*6777b538SAndroid Build Coastguard Worker "predefined entity has no content\n");
4201*6777b538SAndroid Build Coastguard Worker break;
4202*6777b538SAndroid Build Coastguard Worker }
4203*6777b538SAndroid Build Coastguard Worker
4204*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, ent->content, ent->length);
4205*6777b538SAndroid Build Coastguard Worker
4206*6777b538SAndroid Build Coastguard Worker *inSpace = 0;
4207*6777b538SAndroid Build Coastguard Worker } else if ((ent != NULL) && (ent->content != NULL)) {
4208*6777b538SAndroid Build Coastguard Worker if (pent != NULL)
4209*6777b538SAndroid Build Coastguard Worker pent->flags |= XML_ENT_EXPANDING;
4210*6777b538SAndroid Build Coastguard Worker xmlExpandEntityInAttValue(ctxt, buf, ent->content, ent,
4211*6777b538SAndroid Build Coastguard Worker normalize, inSpace, depth, check);
4212*6777b538SAndroid Build Coastguard Worker if (pent != NULL)
4213*6777b538SAndroid Build Coastguard Worker pent->flags &= ~XML_ENT_EXPANDING;
4214*6777b538SAndroid Build Coastguard Worker }
4215*6777b538SAndroid Build Coastguard Worker }
4216*6777b538SAndroid Build Coastguard Worker }
4217*6777b538SAndroid Build Coastguard Worker
4218*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0)
4219*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(buf, str - chunkSize, chunkSize);
4220*6777b538SAndroid Build Coastguard Worker
4221*6777b538SAndroid Build Coastguard Worker return;
4222*6777b538SAndroid Build Coastguard Worker }
4223*6777b538SAndroid Build Coastguard Worker
4224*6777b538SAndroid Build Coastguard Worker /**
4225*6777b538SAndroid Build Coastguard Worker * xmlExpandEntitiesInAttValue:
4226*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
4227*6777b538SAndroid Build Coastguard Worker * @str: entity or attribute value
4228*6777b538SAndroid Build Coastguard Worker * @normalize: whether to collapse whitespace
4229*6777b538SAndroid Build Coastguard Worker *
4230*6777b538SAndroid Build Coastguard Worker * Expand general entity references in an entity or attribute value.
4231*6777b538SAndroid Build Coastguard Worker * Perform attribute value normalization.
4232*6777b538SAndroid Build Coastguard Worker *
4233*6777b538SAndroid Build Coastguard Worker * Returns the expanded attribtue value.
4234*6777b538SAndroid Build Coastguard Worker */
4235*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlExpandEntitiesInAttValue(xmlParserCtxtPtr ctxt,const xmlChar * str,int normalize)4236*6777b538SAndroid Build Coastguard Worker xmlExpandEntitiesInAttValue(xmlParserCtxtPtr ctxt, const xmlChar *str,
4237*6777b538SAndroid Build Coastguard Worker int normalize) {
4238*6777b538SAndroid Build Coastguard Worker unsigned maxLength = (ctxt->options & XML_PARSE_HUGE) ?
4239*6777b538SAndroid Build Coastguard Worker XML_MAX_HUGE_LENGTH :
4240*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH;
4241*6777b538SAndroid Build Coastguard Worker xmlSBuf buf;
4242*6777b538SAndroid Build Coastguard Worker int inSpace = 1;
4243*6777b538SAndroid Build Coastguard Worker
4244*6777b538SAndroid Build Coastguard Worker xmlSBufInit(&buf, maxLength);
4245*6777b538SAndroid Build Coastguard Worker
4246*6777b538SAndroid Build Coastguard Worker xmlExpandEntityInAttValue(ctxt, &buf, str, NULL, normalize, &inSpace,
4247*6777b538SAndroid Build Coastguard Worker ctxt->inputNr, /* check */ 0);
4248*6777b538SAndroid Build Coastguard Worker
4249*6777b538SAndroid Build Coastguard Worker if ((normalize) && (inSpace) && (buf.size > 0))
4250*6777b538SAndroid Build Coastguard Worker buf.size--;
4251*6777b538SAndroid Build Coastguard Worker
4252*6777b538SAndroid Build Coastguard Worker return(xmlSBufFinish(&buf, NULL, ctxt, "AttValue length too long"));
4253*6777b538SAndroid Build Coastguard Worker }
4254*6777b538SAndroid Build Coastguard Worker
4255*6777b538SAndroid Build Coastguard Worker /**
4256*6777b538SAndroid Build Coastguard Worker * xmlParseAttValueInternal:
4257*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
4258*6777b538SAndroid Build Coastguard Worker * @len: attribute len result
4259*6777b538SAndroid Build Coastguard Worker * @alloc: whether the attribute was reallocated as a new string
4260*6777b538SAndroid Build Coastguard Worker * @normalize: if 1 then further non-CDATA normalization must be done
4261*6777b538SAndroid Build Coastguard Worker *
4262*6777b538SAndroid Build Coastguard Worker * parse a value for an attribute.
4263*6777b538SAndroid Build Coastguard Worker * NOTE: if no normalization is needed, the routine will return pointers
4264*6777b538SAndroid Build Coastguard Worker * directly from the data buffer.
4265*6777b538SAndroid Build Coastguard Worker *
4266*6777b538SAndroid Build Coastguard Worker * 3.3.3 Attribute-Value Normalization:
4267*6777b538SAndroid Build Coastguard Worker * Before the value of an attribute is passed to the application or
4268*6777b538SAndroid Build Coastguard Worker * checked for validity, the XML processor must normalize it as follows:
4269*6777b538SAndroid Build Coastguard Worker * - a character reference is processed by appending the referenced
4270*6777b538SAndroid Build Coastguard Worker * character to the attribute value
4271*6777b538SAndroid Build Coastguard Worker * - an entity reference is processed by recursively processing the
4272*6777b538SAndroid Build Coastguard Worker * replacement text of the entity
4273*6777b538SAndroid Build Coastguard Worker * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
4274*6777b538SAndroid Build Coastguard Worker * appending #x20 to the normalized value, except that only a single
4275*6777b538SAndroid Build Coastguard Worker * #x20 is appended for a "#xD#xA" sequence that is part of an external
4276*6777b538SAndroid Build Coastguard Worker * parsed entity or the literal entity value of an internal parsed entity
4277*6777b538SAndroid Build Coastguard Worker * - other characters are processed by appending them to the normalized value
4278*6777b538SAndroid Build Coastguard Worker * If the declared value is not CDATA, then the XML processor must further
4279*6777b538SAndroid Build Coastguard Worker * process the normalized attribute value by discarding any leading and
4280*6777b538SAndroid Build Coastguard Worker * trailing space (#x20) characters, and by replacing sequences of space
4281*6777b538SAndroid Build Coastguard Worker * (#x20) characters by a single space (#x20) character.
4282*6777b538SAndroid Build Coastguard Worker * All attributes for which no declaration has been read should be treated
4283*6777b538SAndroid Build Coastguard Worker * by a non-validating parser as if declared CDATA.
4284*6777b538SAndroid Build Coastguard Worker *
4285*6777b538SAndroid Build Coastguard Worker * Returns the AttValue parsed or NULL. The value has to be freed by the
4286*6777b538SAndroid Build Coastguard Worker * caller if it was copied, this can be detected by val[*len] == 0.
4287*6777b538SAndroid Build Coastguard Worker */
4288*6777b538SAndroid Build Coastguard Worker static xmlChar *
xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,int * attlen,int * alloc,int normalize)4289*6777b538SAndroid Build Coastguard Worker xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *attlen, int *alloc,
4290*6777b538SAndroid Build Coastguard Worker int normalize) {
4291*6777b538SAndroid Build Coastguard Worker unsigned maxLength = (ctxt->options & XML_PARSE_HUGE) ?
4292*6777b538SAndroid Build Coastguard Worker XML_MAX_HUGE_LENGTH :
4293*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH;
4294*6777b538SAndroid Build Coastguard Worker xmlSBuf buf;
4295*6777b538SAndroid Build Coastguard Worker xmlChar *ret;
4296*6777b538SAndroid Build Coastguard Worker int c, l, quote, flags, chunkSize;
4297*6777b538SAndroid Build Coastguard Worker int inSpace = 1;
4298*6777b538SAndroid Build Coastguard Worker
4299*6777b538SAndroid Build Coastguard Worker xmlSBufInit(&buf, maxLength);
4300*6777b538SAndroid Build Coastguard Worker
4301*6777b538SAndroid Build Coastguard Worker GROW;
4302*6777b538SAndroid Build Coastguard Worker
4303*6777b538SAndroid Build Coastguard Worker quote = CUR;
4304*6777b538SAndroid Build Coastguard Worker if ((quote != '"') && (quote != '\'')) {
4305*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
4306*6777b538SAndroid Build Coastguard Worker return(NULL);
4307*6777b538SAndroid Build Coastguard Worker }
4308*6777b538SAndroid Build Coastguard Worker NEXTL(1);
4309*6777b538SAndroid Build Coastguard Worker
4310*6777b538SAndroid Build Coastguard Worker if (ctxt->inSubset == 0)
4311*6777b538SAndroid Build Coastguard Worker flags = XML_ENT_CHECKED | XML_ENT_VALIDATED;
4312*6777b538SAndroid Build Coastguard Worker else
4313*6777b538SAndroid Build Coastguard Worker flags = XML_ENT_VALIDATED;
4314*6777b538SAndroid Build Coastguard Worker
4315*6777b538SAndroid Build Coastguard Worker inSpace = 1;
4316*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4317*6777b538SAndroid Build Coastguard Worker
4318*6777b538SAndroid Build Coastguard Worker while (1) {
4319*6777b538SAndroid Build Coastguard Worker if (PARSER_STOPPED(ctxt))
4320*6777b538SAndroid Build Coastguard Worker goto error;
4321*6777b538SAndroid Build Coastguard Worker
4322*6777b538SAndroid Build Coastguard Worker if (CUR_PTR >= ctxt->input->end) {
4323*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4324*6777b538SAndroid Build Coastguard Worker "AttValue: ' expected\n");
4325*6777b538SAndroid Build Coastguard Worker goto error;
4326*6777b538SAndroid Build Coastguard Worker }
4327*6777b538SAndroid Build Coastguard Worker
4328*6777b538SAndroid Build Coastguard Worker /*
4329*6777b538SAndroid Build Coastguard Worker * TODO: Check growth threshold
4330*6777b538SAndroid Build Coastguard Worker */
4331*6777b538SAndroid Build Coastguard Worker if (ctxt->input->end - CUR_PTR < 10)
4332*6777b538SAndroid Build Coastguard Worker GROW;
4333*6777b538SAndroid Build Coastguard Worker
4334*6777b538SAndroid Build Coastguard Worker c = CUR;
4335*6777b538SAndroid Build Coastguard Worker
4336*6777b538SAndroid Build Coastguard Worker if (c >= 0x80) {
4337*6777b538SAndroid Build Coastguard Worker l = xmlUTF8MultibyteLen(ctxt, CUR_PTR,
4338*6777b538SAndroid Build Coastguard Worker "invalid character in attribute value\n");
4339*6777b538SAndroid Build Coastguard Worker if (l == 0) {
4340*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0) {
4341*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
4342*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4343*6777b538SAndroid Build Coastguard Worker }
4344*6777b538SAndroid Build Coastguard Worker xmlSBufAddReplChar(&buf);
4345*6777b538SAndroid Build Coastguard Worker NEXTL(1);
4346*6777b538SAndroid Build Coastguard Worker } else {
4347*6777b538SAndroid Build Coastguard Worker chunkSize += l;
4348*6777b538SAndroid Build Coastguard Worker NEXTL(l);
4349*6777b538SAndroid Build Coastguard Worker }
4350*6777b538SAndroid Build Coastguard Worker
4351*6777b538SAndroid Build Coastguard Worker inSpace = 0;
4352*6777b538SAndroid Build Coastguard Worker } else if (c != '&') {
4353*6777b538SAndroid Build Coastguard Worker if (c > 0x20) {
4354*6777b538SAndroid Build Coastguard Worker if (c == quote)
4355*6777b538SAndroid Build Coastguard Worker break;
4356*6777b538SAndroid Build Coastguard Worker
4357*6777b538SAndroid Build Coastguard Worker if (c == '<')
4358*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
4359*6777b538SAndroid Build Coastguard Worker
4360*6777b538SAndroid Build Coastguard Worker chunkSize += 1;
4361*6777b538SAndroid Build Coastguard Worker inSpace = 0;
4362*6777b538SAndroid Build Coastguard Worker } else if (!IS_BYTE_CHAR(c)) {
4363*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
4364*6777b538SAndroid Build Coastguard Worker "invalid character in attribute value\n");
4365*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0) {
4366*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
4367*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4368*6777b538SAndroid Build Coastguard Worker }
4369*6777b538SAndroid Build Coastguard Worker xmlSBufAddReplChar(&buf);
4370*6777b538SAndroid Build Coastguard Worker inSpace = 0;
4371*6777b538SAndroid Build Coastguard Worker } else {
4372*6777b538SAndroid Build Coastguard Worker /* Whitespace */
4373*6777b538SAndroid Build Coastguard Worker if ((normalize) && (inSpace)) {
4374*6777b538SAndroid Build Coastguard Worker /* Skip char */
4375*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0) {
4376*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
4377*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4378*6777b538SAndroid Build Coastguard Worker }
4379*6777b538SAndroid Build Coastguard Worker } else if (c < 0x20) {
4380*6777b538SAndroid Build Coastguard Worker /* Convert to space */
4381*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0) {
4382*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
4383*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4384*6777b538SAndroid Build Coastguard Worker }
4385*6777b538SAndroid Build Coastguard Worker
4386*6777b538SAndroid Build Coastguard Worker xmlSBufAddCString(&buf, " ", 1);
4387*6777b538SAndroid Build Coastguard Worker } else {
4388*6777b538SAndroid Build Coastguard Worker chunkSize += 1;
4389*6777b538SAndroid Build Coastguard Worker }
4390*6777b538SAndroid Build Coastguard Worker
4391*6777b538SAndroid Build Coastguard Worker inSpace = 1;
4392*6777b538SAndroid Build Coastguard Worker
4393*6777b538SAndroid Build Coastguard Worker if ((c == 0xD) && (NXT(1) == 0xA))
4394*6777b538SAndroid Build Coastguard Worker CUR_PTR++;
4395*6777b538SAndroid Build Coastguard Worker }
4396*6777b538SAndroid Build Coastguard Worker
4397*6777b538SAndroid Build Coastguard Worker NEXTL(1);
4398*6777b538SAndroid Build Coastguard Worker } else if (NXT(1) == '#') {
4399*6777b538SAndroid Build Coastguard Worker int val;
4400*6777b538SAndroid Build Coastguard Worker
4401*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0) {
4402*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
4403*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4404*6777b538SAndroid Build Coastguard Worker }
4405*6777b538SAndroid Build Coastguard Worker
4406*6777b538SAndroid Build Coastguard Worker val = xmlParseCharRef(ctxt);
4407*6777b538SAndroid Build Coastguard Worker if (val == 0)
4408*6777b538SAndroid Build Coastguard Worker goto error;
4409*6777b538SAndroid Build Coastguard Worker
4410*6777b538SAndroid Build Coastguard Worker if ((val == '&') && (!ctxt->replaceEntities)) {
4411*6777b538SAndroid Build Coastguard Worker /*
4412*6777b538SAndroid Build Coastguard Worker * The reparsing will be done in xmlStringGetNodeList()
4413*6777b538SAndroid Build Coastguard Worker * called by the attribute() function in SAX.c
4414*6777b538SAndroid Build Coastguard Worker */
4415*6777b538SAndroid Build Coastguard Worker xmlSBufAddCString(&buf, "&", 5);
4416*6777b538SAndroid Build Coastguard Worker inSpace = 0;
4417*6777b538SAndroid Build Coastguard Worker } else if (val == ' ') {
4418*6777b538SAndroid Build Coastguard Worker if ((!normalize) || (!inSpace))
4419*6777b538SAndroid Build Coastguard Worker xmlSBufAddCString(&buf, " ", 1);
4420*6777b538SAndroid Build Coastguard Worker inSpace = 1;
4421*6777b538SAndroid Build Coastguard Worker } else {
4422*6777b538SAndroid Build Coastguard Worker xmlSBufAddChar(&buf, val);
4423*6777b538SAndroid Build Coastguard Worker inSpace = 0;
4424*6777b538SAndroid Build Coastguard Worker }
4425*6777b538SAndroid Build Coastguard Worker } else {
4426*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
4427*6777b538SAndroid Build Coastguard Worker xmlEntityPtr ent;
4428*6777b538SAndroid Build Coastguard Worker
4429*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0) {
4430*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
4431*6777b538SAndroid Build Coastguard Worker chunkSize = 0;
4432*6777b538SAndroid Build Coastguard Worker }
4433*6777b538SAndroid Build Coastguard Worker
4434*6777b538SAndroid Build Coastguard Worker name = xmlParseEntityRefInternal(ctxt);
4435*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
4436*6777b538SAndroid Build Coastguard Worker /*
4437*6777b538SAndroid Build Coastguard Worker * Probably a literal '&' which wasn't escaped.
4438*6777b538SAndroid Build Coastguard Worker * TODO: Handle gracefully in recovery mode.
4439*6777b538SAndroid Build Coastguard Worker */
4440*6777b538SAndroid Build Coastguard Worker continue;
4441*6777b538SAndroid Build Coastguard Worker }
4442*6777b538SAndroid Build Coastguard Worker
4443*6777b538SAndroid Build Coastguard Worker ent = xmlLookupGeneralEntity(ctxt, name, /* isAttr */ 1);
4444*6777b538SAndroid Build Coastguard Worker if (ent == NULL)
4445*6777b538SAndroid Build Coastguard Worker continue;
4446*6777b538SAndroid Build Coastguard Worker
4447*6777b538SAndroid Build Coastguard Worker if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
4448*6777b538SAndroid Build Coastguard Worker if ((ent->content[0] == '&') && (!ctxt->replaceEntities))
4449*6777b538SAndroid Build Coastguard Worker xmlSBufAddCString(&buf, "&", 5);
4450*6777b538SAndroid Build Coastguard Worker else
4451*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(&buf, ent->content, ent->length);
4452*6777b538SAndroid Build Coastguard Worker inSpace = 0;
4453*6777b538SAndroid Build Coastguard Worker } else if (ctxt->replaceEntities) {
4454*6777b538SAndroid Build Coastguard Worker xmlExpandEntityInAttValue(ctxt, &buf, ent->content, ent,
4455*6777b538SAndroid Build Coastguard Worker normalize, &inSpace, ctxt->inputNr,
4456*6777b538SAndroid Build Coastguard Worker /* check */ 1);
4457*6777b538SAndroid Build Coastguard Worker } else {
4458*6777b538SAndroid Build Coastguard Worker if ((ent->flags & flags) != flags)
4459*6777b538SAndroid Build Coastguard Worker xmlCheckEntityInAttValue(ctxt, ent, ctxt->inputNr);
4460*6777b538SAndroid Build Coastguard Worker
4461*6777b538SAndroid Build Coastguard Worker if (xmlParserEntityCheck(ctxt, ent->expandedSize)) {
4462*6777b538SAndroid Build Coastguard Worker ent->content[0] = 0;
4463*6777b538SAndroid Build Coastguard Worker goto error;
4464*6777b538SAndroid Build Coastguard Worker }
4465*6777b538SAndroid Build Coastguard Worker
4466*6777b538SAndroid Build Coastguard Worker /*
4467*6777b538SAndroid Build Coastguard Worker * Just output the reference
4468*6777b538SAndroid Build Coastguard Worker */
4469*6777b538SAndroid Build Coastguard Worker xmlSBufAddCString(&buf, "&", 1);
4470*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(&buf, ent->name, xmlStrlen(ent->name));
4471*6777b538SAndroid Build Coastguard Worker xmlSBufAddCString(&buf, ";", 1);
4472*6777b538SAndroid Build Coastguard Worker
4473*6777b538SAndroid Build Coastguard Worker inSpace = 0;
4474*6777b538SAndroid Build Coastguard Worker }
4475*6777b538SAndroid Build Coastguard Worker }
4476*6777b538SAndroid Build Coastguard Worker }
4477*6777b538SAndroid Build Coastguard Worker
4478*6777b538SAndroid Build Coastguard Worker if ((buf.mem == NULL) && (alloc != NULL)) {
4479*6777b538SAndroid Build Coastguard Worker ret = (xmlChar *) CUR_PTR - chunkSize;
4480*6777b538SAndroid Build Coastguard Worker
4481*6777b538SAndroid Build Coastguard Worker if (attlen != NULL)
4482*6777b538SAndroid Build Coastguard Worker *attlen = chunkSize;
4483*6777b538SAndroid Build Coastguard Worker if ((normalize) && (inSpace) && (chunkSize > 0))
4484*6777b538SAndroid Build Coastguard Worker *attlen -= 1;
4485*6777b538SAndroid Build Coastguard Worker *alloc = 0;
4486*6777b538SAndroid Build Coastguard Worker
4487*6777b538SAndroid Build Coastguard Worker /* Report potential error */
4488*6777b538SAndroid Build Coastguard Worker xmlSBufCleanup(&buf, ctxt, "AttValue length too long");
4489*6777b538SAndroid Build Coastguard Worker } else {
4490*6777b538SAndroid Build Coastguard Worker if (chunkSize > 0)
4491*6777b538SAndroid Build Coastguard Worker xmlSBufAddString(&buf, CUR_PTR - chunkSize, chunkSize);
4492*6777b538SAndroid Build Coastguard Worker
4493*6777b538SAndroid Build Coastguard Worker if ((normalize) && (inSpace) && (buf.size > 0))
4494*6777b538SAndroid Build Coastguard Worker buf.size--;
4495*6777b538SAndroid Build Coastguard Worker
4496*6777b538SAndroid Build Coastguard Worker ret = xmlSBufFinish(&buf, attlen, ctxt, "AttValue length too long");
4497*6777b538SAndroid Build Coastguard Worker
4498*6777b538SAndroid Build Coastguard Worker if (ret != NULL) {
4499*6777b538SAndroid Build Coastguard Worker if (attlen != NULL)
4500*6777b538SAndroid Build Coastguard Worker *attlen = buf.size;
4501*6777b538SAndroid Build Coastguard Worker if (alloc != NULL)
4502*6777b538SAndroid Build Coastguard Worker *alloc = 1;
4503*6777b538SAndroid Build Coastguard Worker }
4504*6777b538SAndroid Build Coastguard Worker }
4505*6777b538SAndroid Build Coastguard Worker
4506*6777b538SAndroid Build Coastguard Worker NEXTL(1);
4507*6777b538SAndroid Build Coastguard Worker
4508*6777b538SAndroid Build Coastguard Worker return(ret);
4509*6777b538SAndroid Build Coastguard Worker
4510*6777b538SAndroid Build Coastguard Worker error:
4511*6777b538SAndroid Build Coastguard Worker xmlSBufCleanup(&buf, ctxt, "AttValue length too long");
4512*6777b538SAndroid Build Coastguard Worker return(NULL);
4513*6777b538SAndroid Build Coastguard Worker }
4514*6777b538SAndroid Build Coastguard Worker
4515*6777b538SAndroid Build Coastguard Worker /**
4516*6777b538SAndroid Build Coastguard Worker * xmlParseAttValue:
4517*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
4518*6777b538SAndroid Build Coastguard Worker *
4519*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
4520*6777b538SAndroid Build Coastguard Worker *
4521*6777b538SAndroid Build Coastguard Worker * parse a value for an attribute
4522*6777b538SAndroid Build Coastguard Worker * Note: the parser won't do substitution of entities here, this
4523*6777b538SAndroid Build Coastguard Worker * will be handled later in xmlStringGetNodeList
4524*6777b538SAndroid Build Coastguard Worker *
4525*6777b538SAndroid Build Coastguard Worker * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
4526*6777b538SAndroid Build Coastguard Worker * "'" ([^<&'] | Reference)* "'"
4527*6777b538SAndroid Build Coastguard Worker *
4528*6777b538SAndroid Build Coastguard Worker * 3.3.3 Attribute-Value Normalization:
4529*6777b538SAndroid Build Coastguard Worker * Before the value of an attribute is passed to the application or
4530*6777b538SAndroid Build Coastguard Worker * checked for validity, the XML processor must normalize it as follows:
4531*6777b538SAndroid Build Coastguard Worker * - a character reference is processed by appending the referenced
4532*6777b538SAndroid Build Coastguard Worker * character to the attribute value
4533*6777b538SAndroid Build Coastguard Worker * - an entity reference is processed by recursively processing the
4534*6777b538SAndroid Build Coastguard Worker * replacement text of the entity
4535*6777b538SAndroid Build Coastguard Worker * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
4536*6777b538SAndroid Build Coastguard Worker * appending #x20 to the normalized value, except that only a single
4537*6777b538SAndroid Build Coastguard Worker * #x20 is appended for a "#xD#xA" sequence that is part of an external
4538*6777b538SAndroid Build Coastguard Worker * parsed entity or the literal entity value of an internal parsed entity
4539*6777b538SAndroid Build Coastguard Worker * - other characters are processed by appending them to the normalized value
4540*6777b538SAndroid Build Coastguard Worker * If the declared value is not CDATA, then the XML processor must further
4541*6777b538SAndroid Build Coastguard Worker * process the normalized attribute value by discarding any leading and
4542*6777b538SAndroid Build Coastguard Worker * trailing space (#x20) characters, and by replacing sequences of space
4543*6777b538SAndroid Build Coastguard Worker * (#x20) characters by a single space (#x20) character.
4544*6777b538SAndroid Build Coastguard Worker * All attributes for which no declaration has been read should be treated
4545*6777b538SAndroid Build Coastguard Worker * by a non-validating parser as if declared CDATA.
4546*6777b538SAndroid Build Coastguard Worker *
4547*6777b538SAndroid Build Coastguard Worker * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
4548*6777b538SAndroid Build Coastguard Worker */
4549*6777b538SAndroid Build Coastguard Worker
4550*6777b538SAndroid Build Coastguard Worker
4551*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlParseAttValue(xmlParserCtxtPtr ctxt)4552*6777b538SAndroid Build Coastguard Worker xmlParseAttValue(xmlParserCtxtPtr ctxt) {
4553*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
4554*6777b538SAndroid Build Coastguard Worker return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
4555*6777b538SAndroid Build Coastguard Worker }
4556*6777b538SAndroid Build Coastguard Worker
4557*6777b538SAndroid Build Coastguard Worker /**
4558*6777b538SAndroid Build Coastguard Worker * xmlParseSystemLiteral:
4559*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
4560*6777b538SAndroid Build Coastguard Worker *
4561*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
4562*6777b538SAndroid Build Coastguard Worker *
4563*6777b538SAndroid Build Coastguard Worker * parse an XML Literal
4564*6777b538SAndroid Build Coastguard Worker *
4565*6777b538SAndroid Build Coastguard Worker * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
4566*6777b538SAndroid Build Coastguard Worker *
4567*6777b538SAndroid Build Coastguard Worker * Returns the SystemLiteral parsed or NULL
4568*6777b538SAndroid Build Coastguard Worker */
4569*6777b538SAndroid Build Coastguard Worker
4570*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlParseSystemLiteral(xmlParserCtxtPtr ctxt)4571*6777b538SAndroid Build Coastguard Worker xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
4572*6777b538SAndroid Build Coastguard Worker xmlChar *buf = NULL;
4573*6777b538SAndroid Build Coastguard Worker int len = 0;
4574*6777b538SAndroid Build Coastguard Worker int size = XML_PARSER_BUFFER_SIZE;
4575*6777b538SAndroid Build Coastguard Worker int cur, l;
4576*6777b538SAndroid Build Coastguard Worker int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
4577*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH :
4578*6777b538SAndroid Build Coastguard Worker XML_MAX_NAME_LENGTH;
4579*6777b538SAndroid Build Coastguard Worker xmlChar stop;
4580*6777b538SAndroid Build Coastguard Worker
4581*6777b538SAndroid Build Coastguard Worker if (RAW == '"') {
4582*6777b538SAndroid Build Coastguard Worker NEXT;
4583*6777b538SAndroid Build Coastguard Worker stop = '"';
4584*6777b538SAndroid Build Coastguard Worker } else if (RAW == '\'') {
4585*6777b538SAndroid Build Coastguard Worker NEXT;
4586*6777b538SAndroid Build Coastguard Worker stop = '\'';
4587*6777b538SAndroid Build Coastguard Worker } else {
4588*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4589*6777b538SAndroid Build Coastguard Worker return(NULL);
4590*6777b538SAndroid Build Coastguard Worker }
4591*6777b538SAndroid Build Coastguard Worker
4592*6777b538SAndroid Build Coastguard Worker buf = (xmlChar *) xmlMallocAtomic(size);
4593*6777b538SAndroid Build Coastguard Worker if (buf == NULL) {
4594*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
4595*6777b538SAndroid Build Coastguard Worker return(NULL);
4596*6777b538SAndroid Build Coastguard Worker }
4597*6777b538SAndroid Build Coastguard Worker cur = CUR_CHAR(l);
4598*6777b538SAndroid Build Coastguard Worker while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
4599*6777b538SAndroid Build Coastguard Worker if (len + 5 >= size) {
4600*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
4601*6777b538SAndroid Build Coastguard Worker
4602*6777b538SAndroid Build Coastguard Worker size *= 2;
4603*6777b538SAndroid Build Coastguard Worker tmp = (xmlChar *) xmlRealloc(buf, size);
4604*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
4605*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
4606*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
4607*6777b538SAndroid Build Coastguard Worker return(NULL);
4608*6777b538SAndroid Build Coastguard Worker }
4609*6777b538SAndroid Build Coastguard Worker buf = tmp;
4610*6777b538SAndroid Build Coastguard Worker }
4611*6777b538SAndroid Build Coastguard Worker COPY_BUF(buf, len, cur);
4612*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
4613*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
4614*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
4615*6777b538SAndroid Build Coastguard Worker return(NULL);
4616*6777b538SAndroid Build Coastguard Worker }
4617*6777b538SAndroid Build Coastguard Worker NEXTL(l);
4618*6777b538SAndroid Build Coastguard Worker cur = CUR_CHAR(l);
4619*6777b538SAndroid Build Coastguard Worker }
4620*6777b538SAndroid Build Coastguard Worker buf[len] = 0;
4621*6777b538SAndroid Build Coastguard Worker if (!IS_CHAR(cur)) {
4622*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4623*6777b538SAndroid Build Coastguard Worker } else {
4624*6777b538SAndroid Build Coastguard Worker NEXT;
4625*6777b538SAndroid Build Coastguard Worker }
4626*6777b538SAndroid Build Coastguard Worker return(buf);
4627*6777b538SAndroid Build Coastguard Worker }
4628*6777b538SAndroid Build Coastguard Worker
4629*6777b538SAndroid Build Coastguard Worker /**
4630*6777b538SAndroid Build Coastguard Worker * xmlParsePubidLiteral:
4631*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
4632*6777b538SAndroid Build Coastguard Worker *
4633*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
4634*6777b538SAndroid Build Coastguard Worker *
4635*6777b538SAndroid Build Coastguard Worker * parse an XML public literal
4636*6777b538SAndroid Build Coastguard Worker *
4637*6777b538SAndroid Build Coastguard Worker * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
4638*6777b538SAndroid Build Coastguard Worker *
4639*6777b538SAndroid Build Coastguard Worker * Returns the PubidLiteral parsed or NULL.
4640*6777b538SAndroid Build Coastguard Worker */
4641*6777b538SAndroid Build Coastguard Worker
4642*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlParsePubidLiteral(xmlParserCtxtPtr ctxt)4643*6777b538SAndroid Build Coastguard Worker xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
4644*6777b538SAndroid Build Coastguard Worker xmlChar *buf = NULL;
4645*6777b538SAndroid Build Coastguard Worker int len = 0;
4646*6777b538SAndroid Build Coastguard Worker int size = XML_PARSER_BUFFER_SIZE;
4647*6777b538SAndroid Build Coastguard Worker int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
4648*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH :
4649*6777b538SAndroid Build Coastguard Worker XML_MAX_NAME_LENGTH;
4650*6777b538SAndroid Build Coastguard Worker xmlChar cur;
4651*6777b538SAndroid Build Coastguard Worker xmlChar stop;
4652*6777b538SAndroid Build Coastguard Worker
4653*6777b538SAndroid Build Coastguard Worker if (RAW == '"') {
4654*6777b538SAndroid Build Coastguard Worker NEXT;
4655*6777b538SAndroid Build Coastguard Worker stop = '"';
4656*6777b538SAndroid Build Coastguard Worker } else if (RAW == '\'') {
4657*6777b538SAndroid Build Coastguard Worker NEXT;
4658*6777b538SAndroid Build Coastguard Worker stop = '\'';
4659*6777b538SAndroid Build Coastguard Worker } else {
4660*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4661*6777b538SAndroid Build Coastguard Worker return(NULL);
4662*6777b538SAndroid Build Coastguard Worker }
4663*6777b538SAndroid Build Coastguard Worker buf = (xmlChar *) xmlMallocAtomic(size);
4664*6777b538SAndroid Build Coastguard Worker if (buf == NULL) {
4665*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
4666*6777b538SAndroid Build Coastguard Worker return(NULL);
4667*6777b538SAndroid Build Coastguard Worker }
4668*6777b538SAndroid Build Coastguard Worker cur = CUR;
4669*6777b538SAndroid Build Coastguard Worker while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop) &&
4670*6777b538SAndroid Build Coastguard Worker (PARSER_STOPPED(ctxt) == 0)) { /* checked */
4671*6777b538SAndroid Build Coastguard Worker if (len + 1 >= size) {
4672*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
4673*6777b538SAndroid Build Coastguard Worker
4674*6777b538SAndroid Build Coastguard Worker size *= 2;
4675*6777b538SAndroid Build Coastguard Worker tmp = (xmlChar *) xmlRealloc(buf, size);
4676*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
4677*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
4678*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
4679*6777b538SAndroid Build Coastguard Worker return(NULL);
4680*6777b538SAndroid Build Coastguard Worker }
4681*6777b538SAndroid Build Coastguard Worker buf = tmp;
4682*6777b538SAndroid Build Coastguard Worker }
4683*6777b538SAndroid Build Coastguard Worker buf[len++] = cur;
4684*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
4685*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
4686*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
4687*6777b538SAndroid Build Coastguard Worker return(NULL);
4688*6777b538SAndroid Build Coastguard Worker }
4689*6777b538SAndroid Build Coastguard Worker NEXT;
4690*6777b538SAndroid Build Coastguard Worker cur = CUR;
4691*6777b538SAndroid Build Coastguard Worker }
4692*6777b538SAndroid Build Coastguard Worker buf[len] = 0;
4693*6777b538SAndroid Build Coastguard Worker if (cur != stop) {
4694*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4695*6777b538SAndroid Build Coastguard Worker } else {
4696*6777b538SAndroid Build Coastguard Worker NEXTL(1);
4697*6777b538SAndroid Build Coastguard Worker }
4698*6777b538SAndroid Build Coastguard Worker return(buf);
4699*6777b538SAndroid Build Coastguard Worker }
4700*6777b538SAndroid Build Coastguard Worker
4701*6777b538SAndroid Build Coastguard Worker static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int partial);
4702*6777b538SAndroid Build Coastguard Worker
4703*6777b538SAndroid Build Coastguard Worker /*
4704*6777b538SAndroid Build Coastguard Worker * used for the test in the inner loop of the char data testing
4705*6777b538SAndroid Build Coastguard Worker */
4706*6777b538SAndroid Build Coastguard Worker static const unsigned char test_char_data[256] = {
4707*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4708*6777b538SAndroid Build Coastguard Worker 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
4709*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4710*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4711*6777b538SAndroid Build Coastguard Worker 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
4712*6777b538SAndroid Build Coastguard Worker 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
4713*6777b538SAndroid Build Coastguard Worker 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
4714*6777b538SAndroid Build Coastguard Worker 0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
4715*6777b538SAndroid Build Coastguard Worker 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
4716*6777b538SAndroid Build Coastguard Worker 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
4717*6777b538SAndroid Build Coastguard Worker 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
4718*6777b538SAndroid Build Coastguard Worker 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
4719*6777b538SAndroid Build Coastguard Worker 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
4720*6777b538SAndroid Build Coastguard Worker 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
4721*6777b538SAndroid Build Coastguard Worker 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
4722*6777b538SAndroid Build Coastguard Worker 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
4723*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
4724*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4725*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4726*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4727*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4728*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4729*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4730*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4731*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4732*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4733*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4734*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4735*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4736*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4737*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4738*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4739*6777b538SAndroid Build Coastguard Worker };
4740*6777b538SAndroid Build Coastguard Worker
4741*6777b538SAndroid Build Coastguard Worker /**
4742*6777b538SAndroid Build Coastguard Worker * xmlParseCharDataInternal:
4743*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
4744*6777b538SAndroid Build Coastguard Worker * @partial: buffer may contain partial UTF-8 sequences
4745*6777b538SAndroid Build Coastguard Worker *
4746*6777b538SAndroid Build Coastguard Worker * Parse character data. Always makes progress if the first char isn't
4747*6777b538SAndroid Build Coastguard Worker * '<' or '&'.
4748*6777b538SAndroid Build Coastguard Worker *
4749*6777b538SAndroid Build Coastguard Worker * The right angle bracket (>) may be represented using the string ">",
4750*6777b538SAndroid Build Coastguard Worker * and must, for compatibility, be escaped using ">" or a character
4751*6777b538SAndroid Build Coastguard Worker * reference when it appears in the string "]]>" in content, when that
4752*6777b538SAndroid Build Coastguard Worker * string is not marking the end of a CDATA section.
4753*6777b538SAndroid Build Coastguard Worker *
4754*6777b538SAndroid Build Coastguard Worker * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
4755*6777b538SAndroid Build Coastguard Worker */
4756*6777b538SAndroid Build Coastguard Worker static void
xmlParseCharDataInternal(xmlParserCtxtPtr ctxt,int partial)4757*6777b538SAndroid Build Coastguard Worker xmlParseCharDataInternal(xmlParserCtxtPtr ctxt, int partial) {
4758*6777b538SAndroid Build Coastguard Worker const xmlChar *in;
4759*6777b538SAndroid Build Coastguard Worker int nbchar = 0;
4760*6777b538SAndroid Build Coastguard Worker int line = ctxt->input->line;
4761*6777b538SAndroid Build Coastguard Worker int col = ctxt->input->col;
4762*6777b538SAndroid Build Coastguard Worker int ccol;
4763*6777b538SAndroid Build Coastguard Worker
4764*6777b538SAndroid Build Coastguard Worker GROW;
4765*6777b538SAndroid Build Coastguard Worker /*
4766*6777b538SAndroid Build Coastguard Worker * Accelerated common case where input don't need to be
4767*6777b538SAndroid Build Coastguard Worker * modified before passing it to the handler.
4768*6777b538SAndroid Build Coastguard Worker */
4769*6777b538SAndroid Build Coastguard Worker in = ctxt->input->cur;
4770*6777b538SAndroid Build Coastguard Worker do {
4771*6777b538SAndroid Build Coastguard Worker get_more_space:
4772*6777b538SAndroid Build Coastguard Worker while (*in == 0x20) { in++; ctxt->input->col++; }
4773*6777b538SAndroid Build Coastguard Worker if (*in == 0xA) {
4774*6777b538SAndroid Build Coastguard Worker do {
4775*6777b538SAndroid Build Coastguard Worker ctxt->input->line++; ctxt->input->col = 1;
4776*6777b538SAndroid Build Coastguard Worker in++;
4777*6777b538SAndroid Build Coastguard Worker } while (*in == 0xA);
4778*6777b538SAndroid Build Coastguard Worker goto get_more_space;
4779*6777b538SAndroid Build Coastguard Worker }
4780*6777b538SAndroid Build Coastguard Worker if (*in == '<') {
4781*6777b538SAndroid Build Coastguard Worker nbchar = in - ctxt->input->cur;
4782*6777b538SAndroid Build Coastguard Worker if (nbchar > 0) {
4783*6777b538SAndroid Build Coastguard Worker const xmlChar *tmp = ctxt->input->cur;
4784*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in;
4785*6777b538SAndroid Build Coastguard Worker
4786*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
4787*6777b538SAndroid Build Coastguard Worker (ctxt->disableSAX == 0) &&
4788*6777b538SAndroid Build Coastguard Worker (ctxt->sax->ignorableWhitespace !=
4789*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters)) {
4790*6777b538SAndroid Build Coastguard Worker if (areBlanks(ctxt, tmp, nbchar, 1)) {
4791*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->ignorableWhitespace != NULL)
4792*6777b538SAndroid Build Coastguard Worker ctxt->sax->ignorableWhitespace(ctxt->userData,
4793*6777b538SAndroid Build Coastguard Worker tmp, nbchar);
4794*6777b538SAndroid Build Coastguard Worker } else {
4795*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->characters != NULL)
4796*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData,
4797*6777b538SAndroid Build Coastguard Worker tmp, nbchar);
4798*6777b538SAndroid Build Coastguard Worker if (*ctxt->space == -1)
4799*6777b538SAndroid Build Coastguard Worker *ctxt->space = -2;
4800*6777b538SAndroid Build Coastguard Worker }
4801*6777b538SAndroid Build Coastguard Worker } else if ((ctxt->sax != NULL) &&
4802*6777b538SAndroid Build Coastguard Worker (ctxt->disableSAX == 0) &&
4803*6777b538SAndroid Build Coastguard Worker (ctxt->sax->characters != NULL)) {
4804*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData,
4805*6777b538SAndroid Build Coastguard Worker tmp, nbchar);
4806*6777b538SAndroid Build Coastguard Worker }
4807*6777b538SAndroid Build Coastguard Worker }
4808*6777b538SAndroid Build Coastguard Worker return;
4809*6777b538SAndroid Build Coastguard Worker }
4810*6777b538SAndroid Build Coastguard Worker
4811*6777b538SAndroid Build Coastguard Worker get_more:
4812*6777b538SAndroid Build Coastguard Worker ccol = ctxt->input->col;
4813*6777b538SAndroid Build Coastguard Worker while (test_char_data[*in]) {
4814*6777b538SAndroid Build Coastguard Worker in++;
4815*6777b538SAndroid Build Coastguard Worker ccol++;
4816*6777b538SAndroid Build Coastguard Worker }
4817*6777b538SAndroid Build Coastguard Worker ctxt->input->col = ccol;
4818*6777b538SAndroid Build Coastguard Worker if (*in == 0xA) {
4819*6777b538SAndroid Build Coastguard Worker do {
4820*6777b538SAndroid Build Coastguard Worker ctxt->input->line++; ctxt->input->col = 1;
4821*6777b538SAndroid Build Coastguard Worker in++;
4822*6777b538SAndroid Build Coastguard Worker } while (*in == 0xA);
4823*6777b538SAndroid Build Coastguard Worker goto get_more;
4824*6777b538SAndroid Build Coastguard Worker }
4825*6777b538SAndroid Build Coastguard Worker if (*in == ']') {
4826*6777b538SAndroid Build Coastguard Worker if ((in[1] == ']') && (in[2] == '>')) {
4827*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4828*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in + 1;
4829*6777b538SAndroid Build Coastguard Worker return;
4830*6777b538SAndroid Build Coastguard Worker }
4831*6777b538SAndroid Build Coastguard Worker in++;
4832*6777b538SAndroid Build Coastguard Worker ctxt->input->col++;
4833*6777b538SAndroid Build Coastguard Worker goto get_more;
4834*6777b538SAndroid Build Coastguard Worker }
4835*6777b538SAndroid Build Coastguard Worker nbchar = in - ctxt->input->cur;
4836*6777b538SAndroid Build Coastguard Worker if (nbchar > 0) {
4837*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
4838*6777b538SAndroid Build Coastguard Worker (ctxt->disableSAX == 0) &&
4839*6777b538SAndroid Build Coastguard Worker (ctxt->sax->ignorableWhitespace !=
4840*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters) &&
4841*6777b538SAndroid Build Coastguard Worker (IS_BLANK_CH(*ctxt->input->cur))) {
4842*6777b538SAndroid Build Coastguard Worker const xmlChar *tmp = ctxt->input->cur;
4843*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in;
4844*6777b538SAndroid Build Coastguard Worker
4845*6777b538SAndroid Build Coastguard Worker if (areBlanks(ctxt, tmp, nbchar, 0)) {
4846*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->ignorableWhitespace != NULL)
4847*6777b538SAndroid Build Coastguard Worker ctxt->sax->ignorableWhitespace(ctxt->userData,
4848*6777b538SAndroid Build Coastguard Worker tmp, nbchar);
4849*6777b538SAndroid Build Coastguard Worker } else {
4850*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->characters != NULL)
4851*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData,
4852*6777b538SAndroid Build Coastguard Worker tmp, nbchar);
4853*6777b538SAndroid Build Coastguard Worker if (*ctxt->space == -1)
4854*6777b538SAndroid Build Coastguard Worker *ctxt->space = -2;
4855*6777b538SAndroid Build Coastguard Worker }
4856*6777b538SAndroid Build Coastguard Worker line = ctxt->input->line;
4857*6777b538SAndroid Build Coastguard Worker col = ctxt->input->col;
4858*6777b538SAndroid Build Coastguard Worker } else if ((ctxt->sax != NULL) &&
4859*6777b538SAndroid Build Coastguard Worker (ctxt->disableSAX == 0)) {
4860*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->characters != NULL)
4861*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData,
4862*6777b538SAndroid Build Coastguard Worker ctxt->input->cur, nbchar);
4863*6777b538SAndroid Build Coastguard Worker line = ctxt->input->line;
4864*6777b538SAndroid Build Coastguard Worker col = ctxt->input->col;
4865*6777b538SAndroid Build Coastguard Worker }
4866*6777b538SAndroid Build Coastguard Worker }
4867*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in;
4868*6777b538SAndroid Build Coastguard Worker if (*in == 0xD) {
4869*6777b538SAndroid Build Coastguard Worker in++;
4870*6777b538SAndroid Build Coastguard Worker if (*in == 0xA) {
4871*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in;
4872*6777b538SAndroid Build Coastguard Worker in++;
4873*6777b538SAndroid Build Coastguard Worker ctxt->input->line++; ctxt->input->col = 1;
4874*6777b538SAndroid Build Coastguard Worker continue; /* while */
4875*6777b538SAndroid Build Coastguard Worker }
4876*6777b538SAndroid Build Coastguard Worker in--;
4877*6777b538SAndroid Build Coastguard Worker }
4878*6777b538SAndroid Build Coastguard Worker if (*in == '<') {
4879*6777b538SAndroid Build Coastguard Worker return;
4880*6777b538SAndroid Build Coastguard Worker }
4881*6777b538SAndroid Build Coastguard Worker if (*in == '&') {
4882*6777b538SAndroid Build Coastguard Worker return;
4883*6777b538SAndroid Build Coastguard Worker }
4884*6777b538SAndroid Build Coastguard Worker SHRINK;
4885*6777b538SAndroid Build Coastguard Worker GROW;
4886*6777b538SAndroid Build Coastguard Worker in = ctxt->input->cur;
4887*6777b538SAndroid Build Coastguard Worker } while (((*in >= 0x20) && (*in <= 0x7F)) ||
4888*6777b538SAndroid Build Coastguard Worker (*in == 0x09) || (*in == 0x0a));
4889*6777b538SAndroid Build Coastguard Worker ctxt->input->line = line;
4890*6777b538SAndroid Build Coastguard Worker ctxt->input->col = col;
4891*6777b538SAndroid Build Coastguard Worker xmlParseCharDataComplex(ctxt, partial);
4892*6777b538SAndroid Build Coastguard Worker }
4893*6777b538SAndroid Build Coastguard Worker
4894*6777b538SAndroid Build Coastguard Worker /**
4895*6777b538SAndroid Build Coastguard Worker * xmlParseCharDataComplex:
4896*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
4897*6777b538SAndroid Build Coastguard Worker * @cdata: int indicating whether we are within a CDATA section
4898*6777b538SAndroid Build Coastguard Worker *
4899*6777b538SAndroid Build Coastguard Worker * Always makes progress if the first char isn't '<' or '&'.
4900*6777b538SAndroid Build Coastguard Worker *
4901*6777b538SAndroid Build Coastguard Worker * parse a CharData section.this is the fallback function
4902*6777b538SAndroid Build Coastguard Worker * of xmlParseCharData() when the parsing requires handling
4903*6777b538SAndroid Build Coastguard Worker * of non-ASCII characters.
4904*6777b538SAndroid Build Coastguard Worker */
4905*6777b538SAndroid Build Coastguard Worker static void
xmlParseCharDataComplex(xmlParserCtxtPtr ctxt,int partial)4906*6777b538SAndroid Build Coastguard Worker xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int partial) {
4907*6777b538SAndroid Build Coastguard Worker xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
4908*6777b538SAndroid Build Coastguard Worker int nbchar = 0;
4909*6777b538SAndroid Build Coastguard Worker int cur, l;
4910*6777b538SAndroid Build Coastguard Worker
4911*6777b538SAndroid Build Coastguard Worker cur = CUR_CHAR(l);
4912*6777b538SAndroid Build Coastguard Worker while ((cur != '<') && /* checked */
4913*6777b538SAndroid Build Coastguard Worker (cur != '&') &&
4914*6777b538SAndroid Build Coastguard Worker (IS_CHAR(cur))) {
4915*6777b538SAndroid Build Coastguard Worker if ((cur == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
4916*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4917*6777b538SAndroid Build Coastguard Worker }
4918*6777b538SAndroid Build Coastguard Worker COPY_BUF(buf, nbchar, cur);
4919*6777b538SAndroid Build Coastguard Worker /* move current position before possible calling of ctxt->sax->characters */
4920*6777b538SAndroid Build Coastguard Worker NEXTL(l);
4921*6777b538SAndroid Build Coastguard Worker if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
4922*6777b538SAndroid Build Coastguard Worker buf[nbchar] = 0;
4923*6777b538SAndroid Build Coastguard Worker
4924*6777b538SAndroid Build Coastguard Worker /*
4925*6777b538SAndroid Build Coastguard Worker * OK the segment is to be consumed as chars.
4926*6777b538SAndroid Build Coastguard Worker */
4927*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4928*6777b538SAndroid Build Coastguard Worker if (areBlanks(ctxt, buf, nbchar, 0)) {
4929*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->ignorableWhitespace != NULL)
4930*6777b538SAndroid Build Coastguard Worker ctxt->sax->ignorableWhitespace(ctxt->userData,
4931*6777b538SAndroid Build Coastguard Worker buf, nbchar);
4932*6777b538SAndroid Build Coastguard Worker } else {
4933*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->characters != NULL)
4934*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData, buf, nbchar);
4935*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax->characters !=
4936*6777b538SAndroid Build Coastguard Worker ctxt->sax->ignorableWhitespace) &&
4937*6777b538SAndroid Build Coastguard Worker (*ctxt->space == -1))
4938*6777b538SAndroid Build Coastguard Worker *ctxt->space = -2;
4939*6777b538SAndroid Build Coastguard Worker }
4940*6777b538SAndroid Build Coastguard Worker }
4941*6777b538SAndroid Build Coastguard Worker nbchar = 0;
4942*6777b538SAndroid Build Coastguard Worker SHRINK;
4943*6777b538SAndroid Build Coastguard Worker }
4944*6777b538SAndroid Build Coastguard Worker cur = CUR_CHAR(l);
4945*6777b538SAndroid Build Coastguard Worker }
4946*6777b538SAndroid Build Coastguard Worker if (nbchar != 0) {
4947*6777b538SAndroid Build Coastguard Worker buf[nbchar] = 0;
4948*6777b538SAndroid Build Coastguard Worker /*
4949*6777b538SAndroid Build Coastguard Worker * OK the segment is to be consumed as chars.
4950*6777b538SAndroid Build Coastguard Worker */
4951*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4952*6777b538SAndroid Build Coastguard Worker if (areBlanks(ctxt, buf, nbchar, 0)) {
4953*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->ignorableWhitespace != NULL)
4954*6777b538SAndroid Build Coastguard Worker ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
4955*6777b538SAndroid Build Coastguard Worker } else {
4956*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->characters != NULL)
4957*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData, buf, nbchar);
4958*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
4959*6777b538SAndroid Build Coastguard Worker (*ctxt->space == -1))
4960*6777b538SAndroid Build Coastguard Worker *ctxt->space = -2;
4961*6777b538SAndroid Build Coastguard Worker }
4962*6777b538SAndroid Build Coastguard Worker }
4963*6777b538SAndroid Build Coastguard Worker }
4964*6777b538SAndroid Build Coastguard Worker /*
4965*6777b538SAndroid Build Coastguard Worker * cur == 0 can mean
4966*6777b538SAndroid Build Coastguard Worker *
4967*6777b538SAndroid Build Coastguard Worker * - End of buffer.
4968*6777b538SAndroid Build Coastguard Worker * - An actual 0 character.
4969*6777b538SAndroid Build Coastguard Worker * - An incomplete UTF-8 sequence. This is allowed if partial is set.
4970*6777b538SAndroid Build Coastguard Worker */
4971*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur < ctxt->input->end) {
4972*6777b538SAndroid Build Coastguard Worker if ((cur == 0) && (CUR != 0)) {
4973*6777b538SAndroid Build Coastguard Worker if (partial == 0) {
4974*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4975*6777b538SAndroid Build Coastguard Worker "Incomplete UTF-8 sequence starting with %02X\n", CUR);
4976*6777b538SAndroid Build Coastguard Worker NEXTL(1);
4977*6777b538SAndroid Build Coastguard Worker }
4978*6777b538SAndroid Build Coastguard Worker } else if ((cur != '<') && (cur != '&')) {
4979*6777b538SAndroid Build Coastguard Worker /* Generate the error and skip the offending character */
4980*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4981*6777b538SAndroid Build Coastguard Worker "PCDATA invalid Char value %d\n", cur);
4982*6777b538SAndroid Build Coastguard Worker NEXTL(l);
4983*6777b538SAndroid Build Coastguard Worker }
4984*6777b538SAndroid Build Coastguard Worker }
4985*6777b538SAndroid Build Coastguard Worker }
4986*6777b538SAndroid Build Coastguard Worker
4987*6777b538SAndroid Build Coastguard Worker /**
4988*6777b538SAndroid Build Coastguard Worker * xmlParseCharData:
4989*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
4990*6777b538SAndroid Build Coastguard Worker * @cdata: unused
4991*6777b538SAndroid Build Coastguard Worker *
4992*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
4993*6777b538SAndroid Build Coastguard Worker */
4994*6777b538SAndroid Build Coastguard Worker void
xmlParseCharData(xmlParserCtxtPtr ctxt,ATTRIBUTE_UNUSED int cdata)4995*6777b538SAndroid Build Coastguard Worker xmlParseCharData(xmlParserCtxtPtr ctxt, ATTRIBUTE_UNUSED int cdata) {
4996*6777b538SAndroid Build Coastguard Worker xmlParseCharDataInternal(ctxt, 0);
4997*6777b538SAndroid Build Coastguard Worker }
4998*6777b538SAndroid Build Coastguard Worker
4999*6777b538SAndroid Build Coastguard Worker /**
5000*6777b538SAndroid Build Coastguard Worker * xmlParseExternalID:
5001*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
5002*6777b538SAndroid Build Coastguard Worker * @publicID: a xmlChar** receiving PubidLiteral
5003*6777b538SAndroid Build Coastguard Worker * @strict: indicate whether we should restrict parsing to only
5004*6777b538SAndroid Build Coastguard Worker * production [75], see NOTE below
5005*6777b538SAndroid Build Coastguard Worker *
5006*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
5007*6777b538SAndroid Build Coastguard Worker *
5008*6777b538SAndroid Build Coastguard Worker * Parse an External ID or a Public ID
5009*6777b538SAndroid Build Coastguard Worker *
5010*6777b538SAndroid Build Coastguard Worker * NOTE: Productions [75] and [83] interact badly since [75] can generate
5011*6777b538SAndroid Build Coastguard Worker * 'PUBLIC' S PubidLiteral S SystemLiteral
5012*6777b538SAndroid Build Coastguard Worker *
5013*6777b538SAndroid Build Coastguard Worker * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
5014*6777b538SAndroid Build Coastguard Worker * | 'PUBLIC' S PubidLiteral S SystemLiteral
5015*6777b538SAndroid Build Coastguard Worker *
5016*6777b538SAndroid Build Coastguard Worker * [83] PublicID ::= 'PUBLIC' S PubidLiteral
5017*6777b538SAndroid Build Coastguard Worker *
5018*6777b538SAndroid Build Coastguard Worker * Returns the function returns SystemLiteral and in the second
5019*6777b538SAndroid Build Coastguard Worker * case publicID receives PubidLiteral, is strict is off
5020*6777b538SAndroid Build Coastguard Worker * it is possible to return NULL and have publicID set.
5021*6777b538SAndroid Build Coastguard Worker */
5022*6777b538SAndroid Build Coastguard Worker
5023*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlParseExternalID(xmlParserCtxtPtr ctxt,xmlChar ** publicID,int strict)5024*6777b538SAndroid Build Coastguard Worker xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
5025*6777b538SAndroid Build Coastguard Worker xmlChar *URI = NULL;
5026*6777b538SAndroid Build Coastguard Worker
5027*6777b538SAndroid Build Coastguard Worker *publicID = NULL;
5028*6777b538SAndroid Build Coastguard Worker if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
5029*6777b538SAndroid Build Coastguard Worker SKIP(6);
5030*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS == 0) {
5031*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5032*6777b538SAndroid Build Coastguard Worker "Space required after 'SYSTEM'\n");
5033*6777b538SAndroid Build Coastguard Worker }
5034*6777b538SAndroid Build Coastguard Worker URI = xmlParseSystemLiteral(ctxt);
5035*6777b538SAndroid Build Coastguard Worker if (URI == NULL) {
5036*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
5037*6777b538SAndroid Build Coastguard Worker }
5038*6777b538SAndroid Build Coastguard Worker } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
5039*6777b538SAndroid Build Coastguard Worker SKIP(6);
5040*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS == 0) {
5041*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5042*6777b538SAndroid Build Coastguard Worker "Space required after 'PUBLIC'\n");
5043*6777b538SAndroid Build Coastguard Worker }
5044*6777b538SAndroid Build Coastguard Worker *publicID = xmlParsePubidLiteral(ctxt);
5045*6777b538SAndroid Build Coastguard Worker if (*publicID == NULL) {
5046*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
5047*6777b538SAndroid Build Coastguard Worker }
5048*6777b538SAndroid Build Coastguard Worker if (strict) {
5049*6777b538SAndroid Build Coastguard Worker /*
5050*6777b538SAndroid Build Coastguard Worker * We don't handle [83] so "S SystemLiteral" is required.
5051*6777b538SAndroid Build Coastguard Worker */
5052*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS == 0) {
5053*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5054*6777b538SAndroid Build Coastguard Worker "Space required after the Public Identifier\n");
5055*6777b538SAndroid Build Coastguard Worker }
5056*6777b538SAndroid Build Coastguard Worker } else {
5057*6777b538SAndroid Build Coastguard Worker /*
5058*6777b538SAndroid Build Coastguard Worker * We handle [83] so we return immediately, if
5059*6777b538SAndroid Build Coastguard Worker * "S SystemLiteral" is not detected. We skip blanks if no
5060*6777b538SAndroid Build Coastguard Worker * system literal was found, but this is harmless since we must
5061*6777b538SAndroid Build Coastguard Worker * be at the end of a NotationDecl.
5062*6777b538SAndroid Build Coastguard Worker */
5063*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS == 0) return(NULL);
5064*6777b538SAndroid Build Coastguard Worker if ((CUR != '\'') && (CUR != '"')) return(NULL);
5065*6777b538SAndroid Build Coastguard Worker }
5066*6777b538SAndroid Build Coastguard Worker URI = xmlParseSystemLiteral(ctxt);
5067*6777b538SAndroid Build Coastguard Worker if (URI == NULL) {
5068*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
5069*6777b538SAndroid Build Coastguard Worker }
5070*6777b538SAndroid Build Coastguard Worker }
5071*6777b538SAndroid Build Coastguard Worker return(URI);
5072*6777b538SAndroid Build Coastguard Worker }
5073*6777b538SAndroid Build Coastguard Worker
5074*6777b538SAndroid Build Coastguard Worker /**
5075*6777b538SAndroid Build Coastguard Worker * xmlParseCommentComplex:
5076*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
5077*6777b538SAndroid Build Coastguard Worker * @buf: the already parsed part of the buffer
5078*6777b538SAndroid Build Coastguard Worker * @len: number of bytes in the buffer
5079*6777b538SAndroid Build Coastguard Worker * @size: allocated size of the buffer
5080*6777b538SAndroid Build Coastguard Worker *
5081*6777b538SAndroid Build Coastguard Worker * Skip an XML (SGML) comment <!-- .... -->
5082*6777b538SAndroid Build Coastguard Worker * The spec says that "For compatibility, the string "--" (double-hyphen)
5083*6777b538SAndroid Build Coastguard Worker * must not occur within comments. "
5084*6777b538SAndroid Build Coastguard Worker * This is the slow routine in case the accelerator for ascii didn't work
5085*6777b538SAndroid Build Coastguard Worker *
5086*6777b538SAndroid Build Coastguard Worker * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
5087*6777b538SAndroid Build Coastguard Worker */
5088*6777b538SAndroid Build Coastguard Worker static void
xmlParseCommentComplex(xmlParserCtxtPtr ctxt,xmlChar * buf,size_t len,size_t size)5089*6777b538SAndroid Build Coastguard Worker xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
5090*6777b538SAndroid Build Coastguard Worker size_t len, size_t size) {
5091*6777b538SAndroid Build Coastguard Worker int q, ql;
5092*6777b538SAndroid Build Coastguard Worker int r, rl;
5093*6777b538SAndroid Build Coastguard Worker int cur, l;
5094*6777b538SAndroid Build Coastguard Worker size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
5095*6777b538SAndroid Build Coastguard Worker XML_MAX_HUGE_LENGTH :
5096*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH;
5097*6777b538SAndroid Build Coastguard Worker
5098*6777b538SAndroid Build Coastguard Worker if (buf == NULL) {
5099*6777b538SAndroid Build Coastguard Worker len = 0;
5100*6777b538SAndroid Build Coastguard Worker size = XML_PARSER_BUFFER_SIZE;
5101*6777b538SAndroid Build Coastguard Worker buf = (xmlChar *) xmlMallocAtomic(size);
5102*6777b538SAndroid Build Coastguard Worker if (buf == NULL) {
5103*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5104*6777b538SAndroid Build Coastguard Worker return;
5105*6777b538SAndroid Build Coastguard Worker }
5106*6777b538SAndroid Build Coastguard Worker }
5107*6777b538SAndroid Build Coastguard Worker q = CUR_CHAR(ql);
5108*6777b538SAndroid Build Coastguard Worker if (q == 0)
5109*6777b538SAndroid Build Coastguard Worker goto not_terminated;
5110*6777b538SAndroid Build Coastguard Worker if (!IS_CHAR(q)) {
5111*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
5112*6777b538SAndroid Build Coastguard Worker "xmlParseComment: invalid xmlChar value %d\n",
5113*6777b538SAndroid Build Coastguard Worker q);
5114*6777b538SAndroid Build Coastguard Worker xmlFree (buf);
5115*6777b538SAndroid Build Coastguard Worker return;
5116*6777b538SAndroid Build Coastguard Worker }
5117*6777b538SAndroid Build Coastguard Worker NEXTL(ql);
5118*6777b538SAndroid Build Coastguard Worker r = CUR_CHAR(rl);
5119*6777b538SAndroid Build Coastguard Worker if (r == 0)
5120*6777b538SAndroid Build Coastguard Worker goto not_terminated;
5121*6777b538SAndroid Build Coastguard Worker if (!IS_CHAR(r)) {
5122*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
5123*6777b538SAndroid Build Coastguard Worker "xmlParseComment: invalid xmlChar value %d\n",
5124*6777b538SAndroid Build Coastguard Worker r);
5125*6777b538SAndroid Build Coastguard Worker xmlFree (buf);
5126*6777b538SAndroid Build Coastguard Worker return;
5127*6777b538SAndroid Build Coastguard Worker }
5128*6777b538SAndroid Build Coastguard Worker NEXTL(rl);
5129*6777b538SAndroid Build Coastguard Worker cur = CUR_CHAR(l);
5130*6777b538SAndroid Build Coastguard Worker if (cur == 0)
5131*6777b538SAndroid Build Coastguard Worker goto not_terminated;
5132*6777b538SAndroid Build Coastguard Worker while (IS_CHAR(cur) && /* checked */
5133*6777b538SAndroid Build Coastguard Worker ((cur != '>') ||
5134*6777b538SAndroid Build Coastguard Worker (r != '-') || (q != '-'))) {
5135*6777b538SAndroid Build Coastguard Worker if ((r == '-') && (q == '-')) {
5136*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
5137*6777b538SAndroid Build Coastguard Worker }
5138*6777b538SAndroid Build Coastguard Worker if (len + 5 >= size) {
5139*6777b538SAndroid Build Coastguard Worker xmlChar *new_buf;
5140*6777b538SAndroid Build Coastguard Worker size_t new_size;
5141*6777b538SAndroid Build Coastguard Worker
5142*6777b538SAndroid Build Coastguard Worker new_size = size * 2;
5143*6777b538SAndroid Build Coastguard Worker new_buf = (xmlChar *) xmlRealloc(buf, new_size);
5144*6777b538SAndroid Build Coastguard Worker if (new_buf == NULL) {
5145*6777b538SAndroid Build Coastguard Worker xmlFree (buf);
5146*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5147*6777b538SAndroid Build Coastguard Worker return;
5148*6777b538SAndroid Build Coastguard Worker }
5149*6777b538SAndroid Build Coastguard Worker buf = new_buf;
5150*6777b538SAndroid Build Coastguard Worker size = new_size;
5151*6777b538SAndroid Build Coastguard Worker }
5152*6777b538SAndroid Build Coastguard Worker COPY_BUF(buf, len, q);
5153*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
5154*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
5155*6777b538SAndroid Build Coastguard Worker "Comment too big found", NULL);
5156*6777b538SAndroid Build Coastguard Worker xmlFree (buf);
5157*6777b538SAndroid Build Coastguard Worker return;
5158*6777b538SAndroid Build Coastguard Worker }
5159*6777b538SAndroid Build Coastguard Worker
5160*6777b538SAndroid Build Coastguard Worker q = r;
5161*6777b538SAndroid Build Coastguard Worker ql = rl;
5162*6777b538SAndroid Build Coastguard Worker r = cur;
5163*6777b538SAndroid Build Coastguard Worker rl = l;
5164*6777b538SAndroid Build Coastguard Worker
5165*6777b538SAndroid Build Coastguard Worker NEXTL(l);
5166*6777b538SAndroid Build Coastguard Worker cur = CUR_CHAR(l);
5167*6777b538SAndroid Build Coastguard Worker
5168*6777b538SAndroid Build Coastguard Worker }
5169*6777b538SAndroid Build Coastguard Worker buf[len] = 0;
5170*6777b538SAndroid Build Coastguard Worker if (cur == 0) {
5171*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
5172*6777b538SAndroid Build Coastguard Worker "Comment not terminated \n<!--%.50s\n", buf);
5173*6777b538SAndroid Build Coastguard Worker } else if (!IS_CHAR(cur)) {
5174*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
5175*6777b538SAndroid Build Coastguard Worker "xmlParseComment: invalid xmlChar value %d\n",
5176*6777b538SAndroid Build Coastguard Worker cur);
5177*6777b538SAndroid Build Coastguard Worker } else {
5178*6777b538SAndroid Build Coastguard Worker NEXT;
5179*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
5180*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
5181*6777b538SAndroid Build Coastguard Worker ctxt->sax->comment(ctxt->userData, buf);
5182*6777b538SAndroid Build Coastguard Worker }
5183*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
5184*6777b538SAndroid Build Coastguard Worker return;
5185*6777b538SAndroid Build Coastguard Worker not_terminated:
5186*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
5187*6777b538SAndroid Build Coastguard Worker "Comment not terminated\n", NULL);
5188*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
5189*6777b538SAndroid Build Coastguard Worker return;
5190*6777b538SAndroid Build Coastguard Worker }
5191*6777b538SAndroid Build Coastguard Worker
5192*6777b538SAndroid Build Coastguard Worker /**
5193*6777b538SAndroid Build Coastguard Worker * xmlParseComment:
5194*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
5195*6777b538SAndroid Build Coastguard Worker *
5196*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
5197*6777b538SAndroid Build Coastguard Worker *
5198*6777b538SAndroid Build Coastguard Worker * Parse an XML (SGML) comment. Always consumes '<!'.
5199*6777b538SAndroid Build Coastguard Worker *
5200*6777b538SAndroid Build Coastguard Worker * The spec says that "For compatibility, the string "--" (double-hyphen)
5201*6777b538SAndroid Build Coastguard Worker * must not occur within comments. "
5202*6777b538SAndroid Build Coastguard Worker *
5203*6777b538SAndroid Build Coastguard Worker * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
5204*6777b538SAndroid Build Coastguard Worker */
5205*6777b538SAndroid Build Coastguard Worker void
xmlParseComment(xmlParserCtxtPtr ctxt)5206*6777b538SAndroid Build Coastguard Worker xmlParseComment(xmlParserCtxtPtr ctxt) {
5207*6777b538SAndroid Build Coastguard Worker xmlChar *buf = NULL;
5208*6777b538SAndroid Build Coastguard Worker size_t size = XML_PARSER_BUFFER_SIZE;
5209*6777b538SAndroid Build Coastguard Worker size_t len = 0;
5210*6777b538SAndroid Build Coastguard Worker size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
5211*6777b538SAndroid Build Coastguard Worker XML_MAX_HUGE_LENGTH :
5212*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH;
5213*6777b538SAndroid Build Coastguard Worker const xmlChar *in;
5214*6777b538SAndroid Build Coastguard Worker size_t nbchar = 0;
5215*6777b538SAndroid Build Coastguard Worker int ccol;
5216*6777b538SAndroid Build Coastguard Worker
5217*6777b538SAndroid Build Coastguard Worker /*
5218*6777b538SAndroid Build Coastguard Worker * Check that there is a comment right here.
5219*6777b538SAndroid Build Coastguard Worker */
5220*6777b538SAndroid Build Coastguard Worker if ((RAW != '<') || (NXT(1) != '!'))
5221*6777b538SAndroid Build Coastguard Worker return;
5222*6777b538SAndroid Build Coastguard Worker SKIP(2);
5223*6777b538SAndroid Build Coastguard Worker if ((RAW != '-') || (NXT(1) != '-'))
5224*6777b538SAndroid Build Coastguard Worker return;
5225*6777b538SAndroid Build Coastguard Worker SKIP(2);
5226*6777b538SAndroid Build Coastguard Worker GROW;
5227*6777b538SAndroid Build Coastguard Worker
5228*6777b538SAndroid Build Coastguard Worker /*
5229*6777b538SAndroid Build Coastguard Worker * Accelerated common case where input don't need to be
5230*6777b538SAndroid Build Coastguard Worker * modified before passing it to the handler.
5231*6777b538SAndroid Build Coastguard Worker */
5232*6777b538SAndroid Build Coastguard Worker in = ctxt->input->cur;
5233*6777b538SAndroid Build Coastguard Worker do {
5234*6777b538SAndroid Build Coastguard Worker if (*in == 0xA) {
5235*6777b538SAndroid Build Coastguard Worker do {
5236*6777b538SAndroid Build Coastguard Worker ctxt->input->line++; ctxt->input->col = 1;
5237*6777b538SAndroid Build Coastguard Worker in++;
5238*6777b538SAndroid Build Coastguard Worker } while (*in == 0xA);
5239*6777b538SAndroid Build Coastguard Worker }
5240*6777b538SAndroid Build Coastguard Worker get_more:
5241*6777b538SAndroid Build Coastguard Worker ccol = ctxt->input->col;
5242*6777b538SAndroid Build Coastguard Worker while (((*in > '-') && (*in <= 0x7F)) ||
5243*6777b538SAndroid Build Coastguard Worker ((*in >= 0x20) && (*in < '-')) ||
5244*6777b538SAndroid Build Coastguard Worker (*in == 0x09)) {
5245*6777b538SAndroid Build Coastguard Worker in++;
5246*6777b538SAndroid Build Coastguard Worker ccol++;
5247*6777b538SAndroid Build Coastguard Worker }
5248*6777b538SAndroid Build Coastguard Worker ctxt->input->col = ccol;
5249*6777b538SAndroid Build Coastguard Worker if (*in == 0xA) {
5250*6777b538SAndroid Build Coastguard Worker do {
5251*6777b538SAndroid Build Coastguard Worker ctxt->input->line++; ctxt->input->col = 1;
5252*6777b538SAndroid Build Coastguard Worker in++;
5253*6777b538SAndroid Build Coastguard Worker } while (*in == 0xA);
5254*6777b538SAndroid Build Coastguard Worker goto get_more;
5255*6777b538SAndroid Build Coastguard Worker }
5256*6777b538SAndroid Build Coastguard Worker nbchar = in - ctxt->input->cur;
5257*6777b538SAndroid Build Coastguard Worker /*
5258*6777b538SAndroid Build Coastguard Worker * save current set of data
5259*6777b538SAndroid Build Coastguard Worker */
5260*6777b538SAndroid Build Coastguard Worker if (nbchar > 0) {
5261*6777b538SAndroid Build Coastguard Worker if (buf == NULL) {
5262*6777b538SAndroid Build Coastguard Worker if ((*in == '-') && (in[1] == '-'))
5263*6777b538SAndroid Build Coastguard Worker size = nbchar + 1;
5264*6777b538SAndroid Build Coastguard Worker else
5265*6777b538SAndroid Build Coastguard Worker size = XML_PARSER_BUFFER_SIZE + nbchar;
5266*6777b538SAndroid Build Coastguard Worker buf = (xmlChar *) xmlMallocAtomic(size);
5267*6777b538SAndroid Build Coastguard Worker if (buf == NULL) {
5268*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5269*6777b538SAndroid Build Coastguard Worker return;
5270*6777b538SAndroid Build Coastguard Worker }
5271*6777b538SAndroid Build Coastguard Worker len = 0;
5272*6777b538SAndroid Build Coastguard Worker } else if (len + nbchar + 1 >= size) {
5273*6777b538SAndroid Build Coastguard Worker xmlChar *new_buf;
5274*6777b538SAndroid Build Coastguard Worker size += len + nbchar + XML_PARSER_BUFFER_SIZE;
5275*6777b538SAndroid Build Coastguard Worker new_buf = (xmlChar *) xmlRealloc(buf, size);
5276*6777b538SAndroid Build Coastguard Worker if (new_buf == NULL) {
5277*6777b538SAndroid Build Coastguard Worker xmlFree (buf);
5278*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5279*6777b538SAndroid Build Coastguard Worker return;
5280*6777b538SAndroid Build Coastguard Worker }
5281*6777b538SAndroid Build Coastguard Worker buf = new_buf;
5282*6777b538SAndroid Build Coastguard Worker }
5283*6777b538SAndroid Build Coastguard Worker memcpy(&buf[len], ctxt->input->cur, nbchar);
5284*6777b538SAndroid Build Coastguard Worker len += nbchar;
5285*6777b538SAndroid Build Coastguard Worker buf[len] = 0;
5286*6777b538SAndroid Build Coastguard Worker }
5287*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
5288*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
5289*6777b538SAndroid Build Coastguard Worker "Comment too big found", NULL);
5290*6777b538SAndroid Build Coastguard Worker xmlFree (buf);
5291*6777b538SAndroid Build Coastguard Worker return;
5292*6777b538SAndroid Build Coastguard Worker }
5293*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in;
5294*6777b538SAndroid Build Coastguard Worker if (*in == 0xA) {
5295*6777b538SAndroid Build Coastguard Worker in++;
5296*6777b538SAndroid Build Coastguard Worker ctxt->input->line++; ctxt->input->col = 1;
5297*6777b538SAndroid Build Coastguard Worker }
5298*6777b538SAndroid Build Coastguard Worker if (*in == 0xD) {
5299*6777b538SAndroid Build Coastguard Worker in++;
5300*6777b538SAndroid Build Coastguard Worker if (*in == 0xA) {
5301*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in;
5302*6777b538SAndroid Build Coastguard Worker in++;
5303*6777b538SAndroid Build Coastguard Worker ctxt->input->line++; ctxt->input->col = 1;
5304*6777b538SAndroid Build Coastguard Worker goto get_more;
5305*6777b538SAndroid Build Coastguard Worker }
5306*6777b538SAndroid Build Coastguard Worker in--;
5307*6777b538SAndroid Build Coastguard Worker }
5308*6777b538SAndroid Build Coastguard Worker SHRINK;
5309*6777b538SAndroid Build Coastguard Worker GROW;
5310*6777b538SAndroid Build Coastguard Worker in = ctxt->input->cur;
5311*6777b538SAndroid Build Coastguard Worker if (*in == '-') {
5312*6777b538SAndroid Build Coastguard Worker if (in[1] == '-') {
5313*6777b538SAndroid Build Coastguard Worker if (in[2] == '>') {
5314*6777b538SAndroid Build Coastguard Worker SKIP(3);
5315*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
5316*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX)) {
5317*6777b538SAndroid Build Coastguard Worker if (buf != NULL)
5318*6777b538SAndroid Build Coastguard Worker ctxt->sax->comment(ctxt->userData, buf);
5319*6777b538SAndroid Build Coastguard Worker else
5320*6777b538SAndroid Build Coastguard Worker ctxt->sax->comment(ctxt->userData, BAD_CAST "");
5321*6777b538SAndroid Build Coastguard Worker }
5322*6777b538SAndroid Build Coastguard Worker if (buf != NULL)
5323*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
5324*6777b538SAndroid Build Coastguard Worker return;
5325*6777b538SAndroid Build Coastguard Worker }
5326*6777b538SAndroid Build Coastguard Worker if (buf != NULL) {
5327*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
5328*6777b538SAndroid Build Coastguard Worker "Double hyphen within comment: "
5329*6777b538SAndroid Build Coastguard Worker "<!--%.50s\n",
5330*6777b538SAndroid Build Coastguard Worker buf);
5331*6777b538SAndroid Build Coastguard Worker } else
5332*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
5333*6777b538SAndroid Build Coastguard Worker "Double hyphen within comment\n", NULL);
5334*6777b538SAndroid Build Coastguard Worker in++;
5335*6777b538SAndroid Build Coastguard Worker ctxt->input->col++;
5336*6777b538SAndroid Build Coastguard Worker }
5337*6777b538SAndroid Build Coastguard Worker in++;
5338*6777b538SAndroid Build Coastguard Worker ctxt->input->col++;
5339*6777b538SAndroid Build Coastguard Worker goto get_more;
5340*6777b538SAndroid Build Coastguard Worker }
5341*6777b538SAndroid Build Coastguard Worker } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09) || (*in == 0x0a));
5342*6777b538SAndroid Build Coastguard Worker xmlParseCommentComplex(ctxt, buf, len, size);
5343*6777b538SAndroid Build Coastguard Worker return;
5344*6777b538SAndroid Build Coastguard Worker }
5345*6777b538SAndroid Build Coastguard Worker
5346*6777b538SAndroid Build Coastguard Worker
5347*6777b538SAndroid Build Coastguard Worker /**
5348*6777b538SAndroid Build Coastguard Worker * xmlParsePITarget:
5349*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
5350*6777b538SAndroid Build Coastguard Worker *
5351*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
5352*6777b538SAndroid Build Coastguard Worker *
5353*6777b538SAndroid Build Coastguard Worker * parse the name of a PI
5354*6777b538SAndroid Build Coastguard Worker *
5355*6777b538SAndroid Build Coastguard Worker * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
5356*6777b538SAndroid Build Coastguard Worker *
5357*6777b538SAndroid Build Coastguard Worker * Returns the PITarget name or NULL
5358*6777b538SAndroid Build Coastguard Worker */
5359*6777b538SAndroid Build Coastguard Worker
5360*6777b538SAndroid Build Coastguard Worker const xmlChar *
xmlParsePITarget(xmlParserCtxtPtr ctxt)5361*6777b538SAndroid Build Coastguard Worker xmlParsePITarget(xmlParserCtxtPtr ctxt) {
5362*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
5363*6777b538SAndroid Build Coastguard Worker
5364*6777b538SAndroid Build Coastguard Worker name = xmlParseName(ctxt);
5365*6777b538SAndroid Build Coastguard Worker if ((name != NULL) &&
5366*6777b538SAndroid Build Coastguard Worker ((name[0] == 'x') || (name[0] == 'X')) &&
5367*6777b538SAndroid Build Coastguard Worker ((name[1] == 'm') || (name[1] == 'M')) &&
5368*6777b538SAndroid Build Coastguard Worker ((name[2] == 'l') || (name[2] == 'L'))) {
5369*6777b538SAndroid Build Coastguard Worker int i;
5370*6777b538SAndroid Build Coastguard Worker if ((name[0] == 'x') && (name[1] == 'm') &&
5371*6777b538SAndroid Build Coastguard Worker (name[2] == 'l') && (name[3] == 0)) {
5372*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5373*6777b538SAndroid Build Coastguard Worker "XML declaration allowed only at the start of the document\n");
5374*6777b538SAndroid Build Coastguard Worker return(name);
5375*6777b538SAndroid Build Coastguard Worker } else if (name[3] == 0) {
5376*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
5377*6777b538SAndroid Build Coastguard Worker return(name);
5378*6777b538SAndroid Build Coastguard Worker }
5379*6777b538SAndroid Build Coastguard Worker for (i = 0;;i++) {
5380*6777b538SAndroid Build Coastguard Worker if (xmlW3CPIs[i] == NULL) break;
5381*6777b538SAndroid Build Coastguard Worker if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
5382*6777b538SAndroid Build Coastguard Worker return(name);
5383*6777b538SAndroid Build Coastguard Worker }
5384*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5385*6777b538SAndroid Build Coastguard Worker "xmlParsePITarget: invalid name prefix 'xml'\n",
5386*6777b538SAndroid Build Coastguard Worker NULL, NULL);
5387*6777b538SAndroid Build Coastguard Worker }
5388*6777b538SAndroid Build Coastguard Worker if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
5389*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_COLON,
5390*6777b538SAndroid Build Coastguard Worker "colons are forbidden from PI names '%s'\n", name, NULL, NULL);
5391*6777b538SAndroid Build Coastguard Worker }
5392*6777b538SAndroid Build Coastguard Worker return(name);
5393*6777b538SAndroid Build Coastguard Worker }
5394*6777b538SAndroid Build Coastguard Worker
5395*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
5396*6777b538SAndroid Build Coastguard Worker /**
5397*6777b538SAndroid Build Coastguard Worker * xmlParseCatalogPI:
5398*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
5399*6777b538SAndroid Build Coastguard Worker * @catalog: the PI value string
5400*6777b538SAndroid Build Coastguard Worker *
5401*6777b538SAndroid Build Coastguard Worker * parse an XML Catalog Processing Instruction.
5402*6777b538SAndroid Build Coastguard Worker *
5403*6777b538SAndroid Build Coastguard Worker * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
5404*6777b538SAndroid Build Coastguard Worker *
5405*6777b538SAndroid Build Coastguard Worker * Occurs only if allowed by the user and if happening in the Misc
5406*6777b538SAndroid Build Coastguard Worker * part of the document before any doctype information
5407*6777b538SAndroid Build Coastguard Worker * This will add the given catalog to the parsing context in order
5408*6777b538SAndroid Build Coastguard Worker * to be used if there is a resolution need further down in the document
5409*6777b538SAndroid Build Coastguard Worker */
5410*6777b538SAndroid Build Coastguard Worker
5411*6777b538SAndroid Build Coastguard Worker static void
xmlParseCatalogPI(xmlParserCtxtPtr ctxt,const xmlChar * catalog)5412*6777b538SAndroid Build Coastguard Worker xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
5413*6777b538SAndroid Build Coastguard Worker xmlChar *URL = NULL;
5414*6777b538SAndroid Build Coastguard Worker const xmlChar *tmp, *base;
5415*6777b538SAndroid Build Coastguard Worker xmlChar marker;
5416*6777b538SAndroid Build Coastguard Worker
5417*6777b538SAndroid Build Coastguard Worker tmp = catalog;
5418*6777b538SAndroid Build Coastguard Worker while (IS_BLANK_CH(*tmp)) tmp++;
5419*6777b538SAndroid Build Coastguard Worker if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
5420*6777b538SAndroid Build Coastguard Worker goto error;
5421*6777b538SAndroid Build Coastguard Worker tmp += 7;
5422*6777b538SAndroid Build Coastguard Worker while (IS_BLANK_CH(*tmp)) tmp++;
5423*6777b538SAndroid Build Coastguard Worker if (*tmp != '=') {
5424*6777b538SAndroid Build Coastguard Worker return;
5425*6777b538SAndroid Build Coastguard Worker }
5426*6777b538SAndroid Build Coastguard Worker tmp++;
5427*6777b538SAndroid Build Coastguard Worker while (IS_BLANK_CH(*tmp)) tmp++;
5428*6777b538SAndroid Build Coastguard Worker marker = *tmp;
5429*6777b538SAndroid Build Coastguard Worker if ((marker != '\'') && (marker != '"'))
5430*6777b538SAndroid Build Coastguard Worker goto error;
5431*6777b538SAndroid Build Coastguard Worker tmp++;
5432*6777b538SAndroid Build Coastguard Worker base = tmp;
5433*6777b538SAndroid Build Coastguard Worker while ((*tmp != 0) && (*tmp != marker)) tmp++;
5434*6777b538SAndroid Build Coastguard Worker if (*tmp == 0)
5435*6777b538SAndroid Build Coastguard Worker goto error;
5436*6777b538SAndroid Build Coastguard Worker URL = xmlStrndup(base, tmp - base);
5437*6777b538SAndroid Build Coastguard Worker tmp++;
5438*6777b538SAndroid Build Coastguard Worker while (IS_BLANK_CH(*tmp)) tmp++;
5439*6777b538SAndroid Build Coastguard Worker if (*tmp != 0)
5440*6777b538SAndroid Build Coastguard Worker goto error;
5441*6777b538SAndroid Build Coastguard Worker
5442*6777b538SAndroid Build Coastguard Worker if (URL != NULL) {
5443*6777b538SAndroid Build Coastguard Worker /*
5444*6777b538SAndroid Build Coastguard Worker * Unfortunately, the catalog API doesn't report OOM errors.
5445*6777b538SAndroid Build Coastguard Worker * xmlGetLastError isn't very helpful since we don't know
5446*6777b538SAndroid Build Coastguard Worker * where the last error came from. We'd have to reset it
5447*6777b538SAndroid Build Coastguard Worker * before this call and restore it afterwards.
5448*6777b538SAndroid Build Coastguard Worker */
5449*6777b538SAndroid Build Coastguard Worker ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
5450*6777b538SAndroid Build Coastguard Worker xmlFree(URL);
5451*6777b538SAndroid Build Coastguard Worker }
5452*6777b538SAndroid Build Coastguard Worker return;
5453*6777b538SAndroid Build Coastguard Worker
5454*6777b538SAndroid Build Coastguard Worker error:
5455*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
5456*6777b538SAndroid Build Coastguard Worker "Catalog PI syntax error: %s\n",
5457*6777b538SAndroid Build Coastguard Worker catalog, NULL);
5458*6777b538SAndroid Build Coastguard Worker if (URL != NULL)
5459*6777b538SAndroid Build Coastguard Worker xmlFree(URL);
5460*6777b538SAndroid Build Coastguard Worker }
5461*6777b538SAndroid Build Coastguard Worker #endif
5462*6777b538SAndroid Build Coastguard Worker
5463*6777b538SAndroid Build Coastguard Worker /**
5464*6777b538SAndroid Build Coastguard Worker * xmlParsePI:
5465*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
5466*6777b538SAndroid Build Coastguard Worker *
5467*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
5468*6777b538SAndroid Build Coastguard Worker *
5469*6777b538SAndroid Build Coastguard Worker * parse an XML Processing Instruction.
5470*6777b538SAndroid Build Coastguard Worker *
5471*6777b538SAndroid Build Coastguard Worker * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
5472*6777b538SAndroid Build Coastguard Worker *
5473*6777b538SAndroid Build Coastguard Worker * The processing is transferred to SAX once parsed.
5474*6777b538SAndroid Build Coastguard Worker */
5475*6777b538SAndroid Build Coastguard Worker
5476*6777b538SAndroid Build Coastguard Worker void
xmlParsePI(xmlParserCtxtPtr ctxt)5477*6777b538SAndroid Build Coastguard Worker xmlParsePI(xmlParserCtxtPtr ctxt) {
5478*6777b538SAndroid Build Coastguard Worker xmlChar *buf = NULL;
5479*6777b538SAndroid Build Coastguard Worker size_t len = 0;
5480*6777b538SAndroid Build Coastguard Worker size_t size = XML_PARSER_BUFFER_SIZE;
5481*6777b538SAndroid Build Coastguard Worker size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
5482*6777b538SAndroid Build Coastguard Worker XML_MAX_HUGE_LENGTH :
5483*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH;
5484*6777b538SAndroid Build Coastguard Worker int cur, l;
5485*6777b538SAndroid Build Coastguard Worker const xmlChar *target;
5486*6777b538SAndroid Build Coastguard Worker
5487*6777b538SAndroid Build Coastguard Worker if ((RAW == '<') && (NXT(1) == '?')) {
5488*6777b538SAndroid Build Coastguard Worker /*
5489*6777b538SAndroid Build Coastguard Worker * this is a Processing Instruction.
5490*6777b538SAndroid Build Coastguard Worker */
5491*6777b538SAndroid Build Coastguard Worker SKIP(2);
5492*6777b538SAndroid Build Coastguard Worker
5493*6777b538SAndroid Build Coastguard Worker /*
5494*6777b538SAndroid Build Coastguard Worker * Parse the target name and check for special support like
5495*6777b538SAndroid Build Coastguard Worker * namespace.
5496*6777b538SAndroid Build Coastguard Worker */
5497*6777b538SAndroid Build Coastguard Worker target = xmlParsePITarget(ctxt);
5498*6777b538SAndroid Build Coastguard Worker if (target != NULL) {
5499*6777b538SAndroid Build Coastguard Worker if ((RAW == '?') && (NXT(1) == '>')) {
5500*6777b538SAndroid Build Coastguard Worker SKIP(2);
5501*6777b538SAndroid Build Coastguard Worker
5502*6777b538SAndroid Build Coastguard Worker /*
5503*6777b538SAndroid Build Coastguard Worker * SAX: PI detected.
5504*6777b538SAndroid Build Coastguard Worker */
5505*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax) && (!ctxt->disableSAX) &&
5506*6777b538SAndroid Build Coastguard Worker (ctxt->sax->processingInstruction != NULL))
5507*6777b538SAndroid Build Coastguard Worker ctxt->sax->processingInstruction(ctxt->userData,
5508*6777b538SAndroid Build Coastguard Worker target, NULL);
5509*6777b538SAndroid Build Coastguard Worker return;
5510*6777b538SAndroid Build Coastguard Worker }
5511*6777b538SAndroid Build Coastguard Worker buf = (xmlChar *) xmlMallocAtomic(size);
5512*6777b538SAndroid Build Coastguard Worker if (buf == NULL) {
5513*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5514*6777b538SAndroid Build Coastguard Worker return;
5515*6777b538SAndroid Build Coastguard Worker }
5516*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS == 0) {
5517*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
5518*6777b538SAndroid Build Coastguard Worker "ParsePI: PI %s space expected\n", target);
5519*6777b538SAndroid Build Coastguard Worker }
5520*6777b538SAndroid Build Coastguard Worker cur = CUR_CHAR(l);
5521*6777b538SAndroid Build Coastguard Worker while (IS_CHAR(cur) && /* checked */
5522*6777b538SAndroid Build Coastguard Worker ((cur != '?') || (NXT(1) != '>'))) {
5523*6777b538SAndroid Build Coastguard Worker if (len + 5 >= size) {
5524*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
5525*6777b538SAndroid Build Coastguard Worker size_t new_size = size * 2;
5526*6777b538SAndroid Build Coastguard Worker tmp = (xmlChar *) xmlRealloc(buf, new_size);
5527*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
5528*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5529*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
5530*6777b538SAndroid Build Coastguard Worker return;
5531*6777b538SAndroid Build Coastguard Worker }
5532*6777b538SAndroid Build Coastguard Worker buf = tmp;
5533*6777b538SAndroid Build Coastguard Worker size = new_size;
5534*6777b538SAndroid Build Coastguard Worker }
5535*6777b538SAndroid Build Coastguard Worker COPY_BUF(buf, len, cur);
5536*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
5537*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5538*6777b538SAndroid Build Coastguard Worker "PI %s too big found", target);
5539*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
5540*6777b538SAndroid Build Coastguard Worker return;
5541*6777b538SAndroid Build Coastguard Worker }
5542*6777b538SAndroid Build Coastguard Worker NEXTL(l);
5543*6777b538SAndroid Build Coastguard Worker cur = CUR_CHAR(l);
5544*6777b538SAndroid Build Coastguard Worker }
5545*6777b538SAndroid Build Coastguard Worker buf[len] = 0;
5546*6777b538SAndroid Build Coastguard Worker if (cur != '?') {
5547*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5548*6777b538SAndroid Build Coastguard Worker "ParsePI: PI %s never end ...\n", target);
5549*6777b538SAndroid Build Coastguard Worker } else {
5550*6777b538SAndroid Build Coastguard Worker SKIP(2);
5551*6777b538SAndroid Build Coastguard Worker
5552*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
5553*6777b538SAndroid Build Coastguard Worker if ((ctxt->inSubset == 0) &&
5554*6777b538SAndroid Build Coastguard Worker (xmlStrEqual(target, XML_CATALOG_PI))) {
5555*6777b538SAndroid Build Coastguard Worker xmlCatalogAllow allow = xmlCatalogGetDefaults();
5556*6777b538SAndroid Build Coastguard Worker if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
5557*6777b538SAndroid Build Coastguard Worker (allow == XML_CATA_ALLOW_ALL))
5558*6777b538SAndroid Build Coastguard Worker xmlParseCatalogPI(ctxt, buf);
5559*6777b538SAndroid Build Coastguard Worker }
5560*6777b538SAndroid Build Coastguard Worker #endif
5561*6777b538SAndroid Build Coastguard Worker
5562*6777b538SAndroid Build Coastguard Worker
5563*6777b538SAndroid Build Coastguard Worker /*
5564*6777b538SAndroid Build Coastguard Worker * SAX: PI detected.
5565*6777b538SAndroid Build Coastguard Worker */
5566*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax) && (!ctxt->disableSAX) &&
5567*6777b538SAndroid Build Coastguard Worker (ctxt->sax->processingInstruction != NULL))
5568*6777b538SAndroid Build Coastguard Worker ctxt->sax->processingInstruction(ctxt->userData,
5569*6777b538SAndroid Build Coastguard Worker target, buf);
5570*6777b538SAndroid Build Coastguard Worker }
5571*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
5572*6777b538SAndroid Build Coastguard Worker } else {
5573*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
5574*6777b538SAndroid Build Coastguard Worker }
5575*6777b538SAndroid Build Coastguard Worker }
5576*6777b538SAndroid Build Coastguard Worker }
5577*6777b538SAndroid Build Coastguard Worker
5578*6777b538SAndroid Build Coastguard Worker /**
5579*6777b538SAndroid Build Coastguard Worker * xmlParseNotationDecl:
5580*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
5581*6777b538SAndroid Build Coastguard Worker *
5582*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
5583*6777b538SAndroid Build Coastguard Worker *
5584*6777b538SAndroid Build Coastguard Worker * Parse a notation declaration. Always consumes '<!'.
5585*6777b538SAndroid Build Coastguard Worker *
5586*6777b538SAndroid Build Coastguard Worker * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
5587*6777b538SAndroid Build Coastguard Worker *
5588*6777b538SAndroid Build Coastguard Worker * Hence there is actually 3 choices:
5589*6777b538SAndroid Build Coastguard Worker * 'PUBLIC' S PubidLiteral
5590*6777b538SAndroid Build Coastguard Worker * 'PUBLIC' S PubidLiteral S SystemLiteral
5591*6777b538SAndroid Build Coastguard Worker * and 'SYSTEM' S SystemLiteral
5592*6777b538SAndroid Build Coastguard Worker *
5593*6777b538SAndroid Build Coastguard Worker * See the NOTE on xmlParseExternalID().
5594*6777b538SAndroid Build Coastguard Worker */
5595*6777b538SAndroid Build Coastguard Worker
5596*6777b538SAndroid Build Coastguard Worker void
xmlParseNotationDecl(xmlParserCtxtPtr ctxt)5597*6777b538SAndroid Build Coastguard Worker xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
5598*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
5599*6777b538SAndroid Build Coastguard Worker xmlChar *Pubid;
5600*6777b538SAndroid Build Coastguard Worker xmlChar *Systemid;
5601*6777b538SAndroid Build Coastguard Worker
5602*6777b538SAndroid Build Coastguard Worker if ((CUR != '<') || (NXT(1) != '!'))
5603*6777b538SAndroid Build Coastguard Worker return;
5604*6777b538SAndroid Build Coastguard Worker SKIP(2);
5605*6777b538SAndroid Build Coastguard Worker
5606*6777b538SAndroid Build Coastguard Worker if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5607*6777b538SAndroid Build Coastguard Worker int inputid = ctxt->input->id;
5608*6777b538SAndroid Build Coastguard Worker SKIP(8);
5609*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
5610*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5611*6777b538SAndroid Build Coastguard Worker "Space required after '<!NOTATION'\n");
5612*6777b538SAndroid Build Coastguard Worker return;
5613*6777b538SAndroid Build Coastguard Worker }
5614*6777b538SAndroid Build Coastguard Worker
5615*6777b538SAndroid Build Coastguard Worker name = xmlParseName(ctxt);
5616*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
5617*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5618*6777b538SAndroid Build Coastguard Worker return;
5619*6777b538SAndroid Build Coastguard Worker }
5620*6777b538SAndroid Build Coastguard Worker if (xmlStrchr(name, ':') != NULL) {
5621*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_COLON,
5622*6777b538SAndroid Build Coastguard Worker "colons are forbidden from notation names '%s'\n",
5623*6777b538SAndroid Build Coastguard Worker name, NULL, NULL);
5624*6777b538SAndroid Build Coastguard Worker }
5625*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
5626*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5627*6777b538SAndroid Build Coastguard Worker "Space required after the NOTATION name'\n");
5628*6777b538SAndroid Build Coastguard Worker return;
5629*6777b538SAndroid Build Coastguard Worker }
5630*6777b538SAndroid Build Coastguard Worker
5631*6777b538SAndroid Build Coastguard Worker /*
5632*6777b538SAndroid Build Coastguard Worker * Parse the IDs.
5633*6777b538SAndroid Build Coastguard Worker */
5634*6777b538SAndroid Build Coastguard Worker Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
5635*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
5636*6777b538SAndroid Build Coastguard Worker
5637*6777b538SAndroid Build Coastguard Worker if (RAW == '>') {
5638*6777b538SAndroid Build Coastguard Worker if (inputid != ctxt->input->id) {
5639*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5640*6777b538SAndroid Build Coastguard Worker "Notation declaration doesn't start and stop"
5641*6777b538SAndroid Build Coastguard Worker " in the same entity\n");
5642*6777b538SAndroid Build Coastguard Worker }
5643*6777b538SAndroid Build Coastguard Worker NEXT;
5644*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5645*6777b538SAndroid Build Coastguard Worker (ctxt->sax->notationDecl != NULL))
5646*6777b538SAndroid Build Coastguard Worker ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
5647*6777b538SAndroid Build Coastguard Worker } else {
5648*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5649*6777b538SAndroid Build Coastguard Worker }
5650*6777b538SAndroid Build Coastguard Worker if (Systemid != NULL) xmlFree(Systemid);
5651*6777b538SAndroid Build Coastguard Worker if (Pubid != NULL) xmlFree(Pubid);
5652*6777b538SAndroid Build Coastguard Worker }
5653*6777b538SAndroid Build Coastguard Worker }
5654*6777b538SAndroid Build Coastguard Worker
5655*6777b538SAndroid Build Coastguard Worker /**
5656*6777b538SAndroid Build Coastguard Worker * xmlParseEntityDecl:
5657*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
5658*6777b538SAndroid Build Coastguard Worker *
5659*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
5660*6777b538SAndroid Build Coastguard Worker *
5661*6777b538SAndroid Build Coastguard Worker * Parse an entity declaration. Always consumes '<!'.
5662*6777b538SAndroid Build Coastguard Worker *
5663*6777b538SAndroid Build Coastguard Worker * [70] EntityDecl ::= GEDecl | PEDecl
5664*6777b538SAndroid Build Coastguard Worker *
5665*6777b538SAndroid Build Coastguard Worker * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
5666*6777b538SAndroid Build Coastguard Worker *
5667*6777b538SAndroid Build Coastguard Worker * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
5668*6777b538SAndroid Build Coastguard Worker *
5669*6777b538SAndroid Build Coastguard Worker * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
5670*6777b538SAndroid Build Coastguard Worker *
5671*6777b538SAndroid Build Coastguard Worker * [74] PEDef ::= EntityValue | ExternalID
5672*6777b538SAndroid Build Coastguard Worker *
5673*6777b538SAndroid Build Coastguard Worker * [76] NDataDecl ::= S 'NDATA' S Name
5674*6777b538SAndroid Build Coastguard Worker *
5675*6777b538SAndroid Build Coastguard Worker * [ VC: Notation Declared ]
5676*6777b538SAndroid Build Coastguard Worker * The Name must match the declared name of a notation.
5677*6777b538SAndroid Build Coastguard Worker */
5678*6777b538SAndroid Build Coastguard Worker
5679*6777b538SAndroid Build Coastguard Worker void
xmlParseEntityDecl(xmlParserCtxtPtr ctxt)5680*6777b538SAndroid Build Coastguard Worker xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
5681*6777b538SAndroid Build Coastguard Worker const xmlChar *name = NULL;
5682*6777b538SAndroid Build Coastguard Worker xmlChar *value = NULL;
5683*6777b538SAndroid Build Coastguard Worker xmlChar *URI = NULL, *literal = NULL;
5684*6777b538SAndroid Build Coastguard Worker const xmlChar *ndata = NULL;
5685*6777b538SAndroid Build Coastguard Worker int isParameter = 0;
5686*6777b538SAndroid Build Coastguard Worker xmlChar *orig = NULL;
5687*6777b538SAndroid Build Coastguard Worker
5688*6777b538SAndroid Build Coastguard Worker if ((CUR != '<') || (NXT(1) != '!'))
5689*6777b538SAndroid Build Coastguard Worker return;
5690*6777b538SAndroid Build Coastguard Worker SKIP(2);
5691*6777b538SAndroid Build Coastguard Worker
5692*6777b538SAndroid Build Coastguard Worker /* GROW; done in the caller */
5693*6777b538SAndroid Build Coastguard Worker if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
5694*6777b538SAndroid Build Coastguard Worker int inputid = ctxt->input->id;
5695*6777b538SAndroid Build Coastguard Worker SKIP(6);
5696*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
5697*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5698*6777b538SAndroid Build Coastguard Worker "Space required after '<!ENTITY'\n");
5699*6777b538SAndroid Build Coastguard Worker }
5700*6777b538SAndroid Build Coastguard Worker
5701*6777b538SAndroid Build Coastguard Worker if (RAW == '%') {
5702*6777b538SAndroid Build Coastguard Worker NEXT;
5703*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
5704*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5705*6777b538SAndroid Build Coastguard Worker "Space required after '%%'\n");
5706*6777b538SAndroid Build Coastguard Worker }
5707*6777b538SAndroid Build Coastguard Worker isParameter = 1;
5708*6777b538SAndroid Build Coastguard Worker }
5709*6777b538SAndroid Build Coastguard Worker
5710*6777b538SAndroid Build Coastguard Worker name = xmlParseName(ctxt);
5711*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
5712*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5713*6777b538SAndroid Build Coastguard Worker "xmlParseEntityDecl: no name\n");
5714*6777b538SAndroid Build Coastguard Worker return;
5715*6777b538SAndroid Build Coastguard Worker }
5716*6777b538SAndroid Build Coastguard Worker if (xmlStrchr(name, ':') != NULL) {
5717*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_COLON,
5718*6777b538SAndroid Build Coastguard Worker "colons are forbidden from entities names '%s'\n",
5719*6777b538SAndroid Build Coastguard Worker name, NULL, NULL);
5720*6777b538SAndroid Build Coastguard Worker }
5721*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
5722*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5723*6777b538SAndroid Build Coastguard Worker "Space required after the entity name\n");
5724*6777b538SAndroid Build Coastguard Worker }
5725*6777b538SAndroid Build Coastguard Worker
5726*6777b538SAndroid Build Coastguard Worker /*
5727*6777b538SAndroid Build Coastguard Worker * handle the various case of definitions...
5728*6777b538SAndroid Build Coastguard Worker */
5729*6777b538SAndroid Build Coastguard Worker if (isParameter) {
5730*6777b538SAndroid Build Coastguard Worker if ((RAW == '"') || (RAW == '\'')) {
5731*6777b538SAndroid Build Coastguard Worker value = xmlParseEntityValue(ctxt, &orig);
5732*6777b538SAndroid Build Coastguard Worker if (value) {
5733*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
5734*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5735*6777b538SAndroid Build Coastguard Worker ctxt->sax->entityDecl(ctxt->userData, name,
5736*6777b538SAndroid Build Coastguard Worker XML_INTERNAL_PARAMETER_ENTITY,
5737*6777b538SAndroid Build Coastguard Worker NULL, NULL, value);
5738*6777b538SAndroid Build Coastguard Worker }
5739*6777b538SAndroid Build Coastguard Worker } else {
5740*6777b538SAndroid Build Coastguard Worker URI = xmlParseExternalID(ctxt, &literal, 1);
5741*6777b538SAndroid Build Coastguard Worker if ((URI == NULL) && (literal == NULL)) {
5742*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5743*6777b538SAndroid Build Coastguard Worker }
5744*6777b538SAndroid Build Coastguard Worker if (URI) {
5745*6777b538SAndroid Build Coastguard Worker xmlURIPtr uri;
5746*6777b538SAndroid Build Coastguard Worker
5747*6777b538SAndroid Build Coastguard Worker if (xmlParseURISafe((const char *) URI, &uri) < 0) {
5748*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5749*6777b538SAndroid Build Coastguard Worker } else if (uri == NULL) {
5750*6777b538SAndroid Build Coastguard Worker /*
5751*6777b538SAndroid Build Coastguard Worker * This really ought to be a well formedness error
5752*6777b538SAndroid Build Coastguard Worker * but the XML Core WG decided otherwise c.f. issue
5753*6777b538SAndroid Build Coastguard Worker * E26 of the XML erratas.
5754*6777b538SAndroid Build Coastguard Worker */
5755*6777b538SAndroid Build Coastguard Worker xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5756*6777b538SAndroid Build Coastguard Worker "Invalid URI: %s\n", URI);
5757*6777b538SAndroid Build Coastguard Worker } else if (uri->fragment != NULL) {
5758*6777b538SAndroid Build Coastguard Worker /*
5759*6777b538SAndroid Build Coastguard Worker * Okay this is foolish to block those but not
5760*6777b538SAndroid Build Coastguard Worker * invalid URIs.
5761*6777b538SAndroid Build Coastguard Worker */
5762*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5763*6777b538SAndroid Build Coastguard Worker } else {
5764*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
5765*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX) &&
5766*6777b538SAndroid Build Coastguard Worker (ctxt->sax->entityDecl != NULL))
5767*6777b538SAndroid Build Coastguard Worker ctxt->sax->entityDecl(ctxt->userData, name,
5768*6777b538SAndroid Build Coastguard Worker XML_EXTERNAL_PARAMETER_ENTITY,
5769*6777b538SAndroid Build Coastguard Worker literal, URI, NULL);
5770*6777b538SAndroid Build Coastguard Worker }
5771*6777b538SAndroid Build Coastguard Worker xmlFreeURI(uri);
5772*6777b538SAndroid Build Coastguard Worker }
5773*6777b538SAndroid Build Coastguard Worker }
5774*6777b538SAndroid Build Coastguard Worker } else {
5775*6777b538SAndroid Build Coastguard Worker if ((RAW == '"') || (RAW == '\'')) {
5776*6777b538SAndroid Build Coastguard Worker value = xmlParseEntityValue(ctxt, &orig);
5777*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
5778*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5779*6777b538SAndroid Build Coastguard Worker ctxt->sax->entityDecl(ctxt->userData, name,
5780*6777b538SAndroid Build Coastguard Worker XML_INTERNAL_GENERAL_ENTITY,
5781*6777b538SAndroid Build Coastguard Worker NULL, NULL, value);
5782*6777b538SAndroid Build Coastguard Worker /*
5783*6777b538SAndroid Build Coastguard Worker * For expat compatibility in SAX mode.
5784*6777b538SAndroid Build Coastguard Worker */
5785*6777b538SAndroid Build Coastguard Worker if ((ctxt->myDoc == NULL) ||
5786*6777b538SAndroid Build Coastguard Worker (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
5787*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc == NULL) {
5788*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5789*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc == NULL) {
5790*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5791*6777b538SAndroid Build Coastguard Worker goto done;
5792*6777b538SAndroid Build Coastguard Worker }
5793*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->properties = XML_DOC_INTERNAL;
5794*6777b538SAndroid Build Coastguard Worker }
5795*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc->intSubset == NULL) {
5796*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5797*6777b538SAndroid Build Coastguard Worker BAD_CAST "fake", NULL, NULL);
5798*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc->intSubset == NULL) {
5799*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5800*6777b538SAndroid Build Coastguard Worker goto done;
5801*6777b538SAndroid Build Coastguard Worker }
5802*6777b538SAndroid Build Coastguard Worker }
5803*6777b538SAndroid Build Coastguard Worker
5804*6777b538SAndroid Build Coastguard Worker xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
5805*6777b538SAndroid Build Coastguard Worker NULL, NULL, value);
5806*6777b538SAndroid Build Coastguard Worker }
5807*6777b538SAndroid Build Coastguard Worker } else {
5808*6777b538SAndroid Build Coastguard Worker URI = xmlParseExternalID(ctxt, &literal, 1);
5809*6777b538SAndroid Build Coastguard Worker if ((URI == NULL) && (literal == NULL)) {
5810*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5811*6777b538SAndroid Build Coastguard Worker }
5812*6777b538SAndroid Build Coastguard Worker if (URI) {
5813*6777b538SAndroid Build Coastguard Worker xmlURIPtr uri;
5814*6777b538SAndroid Build Coastguard Worker
5815*6777b538SAndroid Build Coastguard Worker if (xmlParseURISafe((const char *) URI, &uri) < 0) {
5816*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5817*6777b538SAndroid Build Coastguard Worker } else if (uri == NULL) {
5818*6777b538SAndroid Build Coastguard Worker /*
5819*6777b538SAndroid Build Coastguard Worker * This really ought to be a well formedness error
5820*6777b538SAndroid Build Coastguard Worker * but the XML Core WG decided otherwise c.f. issue
5821*6777b538SAndroid Build Coastguard Worker * E26 of the XML erratas.
5822*6777b538SAndroid Build Coastguard Worker */
5823*6777b538SAndroid Build Coastguard Worker xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5824*6777b538SAndroid Build Coastguard Worker "Invalid URI: %s\n", URI);
5825*6777b538SAndroid Build Coastguard Worker } else if (uri->fragment != NULL) {
5826*6777b538SAndroid Build Coastguard Worker /*
5827*6777b538SAndroid Build Coastguard Worker * Okay this is foolish to block those but not
5828*6777b538SAndroid Build Coastguard Worker * invalid URIs.
5829*6777b538SAndroid Build Coastguard Worker */
5830*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5831*6777b538SAndroid Build Coastguard Worker }
5832*6777b538SAndroid Build Coastguard Worker xmlFreeURI(uri);
5833*6777b538SAndroid Build Coastguard Worker }
5834*6777b538SAndroid Build Coastguard Worker if ((RAW != '>') && (SKIP_BLANKS_PE == 0)) {
5835*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5836*6777b538SAndroid Build Coastguard Worker "Space required before 'NDATA'\n");
5837*6777b538SAndroid Build Coastguard Worker }
5838*6777b538SAndroid Build Coastguard Worker if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
5839*6777b538SAndroid Build Coastguard Worker SKIP(5);
5840*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
5841*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5842*6777b538SAndroid Build Coastguard Worker "Space required after 'NDATA'\n");
5843*6777b538SAndroid Build Coastguard Worker }
5844*6777b538SAndroid Build Coastguard Worker ndata = xmlParseName(ctxt);
5845*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5846*6777b538SAndroid Build Coastguard Worker (ctxt->sax->unparsedEntityDecl != NULL))
5847*6777b538SAndroid Build Coastguard Worker ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
5848*6777b538SAndroid Build Coastguard Worker literal, URI, ndata);
5849*6777b538SAndroid Build Coastguard Worker } else {
5850*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
5851*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5852*6777b538SAndroid Build Coastguard Worker ctxt->sax->entityDecl(ctxt->userData, name,
5853*6777b538SAndroid Build Coastguard Worker XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5854*6777b538SAndroid Build Coastguard Worker literal, URI, NULL);
5855*6777b538SAndroid Build Coastguard Worker /*
5856*6777b538SAndroid Build Coastguard Worker * For expat compatibility in SAX mode.
5857*6777b538SAndroid Build Coastguard Worker * assuming the entity replacement was asked for
5858*6777b538SAndroid Build Coastguard Worker */
5859*6777b538SAndroid Build Coastguard Worker if ((ctxt->replaceEntities != 0) &&
5860*6777b538SAndroid Build Coastguard Worker ((ctxt->myDoc == NULL) ||
5861*6777b538SAndroid Build Coastguard Worker (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
5862*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc == NULL) {
5863*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5864*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc == NULL) {
5865*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5866*6777b538SAndroid Build Coastguard Worker goto done;
5867*6777b538SAndroid Build Coastguard Worker }
5868*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->properties = XML_DOC_INTERNAL;
5869*6777b538SAndroid Build Coastguard Worker }
5870*6777b538SAndroid Build Coastguard Worker
5871*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc->intSubset == NULL) {
5872*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5873*6777b538SAndroid Build Coastguard Worker BAD_CAST "fake", NULL, NULL);
5874*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc->intSubset == NULL) {
5875*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
5876*6777b538SAndroid Build Coastguard Worker goto done;
5877*6777b538SAndroid Build Coastguard Worker }
5878*6777b538SAndroid Build Coastguard Worker }
5879*6777b538SAndroid Build Coastguard Worker xmlSAX2EntityDecl(ctxt, name,
5880*6777b538SAndroid Build Coastguard Worker XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5881*6777b538SAndroid Build Coastguard Worker literal, URI, NULL);
5882*6777b538SAndroid Build Coastguard Worker }
5883*6777b538SAndroid Build Coastguard Worker }
5884*6777b538SAndroid Build Coastguard Worker }
5885*6777b538SAndroid Build Coastguard Worker }
5886*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
5887*6777b538SAndroid Build Coastguard Worker if (RAW != '>') {
5888*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
5889*6777b538SAndroid Build Coastguard Worker "xmlParseEntityDecl: entity %s not terminated\n", name);
5890*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
5891*6777b538SAndroid Build Coastguard Worker } else {
5892*6777b538SAndroid Build Coastguard Worker if (inputid != ctxt->input->id) {
5893*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5894*6777b538SAndroid Build Coastguard Worker "Entity declaration doesn't start and stop in"
5895*6777b538SAndroid Build Coastguard Worker " the same entity\n");
5896*6777b538SAndroid Build Coastguard Worker }
5897*6777b538SAndroid Build Coastguard Worker NEXT;
5898*6777b538SAndroid Build Coastguard Worker }
5899*6777b538SAndroid Build Coastguard Worker if (orig != NULL) {
5900*6777b538SAndroid Build Coastguard Worker /*
5901*6777b538SAndroid Build Coastguard Worker * Ugly mechanism to save the raw entity value.
5902*6777b538SAndroid Build Coastguard Worker */
5903*6777b538SAndroid Build Coastguard Worker xmlEntityPtr cur = NULL;
5904*6777b538SAndroid Build Coastguard Worker
5905*6777b538SAndroid Build Coastguard Worker if (isParameter) {
5906*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
5907*6777b538SAndroid Build Coastguard Worker (ctxt->sax->getParameterEntity != NULL))
5908*6777b538SAndroid Build Coastguard Worker cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
5909*6777b538SAndroid Build Coastguard Worker } else {
5910*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
5911*6777b538SAndroid Build Coastguard Worker (ctxt->sax->getEntity != NULL))
5912*6777b538SAndroid Build Coastguard Worker cur = ctxt->sax->getEntity(ctxt->userData, name);
5913*6777b538SAndroid Build Coastguard Worker if ((cur == NULL) && (ctxt->userData==ctxt)) {
5914*6777b538SAndroid Build Coastguard Worker cur = xmlSAX2GetEntity(ctxt, name);
5915*6777b538SAndroid Build Coastguard Worker }
5916*6777b538SAndroid Build Coastguard Worker }
5917*6777b538SAndroid Build Coastguard Worker if ((cur != NULL) && (cur->orig == NULL)) {
5918*6777b538SAndroid Build Coastguard Worker cur->orig = orig;
5919*6777b538SAndroid Build Coastguard Worker orig = NULL;
5920*6777b538SAndroid Build Coastguard Worker }
5921*6777b538SAndroid Build Coastguard Worker }
5922*6777b538SAndroid Build Coastguard Worker
5923*6777b538SAndroid Build Coastguard Worker done:
5924*6777b538SAndroid Build Coastguard Worker if (value != NULL) xmlFree(value);
5925*6777b538SAndroid Build Coastguard Worker if (URI != NULL) xmlFree(URI);
5926*6777b538SAndroid Build Coastguard Worker if (literal != NULL) xmlFree(literal);
5927*6777b538SAndroid Build Coastguard Worker if (orig != NULL) xmlFree(orig);
5928*6777b538SAndroid Build Coastguard Worker }
5929*6777b538SAndroid Build Coastguard Worker }
5930*6777b538SAndroid Build Coastguard Worker
5931*6777b538SAndroid Build Coastguard Worker /**
5932*6777b538SAndroid Build Coastguard Worker * xmlParseDefaultDecl:
5933*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
5934*6777b538SAndroid Build Coastguard Worker * @value: Receive a possible fixed default value for the attribute
5935*6777b538SAndroid Build Coastguard Worker *
5936*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
5937*6777b538SAndroid Build Coastguard Worker *
5938*6777b538SAndroid Build Coastguard Worker * Parse an attribute default declaration
5939*6777b538SAndroid Build Coastguard Worker *
5940*6777b538SAndroid Build Coastguard Worker * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
5941*6777b538SAndroid Build Coastguard Worker *
5942*6777b538SAndroid Build Coastguard Worker * [ VC: Required Attribute ]
5943*6777b538SAndroid Build Coastguard Worker * if the default declaration is the keyword #REQUIRED, then the
5944*6777b538SAndroid Build Coastguard Worker * attribute must be specified for all elements of the type in the
5945*6777b538SAndroid Build Coastguard Worker * attribute-list declaration.
5946*6777b538SAndroid Build Coastguard Worker *
5947*6777b538SAndroid Build Coastguard Worker * [ VC: Attribute Default Legal ]
5948*6777b538SAndroid Build Coastguard Worker * The declared default value must meet the lexical constraints of
5949*6777b538SAndroid Build Coastguard Worker * the declared attribute type c.f. xmlValidateAttributeDecl()
5950*6777b538SAndroid Build Coastguard Worker *
5951*6777b538SAndroid Build Coastguard Worker * [ VC: Fixed Attribute Default ]
5952*6777b538SAndroid Build Coastguard Worker * if an attribute has a default value declared with the #FIXED
5953*6777b538SAndroid Build Coastguard Worker * keyword, instances of that attribute must match the default value.
5954*6777b538SAndroid Build Coastguard Worker *
5955*6777b538SAndroid Build Coastguard Worker * [ WFC: No < in Attribute Values ]
5956*6777b538SAndroid Build Coastguard Worker * handled in xmlParseAttValue()
5957*6777b538SAndroid Build Coastguard Worker *
5958*6777b538SAndroid Build Coastguard Worker * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
5959*6777b538SAndroid Build Coastguard Worker * or XML_ATTRIBUTE_FIXED.
5960*6777b538SAndroid Build Coastguard Worker */
5961*6777b538SAndroid Build Coastguard Worker
5962*6777b538SAndroid Build Coastguard Worker int
xmlParseDefaultDecl(xmlParserCtxtPtr ctxt,xmlChar ** value)5963*6777b538SAndroid Build Coastguard Worker xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
5964*6777b538SAndroid Build Coastguard Worker int val;
5965*6777b538SAndroid Build Coastguard Worker xmlChar *ret;
5966*6777b538SAndroid Build Coastguard Worker
5967*6777b538SAndroid Build Coastguard Worker *value = NULL;
5968*6777b538SAndroid Build Coastguard Worker if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
5969*6777b538SAndroid Build Coastguard Worker SKIP(9);
5970*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_REQUIRED);
5971*6777b538SAndroid Build Coastguard Worker }
5972*6777b538SAndroid Build Coastguard Worker if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
5973*6777b538SAndroid Build Coastguard Worker SKIP(8);
5974*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_IMPLIED);
5975*6777b538SAndroid Build Coastguard Worker }
5976*6777b538SAndroid Build Coastguard Worker val = XML_ATTRIBUTE_NONE;
5977*6777b538SAndroid Build Coastguard Worker if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
5978*6777b538SAndroid Build Coastguard Worker SKIP(6);
5979*6777b538SAndroid Build Coastguard Worker val = XML_ATTRIBUTE_FIXED;
5980*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
5981*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5982*6777b538SAndroid Build Coastguard Worker "Space required after '#FIXED'\n");
5983*6777b538SAndroid Build Coastguard Worker }
5984*6777b538SAndroid Build Coastguard Worker }
5985*6777b538SAndroid Build Coastguard Worker ret = xmlParseAttValue(ctxt);
5986*6777b538SAndroid Build Coastguard Worker if (ret == NULL) {
5987*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
5988*6777b538SAndroid Build Coastguard Worker "Attribute default value declaration error\n");
5989*6777b538SAndroid Build Coastguard Worker } else
5990*6777b538SAndroid Build Coastguard Worker *value = ret;
5991*6777b538SAndroid Build Coastguard Worker return(val);
5992*6777b538SAndroid Build Coastguard Worker }
5993*6777b538SAndroid Build Coastguard Worker
5994*6777b538SAndroid Build Coastguard Worker /**
5995*6777b538SAndroid Build Coastguard Worker * xmlParseNotationType:
5996*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
5997*6777b538SAndroid Build Coastguard Worker *
5998*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
5999*6777b538SAndroid Build Coastguard Worker *
6000*6777b538SAndroid Build Coastguard Worker * parse an Notation attribute type.
6001*6777b538SAndroid Build Coastguard Worker *
6002*6777b538SAndroid Build Coastguard Worker * Note: the leading 'NOTATION' S part has already being parsed...
6003*6777b538SAndroid Build Coastguard Worker *
6004*6777b538SAndroid Build Coastguard Worker * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
6005*6777b538SAndroid Build Coastguard Worker *
6006*6777b538SAndroid Build Coastguard Worker * [ VC: Notation Attributes ]
6007*6777b538SAndroid Build Coastguard Worker * Values of this type must match one of the notation names included
6008*6777b538SAndroid Build Coastguard Worker * in the declaration; all notation names in the declaration must be declared.
6009*6777b538SAndroid Build Coastguard Worker *
6010*6777b538SAndroid Build Coastguard Worker * Returns: the notation attribute tree built while parsing
6011*6777b538SAndroid Build Coastguard Worker */
6012*6777b538SAndroid Build Coastguard Worker
6013*6777b538SAndroid Build Coastguard Worker xmlEnumerationPtr
xmlParseNotationType(xmlParserCtxtPtr ctxt)6014*6777b538SAndroid Build Coastguard Worker xmlParseNotationType(xmlParserCtxtPtr ctxt) {
6015*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
6016*6777b538SAndroid Build Coastguard Worker xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
6017*6777b538SAndroid Build Coastguard Worker
6018*6777b538SAndroid Build Coastguard Worker if (RAW != '(') {
6019*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
6020*6777b538SAndroid Build Coastguard Worker return(NULL);
6021*6777b538SAndroid Build Coastguard Worker }
6022*6777b538SAndroid Build Coastguard Worker do {
6023*6777b538SAndroid Build Coastguard Worker NEXT;
6024*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6025*6777b538SAndroid Build Coastguard Worker name = xmlParseName(ctxt);
6026*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
6027*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6028*6777b538SAndroid Build Coastguard Worker "Name expected in NOTATION declaration\n");
6029*6777b538SAndroid Build Coastguard Worker xmlFreeEnumeration(ret);
6030*6777b538SAndroid Build Coastguard Worker return(NULL);
6031*6777b538SAndroid Build Coastguard Worker }
6032*6777b538SAndroid Build Coastguard Worker tmp = ret;
6033*6777b538SAndroid Build Coastguard Worker while (tmp != NULL) {
6034*6777b538SAndroid Build Coastguard Worker if (xmlStrEqual(name, tmp->name)) {
6035*6777b538SAndroid Build Coastguard Worker xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
6036*6777b538SAndroid Build Coastguard Worker "standalone: attribute notation value token %s duplicated\n",
6037*6777b538SAndroid Build Coastguard Worker name, NULL);
6038*6777b538SAndroid Build Coastguard Worker if (!xmlDictOwns(ctxt->dict, name))
6039*6777b538SAndroid Build Coastguard Worker xmlFree((xmlChar *) name);
6040*6777b538SAndroid Build Coastguard Worker break;
6041*6777b538SAndroid Build Coastguard Worker }
6042*6777b538SAndroid Build Coastguard Worker tmp = tmp->next;
6043*6777b538SAndroid Build Coastguard Worker }
6044*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
6045*6777b538SAndroid Build Coastguard Worker cur = xmlCreateEnumeration(name);
6046*6777b538SAndroid Build Coastguard Worker if (cur == NULL) {
6047*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
6048*6777b538SAndroid Build Coastguard Worker xmlFreeEnumeration(ret);
6049*6777b538SAndroid Build Coastguard Worker return(NULL);
6050*6777b538SAndroid Build Coastguard Worker }
6051*6777b538SAndroid Build Coastguard Worker if (last == NULL) ret = last = cur;
6052*6777b538SAndroid Build Coastguard Worker else {
6053*6777b538SAndroid Build Coastguard Worker last->next = cur;
6054*6777b538SAndroid Build Coastguard Worker last = cur;
6055*6777b538SAndroid Build Coastguard Worker }
6056*6777b538SAndroid Build Coastguard Worker }
6057*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6058*6777b538SAndroid Build Coastguard Worker } while (RAW == '|');
6059*6777b538SAndroid Build Coastguard Worker if (RAW != ')') {
6060*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
6061*6777b538SAndroid Build Coastguard Worker xmlFreeEnumeration(ret);
6062*6777b538SAndroid Build Coastguard Worker return(NULL);
6063*6777b538SAndroid Build Coastguard Worker }
6064*6777b538SAndroid Build Coastguard Worker NEXT;
6065*6777b538SAndroid Build Coastguard Worker return(ret);
6066*6777b538SAndroid Build Coastguard Worker }
6067*6777b538SAndroid Build Coastguard Worker
6068*6777b538SAndroid Build Coastguard Worker /**
6069*6777b538SAndroid Build Coastguard Worker * xmlParseEnumerationType:
6070*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
6071*6777b538SAndroid Build Coastguard Worker *
6072*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
6073*6777b538SAndroid Build Coastguard Worker *
6074*6777b538SAndroid Build Coastguard Worker * parse an Enumeration attribute type.
6075*6777b538SAndroid Build Coastguard Worker *
6076*6777b538SAndroid Build Coastguard Worker * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
6077*6777b538SAndroid Build Coastguard Worker *
6078*6777b538SAndroid Build Coastguard Worker * [ VC: Enumeration ]
6079*6777b538SAndroid Build Coastguard Worker * Values of this type must match one of the Nmtoken tokens in
6080*6777b538SAndroid Build Coastguard Worker * the declaration
6081*6777b538SAndroid Build Coastguard Worker *
6082*6777b538SAndroid Build Coastguard Worker * Returns: the enumeration attribute tree built while parsing
6083*6777b538SAndroid Build Coastguard Worker */
6084*6777b538SAndroid Build Coastguard Worker
6085*6777b538SAndroid Build Coastguard Worker xmlEnumerationPtr
xmlParseEnumerationType(xmlParserCtxtPtr ctxt)6086*6777b538SAndroid Build Coastguard Worker xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
6087*6777b538SAndroid Build Coastguard Worker xmlChar *name;
6088*6777b538SAndroid Build Coastguard Worker xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
6089*6777b538SAndroid Build Coastguard Worker
6090*6777b538SAndroid Build Coastguard Worker if (RAW != '(') {
6091*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
6092*6777b538SAndroid Build Coastguard Worker return(NULL);
6093*6777b538SAndroid Build Coastguard Worker }
6094*6777b538SAndroid Build Coastguard Worker do {
6095*6777b538SAndroid Build Coastguard Worker NEXT;
6096*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6097*6777b538SAndroid Build Coastguard Worker name = xmlParseNmtoken(ctxt);
6098*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
6099*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
6100*6777b538SAndroid Build Coastguard Worker return(ret);
6101*6777b538SAndroid Build Coastguard Worker }
6102*6777b538SAndroid Build Coastguard Worker tmp = ret;
6103*6777b538SAndroid Build Coastguard Worker while (tmp != NULL) {
6104*6777b538SAndroid Build Coastguard Worker if (xmlStrEqual(name, tmp->name)) {
6105*6777b538SAndroid Build Coastguard Worker xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
6106*6777b538SAndroid Build Coastguard Worker "standalone: attribute enumeration value token %s duplicated\n",
6107*6777b538SAndroid Build Coastguard Worker name, NULL);
6108*6777b538SAndroid Build Coastguard Worker if (!xmlDictOwns(ctxt->dict, name))
6109*6777b538SAndroid Build Coastguard Worker xmlFree(name);
6110*6777b538SAndroid Build Coastguard Worker break;
6111*6777b538SAndroid Build Coastguard Worker }
6112*6777b538SAndroid Build Coastguard Worker tmp = tmp->next;
6113*6777b538SAndroid Build Coastguard Worker }
6114*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
6115*6777b538SAndroid Build Coastguard Worker cur = xmlCreateEnumeration(name);
6116*6777b538SAndroid Build Coastguard Worker if (!xmlDictOwns(ctxt->dict, name))
6117*6777b538SAndroid Build Coastguard Worker xmlFree(name);
6118*6777b538SAndroid Build Coastguard Worker if (cur == NULL) {
6119*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
6120*6777b538SAndroid Build Coastguard Worker xmlFreeEnumeration(ret);
6121*6777b538SAndroid Build Coastguard Worker return(NULL);
6122*6777b538SAndroid Build Coastguard Worker }
6123*6777b538SAndroid Build Coastguard Worker if (last == NULL) ret = last = cur;
6124*6777b538SAndroid Build Coastguard Worker else {
6125*6777b538SAndroid Build Coastguard Worker last->next = cur;
6126*6777b538SAndroid Build Coastguard Worker last = cur;
6127*6777b538SAndroid Build Coastguard Worker }
6128*6777b538SAndroid Build Coastguard Worker }
6129*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6130*6777b538SAndroid Build Coastguard Worker } while (RAW == '|');
6131*6777b538SAndroid Build Coastguard Worker if (RAW != ')') {
6132*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
6133*6777b538SAndroid Build Coastguard Worker return(ret);
6134*6777b538SAndroid Build Coastguard Worker }
6135*6777b538SAndroid Build Coastguard Worker NEXT;
6136*6777b538SAndroid Build Coastguard Worker return(ret);
6137*6777b538SAndroid Build Coastguard Worker }
6138*6777b538SAndroid Build Coastguard Worker
6139*6777b538SAndroid Build Coastguard Worker /**
6140*6777b538SAndroid Build Coastguard Worker * xmlParseEnumeratedType:
6141*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
6142*6777b538SAndroid Build Coastguard Worker * @tree: the enumeration tree built while parsing
6143*6777b538SAndroid Build Coastguard Worker *
6144*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
6145*6777b538SAndroid Build Coastguard Worker *
6146*6777b538SAndroid Build Coastguard Worker * parse an Enumerated attribute type.
6147*6777b538SAndroid Build Coastguard Worker *
6148*6777b538SAndroid Build Coastguard Worker * [57] EnumeratedType ::= NotationType | Enumeration
6149*6777b538SAndroid Build Coastguard Worker *
6150*6777b538SAndroid Build Coastguard Worker * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
6151*6777b538SAndroid Build Coastguard Worker *
6152*6777b538SAndroid Build Coastguard Worker *
6153*6777b538SAndroid Build Coastguard Worker * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
6154*6777b538SAndroid Build Coastguard Worker */
6155*6777b538SAndroid Build Coastguard Worker
6156*6777b538SAndroid Build Coastguard Worker int
xmlParseEnumeratedType(xmlParserCtxtPtr ctxt,xmlEnumerationPtr * tree)6157*6777b538SAndroid Build Coastguard Worker xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
6158*6777b538SAndroid Build Coastguard Worker if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
6159*6777b538SAndroid Build Coastguard Worker SKIP(8);
6160*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
6161*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6162*6777b538SAndroid Build Coastguard Worker "Space required after 'NOTATION'\n");
6163*6777b538SAndroid Build Coastguard Worker return(0);
6164*6777b538SAndroid Build Coastguard Worker }
6165*6777b538SAndroid Build Coastguard Worker *tree = xmlParseNotationType(ctxt);
6166*6777b538SAndroid Build Coastguard Worker if (*tree == NULL) return(0);
6167*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_NOTATION);
6168*6777b538SAndroid Build Coastguard Worker }
6169*6777b538SAndroid Build Coastguard Worker *tree = xmlParseEnumerationType(ctxt);
6170*6777b538SAndroid Build Coastguard Worker if (*tree == NULL) return(0);
6171*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_ENUMERATION);
6172*6777b538SAndroid Build Coastguard Worker }
6173*6777b538SAndroid Build Coastguard Worker
6174*6777b538SAndroid Build Coastguard Worker /**
6175*6777b538SAndroid Build Coastguard Worker * xmlParseAttributeType:
6176*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
6177*6777b538SAndroid Build Coastguard Worker * @tree: the enumeration tree built while parsing
6178*6777b538SAndroid Build Coastguard Worker *
6179*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
6180*6777b538SAndroid Build Coastguard Worker *
6181*6777b538SAndroid Build Coastguard Worker * parse the Attribute list def for an element
6182*6777b538SAndroid Build Coastguard Worker *
6183*6777b538SAndroid Build Coastguard Worker * [54] AttType ::= StringType | TokenizedType | EnumeratedType
6184*6777b538SAndroid Build Coastguard Worker *
6185*6777b538SAndroid Build Coastguard Worker * [55] StringType ::= 'CDATA'
6186*6777b538SAndroid Build Coastguard Worker *
6187*6777b538SAndroid Build Coastguard Worker * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
6188*6777b538SAndroid Build Coastguard Worker * 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
6189*6777b538SAndroid Build Coastguard Worker *
6190*6777b538SAndroid Build Coastguard Worker * Validity constraints for attribute values syntax are checked in
6191*6777b538SAndroid Build Coastguard Worker * xmlValidateAttributeValue()
6192*6777b538SAndroid Build Coastguard Worker *
6193*6777b538SAndroid Build Coastguard Worker * [ VC: ID ]
6194*6777b538SAndroid Build Coastguard Worker * Values of type ID must match the Name production. A name must not
6195*6777b538SAndroid Build Coastguard Worker * appear more than once in an XML document as a value of this type;
6196*6777b538SAndroid Build Coastguard Worker * i.e., ID values must uniquely identify the elements which bear them.
6197*6777b538SAndroid Build Coastguard Worker *
6198*6777b538SAndroid Build Coastguard Worker * [ VC: One ID per Element Type ]
6199*6777b538SAndroid Build Coastguard Worker * No element type may have more than one ID attribute specified.
6200*6777b538SAndroid Build Coastguard Worker *
6201*6777b538SAndroid Build Coastguard Worker * [ VC: ID Attribute Default ]
6202*6777b538SAndroid Build Coastguard Worker * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
6203*6777b538SAndroid Build Coastguard Worker *
6204*6777b538SAndroid Build Coastguard Worker * [ VC: IDREF ]
6205*6777b538SAndroid Build Coastguard Worker * Values of type IDREF must match the Name production, and values
6206*6777b538SAndroid Build Coastguard Worker * of type IDREFS must match Names; each IDREF Name must match the value
6207*6777b538SAndroid Build Coastguard Worker * of an ID attribute on some element in the XML document; i.e. IDREF
6208*6777b538SAndroid Build Coastguard Worker * values must match the value of some ID attribute.
6209*6777b538SAndroid Build Coastguard Worker *
6210*6777b538SAndroid Build Coastguard Worker * [ VC: Entity Name ]
6211*6777b538SAndroid Build Coastguard Worker * Values of type ENTITY must match the Name production, values
6212*6777b538SAndroid Build Coastguard Worker * of type ENTITIES must match Names; each Entity Name must match the
6213*6777b538SAndroid Build Coastguard Worker * name of an unparsed entity declared in the DTD.
6214*6777b538SAndroid Build Coastguard Worker *
6215*6777b538SAndroid Build Coastguard Worker * [ VC: Name Token ]
6216*6777b538SAndroid Build Coastguard Worker * Values of type NMTOKEN must match the Nmtoken production; values
6217*6777b538SAndroid Build Coastguard Worker * of type NMTOKENS must match Nmtokens.
6218*6777b538SAndroid Build Coastguard Worker *
6219*6777b538SAndroid Build Coastguard Worker * Returns the attribute type
6220*6777b538SAndroid Build Coastguard Worker */
6221*6777b538SAndroid Build Coastguard Worker int
xmlParseAttributeType(xmlParserCtxtPtr ctxt,xmlEnumerationPtr * tree)6222*6777b538SAndroid Build Coastguard Worker xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
6223*6777b538SAndroid Build Coastguard Worker if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
6224*6777b538SAndroid Build Coastguard Worker SKIP(5);
6225*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_CDATA);
6226*6777b538SAndroid Build Coastguard Worker } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
6227*6777b538SAndroid Build Coastguard Worker SKIP(6);
6228*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_IDREFS);
6229*6777b538SAndroid Build Coastguard Worker } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
6230*6777b538SAndroid Build Coastguard Worker SKIP(5);
6231*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_IDREF);
6232*6777b538SAndroid Build Coastguard Worker } else if ((RAW == 'I') && (NXT(1) == 'D')) {
6233*6777b538SAndroid Build Coastguard Worker SKIP(2);
6234*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_ID);
6235*6777b538SAndroid Build Coastguard Worker } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
6236*6777b538SAndroid Build Coastguard Worker SKIP(6);
6237*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_ENTITY);
6238*6777b538SAndroid Build Coastguard Worker } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
6239*6777b538SAndroid Build Coastguard Worker SKIP(8);
6240*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_ENTITIES);
6241*6777b538SAndroid Build Coastguard Worker } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
6242*6777b538SAndroid Build Coastguard Worker SKIP(8);
6243*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_NMTOKENS);
6244*6777b538SAndroid Build Coastguard Worker } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
6245*6777b538SAndroid Build Coastguard Worker SKIP(7);
6246*6777b538SAndroid Build Coastguard Worker return(XML_ATTRIBUTE_NMTOKEN);
6247*6777b538SAndroid Build Coastguard Worker }
6248*6777b538SAndroid Build Coastguard Worker return(xmlParseEnumeratedType(ctxt, tree));
6249*6777b538SAndroid Build Coastguard Worker }
6250*6777b538SAndroid Build Coastguard Worker
6251*6777b538SAndroid Build Coastguard Worker /**
6252*6777b538SAndroid Build Coastguard Worker * xmlParseAttributeListDecl:
6253*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
6254*6777b538SAndroid Build Coastguard Worker *
6255*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
6256*6777b538SAndroid Build Coastguard Worker *
6257*6777b538SAndroid Build Coastguard Worker * Parse an attribute list declaration for an element. Always consumes '<!'.
6258*6777b538SAndroid Build Coastguard Worker *
6259*6777b538SAndroid Build Coastguard Worker * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
6260*6777b538SAndroid Build Coastguard Worker *
6261*6777b538SAndroid Build Coastguard Worker * [53] AttDef ::= S Name S AttType S DefaultDecl
6262*6777b538SAndroid Build Coastguard Worker *
6263*6777b538SAndroid Build Coastguard Worker */
6264*6777b538SAndroid Build Coastguard Worker void
xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt)6265*6777b538SAndroid Build Coastguard Worker xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
6266*6777b538SAndroid Build Coastguard Worker const xmlChar *elemName;
6267*6777b538SAndroid Build Coastguard Worker const xmlChar *attrName;
6268*6777b538SAndroid Build Coastguard Worker xmlEnumerationPtr tree;
6269*6777b538SAndroid Build Coastguard Worker
6270*6777b538SAndroid Build Coastguard Worker if ((CUR != '<') || (NXT(1) != '!'))
6271*6777b538SAndroid Build Coastguard Worker return;
6272*6777b538SAndroid Build Coastguard Worker SKIP(2);
6273*6777b538SAndroid Build Coastguard Worker
6274*6777b538SAndroid Build Coastguard Worker if (CMP7(CUR_PTR, 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
6275*6777b538SAndroid Build Coastguard Worker int inputid = ctxt->input->id;
6276*6777b538SAndroid Build Coastguard Worker
6277*6777b538SAndroid Build Coastguard Worker SKIP(7);
6278*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
6279*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6280*6777b538SAndroid Build Coastguard Worker "Space required after '<!ATTLIST'\n");
6281*6777b538SAndroid Build Coastguard Worker }
6282*6777b538SAndroid Build Coastguard Worker elemName = xmlParseName(ctxt);
6283*6777b538SAndroid Build Coastguard Worker if (elemName == NULL) {
6284*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6285*6777b538SAndroid Build Coastguard Worker "ATTLIST: no name for Element\n");
6286*6777b538SAndroid Build Coastguard Worker return;
6287*6777b538SAndroid Build Coastguard Worker }
6288*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6289*6777b538SAndroid Build Coastguard Worker GROW;
6290*6777b538SAndroid Build Coastguard Worker while ((RAW != '>') && (PARSER_STOPPED(ctxt) == 0)) {
6291*6777b538SAndroid Build Coastguard Worker int type;
6292*6777b538SAndroid Build Coastguard Worker int def;
6293*6777b538SAndroid Build Coastguard Worker xmlChar *defaultValue = NULL;
6294*6777b538SAndroid Build Coastguard Worker
6295*6777b538SAndroid Build Coastguard Worker GROW;
6296*6777b538SAndroid Build Coastguard Worker tree = NULL;
6297*6777b538SAndroid Build Coastguard Worker attrName = xmlParseName(ctxt);
6298*6777b538SAndroid Build Coastguard Worker if (attrName == NULL) {
6299*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6300*6777b538SAndroid Build Coastguard Worker "ATTLIST: no name for Attribute\n");
6301*6777b538SAndroid Build Coastguard Worker break;
6302*6777b538SAndroid Build Coastguard Worker }
6303*6777b538SAndroid Build Coastguard Worker GROW;
6304*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
6305*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6306*6777b538SAndroid Build Coastguard Worker "Space required after the attribute name\n");
6307*6777b538SAndroid Build Coastguard Worker break;
6308*6777b538SAndroid Build Coastguard Worker }
6309*6777b538SAndroid Build Coastguard Worker
6310*6777b538SAndroid Build Coastguard Worker type = xmlParseAttributeType(ctxt, &tree);
6311*6777b538SAndroid Build Coastguard Worker if (type <= 0) {
6312*6777b538SAndroid Build Coastguard Worker break;
6313*6777b538SAndroid Build Coastguard Worker }
6314*6777b538SAndroid Build Coastguard Worker
6315*6777b538SAndroid Build Coastguard Worker GROW;
6316*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
6317*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6318*6777b538SAndroid Build Coastguard Worker "Space required after the attribute type\n");
6319*6777b538SAndroid Build Coastguard Worker if (tree != NULL)
6320*6777b538SAndroid Build Coastguard Worker xmlFreeEnumeration(tree);
6321*6777b538SAndroid Build Coastguard Worker break;
6322*6777b538SAndroid Build Coastguard Worker }
6323*6777b538SAndroid Build Coastguard Worker
6324*6777b538SAndroid Build Coastguard Worker def = xmlParseDefaultDecl(ctxt, &defaultValue);
6325*6777b538SAndroid Build Coastguard Worker if (def <= 0) {
6326*6777b538SAndroid Build Coastguard Worker if (defaultValue != NULL)
6327*6777b538SAndroid Build Coastguard Worker xmlFree(defaultValue);
6328*6777b538SAndroid Build Coastguard Worker if (tree != NULL)
6329*6777b538SAndroid Build Coastguard Worker xmlFreeEnumeration(tree);
6330*6777b538SAndroid Build Coastguard Worker break;
6331*6777b538SAndroid Build Coastguard Worker }
6332*6777b538SAndroid Build Coastguard Worker if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
6333*6777b538SAndroid Build Coastguard Worker xmlAttrNormalizeSpace(defaultValue, defaultValue);
6334*6777b538SAndroid Build Coastguard Worker
6335*6777b538SAndroid Build Coastguard Worker GROW;
6336*6777b538SAndroid Build Coastguard Worker if (RAW != '>') {
6337*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
6338*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6339*6777b538SAndroid Build Coastguard Worker "Space required after the attribute default value\n");
6340*6777b538SAndroid Build Coastguard Worker if (defaultValue != NULL)
6341*6777b538SAndroid Build Coastguard Worker xmlFree(defaultValue);
6342*6777b538SAndroid Build Coastguard Worker if (tree != NULL)
6343*6777b538SAndroid Build Coastguard Worker xmlFreeEnumeration(tree);
6344*6777b538SAndroid Build Coastguard Worker break;
6345*6777b538SAndroid Build Coastguard Worker }
6346*6777b538SAndroid Build Coastguard Worker }
6347*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6348*6777b538SAndroid Build Coastguard Worker (ctxt->sax->attributeDecl != NULL))
6349*6777b538SAndroid Build Coastguard Worker ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
6350*6777b538SAndroid Build Coastguard Worker type, def, defaultValue, tree);
6351*6777b538SAndroid Build Coastguard Worker else if (tree != NULL)
6352*6777b538SAndroid Build Coastguard Worker xmlFreeEnumeration(tree);
6353*6777b538SAndroid Build Coastguard Worker
6354*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax2) && (defaultValue != NULL) &&
6355*6777b538SAndroid Build Coastguard Worker (def != XML_ATTRIBUTE_IMPLIED) &&
6356*6777b538SAndroid Build Coastguard Worker (def != XML_ATTRIBUTE_REQUIRED)) {
6357*6777b538SAndroid Build Coastguard Worker xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
6358*6777b538SAndroid Build Coastguard Worker }
6359*6777b538SAndroid Build Coastguard Worker if (ctxt->sax2) {
6360*6777b538SAndroid Build Coastguard Worker xmlAddSpecialAttr(ctxt, elemName, attrName, type);
6361*6777b538SAndroid Build Coastguard Worker }
6362*6777b538SAndroid Build Coastguard Worker if (defaultValue != NULL)
6363*6777b538SAndroid Build Coastguard Worker xmlFree(defaultValue);
6364*6777b538SAndroid Build Coastguard Worker GROW;
6365*6777b538SAndroid Build Coastguard Worker }
6366*6777b538SAndroid Build Coastguard Worker if (RAW == '>') {
6367*6777b538SAndroid Build Coastguard Worker if (inputid != ctxt->input->id) {
6368*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6369*6777b538SAndroid Build Coastguard Worker "Attribute list declaration doesn't start and"
6370*6777b538SAndroid Build Coastguard Worker " stop in the same entity\n");
6371*6777b538SAndroid Build Coastguard Worker }
6372*6777b538SAndroid Build Coastguard Worker NEXT;
6373*6777b538SAndroid Build Coastguard Worker }
6374*6777b538SAndroid Build Coastguard Worker }
6375*6777b538SAndroid Build Coastguard Worker }
6376*6777b538SAndroid Build Coastguard Worker
6377*6777b538SAndroid Build Coastguard Worker /**
6378*6777b538SAndroid Build Coastguard Worker * xmlParseElementMixedContentDecl:
6379*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
6380*6777b538SAndroid Build Coastguard Worker * @inputchk: the input used for the current entity, needed for boundary checks
6381*6777b538SAndroid Build Coastguard Worker *
6382*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
6383*6777b538SAndroid Build Coastguard Worker *
6384*6777b538SAndroid Build Coastguard Worker * parse the declaration for a Mixed Element content
6385*6777b538SAndroid Build Coastguard Worker * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6386*6777b538SAndroid Build Coastguard Worker *
6387*6777b538SAndroid Build Coastguard Worker * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
6388*6777b538SAndroid Build Coastguard Worker * '(' S? '#PCDATA' S? ')'
6389*6777b538SAndroid Build Coastguard Worker *
6390*6777b538SAndroid Build Coastguard Worker * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
6391*6777b538SAndroid Build Coastguard Worker *
6392*6777b538SAndroid Build Coastguard Worker * [ VC: No Duplicate Types ]
6393*6777b538SAndroid Build Coastguard Worker * The same name must not appear more than once in a single
6394*6777b538SAndroid Build Coastguard Worker * mixed-content declaration.
6395*6777b538SAndroid Build Coastguard Worker *
6396*6777b538SAndroid Build Coastguard Worker * returns: the list of the xmlElementContentPtr describing the element choices
6397*6777b538SAndroid Build Coastguard Worker */
6398*6777b538SAndroid Build Coastguard Worker xmlElementContentPtr
xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt,int inputchk)6399*6777b538SAndroid Build Coastguard Worker xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6400*6777b538SAndroid Build Coastguard Worker xmlElementContentPtr ret = NULL, cur = NULL, n;
6401*6777b538SAndroid Build Coastguard Worker const xmlChar *elem = NULL;
6402*6777b538SAndroid Build Coastguard Worker
6403*6777b538SAndroid Build Coastguard Worker GROW;
6404*6777b538SAndroid Build Coastguard Worker if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6405*6777b538SAndroid Build Coastguard Worker SKIP(7);
6406*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6407*6777b538SAndroid Build Coastguard Worker if (RAW == ')') {
6408*6777b538SAndroid Build Coastguard Worker if (ctxt->input->id != inputchk) {
6409*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6410*6777b538SAndroid Build Coastguard Worker "Element content declaration doesn't start and"
6411*6777b538SAndroid Build Coastguard Worker " stop in the same entity\n");
6412*6777b538SAndroid Build Coastguard Worker }
6413*6777b538SAndroid Build Coastguard Worker NEXT;
6414*6777b538SAndroid Build Coastguard Worker ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6415*6777b538SAndroid Build Coastguard Worker if (ret == NULL)
6416*6777b538SAndroid Build Coastguard Worker goto mem_error;
6417*6777b538SAndroid Build Coastguard Worker if (RAW == '*') {
6418*6777b538SAndroid Build Coastguard Worker ret->ocur = XML_ELEMENT_CONTENT_MULT;
6419*6777b538SAndroid Build Coastguard Worker NEXT;
6420*6777b538SAndroid Build Coastguard Worker }
6421*6777b538SAndroid Build Coastguard Worker return(ret);
6422*6777b538SAndroid Build Coastguard Worker }
6423*6777b538SAndroid Build Coastguard Worker if ((RAW == '(') || (RAW == '|')) {
6424*6777b538SAndroid Build Coastguard Worker ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6425*6777b538SAndroid Build Coastguard Worker if (ret == NULL)
6426*6777b538SAndroid Build Coastguard Worker goto mem_error;
6427*6777b538SAndroid Build Coastguard Worker }
6428*6777b538SAndroid Build Coastguard Worker while ((RAW == '|') && (PARSER_STOPPED(ctxt) == 0)) {
6429*6777b538SAndroid Build Coastguard Worker NEXT;
6430*6777b538SAndroid Build Coastguard Worker n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6431*6777b538SAndroid Build Coastguard Worker if (n == NULL)
6432*6777b538SAndroid Build Coastguard Worker goto mem_error;
6433*6777b538SAndroid Build Coastguard Worker if (elem == NULL) {
6434*6777b538SAndroid Build Coastguard Worker n->c1 = cur;
6435*6777b538SAndroid Build Coastguard Worker if (cur != NULL)
6436*6777b538SAndroid Build Coastguard Worker cur->parent = n;
6437*6777b538SAndroid Build Coastguard Worker ret = cur = n;
6438*6777b538SAndroid Build Coastguard Worker } else {
6439*6777b538SAndroid Build Coastguard Worker cur->c2 = n;
6440*6777b538SAndroid Build Coastguard Worker n->parent = cur;
6441*6777b538SAndroid Build Coastguard Worker n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6442*6777b538SAndroid Build Coastguard Worker if (n->c1 == NULL)
6443*6777b538SAndroid Build Coastguard Worker goto mem_error;
6444*6777b538SAndroid Build Coastguard Worker n->c1->parent = n;
6445*6777b538SAndroid Build Coastguard Worker cur = n;
6446*6777b538SAndroid Build Coastguard Worker }
6447*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6448*6777b538SAndroid Build Coastguard Worker elem = xmlParseName(ctxt);
6449*6777b538SAndroid Build Coastguard Worker if (elem == NULL) {
6450*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6451*6777b538SAndroid Build Coastguard Worker "xmlParseElementMixedContentDecl : Name expected\n");
6452*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6453*6777b538SAndroid Build Coastguard Worker return(NULL);
6454*6777b538SAndroid Build Coastguard Worker }
6455*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6456*6777b538SAndroid Build Coastguard Worker GROW;
6457*6777b538SAndroid Build Coastguard Worker }
6458*6777b538SAndroid Build Coastguard Worker if ((RAW == ')') && (NXT(1) == '*')) {
6459*6777b538SAndroid Build Coastguard Worker if (elem != NULL) {
6460*6777b538SAndroid Build Coastguard Worker cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
6461*6777b538SAndroid Build Coastguard Worker XML_ELEMENT_CONTENT_ELEMENT);
6462*6777b538SAndroid Build Coastguard Worker if (cur->c2 == NULL)
6463*6777b538SAndroid Build Coastguard Worker goto mem_error;
6464*6777b538SAndroid Build Coastguard Worker cur->c2->parent = cur;
6465*6777b538SAndroid Build Coastguard Worker }
6466*6777b538SAndroid Build Coastguard Worker if (ret != NULL)
6467*6777b538SAndroid Build Coastguard Worker ret->ocur = XML_ELEMENT_CONTENT_MULT;
6468*6777b538SAndroid Build Coastguard Worker if (ctxt->input->id != inputchk) {
6469*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6470*6777b538SAndroid Build Coastguard Worker "Element content declaration doesn't start and"
6471*6777b538SAndroid Build Coastguard Worker " stop in the same entity\n");
6472*6777b538SAndroid Build Coastguard Worker }
6473*6777b538SAndroid Build Coastguard Worker SKIP(2);
6474*6777b538SAndroid Build Coastguard Worker } else {
6475*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6476*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
6477*6777b538SAndroid Build Coastguard Worker return(NULL);
6478*6777b538SAndroid Build Coastguard Worker }
6479*6777b538SAndroid Build Coastguard Worker
6480*6777b538SAndroid Build Coastguard Worker } else {
6481*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
6482*6777b538SAndroid Build Coastguard Worker }
6483*6777b538SAndroid Build Coastguard Worker return(ret);
6484*6777b538SAndroid Build Coastguard Worker
6485*6777b538SAndroid Build Coastguard Worker mem_error:
6486*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
6487*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6488*6777b538SAndroid Build Coastguard Worker return(NULL);
6489*6777b538SAndroid Build Coastguard Worker }
6490*6777b538SAndroid Build Coastguard Worker
6491*6777b538SAndroid Build Coastguard Worker /**
6492*6777b538SAndroid Build Coastguard Worker * xmlParseElementChildrenContentDeclPriv:
6493*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
6494*6777b538SAndroid Build Coastguard Worker * @inputchk: the input used for the current entity, needed for boundary checks
6495*6777b538SAndroid Build Coastguard Worker * @depth: the level of recursion
6496*6777b538SAndroid Build Coastguard Worker *
6497*6777b538SAndroid Build Coastguard Worker * parse the declaration for a Mixed Element content
6498*6777b538SAndroid Build Coastguard Worker * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6499*6777b538SAndroid Build Coastguard Worker *
6500*6777b538SAndroid Build Coastguard Worker *
6501*6777b538SAndroid Build Coastguard Worker * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6502*6777b538SAndroid Build Coastguard Worker *
6503*6777b538SAndroid Build Coastguard Worker * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6504*6777b538SAndroid Build Coastguard Worker *
6505*6777b538SAndroid Build Coastguard Worker * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6506*6777b538SAndroid Build Coastguard Worker *
6507*6777b538SAndroid Build Coastguard Worker * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6508*6777b538SAndroid Build Coastguard Worker *
6509*6777b538SAndroid Build Coastguard Worker * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6510*6777b538SAndroid Build Coastguard Worker * TODO Parameter-entity replacement text must be properly nested
6511*6777b538SAndroid Build Coastguard Worker * with parenthesized groups. That is to say, if either of the
6512*6777b538SAndroid Build Coastguard Worker * opening or closing parentheses in a choice, seq, or Mixed
6513*6777b538SAndroid Build Coastguard Worker * construct is contained in the replacement text for a parameter
6514*6777b538SAndroid Build Coastguard Worker * entity, both must be contained in the same replacement text. For
6515*6777b538SAndroid Build Coastguard Worker * interoperability, if a parameter-entity reference appears in a
6516*6777b538SAndroid Build Coastguard Worker * choice, seq, or Mixed construct, its replacement text should not
6517*6777b538SAndroid Build Coastguard Worker * be empty, and neither the first nor last non-blank character of
6518*6777b538SAndroid Build Coastguard Worker * the replacement text should be a connector (| or ,).
6519*6777b538SAndroid Build Coastguard Worker *
6520*6777b538SAndroid Build Coastguard Worker * Returns the tree of xmlElementContentPtr describing the element
6521*6777b538SAndroid Build Coastguard Worker * hierarchy.
6522*6777b538SAndroid Build Coastguard Worker */
6523*6777b538SAndroid Build Coastguard Worker static xmlElementContentPtr
xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt,int inputchk,int depth)6524*6777b538SAndroid Build Coastguard Worker xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
6525*6777b538SAndroid Build Coastguard Worker int depth) {
6526*6777b538SAndroid Build Coastguard Worker int maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 2048 : 256;
6527*6777b538SAndroid Build Coastguard Worker xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
6528*6777b538SAndroid Build Coastguard Worker const xmlChar *elem;
6529*6777b538SAndroid Build Coastguard Worker xmlChar type = 0;
6530*6777b538SAndroid Build Coastguard Worker
6531*6777b538SAndroid Build Coastguard Worker if (depth > maxDepth) {
6532*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_RESOURCE_LIMIT,
6533*6777b538SAndroid Build Coastguard Worker "xmlParseElementChildrenContentDecl : depth %d too deep, "
6534*6777b538SAndroid Build Coastguard Worker "use XML_PARSE_HUGE\n", depth);
6535*6777b538SAndroid Build Coastguard Worker return(NULL);
6536*6777b538SAndroid Build Coastguard Worker }
6537*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6538*6777b538SAndroid Build Coastguard Worker GROW;
6539*6777b538SAndroid Build Coastguard Worker if (RAW == '(') {
6540*6777b538SAndroid Build Coastguard Worker int inputid = ctxt->input->id;
6541*6777b538SAndroid Build Coastguard Worker
6542*6777b538SAndroid Build Coastguard Worker /* Recurse on first child */
6543*6777b538SAndroid Build Coastguard Worker NEXT;
6544*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6545*6777b538SAndroid Build Coastguard Worker cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6546*6777b538SAndroid Build Coastguard Worker depth + 1);
6547*6777b538SAndroid Build Coastguard Worker if (cur == NULL)
6548*6777b538SAndroid Build Coastguard Worker return(NULL);
6549*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6550*6777b538SAndroid Build Coastguard Worker GROW;
6551*6777b538SAndroid Build Coastguard Worker } else {
6552*6777b538SAndroid Build Coastguard Worker elem = xmlParseName(ctxt);
6553*6777b538SAndroid Build Coastguard Worker if (elem == NULL) {
6554*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6555*6777b538SAndroid Build Coastguard Worker return(NULL);
6556*6777b538SAndroid Build Coastguard Worker }
6557*6777b538SAndroid Build Coastguard Worker cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6558*6777b538SAndroid Build Coastguard Worker if (cur == NULL) {
6559*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
6560*6777b538SAndroid Build Coastguard Worker return(NULL);
6561*6777b538SAndroid Build Coastguard Worker }
6562*6777b538SAndroid Build Coastguard Worker GROW;
6563*6777b538SAndroid Build Coastguard Worker if (RAW == '?') {
6564*6777b538SAndroid Build Coastguard Worker cur->ocur = XML_ELEMENT_CONTENT_OPT;
6565*6777b538SAndroid Build Coastguard Worker NEXT;
6566*6777b538SAndroid Build Coastguard Worker } else if (RAW == '*') {
6567*6777b538SAndroid Build Coastguard Worker cur->ocur = XML_ELEMENT_CONTENT_MULT;
6568*6777b538SAndroid Build Coastguard Worker NEXT;
6569*6777b538SAndroid Build Coastguard Worker } else if (RAW == '+') {
6570*6777b538SAndroid Build Coastguard Worker cur->ocur = XML_ELEMENT_CONTENT_PLUS;
6571*6777b538SAndroid Build Coastguard Worker NEXT;
6572*6777b538SAndroid Build Coastguard Worker } else {
6573*6777b538SAndroid Build Coastguard Worker cur->ocur = XML_ELEMENT_CONTENT_ONCE;
6574*6777b538SAndroid Build Coastguard Worker }
6575*6777b538SAndroid Build Coastguard Worker GROW;
6576*6777b538SAndroid Build Coastguard Worker }
6577*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6578*6777b538SAndroid Build Coastguard Worker while ((RAW != ')') && (PARSER_STOPPED(ctxt) == 0)) {
6579*6777b538SAndroid Build Coastguard Worker /*
6580*6777b538SAndroid Build Coastguard Worker * Each loop we parse one separator and one element.
6581*6777b538SAndroid Build Coastguard Worker */
6582*6777b538SAndroid Build Coastguard Worker if (RAW == ',') {
6583*6777b538SAndroid Build Coastguard Worker if (type == 0) type = CUR;
6584*6777b538SAndroid Build Coastguard Worker
6585*6777b538SAndroid Build Coastguard Worker /*
6586*6777b538SAndroid Build Coastguard Worker * Detect "Name | Name , Name" error
6587*6777b538SAndroid Build Coastguard Worker */
6588*6777b538SAndroid Build Coastguard Worker else if (type != CUR) {
6589*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6590*6777b538SAndroid Build Coastguard Worker "xmlParseElementChildrenContentDecl : '%c' expected\n",
6591*6777b538SAndroid Build Coastguard Worker type);
6592*6777b538SAndroid Build Coastguard Worker if ((last != NULL) && (last != ret))
6593*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, last);
6594*6777b538SAndroid Build Coastguard Worker if (ret != NULL)
6595*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6596*6777b538SAndroid Build Coastguard Worker return(NULL);
6597*6777b538SAndroid Build Coastguard Worker }
6598*6777b538SAndroid Build Coastguard Worker NEXT;
6599*6777b538SAndroid Build Coastguard Worker
6600*6777b538SAndroid Build Coastguard Worker op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
6601*6777b538SAndroid Build Coastguard Worker if (op == NULL) {
6602*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
6603*6777b538SAndroid Build Coastguard Worker if ((last != NULL) && (last != ret))
6604*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, last);
6605*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6606*6777b538SAndroid Build Coastguard Worker return(NULL);
6607*6777b538SAndroid Build Coastguard Worker }
6608*6777b538SAndroid Build Coastguard Worker if (last == NULL) {
6609*6777b538SAndroid Build Coastguard Worker op->c1 = ret;
6610*6777b538SAndroid Build Coastguard Worker if (ret != NULL)
6611*6777b538SAndroid Build Coastguard Worker ret->parent = op;
6612*6777b538SAndroid Build Coastguard Worker ret = cur = op;
6613*6777b538SAndroid Build Coastguard Worker } else {
6614*6777b538SAndroid Build Coastguard Worker cur->c2 = op;
6615*6777b538SAndroid Build Coastguard Worker if (op != NULL)
6616*6777b538SAndroid Build Coastguard Worker op->parent = cur;
6617*6777b538SAndroid Build Coastguard Worker op->c1 = last;
6618*6777b538SAndroid Build Coastguard Worker if (last != NULL)
6619*6777b538SAndroid Build Coastguard Worker last->parent = op;
6620*6777b538SAndroid Build Coastguard Worker cur =op;
6621*6777b538SAndroid Build Coastguard Worker last = NULL;
6622*6777b538SAndroid Build Coastguard Worker }
6623*6777b538SAndroid Build Coastguard Worker } else if (RAW == '|') {
6624*6777b538SAndroid Build Coastguard Worker if (type == 0) type = CUR;
6625*6777b538SAndroid Build Coastguard Worker
6626*6777b538SAndroid Build Coastguard Worker /*
6627*6777b538SAndroid Build Coastguard Worker * Detect "Name , Name | Name" error
6628*6777b538SAndroid Build Coastguard Worker */
6629*6777b538SAndroid Build Coastguard Worker else if (type != CUR) {
6630*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6631*6777b538SAndroid Build Coastguard Worker "xmlParseElementChildrenContentDecl : '%c' expected\n",
6632*6777b538SAndroid Build Coastguard Worker type);
6633*6777b538SAndroid Build Coastguard Worker if ((last != NULL) && (last != ret))
6634*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, last);
6635*6777b538SAndroid Build Coastguard Worker if (ret != NULL)
6636*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6637*6777b538SAndroid Build Coastguard Worker return(NULL);
6638*6777b538SAndroid Build Coastguard Worker }
6639*6777b538SAndroid Build Coastguard Worker NEXT;
6640*6777b538SAndroid Build Coastguard Worker
6641*6777b538SAndroid Build Coastguard Worker op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6642*6777b538SAndroid Build Coastguard Worker if (op == NULL) {
6643*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
6644*6777b538SAndroid Build Coastguard Worker if ((last != NULL) && (last != ret))
6645*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, last);
6646*6777b538SAndroid Build Coastguard Worker if (ret != NULL)
6647*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6648*6777b538SAndroid Build Coastguard Worker return(NULL);
6649*6777b538SAndroid Build Coastguard Worker }
6650*6777b538SAndroid Build Coastguard Worker if (last == NULL) {
6651*6777b538SAndroid Build Coastguard Worker op->c1 = ret;
6652*6777b538SAndroid Build Coastguard Worker if (ret != NULL)
6653*6777b538SAndroid Build Coastguard Worker ret->parent = op;
6654*6777b538SAndroid Build Coastguard Worker ret = cur = op;
6655*6777b538SAndroid Build Coastguard Worker } else {
6656*6777b538SAndroid Build Coastguard Worker cur->c2 = op;
6657*6777b538SAndroid Build Coastguard Worker if (op != NULL)
6658*6777b538SAndroid Build Coastguard Worker op->parent = cur;
6659*6777b538SAndroid Build Coastguard Worker op->c1 = last;
6660*6777b538SAndroid Build Coastguard Worker if (last != NULL)
6661*6777b538SAndroid Build Coastguard Worker last->parent = op;
6662*6777b538SAndroid Build Coastguard Worker cur =op;
6663*6777b538SAndroid Build Coastguard Worker last = NULL;
6664*6777b538SAndroid Build Coastguard Worker }
6665*6777b538SAndroid Build Coastguard Worker } else {
6666*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
6667*6777b538SAndroid Build Coastguard Worker if ((last != NULL) && (last != ret))
6668*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, last);
6669*6777b538SAndroid Build Coastguard Worker if (ret != NULL)
6670*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6671*6777b538SAndroid Build Coastguard Worker return(NULL);
6672*6777b538SAndroid Build Coastguard Worker }
6673*6777b538SAndroid Build Coastguard Worker GROW;
6674*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6675*6777b538SAndroid Build Coastguard Worker GROW;
6676*6777b538SAndroid Build Coastguard Worker if (RAW == '(') {
6677*6777b538SAndroid Build Coastguard Worker int inputid = ctxt->input->id;
6678*6777b538SAndroid Build Coastguard Worker /* Recurse on second child */
6679*6777b538SAndroid Build Coastguard Worker NEXT;
6680*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6681*6777b538SAndroid Build Coastguard Worker last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6682*6777b538SAndroid Build Coastguard Worker depth + 1);
6683*6777b538SAndroid Build Coastguard Worker if (last == NULL) {
6684*6777b538SAndroid Build Coastguard Worker if (ret != NULL)
6685*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6686*6777b538SAndroid Build Coastguard Worker return(NULL);
6687*6777b538SAndroid Build Coastguard Worker }
6688*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6689*6777b538SAndroid Build Coastguard Worker } else {
6690*6777b538SAndroid Build Coastguard Worker elem = xmlParseName(ctxt);
6691*6777b538SAndroid Build Coastguard Worker if (elem == NULL) {
6692*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6693*6777b538SAndroid Build Coastguard Worker if (ret != NULL)
6694*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6695*6777b538SAndroid Build Coastguard Worker return(NULL);
6696*6777b538SAndroid Build Coastguard Worker }
6697*6777b538SAndroid Build Coastguard Worker last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6698*6777b538SAndroid Build Coastguard Worker if (last == NULL) {
6699*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
6700*6777b538SAndroid Build Coastguard Worker if (ret != NULL)
6701*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, ret);
6702*6777b538SAndroid Build Coastguard Worker return(NULL);
6703*6777b538SAndroid Build Coastguard Worker }
6704*6777b538SAndroid Build Coastguard Worker if (RAW == '?') {
6705*6777b538SAndroid Build Coastguard Worker last->ocur = XML_ELEMENT_CONTENT_OPT;
6706*6777b538SAndroid Build Coastguard Worker NEXT;
6707*6777b538SAndroid Build Coastguard Worker } else if (RAW == '*') {
6708*6777b538SAndroid Build Coastguard Worker last->ocur = XML_ELEMENT_CONTENT_MULT;
6709*6777b538SAndroid Build Coastguard Worker NEXT;
6710*6777b538SAndroid Build Coastguard Worker } else if (RAW == '+') {
6711*6777b538SAndroid Build Coastguard Worker last->ocur = XML_ELEMENT_CONTENT_PLUS;
6712*6777b538SAndroid Build Coastguard Worker NEXT;
6713*6777b538SAndroid Build Coastguard Worker } else {
6714*6777b538SAndroid Build Coastguard Worker last->ocur = XML_ELEMENT_CONTENT_ONCE;
6715*6777b538SAndroid Build Coastguard Worker }
6716*6777b538SAndroid Build Coastguard Worker }
6717*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6718*6777b538SAndroid Build Coastguard Worker GROW;
6719*6777b538SAndroid Build Coastguard Worker }
6720*6777b538SAndroid Build Coastguard Worker if ((cur != NULL) && (last != NULL)) {
6721*6777b538SAndroid Build Coastguard Worker cur->c2 = last;
6722*6777b538SAndroid Build Coastguard Worker if (last != NULL)
6723*6777b538SAndroid Build Coastguard Worker last->parent = cur;
6724*6777b538SAndroid Build Coastguard Worker }
6725*6777b538SAndroid Build Coastguard Worker if (ctxt->input->id != inputchk) {
6726*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6727*6777b538SAndroid Build Coastguard Worker "Element content declaration doesn't start and stop in"
6728*6777b538SAndroid Build Coastguard Worker " the same entity\n");
6729*6777b538SAndroid Build Coastguard Worker }
6730*6777b538SAndroid Build Coastguard Worker NEXT;
6731*6777b538SAndroid Build Coastguard Worker if (RAW == '?') {
6732*6777b538SAndroid Build Coastguard Worker if (ret != NULL) {
6733*6777b538SAndroid Build Coastguard Worker if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
6734*6777b538SAndroid Build Coastguard Worker (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6735*6777b538SAndroid Build Coastguard Worker ret->ocur = XML_ELEMENT_CONTENT_MULT;
6736*6777b538SAndroid Build Coastguard Worker else
6737*6777b538SAndroid Build Coastguard Worker ret->ocur = XML_ELEMENT_CONTENT_OPT;
6738*6777b538SAndroid Build Coastguard Worker }
6739*6777b538SAndroid Build Coastguard Worker NEXT;
6740*6777b538SAndroid Build Coastguard Worker } else if (RAW == '*') {
6741*6777b538SAndroid Build Coastguard Worker if (ret != NULL) {
6742*6777b538SAndroid Build Coastguard Worker ret->ocur = XML_ELEMENT_CONTENT_MULT;
6743*6777b538SAndroid Build Coastguard Worker cur = ret;
6744*6777b538SAndroid Build Coastguard Worker /*
6745*6777b538SAndroid Build Coastguard Worker * Some normalization:
6746*6777b538SAndroid Build Coastguard Worker * (a | b* | c?)* == (a | b | c)*
6747*6777b538SAndroid Build Coastguard Worker */
6748*6777b538SAndroid Build Coastguard Worker while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6749*6777b538SAndroid Build Coastguard Worker if ((cur->c1 != NULL) &&
6750*6777b538SAndroid Build Coastguard Worker ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6751*6777b538SAndroid Build Coastguard Worker (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
6752*6777b538SAndroid Build Coastguard Worker cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6753*6777b538SAndroid Build Coastguard Worker if ((cur->c2 != NULL) &&
6754*6777b538SAndroid Build Coastguard Worker ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6755*6777b538SAndroid Build Coastguard Worker (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
6756*6777b538SAndroid Build Coastguard Worker cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6757*6777b538SAndroid Build Coastguard Worker cur = cur->c2;
6758*6777b538SAndroid Build Coastguard Worker }
6759*6777b538SAndroid Build Coastguard Worker }
6760*6777b538SAndroid Build Coastguard Worker NEXT;
6761*6777b538SAndroid Build Coastguard Worker } else if (RAW == '+') {
6762*6777b538SAndroid Build Coastguard Worker if (ret != NULL) {
6763*6777b538SAndroid Build Coastguard Worker int found = 0;
6764*6777b538SAndroid Build Coastguard Worker
6765*6777b538SAndroid Build Coastguard Worker if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
6766*6777b538SAndroid Build Coastguard Worker (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6767*6777b538SAndroid Build Coastguard Worker ret->ocur = XML_ELEMENT_CONTENT_MULT;
6768*6777b538SAndroid Build Coastguard Worker else
6769*6777b538SAndroid Build Coastguard Worker ret->ocur = XML_ELEMENT_CONTENT_PLUS;
6770*6777b538SAndroid Build Coastguard Worker /*
6771*6777b538SAndroid Build Coastguard Worker * Some normalization:
6772*6777b538SAndroid Build Coastguard Worker * (a | b*)+ == (a | b)*
6773*6777b538SAndroid Build Coastguard Worker * (a | b?)+ == (a | b)*
6774*6777b538SAndroid Build Coastguard Worker */
6775*6777b538SAndroid Build Coastguard Worker while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6776*6777b538SAndroid Build Coastguard Worker if ((cur->c1 != NULL) &&
6777*6777b538SAndroid Build Coastguard Worker ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6778*6777b538SAndroid Build Coastguard Worker (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
6779*6777b538SAndroid Build Coastguard Worker cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6780*6777b538SAndroid Build Coastguard Worker found = 1;
6781*6777b538SAndroid Build Coastguard Worker }
6782*6777b538SAndroid Build Coastguard Worker if ((cur->c2 != NULL) &&
6783*6777b538SAndroid Build Coastguard Worker ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6784*6777b538SAndroid Build Coastguard Worker (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
6785*6777b538SAndroid Build Coastguard Worker cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6786*6777b538SAndroid Build Coastguard Worker found = 1;
6787*6777b538SAndroid Build Coastguard Worker }
6788*6777b538SAndroid Build Coastguard Worker cur = cur->c2;
6789*6777b538SAndroid Build Coastguard Worker }
6790*6777b538SAndroid Build Coastguard Worker if (found)
6791*6777b538SAndroid Build Coastguard Worker ret->ocur = XML_ELEMENT_CONTENT_MULT;
6792*6777b538SAndroid Build Coastguard Worker }
6793*6777b538SAndroid Build Coastguard Worker NEXT;
6794*6777b538SAndroid Build Coastguard Worker }
6795*6777b538SAndroid Build Coastguard Worker return(ret);
6796*6777b538SAndroid Build Coastguard Worker }
6797*6777b538SAndroid Build Coastguard Worker
6798*6777b538SAndroid Build Coastguard Worker /**
6799*6777b538SAndroid Build Coastguard Worker * xmlParseElementChildrenContentDecl:
6800*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
6801*6777b538SAndroid Build Coastguard Worker * @inputchk: the input used for the current entity, needed for boundary checks
6802*6777b538SAndroid Build Coastguard Worker *
6803*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
6804*6777b538SAndroid Build Coastguard Worker *
6805*6777b538SAndroid Build Coastguard Worker * parse the declaration for a Mixed Element content
6806*6777b538SAndroid Build Coastguard Worker * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6807*6777b538SAndroid Build Coastguard Worker *
6808*6777b538SAndroid Build Coastguard Worker * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6809*6777b538SAndroid Build Coastguard Worker *
6810*6777b538SAndroid Build Coastguard Worker * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6811*6777b538SAndroid Build Coastguard Worker *
6812*6777b538SAndroid Build Coastguard Worker * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6813*6777b538SAndroid Build Coastguard Worker *
6814*6777b538SAndroid Build Coastguard Worker * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6815*6777b538SAndroid Build Coastguard Worker *
6816*6777b538SAndroid Build Coastguard Worker * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6817*6777b538SAndroid Build Coastguard Worker * TODO Parameter-entity replacement text must be properly nested
6818*6777b538SAndroid Build Coastguard Worker * with parenthesized groups. That is to say, if either of the
6819*6777b538SAndroid Build Coastguard Worker * opening or closing parentheses in a choice, seq, or Mixed
6820*6777b538SAndroid Build Coastguard Worker * construct is contained in the replacement text for a parameter
6821*6777b538SAndroid Build Coastguard Worker * entity, both must be contained in the same replacement text. For
6822*6777b538SAndroid Build Coastguard Worker * interoperability, if a parameter-entity reference appears in a
6823*6777b538SAndroid Build Coastguard Worker * choice, seq, or Mixed construct, its replacement text should not
6824*6777b538SAndroid Build Coastguard Worker * be empty, and neither the first nor last non-blank character of
6825*6777b538SAndroid Build Coastguard Worker * the replacement text should be a connector (| or ,).
6826*6777b538SAndroid Build Coastguard Worker *
6827*6777b538SAndroid Build Coastguard Worker * Returns the tree of xmlElementContentPtr describing the element
6828*6777b538SAndroid Build Coastguard Worker * hierarchy.
6829*6777b538SAndroid Build Coastguard Worker */
6830*6777b538SAndroid Build Coastguard Worker xmlElementContentPtr
xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt,int inputchk)6831*6777b538SAndroid Build Coastguard Worker xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6832*6777b538SAndroid Build Coastguard Worker /* stub left for API/ABI compat */
6833*6777b538SAndroid Build Coastguard Worker return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
6834*6777b538SAndroid Build Coastguard Worker }
6835*6777b538SAndroid Build Coastguard Worker
6836*6777b538SAndroid Build Coastguard Worker /**
6837*6777b538SAndroid Build Coastguard Worker * xmlParseElementContentDecl:
6838*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
6839*6777b538SAndroid Build Coastguard Worker * @name: the name of the element being defined.
6840*6777b538SAndroid Build Coastguard Worker * @result: the Element Content pointer will be stored here if any
6841*6777b538SAndroid Build Coastguard Worker *
6842*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
6843*6777b538SAndroid Build Coastguard Worker *
6844*6777b538SAndroid Build Coastguard Worker * parse the declaration for an Element content either Mixed or Children,
6845*6777b538SAndroid Build Coastguard Worker * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
6846*6777b538SAndroid Build Coastguard Worker *
6847*6777b538SAndroid Build Coastguard Worker * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
6848*6777b538SAndroid Build Coastguard Worker *
6849*6777b538SAndroid Build Coastguard Worker * returns: the type of element content XML_ELEMENT_TYPE_xxx
6850*6777b538SAndroid Build Coastguard Worker */
6851*6777b538SAndroid Build Coastguard Worker
6852*6777b538SAndroid Build Coastguard Worker int
xmlParseElementContentDecl(xmlParserCtxtPtr ctxt,const xmlChar * name,xmlElementContentPtr * result)6853*6777b538SAndroid Build Coastguard Worker xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
6854*6777b538SAndroid Build Coastguard Worker xmlElementContentPtr *result) {
6855*6777b538SAndroid Build Coastguard Worker
6856*6777b538SAndroid Build Coastguard Worker xmlElementContentPtr tree = NULL;
6857*6777b538SAndroid Build Coastguard Worker int inputid = ctxt->input->id;
6858*6777b538SAndroid Build Coastguard Worker int res;
6859*6777b538SAndroid Build Coastguard Worker
6860*6777b538SAndroid Build Coastguard Worker *result = NULL;
6861*6777b538SAndroid Build Coastguard Worker
6862*6777b538SAndroid Build Coastguard Worker if (RAW != '(') {
6863*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6864*6777b538SAndroid Build Coastguard Worker "xmlParseElementContentDecl : %s '(' expected\n", name);
6865*6777b538SAndroid Build Coastguard Worker return(-1);
6866*6777b538SAndroid Build Coastguard Worker }
6867*6777b538SAndroid Build Coastguard Worker NEXT;
6868*6777b538SAndroid Build Coastguard Worker GROW;
6869*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6870*6777b538SAndroid Build Coastguard Worker if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6871*6777b538SAndroid Build Coastguard Worker tree = xmlParseElementMixedContentDecl(ctxt, inputid);
6872*6777b538SAndroid Build Coastguard Worker res = XML_ELEMENT_TYPE_MIXED;
6873*6777b538SAndroid Build Coastguard Worker } else {
6874*6777b538SAndroid Build Coastguard Worker tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
6875*6777b538SAndroid Build Coastguard Worker res = XML_ELEMENT_TYPE_ELEMENT;
6876*6777b538SAndroid Build Coastguard Worker }
6877*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6878*6777b538SAndroid Build Coastguard Worker *result = tree;
6879*6777b538SAndroid Build Coastguard Worker return(res);
6880*6777b538SAndroid Build Coastguard Worker }
6881*6777b538SAndroid Build Coastguard Worker
6882*6777b538SAndroid Build Coastguard Worker /**
6883*6777b538SAndroid Build Coastguard Worker * xmlParseElementDecl:
6884*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
6885*6777b538SAndroid Build Coastguard Worker *
6886*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
6887*6777b538SAndroid Build Coastguard Worker *
6888*6777b538SAndroid Build Coastguard Worker * Parse an element declaration. Always consumes '<!'.
6889*6777b538SAndroid Build Coastguard Worker *
6890*6777b538SAndroid Build Coastguard Worker * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
6891*6777b538SAndroid Build Coastguard Worker *
6892*6777b538SAndroid Build Coastguard Worker * [ VC: Unique Element Type Declaration ]
6893*6777b538SAndroid Build Coastguard Worker * No element type may be declared more than once
6894*6777b538SAndroid Build Coastguard Worker *
6895*6777b538SAndroid Build Coastguard Worker * Returns the type of the element, or -1 in case of error
6896*6777b538SAndroid Build Coastguard Worker */
6897*6777b538SAndroid Build Coastguard Worker int
xmlParseElementDecl(xmlParserCtxtPtr ctxt)6898*6777b538SAndroid Build Coastguard Worker xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
6899*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
6900*6777b538SAndroid Build Coastguard Worker int ret = -1;
6901*6777b538SAndroid Build Coastguard Worker xmlElementContentPtr content = NULL;
6902*6777b538SAndroid Build Coastguard Worker
6903*6777b538SAndroid Build Coastguard Worker if ((CUR != '<') || (NXT(1) != '!'))
6904*6777b538SAndroid Build Coastguard Worker return(ret);
6905*6777b538SAndroid Build Coastguard Worker SKIP(2);
6906*6777b538SAndroid Build Coastguard Worker
6907*6777b538SAndroid Build Coastguard Worker /* GROW; done in the caller */
6908*6777b538SAndroid Build Coastguard Worker if (CMP7(CUR_PTR, 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
6909*6777b538SAndroid Build Coastguard Worker int inputid = ctxt->input->id;
6910*6777b538SAndroid Build Coastguard Worker
6911*6777b538SAndroid Build Coastguard Worker SKIP(7);
6912*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
6913*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6914*6777b538SAndroid Build Coastguard Worker "Space required after 'ELEMENT'\n");
6915*6777b538SAndroid Build Coastguard Worker return(-1);
6916*6777b538SAndroid Build Coastguard Worker }
6917*6777b538SAndroid Build Coastguard Worker name = xmlParseName(ctxt);
6918*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
6919*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6920*6777b538SAndroid Build Coastguard Worker "xmlParseElementDecl: no name for Element\n");
6921*6777b538SAndroid Build Coastguard Worker return(-1);
6922*6777b538SAndroid Build Coastguard Worker }
6923*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS_PE == 0) {
6924*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6925*6777b538SAndroid Build Coastguard Worker "Space required after the element name\n");
6926*6777b538SAndroid Build Coastguard Worker }
6927*6777b538SAndroid Build Coastguard Worker if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
6928*6777b538SAndroid Build Coastguard Worker SKIP(5);
6929*6777b538SAndroid Build Coastguard Worker /*
6930*6777b538SAndroid Build Coastguard Worker * Element must always be empty.
6931*6777b538SAndroid Build Coastguard Worker */
6932*6777b538SAndroid Build Coastguard Worker ret = XML_ELEMENT_TYPE_EMPTY;
6933*6777b538SAndroid Build Coastguard Worker } else if ((RAW == 'A') && (NXT(1) == 'N') &&
6934*6777b538SAndroid Build Coastguard Worker (NXT(2) == 'Y')) {
6935*6777b538SAndroid Build Coastguard Worker SKIP(3);
6936*6777b538SAndroid Build Coastguard Worker /*
6937*6777b538SAndroid Build Coastguard Worker * Element is a generic container.
6938*6777b538SAndroid Build Coastguard Worker */
6939*6777b538SAndroid Build Coastguard Worker ret = XML_ELEMENT_TYPE_ANY;
6940*6777b538SAndroid Build Coastguard Worker } else if (RAW == '(') {
6941*6777b538SAndroid Build Coastguard Worker ret = xmlParseElementContentDecl(ctxt, name, &content);
6942*6777b538SAndroid Build Coastguard Worker } else {
6943*6777b538SAndroid Build Coastguard Worker /*
6944*6777b538SAndroid Build Coastguard Worker * [ WFC: PEs in Internal Subset ] error handling.
6945*6777b538SAndroid Build Coastguard Worker */
6946*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6947*6777b538SAndroid Build Coastguard Worker "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
6948*6777b538SAndroid Build Coastguard Worker return(-1);
6949*6777b538SAndroid Build Coastguard Worker }
6950*6777b538SAndroid Build Coastguard Worker
6951*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
6952*6777b538SAndroid Build Coastguard Worker
6953*6777b538SAndroid Build Coastguard Worker if (RAW != '>') {
6954*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
6955*6777b538SAndroid Build Coastguard Worker if (content != NULL) {
6956*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, content);
6957*6777b538SAndroid Build Coastguard Worker }
6958*6777b538SAndroid Build Coastguard Worker } else {
6959*6777b538SAndroid Build Coastguard Worker if (inputid != ctxt->input->id) {
6960*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6961*6777b538SAndroid Build Coastguard Worker "Element declaration doesn't start and stop in"
6962*6777b538SAndroid Build Coastguard Worker " the same entity\n");
6963*6777b538SAndroid Build Coastguard Worker }
6964*6777b538SAndroid Build Coastguard Worker
6965*6777b538SAndroid Build Coastguard Worker NEXT;
6966*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6967*6777b538SAndroid Build Coastguard Worker (ctxt->sax->elementDecl != NULL)) {
6968*6777b538SAndroid Build Coastguard Worker if (content != NULL)
6969*6777b538SAndroid Build Coastguard Worker content->parent = NULL;
6970*6777b538SAndroid Build Coastguard Worker ctxt->sax->elementDecl(ctxt->userData, name, ret,
6971*6777b538SAndroid Build Coastguard Worker content);
6972*6777b538SAndroid Build Coastguard Worker if ((content != NULL) && (content->parent == NULL)) {
6973*6777b538SAndroid Build Coastguard Worker /*
6974*6777b538SAndroid Build Coastguard Worker * this is a trick: if xmlAddElementDecl is called,
6975*6777b538SAndroid Build Coastguard Worker * instead of copying the full tree it is plugged directly
6976*6777b538SAndroid Build Coastguard Worker * if called from the parser. Avoid duplicating the
6977*6777b538SAndroid Build Coastguard Worker * interfaces or change the API/ABI
6978*6777b538SAndroid Build Coastguard Worker */
6979*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, content);
6980*6777b538SAndroid Build Coastguard Worker }
6981*6777b538SAndroid Build Coastguard Worker } else if (content != NULL) {
6982*6777b538SAndroid Build Coastguard Worker xmlFreeDocElementContent(ctxt->myDoc, content);
6983*6777b538SAndroid Build Coastguard Worker }
6984*6777b538SAndroid Build Coastguard Worker }
6985*6777b538SAndroid Build Coastguard Worker }
6986*6777b538SAndroid Build Coastguard Worker return(ret);
6987*6777b538SAndroid Build Coastguard Worker }
6988*6777b538SAndroid Build Coastguard Worker
6989*6777b538SAndroid Build Coastguard Worker /**
6990*6777b538SAndroid Build Coastguard Worker * xmlParseConditionalSections
6991*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
6992*6777b538SAndroid Build Coastguard Worker *
6993*6777b538SAndroid Build Coastguard Worker * Parse a conditional section. Always consumes '<!['.
6994*6777b538SAndroid Build Coastguard Worker *
6995*6777b538SAndroid Build Coastguard Worker * [61] conditionalSect ::= includeSect | ignoreSect
6996*6777b538SAndroid Build Coastguard Worker * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
6997*6777b538SAndroid Build Coastguard Worker * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
6998*6777b538SAndroid Build Coastguard Worker * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
6999*6777b538SAndroid Build Coastguard Worker * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
7000*6777b538SAndroid Build Coastguard Worker */
7001*6777b538SAndroid Build Coastguard Worker
7002*6777b538SAndroid Build Coastguard Worker static void
xmlParseConditionalSections(xmlParserCtxtPtr ctxt)7003*6777b538SAndroid Build Coastguard Worker xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
7004*6777b538SAndroid Build Coastguard Worker int *inputIds = NULL;
7005*6777b538SAndroid Build Coastguard Worker size_t inputIdsSize = 0;
7006*6777b538SAndroid Build Coastguard Worker size_t depth = 0;
7007*6777b538SAndroid Build Coastguard Worker
7008*6777b538SAndroid Build Coastguard Worker while (PARSER_STOPPED(ctxt) == 0) {
7009*6777b538SAndroid Build Coastguard Worker if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
7010*6777b538SAndroid Build Coastguard Worker int id = ctxt->input->id;
7011*6777b538SAndroid Build Coastguard Worker
7012*6777b538SAndroid Build Coastguard Worker SKIP(3);
7013*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
7014*6777b538SAndroid Build Coastguard Worker
7015*6777b538SAndroid Build Coastguard Worker if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
7016*6777b538SAndroid Build Coastguard Worker SKIP(7);
7017*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
7018*6777b538SAndroid Build Coastguard Worker if (RAW != '[') {
7019*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
7020*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
7021*6777b538SAndroid Build Coastguard Worker goto error;
7022*6777b538SAndroid Build Coastguard Worker }
7023*6777b538SAndroid Build Coastguard Worker if (ctxt->input->id != id) {
7024*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
7025*6777b538SAndroid Build Coastguard Worker "All markup of the conditional section is"
7026*6777b538SAndroid Build Coastguard Worker " not in the same entity\n");
7027*6777b538SAndroid Build Coastguard Worker }
7028*6777b538SAndroid Build Coastguard Worker NEXT;
7029*6777b538SAndroid Build Coastguard Worker
7030*6777b538SAndroid Build Coastguard Worker if (inputIdsSize <= depth) {
7031*6777b538SAndroid Build Coastguard Worker int *tmp;
7032*6777b538SAndroid Build Coastguard Worker
7033*6777b538SAndroid Build Coastguard Worker inputIdsSize = (inputIdsSize == 0 ? 4 : inputIdsSize * 2);
7034*6777b538SAndroid Build Coastguard Worker tmp = (int *) xmlRealloc(inputIds,
7035*6777b538SAndroid Build Coastguard Worker inputIdsSize * sizeof(int));
7036*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
7037*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
7038*6777b538SAndroid Build Coastguard Worker goto error;
7039*6777b538SAndroid Build Coastguard Worker }
7040*6777b538SAndroid Build Coastguard Worker inputIds = tmp;
7041*6777b538SAndroid Build Coastguard Worker }
7042*6777b538SAndroid Build Coastguard Worker inputIds[depth] = id;
7043*6777b538SAndroid Build Coastguard Worker depth++;
7044*6777b538SAndroid Build Coastguard Worker } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
7045*6777b538SAndroid Build Coastguard Worker size_t ignoreDepth = 0;
7046*6777b538SAndroid Build Coastguard Worker
7047*6777b538SAndroid Build Coastguard Worker SKIP(6);
7048*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
7049*6777b538SAndroid Build Coastguard Worker if (RAW != '[') {
7050*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
7051*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
7052*6777b538SAndroid Build Coastguard Worker goto error;
7053*6777b538SAndroid Build Coastguard Worker }
7054*6777b538SAndroid Build Coastguard Worker if (ctxt->input->id != id) {
7055*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
7056*6777b538SAndroid Build Coastguard Worker "All markup of the conditional section is"
7057*6777b538SAndroid Build Coastguard Worker " not in the same entity\n");
7058*6777b538SAndroid Build Coastguard Worker }
7059*6777b538SAndroid Build Coastguard Worker NEXT;
7060*6777b538SAndroid Build Coastguard Worker
7061*6777b538SAndroid Build Coastguard Worker while (PARSER_STOPPED(ctxt) == 0) {
7062*6777b538SAndroid Build Coastguard Worker if (RAW == 0) {
7063*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
7064*6777b538SAndroid Build Coastguard Worker goto error;
7065*6777b538SAndroid Build Coastguard Worker }
7066*6777b538SAndroid Build Coastguard Worker if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
7067*6777b538SAndroid Build Coastguard Worker SKIP(3);
7068*6777b538SAndroid Build Coastguard Worker ignoreDepth++;
7069*6777b538SAndroid Build Coastguard Worker /* Check for integer overflow */
7070*6777b538SAndroid Build Coastguard Worker if (ignoreDepth == 0) {
7071*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
7072*6777b538SAndroid Build Coastguard Worker goto error;
7073*6777b538SAndroid Build Coastguard Worker }
7074*6777b538SAndroid Build Coastguard Worker } else if ((RAW == ']') && (NXT(1) == ']') &&
7075*6777b538SAndroid Build Coastguard Worker (NXT(2) == '>')) {
7076*6777b538SAndroid Build Coastguard Worker SKIP(3);
7077*6777b538SAndroid Build Coastguard Worker if (ignoreDepth == 0)
7078*6777b538SAndroid Build Coastguard Worker break;
7079*6777b538SAndroid Build Coastguard Worker ignoreDepth--;
7080*6777b538SAndroid Build Coastguard Worker } else {
7081*6777b538SAndroid Build Coastguard Worker NEXT;
7082*6777b538SAndroid Build Coastguard Worker }
7083*6777b538SAndroid Build Coastguard Worker }
7084*6777b538SAndroid Build Coastguard Worker
7085*6777b538SAndroid Build Coastguard Worker if (ctxt->input->id != id) {
7086*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
7087*6777b538SAndroid Build Coastguard Worker "All markup of the conditional section is"
7088*6777b538SAndroid Build Coastguard Worker " not in the same entity\n");
7089*6777b538SAndroid Build Coastguard Worker }
7090*6777b538SAndroid Build Coastguard Worker } else {
7091*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
7092*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
7093*6777b538SAndroid Build Coastguard Worker goto error;
7094*6777b538SAndroid Build Coastguard Worker }
7095*6777b538SAndroid Build Coastguard Worker } else if ((depth > 0) &&
7096*6777b538SAndroid Build Coastguard Worker (RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
7097*6777b538SAndroid Build Coastguard Worker depth--;
7098*6777b538SAndroid Build Coastguard Worker if (ctxt->input->id != inputIds[depth]) {
7099*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
7100*6777b538SAndroid Build Coastguard Worker "All markup of the conditional section is not"
7101*6777b538SAndroid Build Coastguard Worker " in the same entity\n");
7102*6777b538SAndroid Build Coastguard Worker }
7103*6777b538SAndroid Build Coastguard Worker SKIP(3);
7104*6777b538SAndroid Build Coastguard Worker } else if ((RAW == '<') && ((NXT(1) == '!') || (NXT(1) == '?'))) {
7105*6777b538SAndroid Build Coastguard Worker xmlParseMarkupDecl(ctxt);
7106*6777b538SAndroid Build Coastguard Worker } else {
7107*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7108*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
7109*6777b538SAndroid Build Coastguard Worker goto error;
7110*6777b538SAndroid Build Coastguard Worker }
7111*6777b538SAndroid Build Coastguard Worker
7112*6777b538SAndroid Build Coastguard Worker if (depth == 0)
7113*6777b538SAndroid Build Coastguard Worker break;
7114*6777b538SAndroid Build Coastguard Worker
7115*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
7116*6777b538SAndroid Build Coastguard Worker SHRINK;
7117*6777b538SAndroid Build Coastguard Worker GROW;
7118*6777b538SAndroid Build Coastguard Worker }
7119*6777b538SAndroid Build Coastguard Worker
7120*6777b538SAndroid Build Coastguard Worker error:
7121*6777b538SAndroid Build Coastguard Worker xmlFree(inputIds);
7122*6777b538SAndroid Build Coastguard Worker }
7123*6777b538SAndroid Build Coastguard Worker
7124*6777b538SAndroid Build Coastguard Worker /**
7125*6777b538SAndroid Build Coastguard Worker * xmlParseMarkupDecl:
7126*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
7127*6777b538SAndroid Build Coastguard Worker *
7128*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
7129*6777b538SAndroid Build Coastguard Worker *
7130*6777b538SAndroid Build Coastguard Worker * Parse markup declarations. Always consumes '<!' or '<?'.
7131*6777b538SAndroid Build Coastguard Worker *
7132*6777b538SAndroid Build Coastguard Worker * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
7133*6777b538SAndroid Build Coastguard Worker * NotationDecl | PI | Comment
7134*6777b538SAndroid Build Coastguard Worker *
7135*6777b538SAndroid Build Coastguard Worker * [ VC: Proper Declaration/PE Nesting ]
7136*6777b538SAndroid Build Coastguard Worker * Parameter-entity replacement text must be properly nested with
7137*6777b538SAndroid Build Coastguard Worker * markup declarations. That is to say, if either the first character
7138*6777b538SAndroid Build Coastguard Worker * or the last character of a markup declaration (markupdecl above) is
7139*6777b538SAndroid Build Coastguard Worker * contained in the replacement text for a parameter-entity reference,
7140*6777b538SAndroid Build Coastguard Worker * both must be contained in the same replacement text.
7141*6777b538SAndroid Build Coastguard Worker *
7142*6777b538SAndroid Build Coastguard Worker * [ WFC: PEs in Internal Subset ]
7143*6777b538SAndroid Build Coastguard Worker * In the internal DTD subset, parameter-entity references can occur
7144*6777b538SAndroid Build Coastguard Worker * only where markup declarations can occur, not within markup declarations.
7145*6777b538SAndroid Build Coastguard Worker * (This does not apply to references that occur in external parameter
7146*6777b538SAndroid Build Coastguard Worker * entities or to the external subset.)
7147*6777b538SAndroid Build Coastguard Worker */
7148*6777b538SAndroid Build Coastguard Worker void
xmlParseMarkupDecl(xmlParserCtxtPtr ctxt)7149*6777b538SAndroid Build Coastguard Worker xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
7150*6777b538SAndroid Build Coastguard Worker GROW;
7151*6777b538SAndroid Build Coastguard Worker if (CUR == '<') {
7152*6777b538SAndroid Build Coastguard Worker if (NXT(1) == '!') {
7153*6777b538SAndroid Build Coastguard Worker switch (NXT(2)) {
7154*6777b538SAndroid Build Coastguard Worker case 'E':
7155*6777b538SAndroid Build Coastguard Worker if (NXT(3) == 'L')
7156*6777b538SAndroid Build Coastguard Worker xmlParseElementDecl(ctxt);
7157*6777b538SAndroid Build Coastguard Worker else if (NXT(3) == 'N')
7158*6777b538SAndroid Build Coastguard Worker xmlParseEntityDecl(ctxt);
7159*6777b538SAndroid Build Coastguard Worker else
7160*6777b538SAndroid Build Coastguard Worker SKIP(2);
7161*6777b538SAndroid Build Coastguard Worker break;
7162*6777b538SAndroid Build Coastguard Worker case 'A':
7163*6777b538SAndroid Build Coastguard Worker xmlParseAttributeListDecl(ctxt);
7164*6777b538SAndroid Build Coastguard Worker break;
7165*6777b538SAndroid Build Coastguard Worker case 'N':
7166*6777b538SAndroid Build Coastguard Worker xmlParseNotationDecl(ctxt);
7167*6777b538SAndroid Build Coastguard Worker break;
7168*6777b538SAndroid Build Coastguard Worker case '-':
7169*6777b538SAndroid Build Coastguard Worker xmlParseComment(ctxt);
7170*6777b538SAndroid Build Coastguard Worker break;
7171*6777b538SAndroid Build Coastguard Worker default:
7172*6777b538SAndroid Build Coastguard Worker /* there is an error but it will be detected later */
7173*6777b538SAndroid Build Coastguard Worker SKIP(2);
7174*6777b538SAndroid Build Coastguard Worker break;
7175*6777b538SAndroid Build Coastguard Worker }
7176*6777b538SAndroid Build Coastguard Worker } else if (NXT(1) == '?') {
7177*6777b538SAndroid Build Coastguard Worker xmlParsePI(ctxt);
7178*6777b538SAndroid Build Coastguard Worker }
7179*6777b538SAndroid Build Coastguard Worker }
7180*6777b538SAndroid Build Coastguard Worker }
7181*6777b538SAndroid Build Coastguard Worker
7182*6777b538SAndroid Build Coastguard Worker /**
7183*6777b538SAndroid Build Coastguard Worker * xmlParseTextDecl:
7184*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
7185*6777b538SAndroid Build Coastguard Worker *
7186*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
7187*6777b538SAndroid Build Coastguard Worker *
7188*6777b538SAndroid Build Coastguard Worker * parse an XML declaration header for external entities
7189*6777b538SAndroid Build Coastguard Worker *
7190*6777b538SAndroid Build Coastguard Worker * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
7191*6777b538SAndroid Build Coastguard Worker */
7192*6777b538SAndroid Build Coastguard Worker
7193*6777b538SAndroid Build Coastguard Worker void
xmlParseTextDecl(xmlParserCtxtPtr ctxt)7194*6777b538SAndroid Build Coastguard Worker xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
7195*6777b538SAndroid Build Coastguard Worker xmlChar *version;
7196*6777b538SAndroid Build Coastguard Worker
7197*6777b538SAndroid Build Coastguard Worker /*
7198*6777b538SAndroid Build Coastguard Worker * We know that '<?xml' is here.
7199*6777b538SAndroid Build Coastguard Worker */
7200*6777b538SAndroid Build Coastguard Worker if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
7201*6777b538SAndroid Build Coastguard Worker SKIP(5);
7202*6777b538SAndroid Build Coastguard Worker } else {
7203*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
7204*6777b538SAndroid Build Coastguard Worker return;
7205*6777b538SAndroid Build Coastguard Worker }
7206*6777b538SAndroid Build Coastguard Worker
7207*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS == 0) {
7208*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
7209*6777b538SAndroid Build Coastguard Worker "Space needed after '<?xml'\n");
7210*6777b538SAndroid Build Coastguard Worker }
7211*6777b538SAndroid Build Coastguard Worker
7212*6777b538SAndroid Build Coastguard Worker /*
7213*6777b538SAndroid Build Coastguard Worker * We may have the VersionInfo here.
7214*6777b538SAndroid Build Coastguard Worker */
7215*6777b538SAndroid Build Coastguard Worker version = xmlParseVersionInfo(ctxt);
7216*6777b538SAndroid Build Coastguard Worker if (version == NULL) {
7217*6777b538SAndroid Build Coastguard Worker version = xmlCharStrdup(XML_DEFAULT_VERSION);
7218*6777b538SAndroid Build Coastguard Worker if (version == NULL) {
7219*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
7220*6777b538SAndroid Build Coastguard Worker return;
7221*6777b538SAndroid Build Coastguard Worker }
7222*6777b538SAndroid Build Coastguard Worker } else {
7223*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS == 0) {
7224*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
7225*6777b538SAndroid Build Coastguard Worker "Space needed here\n");
7226*6777b538SAndroid Build Coastguard Worker }
7227*6777b538SAndroid Build Coastguard Worker }
7228*6777b538SAndroid Build Coastguard Worker ctxt->input->version = version;
7229*6777b538SAndroid Build Coastguard Worker
7230*6777b538SAndroid Build Coastguard Worker /*
7231*6777b538SAndroid Build Coastguard Worker * We must have the encoding declaration
7232*6777b538SAndroid Build Coastguard Worker */
7233*6777b538SAndroid Build Coastguard Worker xmlParseEncodingDecl(ctxt);
7234*6777b538SAndroid Build Coastguard Worker
7235*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
7236*6777b538SAndroid Build Coastguard Worker if ((RAW == '?') && (NXT(1) == '>')) {
7237*6777b538SAndroid Build Coastguard Worker SKIP(2);
7238*6777b538SAndroid Build Coastguard Worker } else if (RAW == '>') {
7239*6777b538SAndroid Build Coastguard Worker /* Deprecated old WD ... */
7240*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
7241*6777b538SAndroid Build Coastguard Worker NEXT;
7242*6777b538SAndroid Build Coastguard Worker } else {
7243*6777b538SAndroid Build Coastguard Worker int c;
7244*6777b538SAndroid Build Coastguard Worker
7245*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
7246*6777b538SAndroid Build Coastguard Worker while ((PARSER_STOPPED(ctxt) == 0) && ((c = CUR) != 0)) {
7247*6777b538SAndroid Build Coastguard Worker NEXT;
7248*6777b538SAndroid Build Coastguard Worker if (c == '>')
7249*6777b538SAndroid Build Coastguard Worker break;
7250*6777b538SAndroid Build Coastguard Worker }
7251*6777b538SAndroid Build Coastguard Worker }
7252*6777b538SAndroid Build Coastguard Worker }
7253*6777b538SAndroid Build Coastguard Worker
7254*6777b538SAndroid Build Coastguard Worker /**
7255*6777b538SAndroid Build Coastguard Worker * xmlParseExternalSubset:
7256*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
7257*6777b538SAndroid Build Coastguard Worker * @ExternalID: the external identifier
7258*6777b538SAndroid Build Coastguard Worker * @SystemID: the system identifier (or URL)
7259*6777b538SAndroid Build Coastguard Worker *
7260*6777b538SAndroid Build Coastguard Worker * parse Markup declarations from an external subset
7261*6777b538SAndroid Build Coastguard Worker *
7262*6777b538SAndroid Build Coastguard Worker * [30] extSubset ::= textDecl? extSubsetDecl
7263*6777b538SAndroid Build Coastguard Worker *
7264*6777b538SAndroid Build Coastguard Worker * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
7265*6777b538SAndroid Build Coastguard Worker */
7266*6777b538SAndroid Build Coastguard Worker void
xmlParseExternalSubset(xmlParserCtxtPtr ctxt,const xmlChar * ExternalID,const xmlChar * SystemID)7267*6777b538SAndroid Build Coastguard Worker xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
7268*6777b538SAndroid Build Coastguard Worker const xmlChar *SystemID) {
7269*6777b538SAndroid Build Coastguard Worker int oldInputNr;
7270*6777b538SAndroid Build Coastguard Worker
7271*6777b538SAndroid Build Coastguard Worker xmlCtxtInitializeLate(ctxt);
7272*6777b538SAndroid Build Coastguard Worker
7273*6777b538SAndroid Build Coastguard Worker xmlDetectEncoding(ctxt);
7274*6777b538SAndroid Build Coastguard Worker
7275*6777b538SAndroid Build Coastguard Worker if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
7276*6777b538SAndroid Build Coastguard Worker xmlParseTextDecl(ctxt);
7277*6777b538SAndroid Build Coastguard Worker }
7278*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc == NULL) {
7279*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
7280*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc == NULL) {
7281*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
7282*6777b538SAndroid Build Coastguard Worker return;
7283*6777b538SAndroid Build Coastguard Worker }
7284*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->properties = XML_DOC_INTERNAL;
7285*6777b538SAndroid Build Coastguard Worker }
7286*6777b538SAndroid Build Coastguard Worker if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL) &&
7287*6777b538SAndroid Build Coastguard Worker (xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID) == NULL)) {
7288*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
7289*6777b538SAndroid Build Coastguard Worker }
7290*6777b538SAndroid Build Coastguard Worker
7291*6777b538SAndroid Build Coastguard Worker ctxt->inSubset = 2;
7292*6777b538SAndroid Build Coastguard Worker oldInputNr = ctxt->inputNr;
7293*6777b538SAndroid Build Coastguard Worker
7294*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
7295*6777b538SAndroid Build Coastguard Worker while (((RAW != 0) || (ctxt->inputNr > oldInputNr)) &&
7296*6777b538SAndroid Build Coastguard Worker (!PARSER_STOPPED(ctxt))) {
7297*6777b538SAndroid Build Coastguard Worker GROW;
7298*6777b538SAndroid Build Coastguard Worker if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
7299*6777b538SAndroid Build Coastguard Worker xmlParseConditionalSections(ctxt);
7300*6777b538SAndroid Build Coastguard Worker } else if ((RAW == '<') && ((NXT(1) == '!') || (NXT(1) == '?'))) {
7301*6777b538SAndroid Build Coastguard Worker xmlParseMarkupDecl(ctxt);
7302*6777b538SAndroid Build Coastguard Worker } else {
7303*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7304*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
7305*6777b538SAndroid Build Coastguard Worker return;
7306*6777b538SAndroid Build Coastguard Worker }
7307*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
7308*6777b538SAndroid Build Coastguard Worker SHRINK;
7309*6777b538SAndroid Build Coastguard Worker }
7310*6777b538SAndroid Build Coastguard Worker
7311*6777b538SAndroid Build Coastguard Worker while (ctxt->inputNr > oldInputNr)
7312*6777b538SAndroid Build Coastguard Worker xmlPopPE(ctxt);
7313*6777b538SAndroid Build Coastguard Worker
7314*6777b538SAndroid Build Coastguard Worker if (RAW != 0) {
7315*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7316*6777b538SAndroid Build Coastguard Worker }
7317*6777b538SAndroid Build Coastguard Worker }
7318*6777b538SAndroid Build Coastguard Worker
7319*6777b538SAndroid Build Coastguard Worker /**
7320*6777b538SAndroid Build Coastguard Worker * xmlParseReference:
7321*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
7322*6777b538SAndroid Build Coastguard Worker *
7323*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
7324*6777b538SAndroid Build Coastguard Worker *
7325*6777b538SAndroid Build Coastguard Worker * parse and handle entity references in content, depending on the SAX
7326*6777b538SAndroid Build Coastguard Worker * interface, this may end-up in a call to character() if this is a
7327*6777b538SAndroid Build Coastguard Worker * CharRef, a predefined entity, if there is no reference() callback.
7328*6777b538SAndroid Build Coastguard Worker * or if the parser was asked to switch to that mode.
7329*6777b538SAndroid Build Coastguard Worker *
7330*6777b538SAndroid Build Coastguard Worker * Always consumes '&'.
7331*6777b538SAndroid Build Coastguard Worker *
7332*6777b538SAndroid Build Coastguard Worker * [67] Reference ::= EntityRef | CharRef
7333*6777b538SAndroid Build Coastguard Worker */
7334*6777b538SAndroid Build Coastguard Worker void
xmlParseReference(xmlParserCtxtPtr ctxt)7335*6777b538SAndroid Build Coastguard Worker xmlParseReference(xmlParserCtxtPtr ctxt) {
7336*6777b538SAndroid Build Coastguard Worker xmlEntityPtr ent = NULL;
7337*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
7338*6777b538SAndroid Build Coastguard Worker xmlChar *val;
7339*6777b538SAndroid Build Coastguard Worker
7340*6777b538SAndroid Build Coastguard Worker if (RAW != '&')
7341*6777b538SAndroid Build Coastguard Worker return;
7342*6777b538SAndroid Build Coastguard Worker
7343*6777b538SAndroid Build Coastguard Worker /*
7344*6777b538SAndroid Build Coastguard Worker * Simple case of a CharRef
7345*6777b538SAndroid Build Coastguard Worker */
7346*6777b538SAndroid Build Coastguard Worker if (NXT(1) == '#') {
7347*6777b538SAndroid Build Coastguard Worker int i = 0;
7348*6777b538SAndroid Build Coastguard Worker xmlChar out[16];
7349*6777b538SAndroid Build Coastguard Worker int value = xmlParseCharRef(ctxt);
7350*6777b538SAndroid Build Coastguard Worker
7351*6777b538SAndroid Build Coastguard Worker if (value == 0)
7352*6777b538SAndroid Build Coastguard Worker return;
7353*6777b538SAndroid Build Coastguard Worker
7354*6777b538SAndroid Build Coastguard Worker /*
7355*6777b538SAndroid Build Coastguard Worker * Just encode the value in UTF-8
7356*6777b538SAndroid Build Coastguard Worker */
7357*6777b538SAndroid Build Coastguard Worker COPY_BUF(out, i, value);
7358*6777b538SAndroid Build Coastguard Worker out[i] = 0;
7359*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7360*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
7361*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData, out, i);
7362*6777b538SAndroid Build Coastguard Worker return;
7363*6777b538SAndroid Build Coastguard Worker }
7364*6777b538SAndroid Build Coastguard Worker
7365*6777b538SAndroid Build Coastguard Worker /*
7366*6777b538SAndroid Build Coastguard Worker * We are seeing an entity reference
7367*6777b538SAndroid Build Coastguard Worker */
7368*6777b538SAndroid Build Coastguard Worker name = xmlParseEntityRefInternal(ctxt);
7369*6777b538SAndroid Build Coastguard Worker if (name != NULL)
7370*6777b538SAndroid Build Coastguard Worker ent = xmlLookupGeneralEntity(ctxt, name, /* isAttr */ 0);
7371*6777b538SAndroid Build Coastguard Worker if (ent == NULL) return;
7372*6777b538SAndroid Build Coastguard Worker if (!ctxt->wellFormed)
7373*6777b538SAndroid Build Coastguard Worker return;
7374*6777b538SAndroid Build Coastguard Worker
7375*6777b538SAndroid Build Coastguard Worker /* special case of predefined entities */
7376*6777b538SAndroid Build Coastguard Worker if ((ent->name == NULL) ||
7377*6777b538SAndroid Build Coastguard Worker (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
7378*6777b538SAndroid Build Coastguard Worker val = ent->content;
7379*6777b538SAndroid Build Coastguard Worker if (val == NULL) return;
7380*6777b538SAndroid Build Coastguard Worker /*
7381*6777b538SAndroid Build Coastguard Worker * inline the entity.
7382*6777b538SAndroid Build Coastguard Worker */
7383*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7384*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
7385*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
7386*6777b538SAndroid Build Coastguard Worker return;
7387*6777b538SAndroid Build Coastguard Worker }
7388*6777b538SAndroid Build Coastguard Worker
7389*6777b538SAndroid Build Coastguard Worker /*
7390*6777b538SAndroid Build Coastguard Worker * The first reference to the entity trigger a parsing phase
7391*6777b538SAndroid Build Coastguard Worker * where the ent->children is filled with the result from
7392*6777b538SAndroid Build Coastguard Worker * the parsing.
7393*6777b538SAndroid Build Coastguard Worker * Note: external parsed entities will not be loaded, it is not
7394*6777b538SAndroid Build Coastguard Worker * required for a non-validating parser, unless the parsing option
7395*6777b538SAndroid Build Coastguard Worker * of validating, or substituting entities were given. Doing so is
7396*6777b538SAndroid Build Coastguard Worker * far more secure as the parser will only process data coming from
7397*6777b538SAndroid Build Coastguard Worker * the document entity by default.
7398*6777b538SAndroid Build Coastguard Worker *
7399*6777b538SAndroid Build Coastguard Worker * FIXME: This doesn't work correctly since entities can be
7400*6777b538SAndroid Build Coastguard Worker * expanded with different namespace declarations in scope.
7401*6777b538SAndroid Build Coastguard Worker * For example:
7402*6777b538SAndroid Build Coastguard Worker *
7403*6777b538SAndroid Build Coastguard Worker * <!DOCTYPE doc [
7404*6777b538SAndroid Build Coastguard Worker * <!ENTITY ent "<ns:elem/>">
7405*6777b538SAndroid Build Coastguard Worker * ]>
7406*6777b538SAndroid Build Coastguard Worker * <doc>
7407*6777b538SAndroid Build Coastguard Worker * <decl1 xmlns:ns="urn:ns1">
7408*6777b538SAndroid Build Coastguard Worker * &ent;
7409*6777b538SAndroid Build Coastguard Worker * </decl1>
7410*6777b538SAndroid Build Coastguard Worker * <decl2 xmlns:ns="urn:ns2">
7411*6777b538SAndroid Build Coastguard Worker * &ent;
7412*6777b538SAndroid Build Coastguard Worker * </decl2>
7413*6777b538SAndroid Build Coastguard Worker * </doc>
7414*6777b538SAndroid Build Coastguard Worker *
7415*6777b538SAndroid Build Coastguard Worker * Proposed fix:
7416*6777b538SAndroid Build Coastguard Worker *
7417*6777b538SAndroid Build Coastguard Worker * - Ignore current namespace declarations when parsing the
7418*6777b538SAndroid Build Coastguard Worker * entity. If a prefix can't be resolved, don't report an error
7419*6777b538SAndroid Build Coastguard Worker * but mark it as unresolved.
7420*6777b538SAndroid Build Coastguard Worker * - Try to resolve these prefixes when expanding the entity.
7421*6777b538SAndroid Build Coastguard Worker * This will require a specialized version of xmlStaticCopyNode
7422*6777b538SAndroid Build Coastguard Worker * which can also make use of the namespace hash table to avoid
7423*6777b538SAndroid Build Coastguard Worker * quadratic behavior.
7424*6777b538SAndroid Build Coastguard Worker *
7425*6777b538SAndroid Build Coastguard Worker * Alternatively, we could simply reparse the entity on each
7426*6777b538SAndroid Build Coastguard Worker * expansion like we already do with custom SAX callbacks.
7427*6777b538SAndroid Build Coastguard Worker * External entity content should be cached in this case.
7428*6777b538SAndroid Build Coastguard Worker */
7429*6777b538SAndroid Build Coastguard Worker if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
7430*6777b538SAndroid Build Coastguard Worker (((ctxt->options & XML_PARSE_NO_XXE) == 0) &&
7431*6777b538SAndroid Build Coastguard Worker ((ctxt->replaceEntities) ||
7432*6777b538SAndroid Build Coastguard Worker (ctxt->validate)))) {
7433*6777b538SAndroid Build Coastguard Worker if ((ent->flags & XML_ENT_PARSED) == 0) {
7434*6777b538SAndroid Build Coastguard Worker xmlCtxtParseEntity(ctxt, ent);
7435*6777b538SAndroid Build Coastguard Worker } else if (ent->children == NULL) {
7436*6777b538SAndroid Build Coastguard Worker /*
7437*6777b538SAndroid Build Coastguard Worker * Probably running in SAX mode and the callbacks don't
7438*6777b538SAndroid Build Coastguard Worker * build the entity content. Parse the entity again.
7439*6777b538SAndroid Build Coastguard Worker *
7440*6777b538SAndroid Build Coastguard Worker * This will also be triggered in normal tree builder mode
7441*6777b538SAndroid Build Coastguard Worker * if an entity happens to be empty, causing unnecessary
7442*6777b538SAndroid Build Coastguard Worker * reloads. It's hard to come up with a reliable check in
7443*6777b538SAndroid Build Coastguard Worker * which mode we're running.
7444*6777b538SAndroid Build Coastguard Worker */
7445*6777b538SAndroid Build Coastguard Worker xmlCtxtParseEntity(ctxt, ent);
7446*6777b538SAndroid Build Coastguard Worker }
7447*6777b538SAndroid Build Coastguard Worker }
7448*6777b538SAndroid Build Coastguard Worker
7449*6777b538SAndroid Build Coastguard Worker /*
7450*6777b538SAndroid Build Coastguard Worker * We also check for amplification if entities aren't substituted.
7451*6777b538SAndroid Build Coastguard Worker * They might be expanded later.
7452*6777b538SAndroid Build Coastguard Worker */
7453*6777b538SAndroid Build Coastguard Worker if (xmlParserEntityCheck(ctxt, ent->expandedSize))
7454*6777b538SAndroid Build Coastguard Worker return;
7455*6777b538SAndroid Build Coastguard Worker
7456*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax == NULL) || (ctxt->disableSAX))
7457*6777b538SAndroid Build Coastguard Worker return;
7458*6777b538SAndroid Build Coastguard Worker
7459*6777b538SAndroid Build Coastguard Worker if (ctxt->replaceEntities == 0) {
7460*6777b538SAndroid Build Coastguard Worker /*
7461*6777b538SAndroid Build Coastguard Worker * Create a reference
7462*6777b538SAndroid Build Coastguard Worker */
7463*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->reference != NULL)
7464*6777b538SAndroid Build Coastguard Worker ctxt->sax->reference(ctxt->userData, ent->name);
7465*6777b538SAndroid Build Coastguard Worker } else if ((ent->children != NULL) && (ctxt->node != NULL)) {
7466*6777b538SAndroid Build Coastguard Worker xmlNodePtr copy, cur;
7467*6777b538SAndroid Build Coastguard Worker
7468*6777b538SAndroid Build Coastguard Worker /*
7469*6777b538SAndroid Build Coastguard Worker * Seems we are generating the DOM content, copy the tree
7470*6777b538SAndroid Build Coastguard Worker */
7471*6777b538SAndroid Build Coastguard Worker cur = ent->children;
7472*6777b538SAndroid Build Coastguard Worker
7473*6777b538SAndroid Build Coastguard Worker /*
7474*6777b538SAndroid Build Coastguard Worker * Handle first text node with SAX to coalesce text efficiently
7475*6777b538SAndroid Build Coastguard Worker */
7476*6777b538SAndroid Build Coastguard Worker if ((cur->type == XML_TEXT_NODE) ||
7477*6777b538SAndroid Build Coastguard Worker (cur->type == XML_CDATA_SECTION_NODE)) {
7478*6777b538SAndroid Build Coastguard Worker int len = xmlStrlen(cur->content);
7479*6777b538SAndroid Build Coastguard Worker
7480*6777b538SAndroid Build Coastguard Worker if ((cur->type == XML_TEXT_NODE) ||
7481*6777b538SAndroid Build Coastguard Worker (ctxt->sax->cdataBlock == NULL)) {
7482*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->characters != NULL)
7483*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt, cur->content, len);
7484*6777b538SAndroid Build Coastguard Worker } else {
7485*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->cdataBlock != NULL)
7486*6777b538SAndroid Build Coastguard Worker ctxt->sax->cdataBlock(ctxt, cur->content, len);
7487*6777b538SAndroid Build Coastguard Worker }
7488*6777b538SAndroid Build Coastguard Worker
7489*6777b538SAndroid Build Coastguard Worker cur = cur->next;
7490*6777b538SAndroid Build Coastguard Worker }
7491*6777b538SAndroid Build Coastguard Worker
7492*6777b538SAndroid Build Coastguard Worker while (cur != NULL) {
7493*6777b538SAndroid Build Coastguard Worker xmlNodePtr last;
7494*6777b538SAndroid Build Coastguard Worker
7495*6777b538SAndroid Build Coastguard Worker /*
7496*6777b538SAndroid Build Coastguard Worker * Handle last text node with SAX to coalesce text efficiently
7497*6777b538SAndroid Build Coastguard Worker */
7498*6777b538SAndroid Build Coastguard Worker if ((cur->next == NULL) &&
7499*6777b538SAndroid Build Coastguard Worker ((cur->type == XML_TEXT_NODE) ||
7500*6777b538SAndroid Build Coastguard Worker (cur->type == XML_CDATA_SECTION_NODE))) {
7501*6777b538SAndroid Build Coastguard Worker int len = xmlStrlen(cur->content);
7502*6777b538SAndroid Build Coastguard Worker
7503*6777b538SAndroid Build Coastguard Worker if ((cur->type == XML_TEXT_NODE) ||
7504*6777b538SAndroid Build Coastguard Worker (ctxt->sax->cdataBlock == NULL)) {
7505*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->characters != NULL)
7506*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt, cur->content, len);
7507*6777b538SAndroid Build Coastguard Worker } else {
7508*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->cdataBlock != NULL)
7509*6777b538SAndroid Build Coastguard Worker ctxt->sax->cdataBlock(ctxt, cur->content, len);
7510*6777b538SAndroid Build Coastguard Worker }
7511*6777b538SAndroid Build Coastguard Worker
7512*6777b538SAndroid Build Coastguard Worker break;
7513*6777b538SAndroid Build Coastguard Worker }
7514*6777b538SAndroid Build Coastguard Worker
7515*6777b538SAndroid Build Coastguard Worker /*
7516*6777b538SAndroid Build Coastguard Worker * Reset coalesce buffer stats only for non-text nodes.
7517*6777b538SAndroid Build Coastguard Worker */
7518*6777b538SAndroid Build Coastguard Worker ctxt->nodemem = 0;
7519*6777b538SAndroid Build Coastguard Worker ctxt->nodelen = 0;
7520*6777b538SAndroid Build Coastguard Worker
7521*6777b538SAndroid Build Coastguard Worker copy = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7522*6777b538SAndroid Build Coastguard Worker
7523*6777b538SAndroid Build Coastguard Worker if (copy == NULL) {
7524*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
7525*6777b538SAndroid Build Coastguard Worker break;
7526*6777b538SAndroid Build Coastguard Worker }
7527*6777b538SAndroid Build Coastguard Worker
7528*6777b538SAndroid Build Coastguard Worker if (ctxt->parseMode == XML_PARSE_READER) {
7529*6777b538SAndroid Build Coastguard Worker /* Needed for reader */
7530*6777b538SAndroid Build Coastguard Worker copy->extra = cur->extra;
7531*6777b538SAndroid Build Coastguard Worker /* Maybe needed for reader */
7532*6777b538SAndroid Build Coastguard Worker copy->_private = cur->_private;
7533*6777b538SAndroid Build Coastguard Worker }
7534*6777b538SAndroid Build Coastguard Worker
7535*6777b538SAndroid Build Coastguard Worker copy->parent = ctxt->node;
7536*6777b538SAndroid Build Coastguard Worker last = ctxt->node->last;
7537*6777b538SAndroid Build Coastguard Worker if (last == NULL) {
7538*6777b538SAndroid Build Coastguard Worker ctxt->node->children = copy;
7539*6777b538SAndroid Build Coastguard Worker } else {
7540*6777b538SAndroid Build Coastguard Worker last->next = copy;
7541*6777b538SAndroid Build Coastguard Worker copy->prev = last;
7542*6777b538SAndroid Build Coastguard Worker }
7543*6777b538SAndroid Build Coastguard Worker ctxt->node->last = copy;
7544*6777b538SAndroid Build Coastguard Worker
7545*6777b538SAndroid Build Coastguard Worker cur = cur->next;
7546*6777b538SAndroid Build Coastguard Worker }
7547*6777b538SAndroid Build Coastguard Worker }
7548*6777b538SAndroid Build Coastguard Worker }
7549*6777b538SAndroid Build Coastguard Worker
7550*6777b538SAndroid Build Coastguard Worker static xmlEntityPtr
xmlLookupGeneralEntity(xmlParserCtxtPtr ctxt,const xmlChar * name,int inAttr)7551*6777b538SAndroid Build Coastguard Worker xmlLookupGeneralEntity(xmlParserCtxtPtr ctxt, const xmlChar *name, int inAttr) {
7552*6777b538SAndroid Build Coastguard Worker xmlEntityPtr ent;
7553*6777b538SAndroid Build Coastguard Worker
7554*6777b538SAndroid Build Coastguard Worker /*
7555*6777b538SAndroid Build Coastguard Worker * Predefined entities override any extra definition
7556*6777b538SAndroid Build Coastguard Worker */
7557*6777b538SAndroid Build Coastguard Worker if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7558*6777b538SAndroid Build Coastguard Worker ent = xmlGetPredefinedEntity(name);
7559*6777b538SAndroid Build Coastguard Worker if (ent != NULL)
7560*6777b538SAndroid Build Coastguard Worker return(ent);
7561*6777b538SAndroid Build Coastguard Worker }
7562*6777b538SAndroid Build Coastguard Worker
7563*6777b538SAndroid Build Coastguard Worker /*
7564*6777b538SAndroid Build Coastguard Worker * Ask first SAX for entity resolution, otherwise try the
7565*6777b538SAndroid Build Coastguard Worker * entities which may have stored in the parser context.
7566*6777b538SAndroid Build Coastguard Worker */
7567*6777b538SAndroid Build Coastguard Worker if (ctxt->sax != NULL) {
7568*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->getEntity != NULL)
7569*6777b538SAndroid Build Coastguard Worker ent = ctxt->sax->getEntity(ctxt->userData, name);
7570*6777b538SAndroid Build Coastguard Worker if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7571*6777b538SAndroid Build Coastguard Worker (ctxt->options & XML_PARSE_OLDSAX))
7572*6777b538SAndroid Build Coastguard Worker ent = xmlGetPredefinedEntity(name);
7573*6777b538SAndroid Build Coastguard Worker if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7574*6777b538SAndroid Build Coastguard Worker (ctxt->userData==ctxt)) {
7575*6777b538SAndroid Build Coastguard Worker ent = xmlSAX2GetEntity(ctxt, name);
7576*6777b538SAndroid Build Coastguard Worker }
7577*6777b538SAndroid Build Coastguard Worker }
7578*6777b538SAndroid Build Coastguard Worker /*
7579*6777b538SAndroid Build Coastguard Worker * [ WFC: Entity Declared ]
7580*6777b538SAndroid Build Coastguard Worker * In a document without any DTD, a document with only an
7581*6777b538SAndroid Build Coastguard Worker * internal DTD subset which contains no parameter entity
7582*6777b538SAndroid Build Coastguard Worker * references, or a document with "standalone='yes'", the
7583*6777b538SAndroid Build Coastguard Worker * Name given in the entity reference must match that in an
7584*6777b538SAndroid Build Coastguard Worker * entity declaration, except that well-formed documents
7585*6777b538SAndroid Build Coastguard Worker * need not declare any of the following entities: amp, lt,
7586*6777b538SAndroid Build Coastguard Worker * gt, apos, quot.
7587*6777b538SAndroid Build Coastguard Worker * The declaration of a parameter entity must precede any
7588*6777b538SAndroid Build Coastguard Worker * reference to it.
7589*6777b538SAndroid Build Coastguard Worker * Similarly, the declaration of a general entity must
7590*6777b538SAndroid Build Coastguard Worker * precede any reference to it which appears in a default
7591*6777b538SAndroid Build Coastguard Worker * value in an attribute-list declaration. Note that if
7592*6777b538SAndroid Build Coastguard Worker * entities are declared in the external subset or in
7593*6777b538SAndroid Build Coastguard Worker * external parameter entities, a non-validating processor
7594*6777b538SAndroid Build Coastguard Worker * is not obligated to read and process their declarations;
7595*6777b538SAndroid Build Coastguard Worker * for such documents, the rule that an entity must be
7596*6777b538SAndroid Build Coastguard Worker * declared is a well-formedness constraint only if
7597*6777b538SAndroid Build Coastguard Worker * standalone='yes'.
7598*6777b538SAndroid Build Coastguard Worker */
7599*6777b538SAndroid Build Coastguard Worker if (ent == NULL) {
7600*6777b538SAndroid Build Coastguard Worker if ((ctxt->standalone == 1) ||
7601*6777b538SAndroid Build Coastguard Worker ((ctxt->hasExternalSubset == 0) &&
7602*6777b538SAndroid Build Coastguard Worker (ctxt->hasPErefs == 0))) {
7603*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7604*6777b538SAndroid Build Coastguard Worker "Entity '%s' not defined\n", name);
7605*6777b538SAndroid Build Coastguard Worker } else {
7606*6777b538SAndroid Build Coastguard Worker xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7607*6777b538SAndroid Build Coastguard Worker "Entity '%s' not defined\n", name);
7608*6777b538SAndroid Build Coastguard Worker if ((ctxt->inSubset == 0) &&
7609*6777b538SAndroid Build Coastguard Worker (ctxt->sax != NULL) &&
7610*6777b538SAndroid Build Coastguard Worker (ctxt->disableSAX == 0) &&
7611*6777b538SAndroid Build Coastguard Worker (ctxt->sax->reference != NULL)) {
7612*6777b538SAndroid Build Coastguard Worker ctxt->sax->reference(ctxt->userData, name);
7613*6777b538SAndroid Build Coastguard Worker }
7614*6777b538SAndroid Build Coastguard Worker }
7615*6777b538SAndroid Build Coastguard Worker ctxt->valid = 0;
7616*6777b538SAndroid Build Coastguard Worker }
7617*6777b538SAndroid Build Coastguard Worker
7618*6777b538SAndroid Build Coastguard Worker /*
7619*6777b538SAndroid Build Coastguard Worker * [ WFC: Parsed Entity ]
7620*6777b538SAndroid Build Coastguard Worker * An entity reference must not contain the name of an
7621*6777b538SAndroid Build Coastguard Worker * unparsed entity
7622*6777b538SAndroid Build Coastguard Worker */
7623*6777b538SAndroid Build Coastguard Worker else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7624*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7625*6777b538SAndroid Build Coastguard Worker "Entity reference to unparsed entity %s\n", name);
7626*6777b538SAndroid Build Coastguard Worker ent = NULL;
7627*6777b538SAndroid Build Coastguard Worker }
7628*6777b538SAndroid Build Coastguard Worker
7629*6777b538SAndroid Build Coastguard Worker /*
7630*6777b538SAndroid Build Coastguard Worker * [ WFC: No External Entity References ]
7631*6777b538SAndroid Build Coastguard Worker * Attribute values cannot contain direct or indirect
7632*6777b538SAndroid Build Coastguard Worker * entity references to external entities.
7633*6777b538SAndroid Build Coastguard Worker */
7634*6777b538SAndroid Build Coastguard Worker else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7635*6777b538SAndroid Build Coastguard Worker if (inAttr) {
7636*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7637*6777b538SAndroid Build Coastguard Worker "Attribute references external entity '%s'\n", name);
7638*6777b538SAndroid Build Coastguard Worker ent = NULL;
7639*6777b538SAndroid Build Coastguard Worker }
7640*6777b538SAndroid Build Coastguard Worker }
7641*6777b538SAndroid Build Coastguard Worker
7642*6777b538SAndroid Build Coastguard Worker return(ent);
7643*6777b538SAndroid Build Coastguard Worker }
7644*6777b538SAndroid Build Coastguard Worker
7645*6777b538SAndroid Build Coastguard Worker /**
7646*6777b538SAndroid Build Coastguard Worker * xmlParseEntityRefInternal:
7647*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
7648*6777b538SAndroid Build Coastguard Worker * @inAttr: whether we are in an attribute value
7649*6777b538SAndroid Build Coastguard Worker *
7650*6777b538SAndroid Build Coastguard Worker * Parse an entity reference. Always consumes '&'.
7651*6777b538SAndroid Build Coastguard Worker *
7652*6777b538SAndroid Build Coastguard Worker * [68] EntityRef ::= '&' Name ';'
7653*6777b538SAndroid Build Coastguard Worker *
7654*6777b538SAndroid Build Coastguard Worker * Returns the name, or NULL in case of error.
7655*6777b538SAndroid Build Coastguard Worker */
7656*6777b538SAndroid Build Coastguard Worker static const xmlChar *
xmlParseEntityRefInternal(xmlParserCtxtPtr ctxt)7657*6777b538SAndroid Build Coastguard Worker xmlParseEntityRefInternal(xmlParserCtxtPtr ctxt) {
7658*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
7659*6777b538SAndroid Build Coastguard Worker
7660*6777b538SAndroid Build Coastguard Worker GROW;
7661*6777b538SAndroid Build Coastguard Worker
7662*6777b538SAndroid Build Coastguard Worker if (RAW != '&')
7663*6777b538SAndroid Build Coastguard Worker return(NULL);
7664*6777b538SAndroid Build Coastguard Worker NEXT;
7665*6777b538SAndroid Build Coastguard Worker name = xmlParseName(ctxt);
7666*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
7667*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7668*6777b538SAndroid Build Coastguard Worker "xmlParseEntityRef: no name\n");
7669*6777b538SAndroid Build Coastguard Worker return(NULL);
7670*6777b538SAndroid Build Coastguard Worker }
7671*6777b538SAndroid Build Coastguard Worker if (RAW != ';') {
7672*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7673*6777b538SAndroid Build Coastguard Worker return(NULL);
7674*6777b538SAndroid Build Coastguard Worker }
7675*6777b538SAndroid Build Coastguard Worker NEXT;
7676*6777b538SAndroid Build Coastguard Worker
7677*6777b538SAndroid Build Coastguard Worker return(name);
7678*6777b538SAndroid Build Coastguard Worker }
7679*6777b538SAndroid Build Coastguard Worker
7680*6777b538SAndroid Build Coastguard Worker /**
7681*6777b538SAndroid Build Coastguard Worker * xmlParseEntityRef:
7682*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
7683*6777b538SAndroid Build Coastguard Worker *
7684*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
7685*6777b538SAndroid Build Coastguard Worker *
7686*6777b538SAndroid Build Coastguard Worker * Returns the xmlEntityPtr if found, or NULL otherwise.
7687*6777b538SAndroid Build Coastguard Worker */
7688*6777b538SAndroid Build Coastguard Worker xmlEntityPtr
xmlParseEntityRef(xmlParserCtxtPtr ctxt)7689*6777b538SAndroid Build Coastguard Worker xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
7690*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
7691*6777b538SAndroid Build Coastguard Worker
7692*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
7693*6777b538SAndroid Build Coastguard Worker return(NULL);
7694*6777b538SAndroid Build Coastguard Worker
7695*6777b538SAndroid Build Coastguard Worker name = xmlParseEntityRefInternal(ctxt);
7696*6777b538SAndroid Build Coastguard Worker if (name == NULL)
7697*6777b538SAndroid Build Coastguard Worker return(NULL);
7698*6777b538SAndroid Build Coastguard Worker
7699*6777b538SAndroid Build Coastguard Worker return(xmlLookupGeneralEntity(ctxt, name, /* inAttr */ 0));
7700*6777b538SAndroid Build Coastguard Worker }
7701*6777b538SAndroid Build Coastguard Worker
7702*6777b538SAndroid Build Coastguard Worker /**
7703*6777b538SAndroid Build Coastguard Worker * xmlParseStringEntityRef:
7704*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
7705*6777b538SAndroid Build Coastguard Worker * @str: a pointer to an index in the string
7706*6777b538SAndroid Build Coastguard Worker *
7707*6777b538SAndroid Build Coastguard Worker * parse ENTITY references declarations, but this version parses it from
7708*6777b538SAndroid Build Coastguard Worker * a string value.
7709*6777b538SAndroid Build Coastguard Worker *
7710*6777b538SAndroid Build Coastguard Worker * [68] EntityRef ::= '&' Name ';'
7711*6777b538SAndroid Build Coastguard Worker *
7712*6777b538SAndroid Build Coastguard Worker * [ WFC: Entity Declared ]
7713*6777b538SAndroid Build Coastguard Worker * In a document without any DTD, a document with only an internal DTD
7714*6777b538SAndroid Build Coastguard Worker * subset which contains no parameter entity references, or a document
7715*6777b538SAndroid Build Coastguard Worker * with "standalone='yes'", the Name given in the entity reference
7716*6777b538SAndroid Build Coastguard Worker * must match that in an entity declaration, except that well-formed
7717*6777b538SAndroid Build Coastguard Worker * documents need not declare any of the following entities: amp, lt,
7718*6777b538SAndroid Build Coastguard Worker * gt, apos, quot. The declaration of a parameter entity must precede
7719*6777b538SAndroid Build Coastguard Worker * any reference to it. Similarly, the declaration of a general entity
7720*6777b538SAndroid Build Coastguard Worker * must precede any reference to it which appears in a default value in an
7721*6777b538SAndroid Build Coastguard Worker * attribute-list declaration. Note that if entities are declared in the
7722*6777b538SAndroid Build Coastguard Worker * external subset or in external parameter entities, a non-validating
7723*6777b538SAndroid Build Coastguard Worker * processor is not obligated to read and process their declarations;
7724*6777b538SAndroid Build Coastguard Worker * for such documents, the rule that an entity must be declared is a
7725*6777b538SAndroid Build Coastguard Worker * well-formedness constraint only if standalone='yes'.
7726*6777b538SAndroid Build Coastguard Worker *
7727*6777b538SAndroid Build Coastguard Worker * [ WFC: Parsed Entity ]
7728*6777b538SAndroid Build Coastguard Worker * An entity reference must not contain the name of an unparsed entity
7729*6777b538SAndroid Build Coastguard Worker *
7730*6777b538SAndroid Build Coastguard Worker * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
7731*6777b538SAndroid Build Coastguard Worker * is updated to the current location in the string.
7732*6777b538SAndroid Build Coastguard Worker */
7733*6777b538SAndroid Build Coastguard Worker static xmlChar *
xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,const xmlChar ** str)7734*6777b538SAndroid Build Coastguard Worker xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
7735*6777b538SAndroid Build Coastguard Worker xmlChar *name;
7736*6777b538SAndroid Build Coastguard Worker const xmlChar *ptr;
7737*6777b538SAndroid Build Coastguard Worker xmlChar cur;
7738*6777b538SAndroid Build Coastguard Worker
7739*6777b538SAndroid Build Coastguard Worker if ((str == NULL) || (*str == NULL))
7740*6777b538SAndroid Build Coastguard Worker return(NULL);
7741*6777b538SAndroid Build Coastguard Worker ptr = *str;
7742*6777b538SAndroid Build Coastguard Worker cur = *ptr;
7743*6777b538SAndroid Build Coastguard Worker if (cur != '&')
7744*6777b538SAndroid Build Coastguard Worker return(NULL);
7745*6777b538SAndroid Build Coastguard Worker
7746*6777b538SAndroid Build Coastguard Worker ptr++;
7747*6777b538SAndroid Build Coastguard Worker name = xmlParseStringName(ctxt, &ptr);
7748*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
7749*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7750*6777b538SAndroid Build Coastguard Worker "xmlParseStringEntityRef: no name\n");
7751*6777b538SAndroid Build Coastguard Worker *str = ptr;
7752*6777b538SAndroid Build Coastguard Worker return(NULL);
7753*6777b538SAndroid Build Coastguard Worker }
7754*6777b538SAndroid Build Coastguard Worker if (*ptr != ';') {
7755*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7756*6777b538SAndroid Build Coastguard Worker xmlFree(name);
7757*6777b538SAndroid Build Coastguard Worker *str = ptr;
7758*6777b538SAndroid Build Coastguard Worker return(NULL);
7759*6777b538SAndroid Build Coastguard Worker }
7760*6777b538SAndroid Build Coastguard Worker ptr++;
7761*6777b538SAndroid Build Coastguard Worker
7762*6777b538SAndroid Build Coastguard Worker *str = ptr;
7763*6777b538SAndroid Build Coastguard Worker return(name);
7764*6777b538SAndroid Build Coastguard Worker }
7765*6777b538SAndroid Build Coastguard Worker
7766*6777b538SAndroid Build Coastguard Worker /**
7767*6777b538SAndroid Build Coastguard Worker * xmlParsePEReference:
7768*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
7769*6777b538SAndroid Build Coastguard Worker *
7770*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
7771*6777b538SAndroid Build Coastguard Worker *
7772*6777b538SAndroid Build Coastguard Worker * Parse a parameter entity reference. Always consumes '%'.
7773*6777b538SAndroid Build Coastguard Worker *
7774*6777b538SAndroid Build Coastguard Worker * The entity content is handled directly by pushing it's content as
7775*6777b538SAndroid Build Coastguard Worker * a new input stream.
7776*6777b538SAndroid Build Coastguard Worker *
7777*6777b538SAndroid Build Coastguard Worker * [69] PEReference ::= '%' Name ';'
7778*6777b538SAndroid Build Coastguard Worker *
7779*6777b538SAndroid Build Coastguard Worker * [ WFC: No Recursion ]
7780*6777b538SAndroid Build Coastguard Worker * A parsed entity must not contain a recursive
7781*6777b538SAndroid Build Coastguard Worker * reference to itself, either directly or indirectly.
7782*6777b538SAndroid Build Coastguard Worker *
7783*6777b538SAndroid Build Coastguard Worker * [ WFC: Entity Declared ]
7784*6777b538SAndroid Build Coastguard Worker * In a document without any DTD, a document with only an internal DTD
7785*6777b538SAndroid Build Coastguard Worker * subset which contains no parameter entity references, or a document
7786*6777b538SAndroid Build Coastguard Worker * with "standalone='yes'", ... ... The declaration of a parameter
7787*6777b538SAndroid Build Coastguard Worker * entity must precede any reference to it...
7788*6777b538SAndroid Build Coastguard Worker *
7789*6777b538SAndroid Build Coastguard Worker * [ VC: Entity Declared ]
7790*6777b538SAndroid Build Coastguard Worker * In a document with an external subset or external parameter entities
7791*6777b538SAndroid Build Coastguard Worker * with "standalone='no'", ... ... The declaration of a parameter entity
7792*6777b538SAndroid Build Coastguard Worker * must precede any reference to it...
7793*6777b538SAndroid Build Coastguard Worker *
7794*6777b538SAndroid Build Coastguard Worker * [ WFC: In DTD ]
7795*6777b538SAndroid Build Coastguard Worker * Parameter-entity references may only appear in the DTD.
7796*6777b538SAndroid Build Coastguard Worker * NOTE: misleading but this is handled.
7797*6777b538SAndroid Build Coastguard Worker */
7798*6777b538SAndroid Build Coastguard Worker void
xmlParsePEReference(xmlParserCtxtPtr ctxt)7799*6777b538SAndroid Build Coastguard Worker xmlParsePEReference(xmlParserCtxtPtr ctxt)
7800*6777b538SAndroid Build Coastguard Worker {
7801*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
7802*6777b538SAndroid Build Coastguard Worker xmlEntityPtr entity = NULL;
7803*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
7804*6777b538SAndroid Build Coastguard Worker
7805*6777b538SAndroid Build Coastguard Worker if (RAW != '%')
7806*6777b538SAndroid Build Coastguard Worker return;
7807*6777b538SAndroid Build Coastguard Worker NEXT;
7808*6777b538SAndroid Build Coastguard Worker name = xmlParseName(ctxt);
7809*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
7810*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_PEREF_NO_NAME, "PEReference: no name\n");
7811*6777b538SAndroid Build Coastguard Worker return;
7812*6777b538SAndroid Build Coastguard Worker }
7813*6777b538SAndroid Build Coastguard Worker if (RAW != ';') {
7814*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
7815*6777b538SAndroid Build Coastguard Worker return;
7816*6777b538SAndroid Build Coastguard Worker }
7817*6777b538SAndroid Build Coastguard Worker
7818*6777b538SAndroid Build Coastguard Worker NEXT;
7819*6777b538SAndroid Build Coastguard Worker
7820*6777b538SAndroid Build Coastguard Worker /*
7821*6777b538SAndroid Build Coastguard Worker * Request the entity from SAX
7822*6777b538SAndroid Build Coastguard Worker */
7823*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
7824*6777b538SAndroid Build Coastguard Worker (ctxt->sax->getParameterEntity != NULL))
7825*6777b538SAndroid Build Coastguard Worker entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
7826*6777b538SAndroid Build Coastguard Worker if (entity == NULL) {
7827*6777b538SAndroid Build Coastguard Worker /*
7828*6777b538SAndroid Build Coastguard Worker * [ WFC: Entity Declared ]
7829*6777b538SAndroid Build Coastguard Worker * In a document without any DTD, a document with only an
7830*6777b538SAndroid Build Coastguard Worker * internal DTD subset which contains no parameter entity
7831*6777b538SAndroid Build Coastguard Worker * references, or a document with "standalone='yes'", ...
7832*6777b538SAndroid Build Coastguard Worker * ... The declaration of a parameter entity must precede
7833*6777b538SAndroid Build Coastguard Worker * any reference to it...
7834*6777b538SAndroid Build Coastguard Worker */
7835*6777b538SAndroid Build Coastguard Worker if ((ctxt->standalone == 1) ||
7836*6777b538SAndroid Build Coastguard Worker ((ctxt->hasExternalSubset == 0) &&
7837*6777b538SAndroid Build Coastguard Worker (ctxt->hasPErefs == 0))) {
7838*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7839*6777b538SAndroid Build Coastguard Worker "PEReference: %%%s; not found\n",
7840*6777b538SAndroid Build Coastguard Worker name);
7841*6777b538SAndroid Build Coastguard Worker } else {
7842*6777b538SAndroid Build Coastguard Worker /*
7843*6777b538SAndroid Build Coastguard Worker * [ VC: Entity Declared ]
7844*6777b538SAndroid Build Coastguard Worker * In a document with an external subset or external
7845*6777b538SAndroid Build Coastguard Worker * parameter entities with "standalone='no'", ...
7846*6777b538SAndroid Build Coastguard Worker * ... The declaration of a parameter entity must
7847*6777b538SAndroid Build Coastguard Worker * precede any reference to it...
7848*6777b538SAndroid Build Coastguard Worker */
7849*6777b538SAndroid Build Coastguard Worker if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
7850*6777b538SAndroid Build Coastguard Worker xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
7851*6777b538SAndroid Build Coastguard Worker "PEReference: %%%s; not found\n",
7852*6777b538SAndroid Build Coastguard Worker name, NULL);
7853*6777b538SAndroid Build Coastguard Worker } else
7854*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7855*6777b538SAndroid Build Coastguard Worker "PEReference: %%%s; not found\n",
7856*6777b538SAndroid Build Coastguard Worker name, NULL);
7857*6777b538SAndroid Build Coastguard Worker ctxt->valid = 0;
7858*6777b538SAndroid Build Coastguard Worker }
7859*6777b538SAndroid Build Coastguard Worker } else {
7860*6777b538SAndroid Build Coastguard Worker /*
7861*6777b538SAndroid Build Coastguard Worker * Internal checking in case the entity quest barfed
7862*6777b538SAndroid Build Coastguard Worker */
7863*6777b538SAndroid Build Coastguard Worker if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
7864*6777b538SAndroid Build Coastguard Worker (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
7865*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7866*6777b538SAndroid Build Coastguard Worker "Internal: %%%s; is not a parameter entity\n",
7867*6777b538SAndroid Build Coastguard Worker name, NULL);
7868*6777b538SAndroid Build Coastguard Worker } else {
7869*6777b538SAndroid Build Coastguard Worker if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
7870*6777b538SAndroid Build Coastguard Worker ((ctxt->options & XML_PARSE_NO_XXE) ||
7871*6777b538SAndroid Build Coastguard Worker ((ctxt->loadsubset == 0) &&
7872*6777b538SAndroid Build Coastguard Worker (ctxt->replaceEntities == 0) &&
7873*6777b538SAndroid Build Coastguard Worker (ctxt->validate == 0))))
7874*6777b538SAndroid Build Coastguard Worker return;
7875*6777b538SAndroid Build Coastguard Worker
7876*6777b538SAndroid Build Coastguard Worker if (entity->flags & XML_ENT_EXPANDING) {
7877*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7878*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
7879*6777b538SAndroid Build Coastguard Worker return;
7880*6777b538SAndroid Build Coastguard Worker }
7881*6777b538SAndroid Build Coastguard Worker
7882*6777b538SAndroid Build Coastguard Worker input = xmlNewEntityInputStream(ctxt, entity);
7883*6777b538SAndroid Build Coastguard Worker if (xmlPushInput(ctxt, input) < 0) {
7884*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(input);
7885*6777b538SAndroid Build Coastguard Worker return;
7886*6777b538SAndroid Build Coastguard Worker }
7887*6777b538SAndroid Build Coastguard Worker
7888*6777b538SAndroid Build Coastguard Worker entity->flags |= XML_ENT_EXPANDING;
7889*6777b538SAndroid Build Coastguard Worker
7890*6777b538SAndroid Build Coastguard Worker if (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) {
7891*6777b538SAndroid Build Coastguard Worker xmlDetectEncoding(ctxt);
7892*6777b538SAndroid Build Coastguard Worker
7893*6777b538SAndroid Build Coastguard Worker if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
7894*6777b538SAndroid Build Coastguard Worker (IS_BLANK_CH(NXT(5)))) {
7895*6777b538SAndroid Build Coastguard Worker xmlParseTextDecl(ctxt);
7896*6777b538SAndroid Build Coastguard Worker }
7897*6777b538SAndroid Build Coastguard Worker }
7898*6777b538SAndroid Build Coastguard Worker }
7899*6777b538SAndroid Build Coastguard Worker }
7900*6777b538SAndroid Build Coastguard Worker ctxt->hasPErefs = 1;
7901*6777b538SAndroid Build Coastguard Worker }
7902*6777b538SAndroid Build Coastguard Worker
7903*6777b538SAndroid Build Coastguard Worker /**
7904*6777b538SAndroid Build Coastguard Worker * xmlLoadEntityContent:
7905*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
7906*6777b538SAndroid Build Coastguard Worker * @entity: an unloaded system entity
7907*6777b538SAndroid Build Coastguard Worker *
7908*6777b538SAndroid Build Coastguard Worker * Load the original content of the given system entity from the
7909*6777b538SAndroid Build Coastguard Worker * ExternalID/SystemID given. This is to be used for Included in Literal
7910*6777b538SAndroid Build Coastguard Worker * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
7911*6777b538SAndroid Build Coastguard Worker *
7912*6777b538SAndroid Build Coastguard Worker * Returns 0 in case of success and -1 in case of failure
7913*6777b538SAndroid Build Coastguard Worker */
7914*6777b538SAndroid Build Coastguard Worker static int
xmlLoadEntityContent(xmlParserCtxtPtr ctxt,xmlEntityPtr entity)7915*6777b538SAndroid Build Coastguard Worker xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
7916*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr oldinput, input = NULL;
7917*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr *oldinputTab;
7918*6777b538SAndroid Build Coastguard Worker const xmlChar *oldencoding;
7919*6777b538SAndroid Build Coastguard Worker xmlChar *content = NULL;
7920*6777b538SAndroid Build Coastguard Worker size_t length, i;
7921*6777b538SAndroid Build Coastguard Worker int oldinputNr, oldinputMax;
7922*6777b538SAndroid Build Coastguard Worker int ret = -1;
7923*6777b538SAndroid Build Coastguard Worker int res;
7924*6777b538SAndroid Build Coastguard Worker
7925*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (entity == NULL) ||
7926*6777b538SAndroid Build Coastguard Worker ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
7927*6777b538SAndroid Build Coastguard Worker (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
7928*6777b538SAndroid Build Coastguard Worker (entity->content != NULL)) {
7929*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ARGUMENT,
7930*6777b538SAndroid Build Coastguard Worker "xmlLoadEntityContent parameter error");
7931*6777b538SAndroid Build Coastguard Worker return(-1);
7932*6777b538SAndroid Build Coastguard Worker }
7933*6777b538SAndroid Build Coastguard Worker
7934*6777b538SAndroid Build Coastguard Worker input = xmlLoadExternalEntity((char *) entity->URI,
7935*6777b538SAndroid Build Coastguard Worker (char *) entity->ExternalID, ctxt);
7936*6777b538SAndroid Build Coastguard Worker if (input == NULL)
7937*6777b538SAndroid Build Coastguard Worker return(-1);
7938*6777b538SAndroid Build Coastguard Worker
7939*6777b538SAndroid Build Coastguard Worker oldinput = ctxt->input;
7940*6777b538SAndroid Build Coastguard Worker oldinputNr = ctxt->inputNr;
7941*6777b538SAndroid Build Coastguard Worker oldinputMax = ctxt->inputMax;
7942*6777b538SAndroid Build Coastguard Worker oldinputTab = ctxt->inputTab;
7943*6777b538SAndroid Build Coastguard Worker oldencoding = ctxt->encoding;
7944*6777b538SAndroid Build Coastguard Worker
7945*6777b538SAndroid Build Coastguard Worker ctxt->input = NULL;
7946*6777b538SAndroid Build Coastguard Worker ctxt->inputNr = 0;
7947*6777b538SAndroid Build Coastguard Worker ctxt->inputMax = 1;
7948*6777b538SAndroid Build Coastguard Worker ctxt->encoding = NULL;
7949*6777b538SAndroid Build Coastguard Worker ctxt->inputTab = xmlMalloc(sizeof(xmlParserInputPtr));
7950*6777b538SAndroid Build Coastguard Worker if (ctxt->inputTab == NULL) {
7951*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
7952*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(input);
7953*6777b538SAndroid Build Coastguard Worker goto error;
7954*6777b538SAndroid Build Coastguard Worker }
7955*6777b538SAndroid Build Coastguard Worker
7956*6777b538SAndroid Build Coastguard Worker xmlBufResetInput(input->buf->buffer, input);
7957*6777b538SAndroid Build Coastguard Worker
7958*6777b538SAndroid Build Coastguard Worker inputPush(ctxt, input);
7959*6777b538SAndroid Build Coastguard Worker
7960*6777b538SAndroid Build Coastguard Worker xmlDetectEncoding(ctxt);
7961*6777b538SAndroid Build Coastguard Worker
7962*6777b538SAndroid Build Coastguard Worker /*
7963*6777b538SAndroid Build Coastguard Worker * Parse a possible text declaration first
7964*6777b538SAndroid Build Coastguard Worker */
7965*6777b538SAndroid Build Coastguard Worker if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
7966*6777b538SAndroid Build Coastguard Worker xmlParseTextDecl(ctxt);
7967*6777b538SAndroid Build Coastguard Worker /*
7968*6777b538SAndroid Build Coastguard Worker * An XML-1.0 document can't reference an entity not XML-1.0
7969*6777b538SAndroid Build Coastguard Worker */
7970*6777b538SAndroid Build Coastguard Worker if ((xmlStrEqual(ctxt->version, BAD_CAST "1.0")) &&
7971*6777b538SAndroid Build Coastguard Worker (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
7972*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
7973*6777b538SAndroid Build Coastguard Worker "Version mismatch between document and entity\n");
7974*6777b538SAndroid Build Coastguard Worker }
7975*6777b538SAndroid Build Coastguard Worker }
7976*6777b538SAndroid Build Coastguard Worker
7977*6777b538SAndroid Build Coastguard Worker length = input->cur - input->base;
7978*6777b538SAndroid Build Coastguard Worker xmlBufShrink(input->buf->buffer, length);
7979*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(&ctxt->sizeentities, length);
7980*6777b538SAndroid Build Coastguard Worker
7981*6777b538SAndroid Build Coastguard Worker while ((res = xmlParserInputBufferGrow(input->buf, 4096)) > 0)
7982*6777b538SAndroid Build Coastguard Worker ;
7983*6777b538SAndroid Build Coastguard Worker
7984*6777b538SAndroid Build Coastguard Worker xmlBufResetInput(input->buf->buffer, input);
7985*6777b538SAndroid Build Coastguard Worker
7986*6777b538SAndroid Build Coastguard Worker if (res < 0) {
7987*6777b538SAndroid Build Coastguard Worker xmlCtxtErrIO(ctxt, input->buf->error, NULL);
7988*6777b538SAndroid Build Coastguard Worker goto error;
7989*6777b538SAndroid Build Coastguard Worker }
7990*6777b538SAndroid Build Coastguard Worker
7991*6777b538SAndroid Build Coastguard Worker length = xmlBufUse(input->buf->buffer);
7992*6777b538SAndroid Build Coastguard Worker content = xmlBufDetach(input->buf->buffer);
7993*6777b538SAndroid Build Coastguard Worker
7994*6777b538SAndroid Build Coastguard Worker if (length > INT_MAX) {
7995*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
7996*6777b538SAndroid Build Coastguard Worker goto error;
7997*6777b538SAndroid Build Coastguard Worker }
7998*6777b538SAndroid Build Coastguard Worker
7999*6777b538SAndroid Build Coastguard Worker for (i = 0; i < length; ) {
8000*6777b538SAndroid Build Coastguard Worker int clen = length - i;
8001*6777b538SAndroid Build Coastguard Worker int c = xmlGetUTF8Char(content + i, &clen);
8002*6777b538SAndroid Build Coastguard Worker
8003*6777b538SAndroid Build Coastguard Worker if ((c < 0) || (!IS_CHAR(c))) {
8004*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
8005*6777b538SAndroid Build Coastguard Worker "xmlLoadEntityContent: invalid char value %d\n",
8006*6777b538SAndroid Build Coastguard Worker content[i]);
8007*6777b538SAndroid Build Coastguard Worker goto error;
8008*6777b538SAndroid Build Coastguard Worker }
8009*6777b538SAndroid Build Coastguard Worker i += clen;
8010*6777b538SAndroid Build Coastguard Worker }
8011*6777b538SAndroid Build Coastguard Worker
8012*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(&ctxt->sizeentities, length);
8013*6777b538SAndroid Build Coastguard Worker entity->content = content;
8014*6777b538SAndroid Build Coastguard Worker entity->length = length;
8015*6777b538SAndroid Build Coastguard Worker content = NULL;
8016*6777b538SAndroid Build Coastguard Worker ret = 0;
8017*6777b538SAndroid Build Coastguard Worker
8018*6777b538SAndroid Build Coastguard Worker error:
8019*6777b538SAndroid Build Coastguard Worker while (ctxt->inputNr > 0)
8020*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(inputPop(ctxt));
8021*6777b538SAndroid Build Coastguard Worker xmlFree(ctxt->inputTab);
8022*6777b538SAndroid Build Coastguard Worker xmlFree((xmlChar *) ctxt->encoding);
8023*6777b538SAndroid Build Coastguard Worker
8024*6777b538SAndroid Build Coastguard Worker ctxt->input = oldinput;
8025*6777b538SAndroid Build Coastguard Worker ctxt->inputNr = oldinputNr;
8026*6777b538SAndroid Build Coastguard Worker ctxt->inputMax = oldinputMax;
8027*6777b538SAndroid Build Coastguard Worker ctxt->inputTab = oldinputTab;
8028*6777b538SAndroid Build Coastguard Worker ctxt->encoding = oldencoding;
8029*6777b538SAndroid Build Coastguard Worker
8030*6777b538SAndroid Build Coastguard Worker xmlFree(content);
8031*6777b538SAndroid Build Coastguard Worker
8032*6777b538SAndroid Build Coastguard Worker return(ret);
8033*6777b538SAndroid Build Coastguard Worker }
8034*6777b538SAndroid Build Coastguard Worker
8035*6777b538SAndroid Build Coastguard Worker /**
8036*6777b538SAndroid Build Coastguard Worker * xmlParseStringPEReference:
8037*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8038*6777b538SAndroid Build Coastguard Worker * @str: a pointer to an index in the string
8039*6777b538SAndroid Build Coastguard Worker *
8040*6777b538SAndroid Build Coastguard Worker * parse PEReference declarations
8041*6777b538SAndroid Build Coastguard Worker *
8042*6777b538SAndroid Build Coastguard Worker * [69] PEReference ::= '%' Name ';'
8043*6777b538SAndroid Build Coastguard Worker *
8044*6777b538SAndroid Build Coastguard Worker * [ WFC: No Recursion ]
8045*6777b538SAndroid Build Coastguard Worker * A parsed entity must not contain a recursive
8046*6777b538SAndroid Build Coastguard Worker * reference to itself, either directly or indirectly.
8047*6777b538SAndroid Build Coastguard Worker *
8048*6777b538SAndroid Build Coastguard Worker * [ WFC: Entity Declared ]
8049*6777b538SAndroid Build Coastguard Worker * In a document without any DTD, a document with only an internal DTD
8050*6777b538SAndroid Build Coastguard Worker * subset which contains no parameter entity references, or a document
8051*6777b538SAndroid Build Coastguard Worker * with "standalone='yes'", ... ... The declaration of a parameter
8052*6777b538SAndroid Build Coastguard Worker * entity must precede any reference to it...
8053*6777b538SAndroid Build Coastguard Worker *
8054*6777b538SAndroid Build Coastguard Worker * [ VC: Entity Declared ]
8055*6777b538SAndroid Build Coastguard Worker * In a document with an external subset or external parameter entities
8056*6777b538SAndroid Build Coastguard Worker * with "standalone='no'", ... ... The declaration of a parameter entity
8057*6777b538SAndroid Build Coastguard Worker * must precede any reference to it...
8058*6777b538SAndroid Build Coastguard Worker *
8059*6777b538SAndroid Build Coastguard Worker * [ WFC: In DTD ]
8060*6777b538SAndroid Build Coastguard Worker * Parameter-entity references may only appear in the DTD.
8061*6777b538SAndroid Build Coastguard Worker * NOTE: misleading but this is handled.
8062*6777b538SAndroid Build Coastguard Worker *
8063*6777b538SAndroid Build Coastguard Worker * Returns the string of the entity content.
8064*6777b538SAndroid Build Coastguard Worker * str is updated to the current value of the index
8065*6777b538SAndroid Build Coastguard Worker */
8066*6777b538SAndroid Build Coastguard Worker static xmlEntityPtr
xmlParseStringPEReference(xmlParserCtxtPtr ctxt,const xmlChar ** str)8067*6777b538SAndroid Build Coastguard Worker xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
8068*6777b538SAndroid Build Coastguard Worker const xmlChar *ptr;
8069*6777b538SAndroid Build Coastguard Worker xmlChar cur;
8070*6777b538SAndroid Build Coastguard Worker xmlChar *name;
8071*6777b538SAndroid Build Coastguard Worker xmlEntityPtr entity = NULL;
8072*6777b538SAndroid Build Coastguard Worker
8073*6777b538SAndroid Build Coastguard Worker if ((str == NULL) || (*str == NULL)) return(NULL);
8074*6777b538SAndroid Build Coastguard Worker ptr = *str;
8075*6777b538SAndroid Build Coastguard Worker cur = *ptr;
8076*6777b538SAndroid Build Coastguard Worker if (cur != '%')
8077*6777b538SAndroid Build Coastguard Worker return(NULL);
8078*6777b538SAndroid Build Coastguard Worker ptr++;
8079*6777b538SAndroid Build Coastguard Worker name = xmlParseStringName(ctxt, &ptr);
8080*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
8081*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8082*6777b538SAndroid Build Coastguard Worker "xmlParseStringPEReference: no name\n");
8083*6777b538SAndroid Build Coastguard Worker *str = ptr;
8084*6777b538SAndroid Build Coastguard Worker return(NULL);
8085*6777b538SAndroid Build Coastguard Worker }
8086*6777b538SAndroid Build Coastguard Worker cur = *ptr;
8087*6777b538SAndroid Build Coastguard Worker if (cur != ';') {
8088*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
8089*6777b538SAndroid Build Coastguard Worker xmlFree(name);
8090*6777b538SAndroid Build Coastguard Worker *str = ptr;
8091*6777b538SAndroid Build Coastguard Worker return(NULL);
8092*6777b538SAndroid Build Coastguard Worker }
8093*6777b538SAndroid Build Coastguard Worker ptr++;
8094*6777b538SAndroid Build Coastguard Worker
8095*6777b538SAndroid Build Coastguard Worker /*
8096*6777b538SAndroid Build Coastguard Worker * Request the entity from SAX
8097*6777b538SAndroid Build Coastguard Worker */
8098*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
8099*6777b538SAndroid Build Coastguard Worker (ctxt->sax->getParameterEntity != NULL))
8100*6777b538SAndroid Build Coastguard Worker entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
8101*6777b538SAndroid Build Coastguard Worker if (entity == NULL) {
8102*6777b538SAndroid Build Coastguard Worker /*
8103*6777b538SAndroid Build Coastguard Worker * [ WFC: Entity Declared ]
8104*6777b538SAndroid Build Coastguard Worker * In a document without any DTD, a document with only an
8105*6777b538SAndroid Build Coastguard Worker * internal DTD subset which contains no parameter entity
8106*6777b538SAndroid Build Coastguard Worker * references, or a document with "standalone='yes'", ...
8107*6777b538SAndroid Build Coastguard Worker * ... The declaration of a parameter entity must precede
8108*6777b538SAndroid Build Coastguard Worker * any reference to it...
8109*6777b538SAndroid Build Coastguard Worker */
8110*6777b538SAndroid Build Coastguard Worker if ((ctxt->standalone == 1) ||
8111*6777b538SAndroid Build Coastguard Worker ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
8112*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
8113*6777b538SAndroid Build Coastguard Worker "PEReference: %%%s; not found\n", name);
8114*6777b538SAndroid Build Coastguard Worker } else {
8115*6777b538SAndroid Build Coastguard Worker /*
8116*6777b538SAndroid Build Coastguard Worker * [ VC: Entity Declared ]
8117*6777b538SAndroid Build Coastguard Worker * In a document with an external subset or external
8118*6777b538SAndroid Build Coastguard Worker * parameter entities with "standalone='no'", ...
8119*6777b538SAndroid Build Coastguard Worker * ... The declaration of a parameter entity must
8120*6777b538SAndroid Build Coastguard Worker * precede any reference to it...
8121*6777b538SAndroid Build Coastguard Worker */
8122*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8123*6777b538SAndroid Build Coastguard Worker "PEReference: %%%s; not found\n",
8124*6777b538SAndroid Build Coastguard Worker name, NULL);
8125*6777b538SAndroid Build Coastguard Worker ctxt->valid = 0;
8126*6777b538SAndroid Build Coastguard Worker }
8127*6777b538SAndroid Build Coastguard Worker } else {
8128*6777b538SAndroid Build Coastguard Worker /*
8129*6777b538SAndroid Build Coastguard Worker * Internal checking in case the entity quest barfed
8130*6777b538SAndroid Build Coastguard Worker */
8131*6777b538SAndroid Build Coastguard Worker if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
8132*6777b538SAndroid Build Coastguard Worker (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
8133*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8134*6777b538SAndroid Build Coastguard Worker "%%%s; is not a parameter entity\n",
8135*6777b538SAndroid Build Coastguard Worker name, NULL);
8136*6777b538SAndroid Build Coastguard Worker }
8137*6777b538SAndroid Build Coastguard Worker }
8138*6777b538SAndroid Build Coastguard Worker ctxt->hasPErefs = 1;
8139*6777b538SAndroid Build Coastguard Worker xmlFree(name);
8140*6777b538SAndroid Build Coastguard Worker *str = ptr;
8141*6777b538SAndroid Build Coastguard Worker return(entity);
8142*6777b538SAndroid Build Coastguard Worker }
8143*6777b538SAndroid Build Coastguard Worker
8144*6777b538SAndroid Build Coastguard Worker /**
8145*6777b538SAndroid Build Coastguard Worker * xmlParseDocTypeDecl:
8146*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8147*6777b538SAndroid Build Coastguard Worker *
8148*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
8149*6777b538SAndroid Build Coastguard Worker *
8150*6777b538SAndroid Build Coastguard Worker * parse a DOCTYPE declaration
8151*6777b538SAndroid Build Coastguard Worker *
8152*6777b538SAndroid Build Coastguard Worker * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
8153*6777b538SAndroid Build Coastguard Worker * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8154*6777b538SAndroid Build Coastguard Worker *
8155*6777b538SAndroid Build Coastguard Worker * [ VC: Root Element Type ]
8156*6777b538SAndroid Build Coastguard Worker * The Name in the document type declaration must match the element
8157*6777b538SAndroid Build Coastguard Worker * type of the root element.
8158*6777b538SAndroid Build Coastguard Worker */
8159*6777b538SAndroid Build Coastguard Worker
8160*6777b538SAndroid Build Coastguard Worker void
xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt)8161*6777b538SAndroid Build Coastguard Worker xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
8162*6777b538SAndroid Build Coastguard Worker const xmlChar *name = NULL;
8163*6777b538SAndroid Build Coastguard Worker xmlChar *ExternalID = NULL;
8164*6777b538SAndroid Build Coastguard Worker xmlChar *URI = NULL;
8165*6777b538SAndroid Build Coastguard Worker
8166*6777b538SAndroid Build Coastguard Worker /*
8167*6777b538SAndroid Build Coastguard Worker * We know that '<!DOCTYPE' has been detected.
8168*6777b538SAndroid Build Coastguard Worker */
8169*6777b538SAndroid Build Coastguard Worker SKIP(9);
8170*6777b538SAndroid Build Coastguard Worker
8171*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8172*6777b538SAndroid Build Coastguard Worker
8173*6777b538SAndroid Build Coastguard Worker /*
8174*6777b538SAndroid Build Coastguard Worker * Parse the DOCTYPE name.
8175*6777b538SAndroid Build Coastguard Worker */
8176*6777b538SAndroid Build Coastguard Worker name = xmlParseName(ctxt);
8177*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
8178*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8179*6777b538SAndroid Build Coastguard Worker "xmlParseDocTypeDecl : no DOCTYPE name !\n");
8180*6777b538SAndroid Build Coastguard Worker }
8181*6777b538SAndroid Build Coastguard Worker ctxt->intSubName = name;
8182*6777b538SAndroid Build Coastguard Worker
8183*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8184*6777b538SAndroid Build Coastguard Worker
8185*6777b538SAndroid Build Coastguard Worker /*
8186*6777b538SAndroid Build Coastguard Worker * Check for SystemID and ExternalID
8187*6777b538SAndroid Build Coastguard Worker */
8188*6777b538SAndroid Build Coastguard Worker URI = xmlParseExternalID(ctxt, &ExternalID, 1);
8189*6777b538SAndroid Build Coastguard Worker
8190*6777b538SAndroid Build Coastguard Worker if ((URI != NULL) || (ExternalID != NULL)) {
8191*6777b538SAndroid Build Coastguard Worker ctxt->hasExternalSubset = 1;
8192*6777b538SAndroid Build Coastguard Worker }
8193*6777b538SAndroid Build Coastguard Worker ctxt->extSubURI = URI;
8194*6777b538SAndroid Build Coastguard Worker ctxt->extSubSystem = ExternalID;
8195*6777b538SAndroid Build Coastguard Worker
8196*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8197*6777b538SAndroid Build Coastguard Worker
8198*6777b538SAndroid Build Coastguard Worker /*
8199*6777b538SAndroid Build Coastguard Worker * Create and update the internal subset.
8200*6777b538SAndroid Build Coastguard Worker */
8201*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
8202*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
8203*6777b538SAndroid Build Coastguard Worker ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
8204*6777b538SAndroid Build Coastguard Worker
8205*6777b538SAndroid Build Coastguard Worker /*
8206*6777b538SAndroid Build Coastguard Worker * Is there any internal subset declarations ?
8207*6777b538SAndroid Build Coastguard Worker * they are handled separately in xmlParseInternalSubset()
8208*6777b538SAndroid Build Coastguard Worker */
8209*6777b538SAndroid Build Coastguard Worker if (RAW == '[')
8210*6777b538SAndroid Build Coastguard Worker return;
8211*6777b538SAndroid Build Coastguard Worker
8212*6777b538SAndroid Build Coastguard Worker /*
8213*6777b538SAndroid Build Coastguard Worker * We should be at the end of the DOCTYPE declaration.
8214*6777b538SAndroid Build Coastguard Worker */
8215*6777b538SAndroid Build Coastguard Worker if (RAW != '>') {
8216*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8217*6777b538SAndroid Build Coastguard Worker }
8218*6777b538SAndroid Build Coastguard Worker NEXT;
8219*6777b538SAndroid Build Coastguard Worker }
8220*6777b538SAndroid Build Coastguard Worker
8221*6777b538SAndroid Build Coastguard Worker /**
8222*6777b538SAndroid Build Coastguard Worker * xmlParseInternalSubset:
8223*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8224*6777b538SAndroid Build Coastguard Worker *
8225*6777b538SAndroid Build Coastguard Worker * parse the internal subset declaration
8226*6777b538SAndroid Build Coastguard Worker *
8227*6777b538SAndroid Build Coastguard Worker * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8228*6777b538SAndroid Build Coastguard Worker */
8229*6777b538SAndroid Build Coastguard Worker
8230*6777b538SAndroid Build Coastguard Worker static void
xmlParseInternalSubset(xmlParserCtxtPtr ctxt)8231*6777b538SAndroid Build Coastguard Worker xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
8232*6777b538SAndroid Build Coastguard Worker /*
8233*6777b538SAndroid Build Coastguard Worker * Is there any DTD definition ?
8234*6777b538SAndroid Build Coastguard Worker */
8235*6777b538SAndroid Build Coastguard Worker if (RAW == '[') {
8236*6777b538SAndroid Build Coastguard Worker int oldInputNr = ctxt->inputNr;
8237*6777b538SAndroid Build Coastguard Worker
8238*6777b538SAndroid Build Coastguard Worker NEXT;
8239*6777b538SAndroid Build Coastguard Worker /*
8240*6777b538SAndroid Build Coastguard Worker * Parse the succession of Markup declarations and
8241*6777b538SAndroid Build Coastguard Worker * PEReferences.
8242*6777b538SAndroid Build Coastguard Worker * Subsequence (markupdecl | PEReference | S)*
8243*6777b538SAndroid Build Coastguard Worker */
8244*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8245*6777b538SAndroid Build Coastguard Worker while (((RAW != ']') || (ctxt->inputNr > oldInputNr)) &&
8246*6777b538SAndroid Build Coastguard Worker (PARSER_STOPPED(ctxt) == 0)) {
8247*6777b538SAndroid Build Coastguard Worker
8248*6777b538SAndroid Build Coastguard Worker /*
8249*6777b538SAndroid Build Coastguard Worker * Conditional sections are allowed from external entities included
8250*6777b538SAndroid Build Coastguard Worker * by PE References in the internal subset.
8251*6777b538SAndroid Build Coastguard Worker */
8252*6777b538SAndroid Build Coastguard Worker if ((PARSER_EXTERNAL(ctxt)) &&
8253*6777b538SAndroid Build Coastguard Worker (RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
8254*6777b538SAndroid Build Coastguard Worker xmlParseConditionalSections(ctxt);
8255*6777b538SAndroid Build Coastguard Worker } else if ((RAW == '<') && ((NXT(1) == '!') || (NXT(1) == '?'))) {
8256*6777b538SAndroid Build Coastguard Worker xmlParseMarkupDecl(ctxt);
8257*6777b538SAndroid Build Coastguard Worker } else if (RAW == '%') {
8258*6777b538SAndroid Build Coastguard Worker xmlParsePEReference(ctxt);
8259*6777b538SAndroid Build Coastguard Worker } else {
8260*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_INT_SUBSET_NOT_FINISHED, NULL);
8261*6777b538SAndroid Build Coastguard Worker break;
8262*6777b538SAndroid Build Coastguard Worker }
8263*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS_PE;
8264*6777b538SAndroid Build Coastguard Worker SHRINK;
8265*6777b538SAndroid Build Coastguard Worker GROW;
8266*6777b538SAndroid Build Coastguard Worker }
8267*6777b538SAndroid Build Coastguard Worker
8268*6777b538SAndroid Build Coastguard Worker while (ctxt->inputNr > oldInputNr)
8269*6777b538SAndroid Build Coastguard Worker xmlPopPE(ctxt);
8270*6777b538SAndroid Build Coastguard Worker
8271*6777b538SAndroid Build Coastguard Worker if (RAW == ']') {
8272*6777b538SAndroid Build Coastguard Worker NEXT;
8273*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8274*6777b538SAndroid Build Coastguard Worker }
8275*6777b538SAndroid Build Coastguard Worker }
8276*6777b538SAndroid Build Coastguard Worker
8277*6777b538SAndroid Build Coastguard Worker /*
8278*6777b538SAndroid Build Coastguard Worker * We should be at the end of the DOCTYPE declaration.
8279*6777b538SAndroid Build Coastguard Worker */
8280*6777b538SAndroid Build Coastguard Worker if ((ctxt->wellFormed) && (RAW != '>')) {
8281*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8282*6777b538SAndroid Build Coastguard Worker return;
8283*6777b538SAndroid Build Coastguard Worker }
8284*6777b538SAndroid Build Coastguard Worker NEXT;
8285*6777b538SAndroid Build Coastguard Worker }
8286*6777b538SAndroid Build Coastguard Worker
8287*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
8288*6777b538SAndroid Build Coastguard Worker /**
8289*6777b538SAndroid Build Coastguard Worker * xmlParseAttribute:
8290*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8291*6777b538SAndroid Build Coastguard Worker * @value: a xmlChar ** used to store the value of the attribute
8292*6777b538SAndroid Build Coastguard Worker *
8293*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
8294*6777b538SAndroid Build Coastguard Worker *
8295*6777b538SAndroid Build Coastguard Worker * parse an attribute
8296*6777b538SAndroid Build Coastguard Worker *
8297*6777b538SAndroid Build Coastguard Worker * [41] Attribute ::= Name Eq AttValue
8298*6777b538SAndroid Build Coastguard Worker *
8299*6777b538SAndroid Build Coastguard Worker * [ WFC: No External Entity References ]
8300*6777b538SAndroid Build Coastguard Worker * Attribute values cannot contain direct or indirect entity references
8301*6777b538SAndroid Build Coastguard Worker * to external entities.
8302*6777b538SAndroid Build Coastguard Worker *
8303*6777b538SAndroid Build Coastguard Worker * [ WFC: No < in Attribute Values ]
8304*6777b538SAndroid Build Coastguard Worker * The replacement text of any entity referred to directly or indirectly in
8305*6777b538SAndroid Build Coastguard Worker * an attribute value (other than "<") must not contain a <.
8306*6777b538SAndroid Build Coastguard Worker *
8307*6777b538SAndroid Build Coastguard Worker * [ VC: Attribute Value Type ]
8308*6777b538SAndroid Build Coastguard Worker * The attribute must have been declared; the value must be of the type
8309*6777b538SAndroid Build Coastguard Worker * declared for it.
8310*6777b538SAndroid Build Coastguard Worker *
8311*6777b538SAndroid Build Coastguard Worker * [25] Eq ::= S? '=' S?
8312*6777b538SAndroid Build Coastguard Worker *
8313*6777b538SAndroid Build Coastguard Worker * With namespace:
8314*6777b538SAndroid Build Coastguard Worker *
8315*6777b538SAndroid Build Coastguard Worker * [NS 11] Attribute ::= QName Eq AttValue
8316*6777b538SAndroid Build Coastguard Worker *
8317*6777b538SAndroid Build Coastguard Worker * Also the case QName == xmlns:??? is handled independently as a namespace
8318*6777b538SAndroid Build Coastguard Worker * definition.
8319*6777b538SAndroid Build Coastguard Worker *
8320*6777b538SAndroid Build Coastguard Worker * Returns the attribute name, and the value in *value.
8321*6777b538SAndroid Build Coastguard Worker */
8322*6777b538SAndroid Build Coastguard Worker
8323*6777b538SAndroid Build Coastguard Worker const xmlChar *
xmlParseAttribute(xmlParserCtxtPtr ctxt,xmlChar ** value)8324*6777b538SAndroid Build Coastguard Worker xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
8325*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
8326*6777b538SAndroid Build Coastguard Worker xmlChar *val;
8327*6777b538SAndroid Build Coastguard Worker
8328*6777b538SAndroid Build Coastguard Worker *value = NULL;
8329*6777b538SAndroid Build Coastguard Worker GROW;
8330*6777b538SAndroid Build Coastguard Worker name = xmlParseName(ctxt);
8331*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
8332*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8333*6777b538SAndroid Build Coastguard Worker "error parsing attribute name\n");
8334*6777b538SAndroid Build Coastguard Worker return(NULL);
8335*6777b538SAndroid Build Coastguard Worker }
8336*6777b538SAndroid Build Coastguard Worker
8337*6777b538SAndroid Build Coastguard Worker /*
8338*6777b538SAndroid Build Coastguard Worker * read the value
8339*6777b538SAndroid Build Coastguard Worker */
8340*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8341*6777b538SAndroid Build Coastguard Worker if (RAW == '=') {
8342*6777b538SAndroid Build Coastguard Worker NEXT;
8343*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8344*6777b538SAndroid Build Coastguard Worker val = xmlParseAttValue(ctxt);
8345*6777b538SAndroid Build Coastguard Worker } else {
8346*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8347*6777b538SAndroid Build Coastguard Worker "Specification mandates value for attribute %s\n", name);
8348*6777b538SAndroid Build Coastguard Worker return(name);
8349*6777b538SAndroid Build Coastguard Worker }
8350*6777b538SAndroid Build Coastguard Worker
8351*6777b538SAndroid Build Coastguard Worker /*
8352*6777b538SAndroid Build Coastguard Worker * Check that xml:lang conforms to the specification
8353*6777b538SAndroid Build Coastguard Worker * No more registered as an error, just generate a warning now
8354*6777b538SAndroid Build Coastguard Worker * since this was deprecated in XML second edition
8355*6777b538SAndroid Build Coastguard Worker */
8356*6777b538SAndroid Build Coastguard Worker if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
8357*6777b538SAndroid Build Coastguard Worker if (!xmlCheckLanguageID(val)) {
8358*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
8359*6777b538SAndroid Build Coastguard Worker "Malformed value for xml:lang : %s\n",
8360*6777b538SAndroid Build Coastguard Worker val, NULL);
8361*6777b538SAndroid Build Coastguard Worker }
8362*6777b538SAndroid Build Coastguard Worker }
8363*6777b538SAndroid Build Coastguard Worker
8364*6777b538SAndroid Build Coastguard Worker /*
8365*6777b538SAndroid Build Coastguard Worker * Check that xml:space conforms to the specification
8366*6777b538SAndroid Build Coastguard Worker */
8367*6777b538SAndroid Build Coastguard Worker if (xmlStrEqual(name, BAD_CAST "xml:space")) {
8368*6777b538SAndroid Build Coastguard Worker if (xmlStrEqual(val, BAD_CAST "default"))
8369*6777b538SAndroid Build Coastguard Worker *(ctxt->space) = 0;
8370*6777b538SAndroid Build Coastguard Worker else if (xmlStrEqual(val, BAD_CAST "preserve"))
8371*6777b538SAndroid Build Coastguard Worker *(ctxt->space) = 1;
8372*6777b538SAndroid Build Coastguard Worker else {
8373*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
8374*6777b538SAndroid Build Coastguard Worker "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
8375*6777b538SAndroid Build Coastguard Worker val, NULL);
8376*6777b538SAndroid Build Coastguard Worker }
8377*6777b538SAndroid Build Coastguard Worker }
8378*6777b538SAndroid Build Coastguard Worker
8379*6777b538SAndroid Build Coastguard Worker *value = val;
8380*6777b538SAndroid Build Coastguard Worker return(name);
8381*6777b538SAndroid Build Coastguard Worker }
8382*6777b538SAndroid Build Coastguard Worker
8383*6777b538SAndroid Build Coastguard Worker /**
8384*6777b538SAndroid Build Coastguard Worker * xmlParseStartTag:
8385*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8386*6777b538SAndroid Build Coastguard Worker *
8387*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
8388*6777b538SAndroid Build Coastguard Worker *
8389*6777b538SAndroid Build Coastguard Worker * Parse a start tag. Always consumes '<'.
8390*6777b538SAndroid Build Coastguard Worker *
8391*6777b538SAndroid Build Coastguard Worker * [40] STag ::= '<' Name (S Attribute)* S? '>'
8392*6777b538SAndroid Build Coastguard Worker *
8393*6777b538SAndroid Build Coastguard Worker * [ WFC: Unique Att Spec ]
8394*6777b538SAndroid Build Coastguard Worker * No attribute name may appear more than once in the same start-tag or
8395*6777b538SAndroid Build Coastguard Worker * empty-element tag.
8396*6777b538SAndroid Build Coastguard Worker *
8397*6777b538SAndroid Build Coastguard Worker * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
8398*6777b538SAndroid Build Coastguard Worker *
8399*6777b538SAndroid Build Coastguard Worker * [ WFC: Unique Att Spec ]
8400*6777b538SAndroid Build Coastguard Worker * No attribute name may appear more than once in the same start-tag or
8401*6777b538SAndroid Build Coastguard Worker * empty-element tag.
8402*6777b538SAndroid Build Coastguard Worker *
8403*6777b538SAndroid Build Coastguard Worker * With namespace:
8404*6777b538SAndroid Build Coastguard Worker *
8405*6777b538SAndroid Build Coastguard Worker * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
8406*6777b538SAndroid Build Coastguard Worker *
8407*6777b538SAndroid Build Coastguard Worker * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
8408*6777b538SAndroid Build Coastguard Worker *
8409*6777b538SAndroid Build Coastguard Worker * Returns the element name parsed
8410*6777b538SAndroid Build Coastguard Worker */
8411*6777b538SAndroid Build Coastguard Worker
8412*6777b538SAndroid Build Coastguard Worker const xmlChar *
xmlParseStartTag(xmlParserCtxtPtr ctxt)8413*6777b538SAndroid Build Coastguard Worker xmlParseStartTag(xmlParserCtxtPtr ctxt) {
8414*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
8415*6777b538SAndroid Build Coastguard Worker const xmlChar *attname;
8416*6777b538SAndroid Build Coastguard Worker xmlChar *attvalue;
8417*6777b538SAndroid Build Coastguard Worker const xmlChar **atts = ctxt->atts;
8418*6777b538SAndroid Build Coastguard Worker int nbatts = 0;
8419*6777b538SAndroid Build Coastguard Worker int maxatts = ctxt->maxatts;
8420*6777b538SAndroid Build Coastguard Worker int i;
8421*6777b538SAndroid Build Coastguard Worker
8422*6777b538SAndroid Build Coastguard Worker if (RAW != '<') return(NULL);
8423*6777b538SAndroid Build Coastguard Worker NEXT1;
8424*6777b538SAndroid Build Coastguard Worker
8425*6777b538SAndroid Build Coastguard Worker name = xmlParseName(ctxt);
8426*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
8427*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8428*6777b538SAndroid Build Coastguard Worker "xmlParseStartTag: invalid element name\n");
8429*6777b538SAndroid Build Coastguard Worker return(NULL);
8430*6777b538SAndroid Build Coastguard Worker }
8431*6777b538SAndroid Build Coastguard Worker
8432*6777b538SAndroid Build Coastguard Worker /*
8433*6777b538SAndroid Build Coastguard Worker * Now parse the attributes, it ends up with the ending
8434*6777b538SAndroid Build Coastguard Worker *
8435*6777b538SAndroid Build Coastguard Worker * (S Attribute)* S?
8436*6777b538SAndroid Build Coastguard Worker */
8437*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8438*6777b538SAndroid Build Coastguard Worker GROW;
8439*6777b538SAndroid Build Coastguard Worker
8440*6777b538SAndroid Build Coastguard Worker while (((RAW != '>') &&
8441*6777b538SAndroid Build Coastguard Worker ((RAW != '/') || (NXT(1) != '>')) &&
8442*6777b538SAndroid Build Coastguard Worker (IS_BYTE_CHAR(RAW))) && (PARSER_STOPPED(ctxt) == 0)) {
8443*6777b538SAndroid Build Coastguard Worker attname = xmlParseAttribute(ctxt, &attvalue);
8444*6777b538SAndroid Build Coastguard Worker if (attname == NULL)
8445*6777b538SAndroid Build Coastguard Worker break;
8446*6777b538SAndroid Build Coastguard Worker if (attvalue != NULL) {
8447*6777b538SAndroid Build Coastguard Worker /*
8448*6777b538SAndroid Build Coastguard Worker * [ WFC: Unique Att Spec ]
8449*6777b538SAndroid Build Coastguard Worker * No attribute name may appear more than once in the same
8450*6777b538SAndroid Build Coastguard Worker * start-tag or empty-element tag.
8451*6777b538SAndroid Build Coastguard Worker */
8452*6777b538SAndroid Build Coastguard Worker for (i = 0; i < nbatts;i += 2) {
8453*6777b538SAndroid Build Coastguard Worker if (xmlStrEqual(atts[i], attname)) {
8454*6777b538SAndroid Build Coastguard Worker xmlErrAttributeDup(ctxt, NULL, attname);
8455*6777b538SAndroid Build Coastguard Worker xmlFree(attvalue);
8456*6777b538SAndroid Build Coastguard Worker goto failed;
8457*6777b538SAndroid Build Coastguard Worker }
8458*6777b538SAndroid Build Coastguard Worker }
8459*6777b538SAndroid Build Coastguard Worker /*
8460*6777b538SAndroid Build Coastguard Worker * Add the pair to atts
8461*6777b538SAndroid Build Coastguard Worker */
8462*6777b538SAndroid Build Coastguard Worker if (atts == NULL) {
8463*6777b538SAndroid Build Coastguard Worker maxatts = 22; /* allow for 10 attrs by default */
8464*6777b538SAndroid Build Coastguard Worker atts = (const xmlChar **)
8465*6777b538SAndroid Build Coastguard Worker xmlMalloc(maxatts * sizeof(xmlChar *));
8466*6777b538SAndroid Build Coastguard Worker if (atts == NULL) {
8467*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
8468*6777b538SAndroid Build Coastguard Worker if (attvalue != NULL)
8469*6777b538SAndroid Build Coastguard Worker xmlFree(attvalue);
8470*6777b538SAndroid Build Coastguard Worker goto failed;
8471*6777b538SAndroid Build Coastguard Worker }
8472*6777b538SAndroid Build Coastguard Worker ctxt->atts = atts;
8473*6777b538SAndroid Build Coastguard Worker ctxt->maxatts = maxatts;
8474*6777b538SAndroid Build Coastguard Worker } else if (nbatts + 4 > maxatts) {
8475*6777b538SAndroid Build Coastguard Worker const xmlChar **n;
8476*6777b538SAndroid Build Coastguard Worker
8477*6777b538SAndroid Build Coastguard Worker maxatts *= 2;
8478*6777b538SAndroid Build Coastguard Worker n = (const xmlChar **) xmlRealloc((void *) atts,
8479*6777b538SAndroid Build Coastguard Worker maxatts * sizeof(const xmlChar *));
8480*6777b538SAndroid Build Coastguard Worker if (n == NULL) {
8481*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
8482*6777b538SAndroid Build Coastguard Worker if (attvalue != NULL)
8483*6777b538SAndroid Build Coastguard Worker xmlFree(attvalue);
8484*6777b538SAndroid Build Coastguard Worker goto failed;
8485*6777b538SAndroid Build Coastguard Worker }
8486*6777b538SAndroid Build Coastguard Worker atts = n;
8487*6777b538SAndroid Build Coastguard Worker ctxt->atts = atts;
8488*6777b538SAndroid Build Coastguard Worker ctxt->maxatts = maxatts;
8489*6777b538SAndroid Build Coastguard Worker }
8490*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = attname;
8491*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = attvalue;
8492*6777b538SAndroid Build Coastguard Worker atts[nbatts] = NULL;
8493*6777b538SAndroid Build Coastguard Worker atts[nbatts + 1] = NULL;
8494*6777b538SAndroid Build Coastguard Worker } else {
8495*6777b538SAndroid Build Coastguard Worker if (attvalue != NULL)
8496*6777b538SAndroid Build Coastguard Worker xmlFree(attvalue);
8497*6777b538SAndroid Build Coastguard Worker }
8498*6777b538SAndroid Build Coastguard Worker
8499*6777b538SAndroid Build Coastguard Worker failed:
8500*6777b538SAndroid Build Coastguard Worker
8501*6777b538SAndroid Build Coastguard Worker GROW
8502*6777b538SAndroid Build Coastguard Worker if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
8503*6777b538SAndroid Build Coastguard Worker break;
8504*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS == 0) {
8505*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
8506*6777b538SAndroid Build Coastguard Worker "attributes construct error\n");
8507*6777b538SAndroid Build Coastguard Worker }
8508*6777b538SAndroid Build Coastguard Worker SHRINK;
8509*6777b538SAndroid Build Coastguard Worker GROW;
8510*6777b538SAndroid Build Coastguard Worker }
8511*6777b538SAndroid Build Coastguard Worker
8512*6777b538SAndroid Build Coastguard Worker /*
8513*6777b538SAndroid Build Coastguard Worker * SAX: Start of Element !
8514*6777b538SAndroid Build Coastguard Worker */
8515*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
8516*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX)) {
8517*6777b538SAndroid Build Coastguard Worker if (nbatts > 0)
8518*6777b538SAndroid Build Coastguard Worker ctxt->sax->startElement(ctxt->userData, name, atts);
8519*6777b538SAndroid Build Coastguard Worker else
8520*6777b538SAndroid Build Coastguard Worker ctxt->sax->startElement(ctxt->userData, name, NULL);
8521*6777b538SAndroid Build Coastguard Worker }
8522*6777b538SAndroid Build Coastguard Worker
8523*6777b538SAndroid Build Coastguard Worker if (atts != NULL) {
8524*6777b538SAndroid Build Coastguard Worker /* Free only the content strings */
8525*6777b538SAndroid Build Coastguard Worker for (i = 1;i < nbatts;i+=2)
8526*6777b538SAndroid Build Coastguard Worker if (atts[i] != NULL)
8527*6777b538SAndroid Build Coastguard Worker xmlFree((xmlChar *) atts[i]);
8528*6777b538SAndroid Build Coastguard Worker }
8529*6777b538SAndroid Build Coastguard Worker return(name);
8530*6777b538SAndroid Build Coastguard Worker }
8531*6777b538SAndroid Build Coastguard Worker
8532*6777b538SAndroid Build Coastguard Worker /**
8533*6777b538SAndroid Build Coastguard Worker * xmlParseEndTag1:
8534*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8535*6777b538SAndroid Build Coastguard Worker * @line: line of the start tag
8536*6777b538SAndroid Build Coastguard Worker * @nsNr: number of namespaces on the start tag
8537*6777b538SAndroid Build Coastguard Worker *
8538*6777b538SAndroid Build Coastguard Worker * Parse an end tag. Always consumes '</'.
8539*6777b538SAndroid Build Coastguard Worker *
8540*6777b538SAndroid Build Coastguard Worker * [42] ETag ::= '</' Name S? '>'
8541*6777b538SAndroid Build Coastguard Worker *
8542*6777b538SAndroid Build Coastguard Worker * With namespace
8543*6777b538SAndroid Build Coastguard Worker *
8544*6777b538SAndroid Build Coastguard Worker * [NS 9] ETag ::= '</' QName S? '>'
8545*6777b538SAndroid Build Coastguard Worker */
8546*6777b538SAndroid Build Coastguard Worker
8547*6777b538SAndroid Build Coastguard Worker static void
xmlParseEndTag1(xmlParserCtxtPtr ctxt,int line)8548*6777b538SAndroid Build Coastguard Worker xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
8549*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
8550*6777b538SAndroid Build Coastguard Worker
8551*6777b538SAndroid Build Coastguard Worker GROW;
8552*6777b538SAndroid Build Coastguard Worker if ((RAW != '<') || (NXT(1) != '/')) {
8553*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
8554*6777b538SAndroid Build Coastguard Worker "xmlParseEndTag: '</' not found\n");
8555*6777b538SAndroid Build Coastguard Worker return;
8556*6777b538SAndroid Build Coastguard Worker }
8557*6777b538SAndroid Build Coastguard Worker SKIP(2);
8558*6777b538SAndroid Build Coastguard Worker
8559*6777b538SAndroid Build Coastguard Worker name = xmlParseNameAndCompare(ctxt,ctxt->name);
8560*6777b538SAndroid Build Coastguard Worker
8561*6777b538SAndroid Build Coastguard Worker /*
8562*6777b538SAndroid Build Coastguard Worker * We should definitely be at the ending "S? '>'" part
8563*6777b538SAndroid Build Coastguard Worker */
8564*6777b538SAndroid Build Coastguard Worker GROW;
8565*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8566*6777b538SAndroid Build Coastguard Worker if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
8567*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
8568*6777b538SAndroid Build Coastguard Worker } else
8569*6777b538SAndroid Build Coastguard Worker NEXT1;
8570*6777b538SAndroid Build Coastguard Worker
8571*6777b538SAndroid Build Coastguard Worker /*
8572*6777b538SAndroid Build Coastguard Worker * [ WFC: Element Type Match ]
8573*6777b538SAndroid Build Coastguard Worker * The Name in an element's end-tag must match the element type in the
8574*6777b538SAndroid Build Coastguard Worker * start-tag.
8575*6777b538SAndroid Build Coastguard Worker *
8576*6777b538SAndroid Build Coastguard Worker */
8577*6777b538SAndroid Build Coastguard Worker if (name != (xmlChar*)1) {
8578*6777b538SAndroid Build Coastguard Worker if (name == NULL) name = BAD_CAST "unparsable";
8579*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
8580*6777b538SAndroid Build Coastguard Worker "Opening and ending tag mismatch: %s line %d and %s\n",
8581*6777b538SAndroid Build Coastguard Worker ctxt->name, line, name);
8582*6777b538SAndroid Build Coastguard Worker }
8583*6777b538SAndroid Build Coastguard Worker
8584*6777b538SAndroid Build Coastguard Worker /*
8585*6777b538SAndroid Build Coastguard Worker * SAX: End of Tag
8586*6777b538SAndroid Build Coastguard Worker */
8587*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
8588*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
8589*6777b538SAndroid Build Coastguard Worker ctxt->sax->endElement(ctxt->userData, ctxt->name);
8590*6777b538SAndroid Build Coastguard Worker
8591*6777b538SAndroid Build Coastguard Worker namePop(ctxt);
8592*6777b538SAndroid Build Coastguard Worker spacePop(ctxt);
8593*6777b538SAndroid Build Coastguard Worker return;
8594*6777b538SAndroid Build Coastguard Worker }
8595*6777b538SAndroid Build Coastguard Worker
8596*6777b538SAndroid Build Coastguard Worker /**
8597*6777b538SAndroid Build Coastguard Worker * xmlParseEndTag:
8598*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8599*6777b538SAndroid Build Coastguard Worker *
8600*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
8601*6777b538SAndroid Build Coastguard Worker *
8602*6777b538SAndroid Build Coastguard Worker * parse an end of tag
8603*6777b538SAndroid Build Coastguard Worker *
8604*6777b538SAndroid Build Coastguard Worker * [42] ETag ::= '</' Name S? '>'
8605*6777b538SAndroid Build Coastguard Worker *
8606*6777b538SAndroid Build Coastguard Worker * With namespace
8607*6777b538SAndroid Build Coastguard Worker *
8608*6777b538SAndroid Build Coastguard Worker * [NS 9] ETag ::= '</' QName S? '>'
8609*6777b538SAndroid Build Coastguard Worker */
8610*6777b538SAndroid Build Coastguard Worker
8611*6777b538SAndroid Build Coastguard Worker void
xmlParseEndTag(xmlParserCtxtPtr ctxt)8612*6777b538SAndroid Build Coastguard Worker xmlParseEndTag(xmlParserCtxtPtr ctxt) {
8613*6777b538SAndroid Build Coastguard Worker xmlParseEndTag1(ctxt, 0);
8614*6777b538SAndroid Build Coastguard Worker }
8615*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
8616*6777b538SAndroid Build Coastguard Worker
8617*6777b538SAndroid Build Coastguard Worker /************************************************************************
8618*6777b538SAndroid Build Coastguard Worker * *
8619*6777b538SAndroid Build Coastguard Worker * SAX 2 specific operations *
8620*6777b538SAndroid Build Coastguard Worker * *
8621*6777b538SAndroid Build Coastguard Worker ************************************************************************/
8622*6777b538SAndroid Build Coastguard Worker
8623*6777b538SAndroid Build Coastguard Worker /**
8624*6777b538SAndroid Build Coastguard Worker * xmlParseQNameHashed:
8625*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8626*6777b538SAndroid Build Coastguard Worker * @prefix: pointer to store the prefix part
8627*6777b538SAndroid Build Coastguard Worker *
8628*6777b538SAndroid Build Coastguard Worker * parse an XML Namespace QName
8629*6777b538SAndroid Build Coastguard Worker *
8630*6777b538SAndroid Build Coastguard Worker * [6] QName ::= (Prefix ':')? LocalPart
8631*6777b538SAndroid Build Coastguard Worker * [7] Prefix ::= NCName
8632*6777b538SAndroid Build Coastguard Worker * [8] LocalPart ::= NCName
8633*6777b538SAndroid Build Coastguard Worker *
8634*6777b538SAndroid Build Coastguard Worker * Returns the Name parsed or NULL
8635*6777b538SAndroid Build Coastguard Worker */
8636*6777b538SAndroid Build Coastguard Worker
8637*6777b538SAndroid Build Coastguard Worker static xmlHashedString
xmlParseQNameHashed(xmlParserCtxtPtr ctxt,xmlHashedString * prefix)8638*6777b538SAndroid Build Coastguard Worker xmlParseQNameHashed(xmlParserCtxtPtr ctxt, xmlHashedString *prefix) {
8639*6777b538SAndroid Build Coastguard Worker xmlHashedString l, p;
8640*6777b538SAndroid Build Coastguard Worker int start, isNCName = 0;
8641*6777b538SAndroid Build Coastguard Worker
8642*6777b538SAndroid Build Coastguard Worker l.name = NULL;
8643*6777b538SAndroid Build Coastguard Worker p.name = NULL;
8644*6777b538SAndroid Build Coastguard Worker
8645*6777b538SAndroid Build Coastguard Worker GROW;
8646*6777b538SAndroid Build Coastguard Worker start = CUR_PTR - BASE_PTR;
8647*6777b538SAndroid Build Coastguard Worker
8648*6777b538SAndroid Build Coastguard Worker l = xmlParseNCName(ctxt);
8649*6777b538SAndroid Build Coastguard Worker if (l.name != NULL) {
8650*6777b538SAndroid Build Coastguard Worker isNCName = 1;
8651*6777b538SAndroid Build Coastguard Worker if (CUR == ':') {
8652*6777b538SAndroid Build Coastguard Worker NEXT;
8653*6777b538SAndroid Build Coastguard Worker p = l;
8654*6777b538SAndroid Build Coastguard Worker l = xmlParseNCName(ctxt);
8655*6777b538SAndroid Build Coastguard Worker }
8656*6777b538SAndroid Build Coastguard Worker }
8657*6777b538SAndroid Build Coastguard Worker if ((l.name == NULL) || (CUR == ':')) {
8658*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
8659*6777b538SAndroid Build Coastguard Worker
8660*6777b538SAndroid Build Coastguard Worker l.name = NULL;
8661*6777b538SAndroid Build Coastguard Worker p.name = NULL;
8662*6777b538SAndroid Build Coastguard Worker if ((isNCName == 0) && (CUR != ':'))
8663*6777b538SAndroid Build Coastguard Worker return(l);
8664*6777b538SAndroid Build Coastguard Worker tmp = xmlParseNmtoken(ctxt);
8665*6777b538SAndroid Build Coastguard Worker if (tmp != NULL)
8666*6777b538SAndroid Build Coastguard Worker xmlFree(tmp);
8667*6777b538SAndroid Build Coastguard Worker l = xmlDictLookupHashed(ctxt->dict, BASE_PTR + start,
8668*6777b538SAndroid Build Coastguard Worker CUR_PTR - (BASE_PTR + start));
8669*6777b538SAndroid Build Coastguard Worker if (l.name == NULL) {
8670*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
8671*6777b538SAndroid Build Coastguard Worker return(l);
8672*6777b538SAndroid Build Coastguard Worker }
8673*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8674*6777b538SAndroid Build Coastguard Worker "Failed to parse QName '%s'\n", l.name, NULL, NULL);
8675*6777b538SAndroid Build Coastguard Worker }
8676*6777b538SAndroid Build Coastguard Worker
8677*6777b538SAndroid Build Coastguard Worker *prefix = p;
8678*6777b538SAndroid Build Coastguard Worker return(l);
8679*6777b538SAndroid Build Coastguard Worker }
8680*6777b538SAndroid Build Coastguard Worker
8681*6777b538SAndroid Build Coastguard Worker /**
8682*6777b538SAndroid Build Coastguard Worker * xmlParseQName:
8683*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8684*6777b538SAndroid Build Coastguard Worker * @prefix: pointer to store the prefix part
8685*6777b538SAndroid Build Coastguard Worker *
8686*6777b538SAndroid Build Coastguard Worker * parse an XML Namespace QName
8687*6777b538SAndroid Build Coastguard Worker *
8688*6777b538SAndroid Build Coastguard Worker * [6] QName ::= (Prefix ':')? LocalPart
8689*6777b538SAndroid Build Coastguard Worker * [7] Prefix ::= NCName
8690*6777b538SAndroid Build Coastguard Worker * [8] LocalPart ::= NCName
8691*6777b538SAndroid Build Coastguard Worker *
8692*6777b538SAndroid Build Coastguard Worker * Returns the Name parsed or NULL
8693*6777b538SAndroid Build Coastguard Worker */
8694*6777b538SAndroid Build Coastguard Worker
8695*6777b538SAndroid Build Coastguard Worker static const xmlChar *
xmlParseQName(xmlParserCtxtPtr ctxt,const xmlChar ** prefix)8696*6777b538SAndroid Build Coastguard Worker xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
8697*6777b538SAndroid Build Coastguard Worker xmlHashedString n, p;
8698*6777b538SAndroid Build Coastguard Worker
8699*6777b538SAndroid Build Coastguard Worker n = xmlParseQNameHashed(ctxt, &p);
8700*6777b538SAndroid Build Coastguard Worker if (n.name == NULL)
8701*6777b538SAndroid Build Coastguard Worker return(NULL);
8702*6777b538SAndroid Build Coastguard Worker *prefix = p.name;
8703*6777b538SAndroid Build Coastguard Worker return(n.name);
8704*6777b538SAndroid Build Coastguard Worker }
8705*6777b538SAndroid Build Coastguard Worker
8706*6777b538SAndroid Build Coastguard Worker /**
8707*6777b538SAndroid Build Coastguard Worker * xmlParseQNameAndCompare:
8708*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8709*6777b538SAndroid Build Coastguard Worker * @name: the localname
8710*6777b538SAndroid Build Coastguard Worker * @prefix: the prefix, if any.
8711*6777b538SAndroid Build Coastguard Worker *
8712*6777b538SAndroid Build Coastguard Worker * parse an XML name and compares for match
8713*6777b538SAndroid Build Coastguard Worker * (specialized for endtag parsing)
8714*6777b538SAndroid Build Coastguard Worker *
8715*6777b538SAndroid Build Coastguard Worker * Returns NULL for an illegal name, (xmlChar*) 1 for success
8716*6777b538SAndroid Build Coastguard Worker * and the name for mismatch
8717*6777b538SAndroid Build Coastguard Worker */
8718*6777b538SAndroid Build Coastguard Worker
8719*6777b538SAndroid Build Coastguard Worker static const xmlChar *
xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt,xmlChar const * name,xmlChar const * prefix)8720*6777b538SAndroid Build Coastguard Worker xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
8721*6777b538SAndroid Build Coastguard Worker xmlChar const *prefix) {
8722*6777b538SAndroid Build Coastguard Worker const xmlChar *cmp;
8723*6777b538SAndroid Build Coastguard Worker const xmlChar *in;
8724*6777b538SAndroid Build Coastguard Worker const xmlChar *ret;
8725*6777b538SAndroid Build Coastguard Worker const xmlChar *prefix2;
8726*6777b538SAndroid Build Coastguard Worker
8727*6777b538SAndroid Build Coastguard Worker if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
8728*6777b538SAndroid Build Coastguard Worker
8729*6777b538SAndroid Build Coastguard Worker GROW;
8730*6777b538SAndroid Build Coastguard Worker in = ctxt->input->cur;
8731*6777b538SAndroid Build Coastguard Worker
8732*6777b538SAndroid Build Coastguard Worker cmp = prefix;
8733*6777b538SAndroid Build Coastguard Worker while (*in != 0 && *in == *cmp) {
8734*6777b538SAndroid Build Coastguard Worker ++in;
8735*6777b538SAndroid Build Coastguard Worker ++cmp;
8736*6777b538SAndroid Build Coastguard Worker }
8737*6777b538SAndroid Build Coastguard Worker if ((*cmp == 0) && (*in == ':')) {
8738*6777b538SAndroid Build Coastguard Worker in++;
8739*6777b538SAndroid Build Coastguard Worker cmp = name;
8740*6777b538SAndroid Build Coastguard Worker while (*in != 0 && *in == *cmp) {
8741*6777b538SAndroid Build Coastguard Worker ++in;
8742*6777b538SAndroid Build Coastguard Worker ++cmp;
8743*6777b538SAndroid Build Coastguard Worker }
8744*6777b538SAndroid Build Coastguard Worker if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
8745*6777b538SAndroid Build Coastguard Worker /* success */
8746*6777b538SAndroid Build Coastguard Worker ctxt->input->col += in - ctxt->input->cur;
8747*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = in;
8748*6777b538SAndroid Build Coastguard Worker return((const xmlChar*) 1);
8749*6777b538SAndroid Build Coastguard Worker }
8750*6777b538SAndroid Build Coastguard Worker }
8751*6777b538SAndroid Build Coastguard Worker /*
8752*6777b538SAndroid Build Coastguard Worker * all strings coms from the dictionary, equality can be done directly
8753*6777b538SAndroid Build Coastguard Worker */
8754*6777b538SAndroid Build Coastguard Worker ret = xmlParseQName (ctxt, &prefix2);
8755*6777b538SAndroid Build Coastguard Worker if (ret == NULL)
8756*6777b538SAndroid Build Coastguard Worker return(NULL);
8757*6777b538SAndroid Build Coastguard Worker if ((ret == name) && (prefix == prefix2))
8758*6777b538SAndroid Build Coastguard Worker return((const xmlChar*) 1);
8759*6777b538SAndroid Build Coastguard Worker return ret;
8760*6777b538SAndroid Build Coastguard Worker }
8761*6777b538SAndroid Build Coastguard Worker
8762*6777b538SAndroid Build Coastguard Worker /**
8763*6777b538SAndroid Build Coastguard Worker * xmlParseAttribute2:
8764*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8765*6777b538SAndroid Build Coastguard Worker * @pref: the element prefix
8766*6777b538SAndroid Build Coastguard Worker * @elem: the element name
8767*6777b538SAndroid Build Coastguard Worker * @prefix: a xmlChar ** used to store the value of the attribute prefix
8768*6777b538SAndroid Build Coastguard Worker * @value: a xmlChar ** used to store the value of the attribute
8769*6777b538SAndroid Build Coastguard Worker * @len: an int * to save the length of the attribute
8770*6777b538SAndroid Build Coastguard Worker * @alloc: an int * to indicate if the attribute was allocated
8771*6777b538SAndroid Build Coastguard Worker *
8772*6777b538SAndroid Build Coastguard Worker * parse an attribute in the new SAX2 framework.
8773*6777b538SAndroid Build Coastguard Worker *
8774*6777b538SAndroid Build Coastguard Worker * Returns the attribute name, and the value in *value, .
8775*6777b538SAndroid Build Coastguard Worker */
8776*6777b538SAndroid Build Coastguard Worker
8777*6777b538SAndroid Build Coastguard Worker static xmlHashedString
xmlParseAttribute2(xmlParserCtxtPtr ctxt,const xmlChar * pref,const xmlChar * elem,xmlHashedString * hprefix,xmlChar ** value,int * len,int * alloc)8778*6777b538SAndroid Build Coastguard Worker xmlParseAttribute2(xmlParserCtxtPtr ctxt,
8779*6777b538SAndroid Build Coastguard Worker const xmlChar * pref, const xmlChar * elem,
8780*6777b538SAndroid Build Coastguard Worker xmlHashedString * hprefix, xmlChar ** value,
8781*6777b538SAndroid Build Coastguard Worker int *len, int *alloc)
8782*6777b538SAndroid Build Coastguard Worker {
8783*6777b538SAndroid Build Coastguard Worker xmlHashedString hname;
8784*6777b538SAndroid Build Coastguard Worker const xmlChar *prefix, *name;
8785*6777b538SAndroid Build Coastguard Worker xmlChar *val = NULL, *internal_val = NULL;
8786*6777b538SAndroid Build Coastguard Worker int normalize = 0;
8787*6777b538SAndroid Build Coastguard Worker
8788*6777b538SAndroid Build Coastguard Worker *value = NULL;
8789*6777b538SAndroid Build Coastguard Worker GROW;
8790*6777b538SAndroid Build Coastguard Worker hname = xmlParseQNameHashed(ctxt, hprefix);
8791*6777b538SAndroid Build Coastguard Worker if (hname.name == NULL) {
8792*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8793*6777b538SAndroid Build Coastguard Worker "error parsing attribute name\n");
8794*6777b538SAndroid Build Coastguard Worker return(hname);
8795*6777b538SAndroid Build Coastguard Worker }
8796*6777b538SAndroid Build Coastguard Worker name = hname.name;
8797*6777b538SAndroid Build Coastguard Worker if (hprefix->name != NULL)
8798*6777b538SAndroid Build Coastguard Worker prefix = hprefix->name;
8799*6777b538SAndroid Build Coastguard Worker else
8800*6777b538SAndroid Build Coastguard Worker prefix = NULL;
8801*6777b538SAndroid Build Coastguard Worker
8802*6777b538SAndroid Build Coastguard Worker /*
8803*6777b538SAndroid Build Coastguard Worker * get the type if needed
8804*6777b538SAndroid Build Coastguard Worker */
8805*6777b538SAndroid Build Coastguard Worker if (ctxt->attsSpecial != NULL) {
8806*6777b538SAndroid Build Coastguard Worker int type;
8807*6777b538SAndroid Build Coastguard Worker
8808*6777b538SAndroid Build Coastguard Worker type = (int) (ptrdiff_t) xmlHashQLookup2(ctxt->attsSpecial,
8809*6777b538SAndroid Build Coastguard Worker pref, elem,
8810*6777b538SAndroid Build Coastguard Worker prefix, name);
8811*6777b538SAndroid Build Coastguard Worker if (type != 0)
8812*6777b538SAndroid Build Coastguard Worker normalize = 1;
8813*6777b538SAndroid Build Coastguard Worker }
8814*6777b538SAndroid Build Coastguard Worker
8815*6777b538SAndroid Build Coastguard Worker /*
8816*6777b538SAndroid Build Coastguard Worker * read the value
8817*6777b538SAndroid Build Coastguard Worker */
8818*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8819*6777b538SAndroid Build Coastguard Worker if (RAW == '=') {
8820*6777b538SAndroid Build Coastguard Worker NEXT;
8821*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
8822*6777b538SAndroid Build Coastguard Worker val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
8823*6777b538SAndroid Build Coastguard Worker if (val == NULL)
8824*6777b538SAndroid Build Coastguard Worker goto error;
8825*6777b538SAndroid Build Coastguard Worker } else {
8826*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8827*6777b538SAndroid Build Coastguard Worker "Specification mandates value for attribute %s\n",
8828*6777b538SAndroid Build Coastguard Worker name);
8829*6777b538SAndroid Build Coastguard Worker goto error;
8830*6777b538SAndroid Build Coastguard Worker }
8831*6777b538SAndroid Build Coastguard Worker
8832*6777b538SAndroid Build Coastguard Worker if (prefix == ctxt->str_xml) {
8833*6777b538SAndroid Build Coastguard Worker /*
8834*6777b538SAndroid Build Coastguard Worker * Check that xml:lang conforms to the specification
8835*6777b538SAndroid Build Coastguard Worker * No more registered as an error, just generate a warning now
8836*6777b538SAndroid Build Coastguard Worker * since this was deprecated in XML second edition
8837*6777b538SAndroid Build Coastguard Worker */
8838*6777b538SAndroid Build Coastguard Worker if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
8839*6777b538SAndroid Build Coastguard Worker internal_val = xmlStrndup(val, *len);
8840*6777b538SAndroid Build Coastguard Worker if (internal_val == NULL)
8841*6777b538SAndroid Build Coastguard Worker goto mem_error;
8842*6777b538SAndroid Build Coastguard Worker if (!xmlCheckLanguageID(internal_val)) {
8843*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
8844*6777b538SAndroid Build Coastguard Worker "Malformed value for xml:lang : %s\n",
8845*6777b538SAndroid Build Coastguard Worker internal_val, NULL);
8846*6777b538SAndroid Build Coastguard Worker }
8847*6777b538SAndroid Build Coastguard Worker }
8848*6777b538SAndroid Build Coastguard Worker
8849*6777b538SAndroid Build Coastguard Worker /*
8850*6777b538SAndroid Build Coastguard Worker * Check that xml:space conforms to the specification
8851*6777b538SAndroid Build Coastguard Worker */
8852*6777b538SAndroid Build Coastguard Worker if (xmlStrEqual(name, BAD_CAST "space")) {
8853*6777b538SAndroid Build Coastguard Worker internal_val = xmlStrndup(val, *len);
8854*6777b538SAndroid Build Coastguard Worker if (internal_val == NULL)
8855*6777b538SAndroid Build Coastguard Worker goto mem_error;
8856*6777b538SAndroid Build Coastguard Worker if (xmlStrEqual(internal_val, BAD_CAST "default"))
8857*6777b538SAndroid Build Coastguard Worker *(ctxt->space) = 0;
8858*6777b538SAndroid Build Coastguard Worker else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
8859*6777b538SAndroid Build Coastguard Worker *(ctxt->space) = 1;
8860*6777b538SAndroid Build Coastguard Worker else {
8861*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
8862*6777b538SAndroid Build Coastguard Worker "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
8863*6777b538SAndroid Build Coastguard Worker internal_val, NULL);
8864*6777b538SAndroid Build Coastguard Worker }
8865*6777b538SAndroid Build Coastguard Worker }
8866*6777b538SAndroid Build Coastguard Worker if (internal_val) {
8867*6777b538SAndroid Build Coastguard Worker xmlFree(internal_val);
8868*6777b538SAndroid Build Coastguard Worker }
8869*6777b538SAndroid Build Coastguard Worker }
8870*6777b538SAndroid Build Coastguard Worker
8871*6777b538SAndroid Build Coastguard Worker *value = val;
8872*6777b538SAndroid Build Coastguard Worker return (hname);
8873*6777b538SAndroid Build Coastguard Worker
8874*6777b538SAndroid Build Coastguard Worker mem_error:
8875*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
8876*6777b538SAndroid Build Coastguard Worker error:
8877*6777b538SAndroid Build Coastguard Worker if ((val != NULL) && (*alloc != 0))
8878*6777b538SAndroid Build Coastguard Worker xmlFree(val);
8879*6777b538SAndroid Build Coastguard Worker return(hname);
8880*6777b538SAndroid Build Coastguard Worker }
8881*6777b538SAndroid Build Coastguard Worker
8882*6777b538SAndroid Build Coastguard Worker /**
8883*6777b538SAndroid Build Coastguard Worker * xmlAttrHashInsert:
8884*6777b538SAndroid Build Coastguard Worker * @ctxt: parser context
8885*6777b538SAndroid Build Coastguard Worker * @size: size of the hash table
8886*6777b538SAndroid Build Coastguard Worker * @name: attribute name
8887*6777b538SAndroid Build Coastguard Worker * @uri: namespace uri
8888*6777b538SAndroid Build Coastguard Worker * @hashValue: combined hash value of name and uri
8889*6777b538SAndroid Build Coastguard Worker * @aindex: attribute index (this is a multiple of 5)
8890*6777b538SAndroid Build Coastguard Worker *
8891*6777b538SAndroid Build Coastguard Worker * Inserts a new attribute into the hash table.
8892*6777b538SAndroid Build Coastguard Worker *
8893*6777b538SAndroid Build Coastguard Worker * Returns INT_MAX if no existing attribute was found, the attribute
8894*6777b538SAndroid Build Coastguard Worker * index if an attribute was found, -1 if a memory allocation failed.
8895*6777b538SAndroid Build Coastguard Worker */
8896*6777b538SAndroid Build Coastguard Worker static int
xmlAttrHashInsert(xmlParserCtxtPtr ctxt,unsigned size,const xmlChar * name,const xmlChar * uri,unsigned hashValue,int aindex)8897*6777b538SAndroid Build Coastguard Worker xmlAttrHashInsert(xmlParserCtxtPtr ctxt, unsigned size, const xmlChar *name,
8898*6777b538SAndroid Build Coastguard Worker const xmlChar *uri, unsigned hashValue, int aindex) {
8899*6777b538SAndroid Build Coastguard Worker xmlAttrHashBucket *table = ctxt->attrHash;
8900*6777b538SAndroid Build Coastguard Worker xmlAttrHashBucket *bucket;
8901*6777b538SAndroid Build Coastguard Worker unsigned hindex;
8902*6777b538SAndroid Build Coastguard Worker
8903*6777b538SAndroid Build Coastguard Worker hindex = hashValue & (size - 1);
8904*6777b538SAndroid Build Coastguard Worker bucket = &table[hindex];
8905*6777b538SAndroid Build Coastguard Worker
8906*6777b538SAndroid Build Coastguard Worker while (bucket->index >= 0) {
8907*6777b538SAndroid Build Coastguard Worker const xmlChar **atts = &ctxt->atts[bucket->index];
8908*6777b538SAndroid Build Coastguard Worker
8909*6777b538SAndroid Build Coastguard Worker if (name == atts[0]) {
8910*6777b538SAndroid Build Coastguard Worker int nsIndex = (int) (ptrdiff_t) atts[2];
8911*6777b538SAndroid Build Coastguard Worker
8912*6777b538SAndroid Build Coastguard Worker if ((nsIndex == NS_INDEX_EMPTY) ? (uri == NULL) :
8913*6777b538SAndroid Build Coastguard Worker (nsIndex == NS_INDEX_XML) ? (uri == ctxt->str_xml) :
8914*6777b538SAndroid Build Coastguard Worker (uri == ctxt->nsTab[nsIndex * 2 + 1]))
8915*6777b538SAndroid Build Coastguard Worker return(bucket->index);
8916*6777b538SAndroid Build Coastguard Worker }
8917*6777b538SAndroid Build Coastguard Worker
8918*6777b538SAndroid Build Coastguard Worker hindex++;
8919*6777b538SAndroid Build Coastguard Worker bucket++;
8920*6777b538SAndroid Build Coastguard Worker if (hindex >= size) {
8921*6777b538SAndroid Build Coastguard Worker hindex = 0;
8922*6777b538SAndroid Build Coastguard Worker bucket = table;
8923*6777b538SAndroid Build Coastguard Worker }
8924*6777b538SAndroid Build Coastguard Worker }
8925*6777b538SAndroid Build Coastguard Worker
8926*6777b538SAndroid Build Coastguard Worker bucket->index = aindex;
8927*6777b538SAndroid Build Coastguard Worker
8928*6777b538SAndroid Build Coastguard Worker return(INT_MAX);
8929*6777b538SAndroid Build Coastguard Worker }
8930*6777b538SAndroid Build Coastguard Worker
8931*6777b538SAndroid Build Coastguard Worker /**
8932*6777b538SAndroid Build Coastguard Worker * xmlParseStartTag2:
8933*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
8934*6777b538SAndroid Build Coastguard Worker *
8935*6777b538SAndroid Build Coastguard Worker * Parse a start tag. Always consumes '<'.
8936*6777b538SAndroid Build Coastguard Worker *
8937*6777b538SAndroid Build Coastguard Worker * This routine is called when running SAX2 parsing
8938*6777b538SAndroid Build Coastguard Worker *
8939*6777b538SAndroid Build Coastguard Worker * [40] STag ::= '<' Name (S Attribute)* S? '>'
8940*6777b538SAndroid Build Coastguard Worker *
8941*6777b538SAndroid Build Coastguard Worker * [ WFC: Unique Att Spec ]
8942*6777b538SAndroid Build Coastguard Worker * No attribute name may appear more than once in the same start-tag or
8943*6777b538SAndroid Build Coastguard Worker * empty-element tag.
8944*6777b538SAndroid Build Coastguard Worker *
8945*6777b538SAndroid Build Coastguard Worker * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
8946*6777b538SAndroid Build Coastguard Worker *
8947*6777b538SAndroid Build Coastguard Worker * [ WFC: Unique Att Spec ]
8948*6777b538SAndroid Build Coastguard Worker * No attribute name may appear more than once in the same start-tag or
8949*6777b538SAndroid Build Coastguard Worker * empty-element tag.
8950*6777b538SAndroid Build Coastguard Worker *
8951*6777b538SAndroid Build Coastguard Worker * With namespace:
8952*6777b538SAndroid Build Coastguard Worker *
8953*6777b538SAndroid Build Coastguard Worker * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
8954*6777b538SAndroid Build Coastguard Worker *
8955*6777b538SAndroid Build Coastguard Worker * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
8956*6777b538SAndroid Build Coastguard Worker *
8957*6777b538SAndroid Build Coastguard Worker * Returns the element name parsed
8958*6777b538SAndroid Build Coastguard Worker */
8959*6777b538SAndroid Build Coastguard Worker
8960*6777b538SAndroid Build Coastguard Worker static const xmlChar *
xmlParseStartTag2(xmlParserCtxtPtr ctxt,const xmlChar ** pref,const xmlChar ** URI,int * nbNsPtr)8961*6777b538SAndroid Build Coastguard Worker xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
8962*6777b538SAndroid Build Coastguard Worker const xmlChar **URI, int *nbNsPtr) {
8963*6777b538SAndroid Build Coastguard Worker xmlHashedString hlocalname;
8964*6777b538SAndroid Build Coastguard Worker xmlHashedString hprefix;
8965*6777b538SAndroid Build Coastguard Worker xmlHashedString hattname;
8966*6777b538SAndroid Build Coastguard Worker xmlHashedString haprefix;
8967*6777b538SAndroid Build Coastguard Worker const xmlChar *localname;
8968*6777b538SAndroid Build Coastguard Worker const xmlChar *prefix;
8969*6777b538SAndroid Build Coastguard Worker const xmlChar *attname;
8970*6777b538SAndroid Build Coastguard Worker const xmlChar *aprefix;
8971*6777b538SAndroid Build Coastguard Worker const xmlChar *uri;
8972*6777b538SAndroid Build Coastguard Worker xmlChar *attvalue = NULL;
8973*6777b538SAndroid Build Coastguard Worker const xmlChar **atts = ctxt->atts;
8974*6777b538SAndroid Build Coastguard Worker unsigned attrHashSize = 0;
8975*6777b538SAndroid Build Coastguard Worker int maxatts = ctxt->maxatts;
8976*6777b538SAndroid Build Coastguard Worker int nratts, nbatts, nbdef;
8977*6777b538SAndroid Build Coastguard Worker int i, j, nbNs, nbTotalDef, attval, nsIndex, maxAtts;
8978*6777b538SAndroid Build Coastguard Worker int alloc = 0;
8979*6777b538SAndroid Build Coastguard Worker
8980*6777b538SAndroid Build Coastguard Worker if (RAW != '<') return(NULL);
8981*6777b538SAndroid Build Coastguard Worker NEXT1;
8982*6777b538SAndroid Build Coastguard Worker
8983*6777b538SAndroid Build Coastguard Worker nbatts = 0;
8984*6777b538SAndroid Build Coastguard Worker nratts = 0;
8985*6777b538SAndroid Build Coastguard Worker nbdef = 0;
8986*6777b538SAndroid Build Coastguard Worker nbNs = 0;
8987*6777b538SAndroid Build Coastguard Worker nbTotalDef = 0;
8988*6777b538SAndroid Build Coastguard Worker attval = 0;
8989*6777b538SAndroid Build Coastguard Worker
8990*6777b538SAndroid Build Coastguard Worker if (xmlParserNsStartElement(ctxt->nsdb) < 0) {
8991*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
8992*6777b538SAndroid Build Coastguard Worker return(NULL);
8993*6777b538SAndroid Build Coastguard Worker }
8994*6777b538SAndroid Build Coastguard Worker
8995*6777b538SAndroid Build Coastguard Worker hlocalname = xmlParseQNameHashed(ctxt, &hprefix);
8996*6777b538SAndroid Build Coastguard Worker if (hlocalname.name == NULL) {
8997*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8998*6777b538SAndroid Build Coastguard Worker "StartTag: invalid element name\n");
8999*6777b538SAndroid Build Coastguard Worker return(NULL);
9000*6777b538SAndroid Build Coastguard Worker }
9001*6777b538SAndroid Build Coastguard Worker localname = hlocalname.name;
9002*6777b538SAndroid Build Coastguard Worker prefix = hprefix.name;
9003*6777b538SAndroid Build Coastguard Worker
9004*6777b538SAndroid Build Coastguard Worker /*
9005*6777b538SAndroid Build Coastguard Worker * Now parse the attributes, it ends up with the ending
9006*6777b538SAndroid Build Coastguard Worker *
9007*6777b538SAndroid Build Coastguard Worker * (S Attribute)* S?
9008*6777b538SAndroid Build Coastguard Worker */
9009*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
9010*6777b538SAndroid Build Coastguard Worker GROW;
9011*6777b538SAndroid Build Coastguard Worker
9012*6777b538SAndroid Build Coastguard Worker /*
9013*6777b538SAndroid Build Coastguard Worker * The ctxt->atts array will be ultimately passed to the SAX callback
9014*6777b538SAndroid Build Coastguard Worker * containing five xmlChar pointers for each attribute:
9015*6777b538SAndroid Build Coastguard Worker *
9016*6777b538SAndroid Build Coastguard Worker * [0] attribute name
9017*6777b538SAndroid Build Coastguard Worker * [1] attribute prefix
9018*6777b538SAndroid Build Coastguard Worker * [2] namespace URI
9019*6777b538SAndroid Build Coastguard Worker * [3] attribute value
9020*6777b538SAndroid Build Coastguard Worker * [4] end of attribute value
9021*6777b538SAndroid Build Coastguard Worker *
9022*6777b538SAndroid Build Coastguard Worker * To save memory, we reuse this array temporarily and store integers
9023*6777b538SAndroid Build Coastguard Worker * in these pointer variables.
9024*6777b538SAndroid Build Coastguard Worker *
9025*6777b538SAndroid Build Coastguard Worker * [0] attribute name
9026*6777b538SAndroid Build Coastguard Worker * [1] attribute prefix
9027*6777b538SAndroid Build Coastguard Worker * [2] hash value of attribute prefix, and later namespace index
9028*6777b538SAndroid Build Coastguard Worker * [3] for non-allocated values: ptrdiff_t offset into input buffer
9029*6777b538SAndroid Build Coastguard Worker * [4] for non-allocated values: ptrdiff_t offset into input buffer
9030*6777b538SAndroid Build Coastguard Worker *
9031*6777b538SAndroid Build Coastguard Worker * The ctxt->attallocs array contains an additional unsigned int for
9032*6777b538SAndroid Build Coastguard Worker * each attribute, containing the hash value of the attribute name
9033*6777b538SAndroid Build Coastguard Worker * and the alloc flag in bit 31.
9034*6777b538SAndroid Build Coastguard Worker */
9035*6777b538SAndroid Build Coastguard Worker
9036*6777b538SAndroid Build Coastguard Worker while (((RAW != '>') &&
9037*6777b538SAndroid Build Coastguard Worker ((RAW != '/') || (NXT(1) != '>')) &&
9038*6777b538SAndroid Build Coastguard Worker (IS_BYTE_CHAR(RAW))) && (PARSER_STOPPED(ctxt) == 0)) {
9039*6777b538SAndroid Build Coastguard Worker int len = -1;
9040*6777b538SAndroid Build Coastguard Worker
9041*6777b538SAndroid Build Coastguard Worker hattname = xmlParseAttribute2(ctxt, prefix, localname,
9042*6777b538SAndroid Build Coastguard Worker &haprefix, &attvalue, &len,
9043*6777b538SAndroid Build Coastguard Worker &alloc);
9044*6777b538SAndroid Build Coastguard Worker if (hattname.name == NULL)
9045*6777b538SAndroid Build Coastguard Worker break;
9046*6777b538SAndroid Build Coastguard Worker if (attvalue == NULL)
9047*6777b538SAndroid Build Coastguard Worker goto next_attr;
9048*6777b538SAndroid Build Coastguard Worker attname = hattname.name;
9049*6777b538SAndroid Build Coastguard Worker aprefix = haprefix.name;
9050*6777b538SAndroid Build Coastguard Worker if (len < 0) len = xmlStrlen(attvalue);
9051*6777b538SAndroid Build Coastguard Worker
9052*6777b538SAndroid Build Coastguard Worker if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9053*6777b538SAndroid Build Coastguard Worker xmlHashedString huri;
9054*6777b538SAndroid Build Coastguard Worker xmlURIPtr parsedUri;
9055*6777b538SAndroid Build Coastguard Worker
9056*6777b538SAndroid Build Coastguard Worker huri = xmlDictLookupHashed(ctxt->dict, attvalue, len);
9057*6777b538SAndroid Build Coastguard Worker uri = huri.name;
9058*6777b538SAndroid Build Coastguard Worker if (uri == NULL) {
9059*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
9060*6777b538SAndroid Build Coastguard Worker goto next_attr;
9061*6777b538SAndroid Build Coastguard Worker }
9062*6777b538SAndroid Build Coastguard Worker if (*uri != 0) {
9063*6777b538SAndroid Build Coastguard Worker if (xmlParseURISafe((const char *) uri, &parsedUri) < 0) {
9064*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
9065*6777b538SAndroid Build Coastguard Worker goto next_attr;
9066*6777b538SAndroid Build Coastguard Worker }
9067*6777b538SAndroid Build Coastguard Worker if (parsedUri == NULL) {
9068*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_WAR_NS_URI,
9069*6777b538SAndroid Build Coastguard Worker "xmlns: '%s' is not a valid URI\n",
9070*6777b538SAndroid Build Coastguard Worker uri, NULL, NULL);
9071*6777b538SAndroid Build Coastguard Worker } else {
9072*6777b538SAndroid Build Coastguard Worker if (parsedUri->scheme == NULL) {
9073*6777b538SAndroid Build Coastguard Worker xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9074*6777b538SAndroid Build Coastguard Worker "xmlns: URI %s is not absolute\n",
9075*6777b538SAndroid Build Coastguard Worker uri, NULL, NULL);
9076*6777b538SAndroid Build Coastguard Worker }
9077*6777b538SAndroid Build Coastguard Worker xmlFreeURI(parsedUri);
9078*6777b538SAndroid Build Coastguard Worker }
9079*6777b538SAndroid Build Coastguard Worker if (uri == ctxt->str_xml_ns) {
9080*6777b538SAndroid Build Coastguard Worker if (attname != ctxt->str_xml) {
9081*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9082*6777b538SAndroid Build Coastguard Worker "xml namespace URI cannot be the default namespace\n",
9083*6777b538SAndroid Build Coastguard Worker NULL, NULL, NULL);
9084*6777b538SAndroid Build Coastguard Worker }
9085*6777b538SAndroid Build Coastguard Worker goto next_attr;
9086*6777b538SAndroid Build Coastguard Worker }
9087*6777b538SAndroid Build Coastguard Worker if ((len == 29) &&
9088*6777b538SAndroid Build Coastguard Worker (xmlStrEqual(uri,
9089*6777b538SAndroid Build Coastguard Worker BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9090*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9091*6777b538SAndroid Build Coastguard Worker "reuse of the xmlns namespace name is forbidden\n",
9092*6777b538SAndroid Build Coastguard Worker NULL, NULL, NULL);
9093*6777b538SAndroid Build Coastguard Worker goto next_attr;
9094*6777b538SAndroid Build Coastguard Worker }
9095*6777b538SAndroid Build Coastguard Worker }
9096*6777b538SAndroid Build Coastguard Worker
9097*6777b538SAndroid Build Coastguard Worker if (xmlParserNsPush(ctxt, NULL, &huri, NULL, 0) > 0)
9098*6777b538SAndroid Build Coastguard Worker nbNs++;
9099*6777b538SAndroid Build Coastguard Worker } else if (aprefix == ctxt->str_xmlns) {
9100*6777b538SAndroid Build Coastguard Worker xmlHashedString huri;
9101*6777b538SAndroid Build Coastguard Worker xmlURIPtr parsedUri;
9102*6777b538SAndroid Build Coastguard Worker
9103*6777b538SAndroid Build Coastguard Worker huri = xmlDictLookupHashed(ctxt->dict, attvalue, len);
9104*6777b538SAndroid Build Coastguard Worker uri = huri.name;
9105*6777b538SAndroid Build Coastguard Worker if (uri == NULL) {
9106*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
9107*6777b538SAndroid Build Coastguard Worker goto next_attr;
9108*6777b538SAndroid Build Coastguard Worker }
9109*6777b538SAndroid Build Coastguard Worker
9110*6777b538SAndroid Build Coastguard Worker if (attname == ctxt->str_xml) {
9111*6777b538SAndroid Build Coastguard Worker if (uri != ctxt->str_xml_ns) {
9112*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9113*6777b538SAndroid Build Coastguard Worker "xml namespace prefix mapped to wrong URI\n",
9114*6777b538SAndroid Build Coastguard Worker NULL, NULL, NULL);
9115*6777b538SAndroid Build Coastguard Worker }
9116*6777b538SAndroid Build Coastguard Worker /*
9117*6777b538SAndroid Build Coastguard Worker * Do not keep a namespace definition node
9118*6777b538SAndroid Build Coastguard Worker */
9119*6777b538SAndroid Build Coastguard Worker goto next_attr;
9120*6777b538SAndroid Build Coastguard Worker }
9121*6777b538SAndroid Build Coastguard Worker if (uri == ctxt->str_xml_ns) {
9122*6777b538SAndroid Build Coastguard Worker if (attname != ctxt->str_xml) {
9123*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9124*6777b538SAndroid Build Coastguard Worker "xml namespace URI mapped to wrong prefix\n",
9125*6777b538SAndroid Build Coastguard Worker NULL, NULL, NULL);
9126*6777b538SAndroid Build Coastguard Worker }
9127*6777b538SAndroid Build Coastguard Worker goto next_attr;
9128*6777b538SAndroid Build Coastguard Worker }
9129*6777b538SAndroid Build Coastguard Worker if (attname == ctxt->str_xmlns) {
9130*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9131*6777b538SAndroid Build Coastguard Worker "redefinition of the xmlns prefix is forbidden\n",
9132*6777b538SAndroid Build Coastguard Worker NULL, NULL, NULL);
9133*6777b538SAndroid Build Coastguard Worker goto next_attr;
9134*6777b538SAndroid Build Coastguard Worker }
9135*6777b538SAndroid Build Coastguard Worker if ((len == 29) &&
9136*6777b538SAndroid Build Coastguard Worker (xmlStrEqual(uri,
9137*6777b538SAndroid Build Coastguard Worker BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9138*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9139*6777b538SAndroid Build Coastguard Worker "reuse of the xmlns namespace name is forbidden\n",
9140*6777b538SAndroid Build Coastguard Worker NULL, NULL, NULL);
9141*6777b538SAndroid Build Coastguard Worker goto next_attr;
9142*6777b538SAndroid Build Coastguard Worker }
9143*6777b538SAndroid Build Coastguard Worker if ((uri == NULL) || (uri[0] == 0)) {
9144*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9145*6777b538SAndroid Build Coastguard Worker "xmlns:%s: Empty XML namespace is not allowed\n",
9146*6777b538SAndroid Build Coastguard Worker attname, NULL, NULL);
9147*6777b538SAndroid Build Coastguard Worker goto next_attr;
9148*6777b538SAndroid Build Coastguard Worker } else {
9149*6777b538SAndroid Build Coastguard Worker if (xmlParseURISafe((const char *) uri, &parsedUri) < 0) {
9150*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
9151*6777b538SAndroid Build Coastguard Worker goto next_attr;
9152*6777b538SAndroid Build Coastguard Worker }
9153*6777b538SAndroid Build Coastguard Worker if (parsedUri == NULL) {
9154*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_WAR_NS_URI,
9155*6777b538SAndroid Build Coastguard Worker "xmlns:%s: '%s' is not a valid URI\n",
9156*6777b538SAndroid Build Coastguard Worker attname, uri, NULL);
9157*6777b538SAndroid Build Coastguard Worker } else {
9158*6777b538SAndroid Build Coastguard Worker if ((ctxt->pedantic) && (parsedUri->scheme == NULL)) {
9159*6777b538SAndroid Build Coastguard Worker xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9160*6777b538SAndroid Build Coastguard Worker "xmlns:%s: URI %s is not absolute\n",
9161*6777b538SAndroid Build Coastguard Worker attname, uri, NULL);
9162*6777b538SAndroid Build Coastguard Worker }
9163*6777b538SAndroid Build Coastguard Worker xmlFreeURI(parsedUri);
9164*6777b538SAndroid Build Coastguard Worker }
9165*6777b538SAndroid Build Coastguard Worker }
9166*6777b538SAndroid Build Coastguard Worker
9167*6777b538SAndroid Build Coastguard Worker if (xmlParserNsPush(ctxt, &hattname, &huri, NULL, 0) > 0)
9168*6777b538SAndroid Build Coastguard Worker nbNs++;
9169*6777b538SAndroid Build Coastguard Worker } else {
9170*6777b538SAndroid Build Coastguard Worker /*
9171*6777b538SAndroid Build Coastguard Worker * Populate attributes array, see above for repurposing
9172*6777b538SAndroid Build Coastguard Worker * of xmlChar pointers.
9173*6777b538SAndroid Build Coastguard Worker */
9174*6777b538SAndroid Build Coastguard Worker if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9175*6777b538SAndroid Build Coastguard Worker if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9176*6777b538SAndroid Build Coastguard Worker goto next_attr;
9177*6777b538SAndroid Build Coastguard Worker }
9178*6777b538SAndroid Build Coastguard Worker maxatts = ctxt->maxatts;
9179*6777b538SAndroid Build Coastguard Worker atts = ctxt->atts;
9180*6777b538SAndroid Build Coastguard Worker }
9181*6777b538SAndroid Build Coastguard Worker ctxt->attallocs[nratts++] = (hattname.hashValue & 0x7FFFFFFF) |
9182*6777b538SAndroid Build Coastguard Worker ((unsigned) alloc << 31);
9183*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = attname;
9184*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = aprefix;
9185*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = (const xmlChar *) (size_t) haprefix.hashValue;
9186*6777b538SAndroid Build Coastguard Worker if (alloc) {
9187*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = attvalue;
9188*6777b538SAndroid Build Coastguard Worker attvalue += len;
9189*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = attvalue;
9190*6777b538SAndroid Build Coastguard Worker } else {
9191*6777b538SAndroid Build Coastguard Worker /*
9192*6777b538SAndroid Build Coastguard Worker * attvalue points into the input buffer which can be
9193*6777b538SAndroid Build Coastguard Worker * reallocated. Store differences to input->base instead.
9194*6777b538SAndroid Build Coastguard Worker * The pointers will be reconstructed later.
9195*6777b538SAndroid Build Coastguard Worker */
9196*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = (void *) (attvalue - BASE_PTR);
9197*6777b538SAndroid Build Coastguard Worker attvalue += len;
9198*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = (void *) (attvalue - BASE_PTR);
9199*6777b538SAndroid Build Coastguard Worker }
9200*6777b538SAndroid Build Coastguard Worker /*
9201*6777b538SAndroid Build Coastguard Worker * tag if some deallocation is needed
9202*6777b538SAndroid Build Coastguard Worker */
9203*6777b538SAndroid Build Coastguard Worker if (alloc != 0) attval = 1;
9204*6777b538SAndroid Build Coastguard Worker attvalue = NULL; /* moved into atts */
9205*6777b538SAndroid Build Coastguard Worker }
9206*6777b538SAndroid Build Coastguard Worker
9207*6777b538SAndroid Build Coastguard Worker next_attr:
9208*6777b538SAndroid Build Coastguard Worker if ((attvalue != NULL) && (alloc != 0)) {
9209*6777b538SAndroid Build Coastguard Worker xmlFree(attvalue);
9210*6777b538SAndroid Build Coastguard Worker attvalue = NULL;
9211*6777b538SAndroid Build Coastguard Worker }
9212*6777b538SAndroid Build Coastguard Worker
9213*6777b538SAndroid Build Coastguard Worker GROW
9214*6777b538SAndroid Build Coastguard Worker if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
9215*6777b538SAndroid Build Coastguard Worker break;
9216*6777b538SAndroid Build Coastguard Worker if (SKIP_BLANKS == 0) {
9217*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9218*6777b538SAndroid Build Coastguard Worker "attributes construct error\n");
9219*6777b538SAndroid Build Coastguard Worker break;
9220*6777b538SAndroid Build Coastguard Worker }
9221*6777b538SAndroid Build Coastguard Worker GROW;
9222*6777b538SAndroid Build Coastguard Worker }
9223*6777b538SAndroid Build Coastguard Worker
9224*6777b538SAndroid Build Coastguard Worker /*
9225*6777b538SAndroid Build Coastguard Worker * Namespaces from default attributes
9226*6777b538SAndroid Build Coastguard Worker */
9227*6777b538SAndroid Build Coastguard Worker if (ctxt->attsDefault != NULL) {
9228*6777b538SAndroid Build Coastguard Worker xmlDefAttrsPtr defaults;
9229*6777b538SAndroid Build Coastguard Worker
9230*6777b538SAndroid Build Coastguard Worker defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
9231*6777b538SAndroid Build Coastguard Worker if (defaults != NULL) {
9232*6777b538SAndroid Build Coastguard Worker for (i = 0; i < defaults->nbAttrs; i++) {
9233*6777b538SAndroid Build Coastguard Worker xmlDefAttr *attr = &defaults->attrs[i];
9234*6777b538SAndroid Build Coastguard Worker
9235*6777b538SAndroid Build Coastguard Worker attname = attr->name.name;
9236*6777b538SAndroid Build Coastguard Worker aprefix = attr->prefix.name;
9237*6777b538SAndroid Build Coastguard Worker
9238*6777b538SAndroid Build Coastguard Worker if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9239*6777b538SAndroid Build Coastguard Worker xmlParserEntityCheck(ctxt, attr->expandedSize);
9240*6777b538SAndroid Build Coastguard Worker
9241*6777b538SAndroid Build Coastguard Worker if (xmlParserNsPush(ctxt, NULL, &attr->value, NULL, 1) > 0)
9242*6777b538SAndroid Build Coastguard Worker nbNs++;
9243*6777b538SAndroid Build Coastguard Worker } else if (aprefix == ctxt->str_xmlns) {
9244*6777b538SAndroid Build Coastguard Worker xmlParserEntityCheck(ctxt, attr->expandedSize);
9245*6777b538SAndroid Build Coastguard Worker
9246*6777b538SAndroid Build Coastguard Worker if (xmlParserNsPush(ctxt, &attr->name, &attr->value,
9247*6777b538SAndroid Build Coastguard Worker NULL, 1) > 0)
9248*6777b538SAndroid Build Coastguard Worker nbNs++;
9249*6777b538SAndroid Build Coastguard Worker } else {
9250*6777b538SAndroid Build Coastguard Worker nbTotalDef += 1;
9251*6777b538SAndroid Build Coastguard Worker }
9252*6777b538SAndroid Build Coastguard Worker }
9253*6777b538SAndroid Build Coastguard Worker }
9254*6777b538SAndroid Build Coastguard Worker }
9255*6777b538SAndroid Build Coastguard Worker
9256*6777b538SAndroid Build Coastguard Worker /*
9257*6777b538SAndroid Build Coastguard Worker * Resolve attribute namespaces
9258*6777b538SAndroid Build Coastguard Worker */
9259*6777b538SAndroid Build Coastguard Worker for (i = 0; i < nbatts; i += 5) {
9260*6777b538SAndroid Build Coastguard Worker attname = atts[i];
9261*6777b538SAndroid Build Coastguard Worker aprefix = atts[i+1];
9262*6777b538SAndroid Build Coastguard Worker
9263*6777b538SAndroid Build Coastguard Worker /*
9264*6777b538SAndroid Build Coastguard Worker * The default namespace does not apply to attribute names.
9265*6777b538SAndroid Build Coastguard Worker */
9266*6777b538SAndroid Build Coastguard Worker if (aprefix == NULL) {
9267*6777b538SAndroid Build Coastguard Worker nsIndex = NS_INDEX_EMPTY;
9268*6777b538SAndroid Build Coastguard Worker } else if (aprefix == ctxt->str_xml) {
9269*6777b538SAndroid Build Coastguard Worker nsIndex = NS_INDEX_XML;
9270*6777b538SAndroid Build Coastguard Worker } else {
9271*6777b538SAndroid Build Coastguard Worker haprefix.name = aprefix;
9272*6777b538SAndroid Build Coastguard Worker haprefix.hashValue = (size_t) atts[i+2];
9273*6777b538SAndroid Build Coastguard Worker nsIndex = xmlParserNsLookup(ctxt, &haprefix, NULL);
9274*6777b538SAndroid Build Coastguard Worker
9275*6777b538SAndroid Build Coastguard Worker if ((nsIndex == INT_MAX) || (nsIndex < ctxt->nsdb->minNsIndex)) {
9276*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9277*6777b538SAndroid Build Coastguard Worker "Namespace prefix %s for %s on %s is not defined\n",
9278*6777b538SAndroid Build Coastguard Worker aprefix, attname, localname);
9279*6777b538SAndroid Build Coastguard Worker nsIndex = NS_INDEX_EMPTY;
9280*6777b538SAndroid Build Coastguard Worker }
9281*6777b538SAndroid Build Coastguard Worker }
9282*6777b538SAndroid Build Coastguard Worker
9283*6777b538SAndroid Build Coastguard Worker atts[i+2] = (const xmlChar *) (ptrdiff_t) nsIndex;
9284*6777b538SAndroid Build Coastguard Worker }
9285*6777b538SAndroid Build Coastguard Worker
9286*6777b538SAndroid Build Coastguard Worker /*
9287*6777b538SAndroid Build Coastguard Worker * Maximum number of attributes including default attributes.
9288*6777b538SAndroid Build Coastguard Worker */
9289*6777b538SAndroid Build Coastguard Worker maxAtts = nratts + nbTotalDef;
9290*6777b538SAndroid Build Coastguard Worker
9291*6777b538SAndroid Build Coastguard Worker /*
9292*6777b538SAndroid Build Coastguard Worker * Verify that attribute names are unique.
9293*6777b538SAndroid Build Coastguard Worker */
9294*6777b538SAndroid Build Coastguard Worker if (maxAtts > 1) {
9295*6777b538SAndroid Build Coastguard Worker attrHashSize = 4;
9296*6777b538SAndroid Build Coastguard Worker while (attrHashSize / 2 < (unsigned) maxAtts)
9297*6777b538SAndroid Build Coastguard Worker attrHashSize *= 2;
9298*6777b538SAndroid Build Coastguard Worker
9299*6777b538SAndroid Build Coastguard Worker if (attrHashSize > ctxt->attrHashMax) {
9300*6777b538SAndroid Build Coastguard Worker xmlAttrHashBucket *tmp;
9301*6777b538SAndroid Build Coastguard Worker
9302*6777b538SAndroid Build Coastguard Worker tmp = xmlRealloc(ctxt->attrHash, attrHashSize * sizeof(tmp[0]));
9303*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
9304*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
9305*6777b538SAndroid Build Coastguard Worker goto done;
9306*6777b538SAndroid Build Coastguard Worker }
9307*6777b538SAndroid Build Coastguard Worker
9308*6777b538SAndroid Build Coastguard Worker ctxt->attrHash = tmp;
9309*6777b538SAndroid Build Coastguard Worker ctxt->attrHashMax = attrHashSize;
9310*6777b538SAndroid Build Coastguard Worker }
9311*6777b538SAndroid Build Coastguard Worker
9312*6777b538SAndroid Build Coastguard Worker memset(ctxt->attrHash, -1, attrHashSize * sizeof(ctxt->attrHash[0]));
9313*6777b538SAndroid Build Coastguard Worker
9314*6777b538SAndroid Build Coastguard Worker for (i = 0, j = 0; j < nratts; i += 5, j++) {
9315*6777b538SAndroid Build Coastguard Worker const xmlChar *nsuri;
9316*6777b538SAndroid Build Coastguard Worker unsigned hashValue, nameHashValue, uriHashValue;
9317*6777b538SAndroid Build Coastguard Worker int res;
9318*6777b538SAndroid Build Coastguard Worker
9319*6777b538SAndroid Build Coastguard Worker attname = atts[i];
9320*6777b538SAndroid Build Coastguard Worker aprefix = atts[i+1];
9321*6777b538SAndroid Build Coastguard Worker nsIndex = (ptrdiff_t) atts[i+2];
9322*6777b538SAndroid Build Coastguard Worker /* Hash values always have bit 31 set, see dict.c */
9323*6777b538SAndroid Build Coastguard Worker nameHashValue = ctxt->attallocs[j] | 0x80000000;
9324*6777b538SAndroid Build Coastguard Worker
9325*6777b538SAndroid Build Coastguard Worker if (nsIndex == NS_INDEX_EMPTY) {
9326*6777b538SAndroid Build Coastguard Worker /*
9327*6777b538SAndroid Build Coastguard Worker * Prefix with empty namespace means an undeclared
9328*6777b538SAndroid Build Coastguard Worker * prefix which was already reported above.
9329*6777b538SAndroid Build Coastguard Worker */
9330*6777b538SAndroid Build Coastguard Worker if (aprefix != NULL)
9331*6777b538SAndroid Build Coastguard Worker continue;
9332*6777b538SAndroid Build Coastguard Worker nsuri = NULL;
9333*6777b538SAndroid Build Coastguard Worker uriHashValue = URI_HASH_EMPTY;
9334*6777b538SAndroid Build Coastguard Worker } else if (nsIndex == NS_INDEX_XML) {
9335*6777b538SAndroid Build Coastguard Worker nsuri = ctxt->str_xml_ns;
9336*6777b538SAndroid Build Coastguard Worker uriHashValue = URI_HASH_XML;
9337*6777b538SAndroid Build Coastguard Worker } else {
9338*6777b538SAndroid Build Coastguard Worker nsuri = ctxt->nsTab[nsIndex * 2 + 1];
9339*6777b538SAndroid Build Coastguard Worker uriHashValue = ctxt->nsdb->extra[nsIndex].uriHashValue;
9340*6777b538SAndroid Build Coastguard Worker }
9341*6777b538SAndroid Build Coastguard Worker
9342*6777b538SAndroid Build Coastguard Worker hashValue = xmlDictCombineHash(nameHashValue, uriHashValue);
9343*6777b538SAndroid Build Coastguard Worker res = xmlAttrHashInsert(ctxt, attrHashSize, attname, nsuri,
9344*6777b538SAndroid Build Coastguard Worker hashValue, i);
9345*6777b538SAndroid Build Coastguard Worker if (res < 0)
9346*6777b538SAndroid Build Coastguard Worker continue;
9347*6777b538SAndroid Build Coastguard Worker
9348*6777b538SAndroid Build Coastguard Worker /*
9349*6777b538SAndroid Build Coastguard Worker * [ WFC: Unique Att Spec ]
9350*6777b538SAndroid Build Coastguard Worker * No attribute name may appear more than once in the same
9351*6777b538SAndroid Build Coastguard Worker * start-tag or empty-element tag.
9352*6777b538SAndroid Build Coastguard Worker * As extended by the Namespace in XML REC.
9353*6777b538SAndroid Build Coastguard Worker */
9354*6777b538SAndroid Build Coastguard Worker if (res < INT_MAX) {
9355*6777b538SAndroid Build Coastguard Worker if (aprefix == atts[res+1]) {
9356*6777b538SAndroid Build Coastguard Worker xmlErrAttributeDup(ctxt, aprefix, attname);
9357*6777b538SAndroid Build Coastguard Worker } else {
9358*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
9359*6777b538SAndroid Build Coastguard Worker "Namespaced Attribute %s in '%s' redefined\n",
9360*6777b538SAndroid Build Coastguard Worker attname, nsuri, NULL);
9361*6777b538SAndroid Build Coastguard Worker }
9362*6777b538SAndroid Build Coastguard Worker }
9363*6777b538SAndroid Build Coastguard Worker }
9364*6777b538SAndroid Build Coastguard Worker }
9365*6777b538SAndroid Build Coastguard Worker
9366*6777b538SAndroid Build Coastguard Worker /*
9367*6777b538SAndroid Build Coastguard Worker * Default attributes
9368*6777b538SAndroid Build Coastguard Worker */
9369*6777b538SAndroid Build Coastguard Worker if (ctxt->attsDefault != NULL) {
9370*6777b538SAndroid Build Coastguard Worker xmlDefAttrsPtr defaults;
9371*6777b538SAndroid Build Coastguard Worker
9372*6777b538SAndroid Build Coastguard Worker defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
9373*6777b538SAndroid Build Coastguard Worker if (defaults != NULL) {
9374*6777b538SAndroid Build Coastguard Worker for (i = 0; i < defaults->nbAttrs; i++) {
9375*6777b538SAndroid Build Coastguard Worker xmlDefAttr *attr = &defaults->attrs[i];
9376*6777b538SAndroid Build Coastguard Worker const xmlChar *nsuri;
9377*6777b538SAndroid Build Coastguard Worker unsigned hashValue, uriHashValue;
9378*6777b538SAndroid Build Coastguard Worker int res;
9379*6777b538SAndroid Build Coastguard Worker
9380*6777b538SAndroid Build Coastguard Worker attname = attr->name.name;
9381*6777b538SAndroid Build Coastguard Worker aprefix = attr->prefix.name;
9382*6777b538SAndroid Build Coastguard Worker
9383*6777b538SAndroid Build Coastguard Worker if ((attname == ctxt->str_xmlns) && (aprefix == NULL))
9384*6777b538SAndroid Build Coastguard Worker continue;
9385*6777b538SAndroid Build Coastguard Worker if (aprefix == ctxt->str_xmlns)
9386*6777b538SAndroid Build Coastguard Worker continue;
9387*6777b538SAndroid Build Coastguard Worker
9388*6777b538SAndroid Build Coastguard Worker if (aprefix == NULL) {
9389*6777b538SAndroid Build Coastguard Worker nsIndex = NS_INDEX_EMPTY;
9390*6777b538SAndroid Build Coastguard Worker nsuri = NULL;
9391*6777b538SAndroid Build Coastguard Worker uriHashValue = URI_HASH_EMPTY;
9392*6777b538SAndroid Build Coastguard Worker } if (aprefix == ctxt->str_xml) {
9393*6777b538SAndroid Build Coastguard Worker nsIndex = NS_INDEX_XML;
9394*6777b538SAndroid Build Coastguard Worker nsuri = ctxt->str_xml_ns;
9395*6777b538SAndroid Build Coastguard Worker uriHashValue = URI_HASH_XML;
9396*6777b538SAndroid Build Coastguard Worker } else if (aprefix != NULL) {
9397*6777b538SAndroid Build Coastguard Worker nsIndex = xmlParserNsLookup(ctxt, &attr->prefix, NULL);
9398*6777b538SAndroid Build Coastguard Worker if ((nsIndex == INT_MAX) ||
9399*6777b538SAndroid Build Coastguard Worker (nsIndex < ctxt->nsdb->minNsIndex)) {
9400*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9401*6777b538SAndroid Build Coastguard Worker "Namespace prefix %s for %s on %s is not "
9402*6777b538SAndroid Build Coastguard Worker "defined\n",
9403*6777b538SAndroid Build Coastguard Worker aprefix, attname, localname);
9404*6777b538SAndroid Build Coastguard Worker nsIndex = NS_INDEX_EMPTY;
9405*6777b538SAndroid Build Coastguard Worker nsuri = NULL;
9406*6777b538SAndroid Build Coastguard Worker uriHashValue = URI_HASH_EMPTY;
9407*6777b538SAndroid Build Coastguard Worker } else {
9408*6777b538SAndroid Build Coastguard Worker nsuri = ctxt->nsTab[nsIndex * 2 + 1];
9409*6777b538SAndroid Build Coastguard Worker uriHashValue = ctxt->nsdb->extra[nsIndex].uriHashValue;
9410*6777b538SAndroid Build Coastguard Worker }
9411*6777b538SAndroid Build Coastguard Worker }
9412*6777b538SAndroid Build Coastguard Worker
9413*6777b538SAndroid Build Coastguard Worker /*
9414*6777b538SAndroid Build Coastguard Worker * Check whether the attribute exists
9415*6777b538SAndroid Build Coastguard Worker */
9416*6777b538SAndroid Build Coastguard Worker if (maxAtts > 1) {
9417*6777b538SAndroid Build Coastguard Worker hashValue = xmlDictCombineHash(attr->name.hashValue,
9418*6777b538SAndroid Build Coastguard Worker uriHashValue);
9419*6777b538SAndroid Build Coastguard Worker res = xmlAttrHashInsert(ctxt, attrHashSize, attname, nsuri,
9420*6777b538SAndroid Build Coastguard Worker hashValue, nbatts);
9421*6777b538SAndroid Build Coastguard Worker if (res < 0)
9422*6777b538SAndroid Build Coastguard Worker continue;
9423*6777b538SAndroid Build Coastguard Worker if (res < INT_MAX) {
9424*6777b538SAndroid Build Coastguard Worker if (aprefix == atts[res+1])
9425*6777b538SAndroid Build Coastguard Worker continue;
9426*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
9427*6777b538SAndroid Build Coastguard Worker "Namespaced Attribute %s in '%s' redefined\n",
9428*6777b538SAndroid Build Coastguard Worker attname, nsuri, NULL);
9429*6777b538SAndroid Build Coastguard Worker }
9430*6777b538SAndroid Build Coastguard Worker }
9431*6777b538SAndroid Build Coastguard Worker
9432*6777b538SAndroid Build Coastguard Worker xmlParserEntityCheck(ctxt, attr->expandedSize);
9433*6777b538SAndroid Build Coastguard Worker
9434*6777b538SAndroid Build Coastguard Worker if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9435*6777b538SAndroid Build Coastguard Worker if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9436*6777b538SAndroid Build Coastguard Worker localname = NULL;
9437*6777b538SAndroid Build Coastguard Worker goto done;
9438*6777b538SAndroid Build Coastguard Worker }
9439*6777b538SAndroid Build Coastguard Worker maxatts = ctxt->maxatts;
9440*6777b538SAndroid Build Coastguard Worker atts = ctxt->atts;
9441*6777b538SAndroid Build Coastguard Worker }
9442*6777b538SAndroid Build Coastguard Worker
9443*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = attname;
9444*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = aprefix;
9445*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = (const xmlChar *) (ptrdiff_t) nsIndex;
9446*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = attr->value.name;
9447*6777b538SAndroid Build Coastguard Worker atts[nbatts++] = attr->valueEnd;
9448*6777b538SAndroid Build Coastguard Worker if ((ctxt->standalone == 1) && (attr->external != 0)) {
9449*6777b538SAndroid Build Coastguard Worker xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
9450*6777b538SAndroid Build Coastguard Worker "standalone: attribute %s on %s defaulted "
9451*6777b538SAndroid Build Coastguard Worker "from external subset\n",
9452*6777b538SAndroid Build Coastguard Worker attname, localname);
9453*6777b538SAndroid Build Coastguard Worker }
9454*6777b538SAndroid Build Coastguard Worker nbdef++;
9455*6777b538SAndroid Build Coastguard Worker }
9456*6777b538SAndroid Build Coastguard Worker }
9457*6777b538SAndroid Build Coastguard Worker }
9458*6777b538SAndroid Build Coastguard Worker
9459*6777b538SAndroid Build Coastguard Worker /*
9460*6777b538SAndroid Build Coastguard Worker * Reconstruct attribute pointers
9461*6777b538SAndroid Build Coastguard Worker */
9462*6777b538SAndroid Build Coastguard Worker for (i = 0, j = 0; i < nbatts; i += 5, j++) {
9463*6777b538SAndroid Build Coastguard Worker /* namespace URI */
9464*6777b538SAndroid Build Coastguard Worker nsIndex = (ptrdiff_t) atts[i+2];
9465*6777b538SAndroid Build Coastguard Worker if (nsIndex == INT_MAX)
9466*6777b538SAndroid Build Coastguard Worker atts[i+2] = NULL;
9467*6777b538SAndroid Build Coastguard Worker else if (nsIndex == INT_MAX - 1)
9468*6777b538SAndroid Build Coastguard Worker atts[i+2] = ctxt->str_xml_ns;
9469*6777b538SAndroid Build Coastguard Worker else
9470*6777b538SAndroid Build Coastguard Worker atts[i+2] = ctxt->nsTab[nsIndex * 2 + 1];
9471*6777b538SAndroid Build Coastguard Worker
9472*6777b538SAndroid Build Coastguard Worker if ((j < nratts) && (ctxt->attallocs[j] & 0x80000000) == 0) {
9473*6777b538SAndroid Build Coastguard Worker atts[i+3] = BASE_PTR + (ptrdiff_t) atts[i+3]; /* value */
9474*6777b538SAndroid Build Coastguard Worker atts[i+4] = BASE_PTR + (ptrdiff_t) atts[i+4]; /* valuend */
9475*6777b538SAndroid Build Coastguard Worker }
9476*6777b538SAndroid Build Coastguard Worker }
9477*6777b538SAndroid Build Coastguard Worker
9478*6777b538SAndroid Build Coastguard Worker uri = xmlParserNsLookupUri(ctxt, &hprefix);
9479*6777b538SAndroid Build Coastguard Worker if ((prefix != NULL) && (uri == NULL)) {
9480*6777b538SAndroid Build Coastguard Worker xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9481*6777b538SAndroid Build Coastguard Worker "Namespace prefix %s on %s is not defined\n",
9482*6777b538SAndroid Build Coastguard Worker prefix, localname, NULL);
9483*6777b538SAndroid Build Coastguard Worker }
9484*6777b538SAndroid Build Coastguard Worker *pref = prefix;
9485*6777b538SAndroid Build Coastguard Worker *URI = uri;
9486*6777b538SAndroid Build Coastguard Worker
9487*6777b538SAndroid Build Coastguard Worker /*
9488*6777b538SAndroid Build Coastguard Worker * SAX callback
9489*6777b538SAndroid Build Coastguard Worker */
9490*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
9491*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX)) {
9492*6777b538SAndroid Build Coastguard Worker if (nbNs > 0)
9493*6777b538SAndroid Build Coastguard Worker ctxt->sax->startElementNs(ctxt->userData, localname, prefix, uri,
9494*6777b538SAndroid Build Coastguard Worker nbNs, ctxt->nsTab + 2 * (ctxt->nsNr - nbNs),
9495*6777b538SAndroid Build Coastguard Worker nbatts / 5, nbdef, atts);
9496*6777b538SAndroid Build Coastguard Worker else
9497*6777b538SAndroid Build Coastguard Worker ctxt->sax->startElementNs(ctxt->userData, localname, prefix, uri,
9498*6777b538SAndroid Build Coastguard Worker 0, NULL, nbatts / 5, nbdef, atts);
9499*6777b538SAndroid Build Coastguard Worker }
9500*6777b538SAndroid Build Coastguard Worker
9501*6777b538SAndroid Build Coastguard Worker done:
9502*6777b538SAndroid Build Coastguard Worker /*
9503*6777b538SAndroid Build Coastguard Worker * Free allocated attribute values
9504*6777b538SAndroid Build Coastguard Worker */
9505*6777b538SAndroid Build Coastguard Worker if (attval != 0) {
9506*6777b538SAndroid Build Coastguard Worker for (i = 0, j = 0; j < nratts; i += 5, j++)
9507*6777b538SAndroid Build Coastguard Worker if (ctxt->attallocs[j] & 0x80000000)
9508*6777b538SAndroid Build Coastguard Worker xmlFree((xmlChar *) atts[i+3]);
9509*6777b538SAndroid Build Coastguard Worker }
9510*6777b538SAndroid Build Coastguard Worker
9511*6777b538SAndroid Build Coastguard Worker *nbNsPtr = nbNs;
9512*6777b538SAndroid Build Coastguard Worker return(localname);
9513*6777b538SAndroid Build Coastguard Worker }
9514*6777b538SAndroid Build Coastguard Worker
9515*6777b538SAndroid Build Coastguard Worker /**
9516*6777b538SAndroid Build Coastguard Worker * xmlParseEndTag2:
9517*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
9518*6777b538SAndroid Build Coastguard Worker * @line: line of the start tag
9519*6777b538SAndroid Build Coastguard Worker * @nsNr: number of namespaces on the start tag
9520*6777b538SAndroid Build Coastguard Worker *
9521*6777b538SAndroid Build Coastguard Worker * Parse an end tag. Always consumes '</'.
9522*6777b538SAndroid Build Coastguard Worker *
9523*6777b538SAndroid Build Coastguard Worker * [42] ETag ::= '</' Name S? '>'
9524*6777b538SAndroid Build Coastguard Worker *
9525*6777b538SAndroid Build Coastguard Worker * With namespace
9526*6777b538SAndroid Build Coastguard Worker *
9527*6777b538SAndroid Build Coastguard Worker * [NS 9] ETag ::= '</' QName S? '>'
9528*6777b538SAndroid Build Coastguard Worker */
9529*6777b538SAndroid Build Coastguard Worker
9530*6777b538SAndroid Build Coastguard Worker static void
xmlParseEndTag2(xmlParserCtxtPtr ctxt,const xmlStartTag * tag)9531*6777b538SAndroid Build Coastguard Worker xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlStartTag *tag) {
9532*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
9533*6777b538SAndroid Build Coastguard Worker
9534*6777b538SAndroid Build Coastguard Worker GROW;
9535*6777b538SAndroid Build Coastguard Worker if ((RAW != '<') || (NXT(1) != '/')) {
9536*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
9537*6777b538SAndroid Build Coastguard Worker return;
9538*6777b538SAndroid Build Coastguard Worker }
9539*6777b538SAndroid Build Coastguard Worker SKIP(2);
9540*6777b538SAndroid Build Coastguard Worker
9541*6777b538SAndroid Build Coastguard Worker if (tag->prefix == NULL)
9542*6777b538SAndroid Build Coastguard Worker name = xmlParseNameAndCompare(ctxt, ctxt->name);
9543*6777b538SAndroid Build Coastguard Worker else
9544*6777b538SAndroid Build Coastguard Worker name = xmlParseQNameAndCompare(ctxt, ctxt->name, tag->prefix);
9545*6777b538SAndroid Build Coastguard Worker
9546*6777b538SAndroid Build Coastguard Worker /*
9547*6777b538SAndroid Build Coastguard Worker * We should definitely be at the ending "S? '>'" part
9548*6777b538SAndroid Build Coastguard Worker */
9549*6777b538SAndroid Build Coastguard Worker GROW;
9550*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
9551*6777b538SAndroid Build Coastguard Worker if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
9552*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
9553*6777b538SAndroid Build Coastguard Worker } else
9554*6777b538SAndroid Build Coastguard Worker NEXT1;
9555*6777b538SAndroid Build Coastguard Worker
9556*6777b538SAndroid Build Coastguard Worker /*
9557*6777b538SAndroid Build Coastguard Worker * [ WFC: Element Type Match ]
9558*6777b538SAndroid Build Coastguard Worker * The Name in an element's end-tag must match the element type in the
9559*6777b538SAndroid Build Coastguard Worker * start-tag.
9560*6777b538SAndroid Build Coastguard Worker *
9561*6777b538SAndroid Build Coastguard Worker */
9562*6777b538SAndroid Build Coastguard Worker if (name != (xmlChar*)1) {
9563*6777b538SAndroid Build Coastguard Worker if (name == NULL) name = BAD_CAST "unparsable";
9564*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
9565*6777b538SAndroid Build Coastguard Worker "Opening and ending tag mismatch: %s line %d and %s\n",
9566*6777b538SAndroid Build Coastguard Worker ctxt->name, tag->line, name);
9567*6777b538SAndroid Build Coastguard Worker }
9568*6777b538SAndroid Build Coastguard Worker
9569*6777b538SAndroid Build Coastguard Worker /*
9570*6777b538SAndroid Build Coastguard Worker * SAX: End of Tag
9571*6777b538SAndroid Build Coastguard Worker */
9572*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9573*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
9574*6777b538SAndroid Build Coastguard Worker ctxt->sax->endElementNs(ctxt->userData, ctxt->name, tag->prefix,
9575*6777b538SAndroid Build Coastguard Worker tag->URI);
9576*6777b538SAndroid Build Coastguard Worker
9577*6777b538SAndroid Build Coastguard Worker spacePop(ctxt);
9578*6777b538SAndroid Build Coastguard Worker if (tag->nsNr != 0)
9579*6777b538SAndroid Build Coastguard Worker xmlParserNsPop(ctxt, tag->nsNr);
9580*6777b538SAndroid Build Coastguard Worker }
9581*6777b538SAndroid Build Coastguard Worker
9582*6777b538SAndroid Build Coastguard Worker /**
9583*6777b538SAndroid Build Coastguard Worker * xmlParseCDSect:
9584*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
9585*6777b538SAndroid Build Coastguard Worker *
9586*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
9587*6777b538SAndroid Build Coastguard Worker *
9588*6777b538SAndroid Build Coastguard Worker * Parse escaped pure raw content. Always consumes '<!['.
9589*6777b538SAndroid Build Coastguard Worker *
9590*6777b538SAndroid Build Coastguard Worker * [18] CDSect ::= CDStart CData CDEnd
9591*6777b538SAndroid Build Coastguard Worker *
9592*6777b538SAndroid Build Coastguard Worker * [19] CDStart ::= '<![CDATA['
9593*6777b538SAndroid Build Coastguard Worker *
9594*6777b538SAndroid Build Coastguard Worker * [20] Data ::= (Char* - (Char* ']]>' Char*))
9595*6777b538SAndroid Build Coastguard Worker *
9596*6777b538SAndroid Build Coastguard Worker * [21] CDEnd ::= ']]>'
9597*6777b538SAndroid Build Coastguard Worker */
9598*6777b538SAndroid Build Coastguard Worker void
xmlParseCDSect(xmlParserCtxtPtr ctxt)9599*6777b538SAndroid Build Coastguard Worker xmlParseCDSect(xmlParserCtxtPtr ctxt) {
9600*6777b538SAndroid Build Coastguard Worker xmlChar *buf = NULL;
9601*6777b538SAndroid Build Coastguard Worker int len = 0;
9602*6777b538SAndroid Build Coastguard Worker int size = XML_PARSER_BUFFER_SIZE;
9603*6777b538SAndroid Build Coastguard Worker int r, rl;
9604*6777b538SAndroid Build Coastguard Worker int s, sl;
9605*6777b538SAndroid Build Coastguard Worker int cur, l;
9606*6777b538SAndroid Build Coastguard Worker int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
9607*6777b538SAndroid Build Coastguard Worker XML_MAX_HUGE_LENGTH :
9608*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH;
9609*6777b538SAndroid Build Coastguard Worker
9610*6777b538SAndroid Build Coastguard Worker if ((CUR != '<') || (NXT(1) != '!') || (NXT(2) != '['))
9611*6777b538SAndroid Build Coastguard Worker return;
9612*6777b538SAndroid Build Coastguard Worker SKIP(3);
9613*6777b538SAndroid Build Coastguard Worker
9614*6777b538SAndroid Build Coastguard Worker if (!CMP6(CUR_PTR, 'C', 'D', 'A', 'T', 'A', '['))
9615*6777b538SAndroid Build Coastguard Worker return;
9616*6777b538SAndroid Build Coastguard Worker SKIP(6);
9617*6777b538SAndroid Build Coastguard Worker
9618*6777b538SAndroid Build Coastguard Worker r = CUR_CHAR(rl);
9619*6777b538SAndroid Build Coastguard Worker if (!IS_CHAR(r)) {
9620*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9621*6777b538SAndroid Build Coastguard Worker goto out;
9622*6777b538SAndroid Build Coastguard Worker }
9623*6777b538SAndroid Build Coastguard Worker NEXTL(rl);
9624*6777b538SAndroid Build Coastguard Worker s = CUR_CHAR(sl);
9625*6777b538SAndroid Build Coastguard Worker if (!IS_CHAR(s)) {
9626*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9627*6777b538SAndroid Build Coastguard Worker goto out;
9628*6777b538SAndroid Build Coastguard Worker }
9629*6777b538SAndroid Build Coastguard Worker NEXTL(sl);
9630*6777b538SAndroid Build Coastguard Worker cur = CUR_CHAR(l);
9631*6777b538SAndroid Build Coastguard Worker buf = (xmlChar *) xmlMallocAtomic(size);
9632*6777b538SAndroid Build Coastguard Worker if (buf == NULL) {
9633*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
9634*6777b538SAndroid Build Coastguard Worker goto out;
9635*6777b538SAndroid Build Coastguard Worker }
9636*6777b538SAndroid Build Coastguard Worker while (IS_CHAR(cur) &&
9637*6777b538SAndroid Build Coastguard Worker ((r != ']') || (s != ']') || (cur != '>'))) {
9638*6777b538SAndroid Build Coastguard Worker if (len + 5 >= size) {
9639*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
9640*6777b538SAndroid Build Coastguard Worker
9641*6777b538SAndroid Build Coastguard Worker tmp = (xmlChar *) xmlRealloc(buf, size * 2);
9642*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
9643*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
9644*6777b538SAndroid Build Coastguard Worker goto out;
9645*6777b538SAndroid Build Coastguard Worker }
9646*6777b538SAndroid Build Coastguard Worker buf = tmp;
9647*6777b538SAndroid Build Coastguard Worker size *= 2;
9648*6777b538SAndroid Build Coastguard Worker }
9649*6777b538SAndroid Build Coastguard Worker COPY_BUF(buf, len, r);
9650*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
9651*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9652*6777b538SAndroid Build Coastguard Worker "CData section too big found\n");
9653*6777b538SAndroid Build Coastguard Worker goto out;
9654*6777b538SAndroid Build Coastguard Worker }
9655*6777b538SAndroid Build Coastguard Worker r = s;
9656*6777b538SAndroid Build Coastguard Worker rl = sl;
9657*6777b538SAndroid Build Coastguard Worker s = cur;
9658*6777b538SAndroid Build Coastguard Worker sl = l;
9659*6777b538SAndroid Build Coastguard Worker NEXTL(l);
9660*6777b538SAndroid Build Coastguard Worker cur = CUR_CHAR(l);
9661*6777b538SAndroid Build Coastguard Worker }
9662*6777b538SAndroid Build Coastguard Worker buf[len] = 0;
9663*6777b538SAndroid Build Coastguard Worker if (cur != '>') {
9664*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9665*6777b538SAndroid Build Coastguard Worker "CData section not finished\n%.50s\n", buf);
9666*6777b538SAndroid Build Coastguard Worker goto out;
9667*6777b538SAndroid Build Coastguard Worker }
9668*6777b538SAndroid Build Coastguard Worker NEXTL(l);
9669*6777b538SAndroid Build Coastguard Worker
9670*6777b538SAndroid Build Coastguard Worker /*
9671*6777b538SAndroid Build Coastguard Worker * OK the buffer is to be consumed as cdata.
9672*6777b538SAndroid Build Coastguard Worker */
9673*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
9674*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->cdataBlock != NULL)
9675*6777b538SAndroid Build Coastguard Worker ctxt->sax->cdataBlock(ctxt->userData, buf, len);
9676*6777b538SAndroid Build Coastguard Worker else if (ctxt->sax->characters != NULL)
9677*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData, buf, len);
9678*6777b538SAndroid Build Coastguard Worker }
9679*6777b538SAndroid Build Coastguard Worker
9680*6777b538SAndroid Build Coastguard Worker out:
9681*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
9682*6777b538SAndroid Build Coastguard Worker }
9683*6777b538SAndroid Build Coastguard Worker
9684*6777b538SAndroid Build Coastguard Worker /**
9685*6777b538SAndroid Build Coastguard Worker * xmlParseContentInternal:
9686*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
9687*6777b538SAndroid Build Coastguard Worker *
9688*6777b538SAndroid Build Coastguard Worker * Parse a content sequence. Stops at EOF or '</'. Leaves checking of
9689*6777b538SAndroid Build Coastguard Worker * unexpected EOF to the caller.
9690*6777b538SAndroid Build Coastguard Worker */
9691*6777b538SAndroid Build Coastguard Worker
9692*6777b538SAndroid Build Coastguard Worker static void
xmlParseContentInternal(xmlParserCtxtPtr ctxt)9693*6777b538SAndroid Build Coastguard Worker xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
9694*6777b538SAndroid Build Coastguard Worker int oldNameNr = ctxt->nameNr;
9695*6777b538SAndroid Build Coastguard Worker int oldSpaceNr = ctxt->spaceNr;
9696*6777b538SAndroid Build Coastguard Worker int oldNodeNr = ctxt->nodeNr;
9697*6777b538SAndroid Build Coastguard Worker
9698*6777b538SAndroid Build Coastguard Worker GROW;
9699*6777b538SAndroid Build Coastguard Worker while ((ctxt->input->cur < ctxt->input->end) &&
9700*6777b538SAndroid Build Coastguard Worker (PARSER_STOPPED(ctxt) == 0)) {
9701*6777b538SAndroid Build Coastguard Worker const xmlChar *cur = ctxt->input->cur;
9702*6777b538SAndroid Build Coastguard Worker
9703*6777b538SAndroid Build Coastguard Worker /*
9704*6777b538SAndroid Build Coastguard Worker * First case : a Processing Instruction.
9705*6777b538SAndroid Build Coastguard Worker */
9706*6777b538SAndroid Build Coastguard Worker if ((*cur == '<') && (cur[1] == '?')) {
9707*6777b538SAndroid Build Coastguard Worker xmlParsePI(ctxt);
9708*6777b538SAndroid Build Coastguard Worker }
9709*6777b538SAndroid Build Coastguard Worker
9710*6777b538SAndroid Build Coastguard Worker /*
9711*6777b538SAndroid Build Coastguard Worker * Second case : a CDSection
9712*6777b538SAndroid Build Coastguard Worker */
9713*6777b538SAndroid Build Coastguard Worker /* 2.6.0 test was *cur not RAW */
9714*6777b538SAndroid Build Coastguard Worker else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9715*6777b538SAndroid Build Coastguard Worker xmlParseCDSect(ctxt);
9716*6777b538SAndroid Build Coastguard Worker }
9717*6777b538SAndroid Build Coastguard Worker
9718*6777b538SAndroid Build Coastguard Worker /*
9719*6777b538SAndroid Build Coastguard Worker * Third case : a comment
9720*6777b538SAndroid Build Coastguard Worker */
9721*6777b538SAndroid Build Coastguard Worker else if ((*cur == '<') && (NXT(1) == '!') &&
9722*6777b538SAndroid Build Coastguard Worker (NXT(2) == '-') && (NXT(3) == '-')) {
9723*6777b538SAndroid Build Coastguard Worker xmlParseComment(ctxt);
9724*6777b538SAndroid Build Coastguard Worker }
9725*6777b538SAndroid Build Coastguard Worker
9726*6777b538SAndroid Build Coastguard Worker /*
9727*6777b538SAndroid Build Coastguard Worker * Fourth case : a sub-element.
9728*6777b538SAndroid Build Coastguard Worker */
9729*6777b538SAndroid Build Coastguard Worker else if (*cur == '<') {
9730*6777b538SAndroid Build Coastguard Worker if (NXT(1) == '/') {
9731*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr <= oldNameNr)
9732*6777b538SAndroid Build Coastguard Worker break;
9733*6777b538SAndroid Build Coastguard Worker xmlParseElementEnd(ctxt);
9734*6777b538SAndroid Build Coastguard Worker } else {
9735*6777b538SAndroid Build Coastguard Worker xmlParseElementStart(ctxt);
9736*6777b538SAndroid Build Coastguard Worker }
9737*6777b538SAndroid Build Coastguard Worker }
9738*6777b538SAndroid Build Coastguard Worker
9739*6777b538SAndroid Build Coastguard Worker /*
9740*6777b538SAndroid Build Coastguard Worker * Fifth case : a reference. If if has not been resolved,
9741*6777b538SAndroid Build Coastguard Worker * parsing returns it's Name, create the node
9742*6777b538SAndroid Build Coastguard Worker */
9743*6777b538SAndroid Build Coastguard Worker
9744*6777b538SAndroid Build Coastguard Worker else if (*cur == '&') {
9745*6777b538SAndroid Build Coastguard Worker xmlParseReference(ctxt);
9746*6777b538SAndroid Build Coastguard Worker }
9747*6777b538SAndroid Build Coastguard Worker
9748*6777b538SAndroid Build Coastguard Worker /*
9749*6777b538SAndroid Build Coastguard Worker * Last case, text. Note that References are handled directly.
9750*6777b538SAndroid Build Coastguard Worker */
9751*6777b538SAndroid Build Coastguard Worker else {
9752*6777b538SAndroid Build Coastguard Worker xmlParseCharDataInternal(ctxt, 0);
9753*6777b538SAndroid Build Coastguard Worker }
9754*6777b538SAndroid Build Coastguard Worker
9755*6777b538SAndroid Build Coastguard Worker SHRINK;
9756*6777b538SAndroid Build Coastguard Worker GROW;
9757*6777b538SAndroid Build Coastguard Worker }
9758*6777b538SAndroid Build Coastguard Worker
9759*6777b538SAndroid Build Coastguard Worker if ((ctxt->nameNr > oldNameNr) &&
9760*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur >= ctxt->input->end) &&
9761*6777b538SAndroid Build Coastguard Worker (ctxt->wellFormed)) {
9762*6777b538SAndroid Build Coastguard Worker const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
9763*6777b538SAndroid Build Coastguard Worker int line = ctxt->pushTab[ctxt->nameNr - 1].line;
9764*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
9765*6777b538SAndroid Build Coastguard Worker "Premature end of data in tag %s line %d\n",
9766*6777b538SAndroid Build Coastguard Worker name, line, NULL);
9767*6777b538SAndroid Build Coastguard Worker }
9768*6777b538SAndroid Build Coastguard Worker
9769*6777b538SAndroid Build Coastguard Worker /*
9770*6777b538SAndroid Build Coastguard Worker * Clean up in error case
9771*6777b538SAndroid Build Coastguard Worker */
9772*6777b538SAndroid Build Coastguard Worker
9773*6777b538SAndroid Build Coastguard Worker while (ctxt->nodeNr > oldNodeNr)
9774*6777b538SAndroid Build Coastguard Worker nodePop(ctxt);
9775*6777b538SAndroid Build Coastguard Worker
9776*6777b538SAndroid Build Coastguard Worker while (ctxt->nameNr > oldNameNr) {
9777*6777b538SAndroid Build Coastguard Worker xmlStartTag *tag = &ctxt->pushTab[ctxt->nameNr - 1];
9778*6777b538SAndroid Build Coastguard Worker
9779*6777b538SAndroid Build Coastguard Worker if (tag->nsNr != 0)
9780*6777b538SAndroid Build Coastguard Worker xmlParserNsPop(ctxt, tag->nsNr);
9781*6777b538SAndroid Build Coastguard Worker
9782*6777b538SAndroid Build Coastguard Worker namePop(ctxt);
9783*6777b538SAndroid Build Coastguard Worker }
9784*6777b538SAndroid Build Coastguard Worker
9785*6777b538SAndroid Build Coastguard Worker while (ctxt->spaceNr > oldSpaceNr)
9786*6777b538SAndroid Build Coastguard Worker spacePop(ctxt);
9787*6777b538SAndroid Build Coastguard Worker }
9788*6777b538SAndroid Build Coastguard Worker
9789*6777b538SAndroid Build Coastguard Worker /**
9790*6777b538SAndroid Build Coastguard Worker * xmlParseContent:
9791*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
9792*6777b538SAndroid Build Coastguard Worker *
9793*6777b538SAndroid Build Coastguard Worker * Parse XML element content. This is useful if you're only interested
9794*6777b538SAndroid Build Coastguard Worker * in custom SAX callbacks. If you want a node list, use
9795*6777b538SAndroid Build Coastguard Worker * xmlParseInNodeContext.
9796*6777b538SAndroid Build Coastguard Worker */
9797*6777b538SAndroid Build Coastguard Worker void
xmlParseContent(xmlParserCtxtPtr ctxt)9798*6777b538SAndroid Build Coastguard Worker xmlParseContent(xmlParserCtxtPtr ctxt) {
9799*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->input == NULL))
9800*6777b538SAndroid Build Coastguard Worker return;
9801*6777b538SAndroid Build Coastguard Worker
9802*6777b538SAndroid Build Coastguard Worker xmlCtxtInitializeLate(ctxt);
9803*6777b538SAndroid Build Coastguard Worker
9804*6777b538SAndroid Build Coastguard Worker xmlParseContentInternal(ctxt);
9805*6777b538SAndroid Build Coastguard Worker
9806*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur < ctxt->input->end)
9807*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
9808*6777b538SAndroid Build Coastguard Worker }
9809*6777b538SAndroid Build Coastguard Worker
9810*6777b538SAndroid Build Coastguard Worker /**
9811*6777b538SAndroid Build Coastguard Worker * xmlParseElement:
9812*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
9813*6777b538SAndroid Build Coastguard Worker *
9814*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
9815*6777b538SAndroid Build Coastguard Worker *
9816*6777b538SAndroid Build Coastguard Worker * parse an XML element
9817*6777b538SAndroid Build Coastguard Worker *
9818*6777b538SAndroid Build Coastguard Worker * [39] element ::= EmptyElemTag | STag content ETag
9819*6777b538SAndroid Build Coastguard Worker *
9820*6777b538SAndroid Build Coastguard Worker * [ WFC: Element Type Match ]
9821*6777b538SAndroid Build Coastguard Worker * The Name in an element's end-tag must match the element type in the
9822*6777b538SAndroid Build Coastguard Worker * start-tag.
9823*6777b538SAndroid Build Coastguard Worker *
9824*6777b538SAndroid Build Coastguard Worker */
9825*6777b538SAndroid Build Coastguard Worker
9826*6777b538SAndroid Build Coastguard Worker void
xmlParseElement(xmlParserCtxtPtr ctxt)9827*6777b538SAndroid Build Coastguard Worker xmlParseElement(xmlParserCtxtPtr ctxt) {
9828*6777b538SAndroid Build Coastguard Worker if (xmlParseElementStart(ctxt) != 0)
9829*6777b538SAndroid Build Coastguard Worker return;
9830*6777b538SAndroid Build Coastguard Worker
9831*6777b538SAndroid Build Coastguard Worker xmlParseContentInternal(ctxt);
9832*6777b538SAndroid Build Coastguard Worker
9833*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur >= ctxt->input->end) {
9834*6777b538SAndroid Build Coastguard Worker if (ctxt->wellFormed) {
9835*6777b538SAndroid Build Coastguard Worker const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
9836*6777b538SAndroid Build Coastguard Worker int line = ctxt->pushTab[ctxt->nameNr - 1].line;
9837*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
9838*6777b538SAndroid Build Coastguard Worker "Premature end of data in tag %s line %d\n",
9839*6777b538SAndroid Build Coastguard Worker name, line, NULL);
9840*6777b538SAndroid Build Coastguard Worker }
9841*6777b538SAndroid Build Coastguard Worker return;
9842*6777b538SAndroid Build Coastguard Worker }
9843*6777b538SAndroid Build Coastguard Worker
9844*6777b538SAndroid Build Coastguard Worker xmlParseElementEnd(ctxt);
9845*6777b538SAndroid Build Coastguard Worker }
9846*6777b538SAndroid Build Coastguard Worker
9847*6777b538SAndroid Build Coastguard Worker /**
9848*6777b538SAndroid Build Coastguard Worker * xmlParseElementStart:
9849*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
9850*6777b538SAndroid Build Coastguard Worker *
9851*6777b538SAndroid Build Coastguard Worker * Parse the start of an XML element. Returns -1 in case of error, 0 if an
9852*6777b538SAndroid Build Coastguard Worker * opening tag was parsed, 1 if an empty element was parsed.
9853*6777b538SAndroid Build Coastguard Worker *
9854*6777b538SAndroid Build Coastguard Worker * Always consumes '<'.
9855*6777b538SAndroid Build Coastguard Worker */
9856*6777b538SAndroid Build Coastguard Worker static int
xmlParseElementStart(xmlParserCtxtPtr ctxt)9857*6777b538SAndroid Build Coastguard Worker xmlParseElementStart(xmlParserCtxtPtr ctxt) {
9858*6777b538SAndroid Build Coastguard Worker int maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 2048 : 256;
9859*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
9860*6777b538SAndroid Build Coastguard Worker const xmlChar *prefix = NULL;
9861*6777b538SAndroid Build Coastguard Worker const xmlChar *URI = NULL;
9862*6777b538SAndroid Build Coastguard Worker xmlParserNodeInfo node_info;
9863*6777b538SAndroid Build Coastguard Worker int line;
9864*6777b538SAndroid Build Coastguard Worker xmlNodePtr cur;
9865*6777b538SAndroid Build Coastguard Worker int nbNs = 0;
9866*6777b538SAndroid Build Coastguard Worker
9867*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr > maxDepth) {
9868*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgInt(ctxt, XML_ERR_RESOURCE_LIMIT,
9869*6777b538SAndroid Build Coastguard Worker "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
9870*6777b538SAndroid Build Coastguard Worker ctxt->nameNr);
9871*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
9872*6777b538SAndroid Build Coastguard Worker return(-1);
9873*6777b538SAndroid Build Coastguard Worker }
9874*6777b538SAndroid Build Coastguard Worker
9875*6777b538SAndroid Build Coastguard Worker /* Capture start position */
9876*6777b538SAndroid Build Coastguard Worker if (ctxt->record_info) {
9877*6777b538SAndroid Build Coastguard Worker node_info.begin_pos = ctxt->input->consumed +
9878*6777b538SAndroid Build Coastguard Worker (CUR_PTR - ctxt->input->base);
9879*6777b538SAndroid Build Coastguard Worker node_info.begin_line = ctxt->input->line;
9880*6777b538SAndroid Build Coastguard Worker }
9881*6777b538SAndroid Build Coastguard Worker
9882*6777b538SAndroid Build Coastguard Worker if (ctxt->spaceNr == 0)
9883*6777b538SAndroid Build Coastguard Worker spacePush(ctxt, -1);
9884*6777b538SAndroid Build Coastguard Worker else if (*ctxt->space == -2)
9885*6777b538SAndroid Build Coastguard Worker spacePush(ctxt, -1);
9886*6777b538SAndroid Build Coastguard Worker else
9887*6777b538SAndroid Build Coastguard Worker spacePush(ctxt, *ctxt->space);
9888*6777b538SAndroid Build Coastguard Worker
9889*6777b538SAndroid Build Coastguard Worker line = ctxt->input->line;
9890*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
9891*6777b538SAndroid Build Coastguard Worker if (ctxt->sax2)
9892*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
9893*6777b538SAndroid Build Coastguard Worker name = xmlParseStartTag2(ctxt, &prefix, &URI, &nbNs);
9894*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
9895*6777b538SAndroid Build Coastguard Worker else
9896*6777b538SAndroid Build Coastguard Worker name = xmlParseStartTag(ctxt);
9897*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
9898*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
9899*6777b538SAndroid Build Coastguard Worker spacePop(ctxt);
9900*6777b538SAndroid Build Coastguard Worker return(-1);
9901*6777b538SAndroid Build Coastguard Worker }
9902*6777b538SAndroid Build Coastguard Worker nameNsPush(ctxt, name, prefix, URI, line, nbNs);
9903*6777b538SAndroid Build Coastguard Worker cur = ctxt->node;
9904*6777b538SAndroid Build Coastguard Worker
9905*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_VALID_ENABLED
9906*6777b538SAndroid Build Coastguard Worker /*
9907*6777b538SAndroid Build Coastguard Worker * [ VC: Root Element Type ]
9908*6777b538SAndroid Build Coastguard Worker * The Name in the document type declaration must match the element
9909*6777b538SAndroid Build Coastguard Worker * type of the root element.
9910*6777b538SAndroid Build Coastguard Worker */
9911*6777b538SAndroid Build Coastguard Worker if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
9912*6777b538SAndroid Build Coastguard Worker ctxt->node && (ctxt->node == ctxt->myDoc->children))
9913*6777b538SAndroid Build Coastguard Worker ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
9914*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_VALID_ENABLED */
9915*6777b538SAndroid Build Coastguard Worker
9916*6777b538SAndroid Build Coastguard Worker /*
9917*6777b538SAndroid Build Coastguard Worker * Check for an Empty Element.
9918*6777b538SAndroid Build Coastguard Worker */
9919*6777b538SAndroid Build Coastguard Worker if ((RAW == '/') && (NXT(1) == '>')) {
9920*6777b538SAndroid Build Coastguard Worker SKIP(2);
9921*6777b538SAndroid Build Coastguard Worker if (ctxt->sax2) {
9922*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9923*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
9924*6777b538SAndroid Build Coastguard Worker ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
9925*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
9926*6777b538SAndroid Build Coastguard Worker } else {
9927*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
9928*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
9929*6777b538SAndroid Build Coastguard Worker ctxt->sax->endElement(ctxt->userData, name);
9930*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
9931*6777b538SAndroid Build Coastguard Worker }
9932*6777b538SAndroid Build Coastguard Worker namePop(ctxt);
9933*6777b538SAndroid Build Coastguard Worker spacePop(ctxt);
9934*6777b538SAndroid Build Coastguard Worker if (nbNs > 0)
9935*6777b538SAndroid Build Coastguard Worker xmlParserNsPop(ctxt, nbNs);
9936*6777b538SAndroid Build Coastguard Worker if (cur != NULL && ctxt->record_info) {
9937*6777b538SAndroid Build Coastguard Worker node_info.node = cur;
9938*6777b538SAndroid Build Coastguard Worker node_info.end_pos = ctxt->input->consumed +
9939*6777b538SAndroid Build Coastguard Worker (CUR_PTR - ctxt->input->base);
9940*6777b538SAndroid Build Coastguard Worker node_info.end_line = ctxt->input->line;
9941*6777b538SAndroid Build Coastguard Worker xmlParserAddNodeInfo(ctxt, &node_info);
9942*6777b538SAndroid Build Coastguard Worker }
9943*6777b538SAndroid Build Coastguard Worker return(1);
9944*6777b538SAndroid Build Coastguard Worker }
9945*6777b538SAndroid Build Coastguard Worker if (RAW == '>') {
9946*6777b538SAndroid Build Coastguard Worker NEXT1;
9947*6777b538SAndroid Build Coastguard Worker if (cur != NULL && ctxt->record_info) {
9948*6777b538SAndroid Build Coastguard Worker node_info.node = cur;
9949*6777b538SAndroid Build Coastguard Worker node_info.end_pos = 0;
9950*6777b538SAndroid Build Coastguard Worker node_info.end_line = 0;
9951*6777b538SAndroid Build Coastguard Worker xmlParserAddNodeInfo(ctxt, &node_info);
9952*6777b538SAndroid Build Coastguard Worker }
9953*6777b538SAndroid Build Coastguard Worker } else {
9954*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
9955*6777b538SAndroid Build Coastguard Worker "Couldn't find end of Start Tag %s line %d\n",
9956*6777b538SAndroid Build Coastguard Worker name, line, NULL);
9957*6777b538SAndroid Build Coastguard Worker
9958*6777b538SAndroid Build Coastguard Worker /*
9959*6777b538SAndroid Build Coastguard Worker * end of parsing of this node.
9960*6777b538SAndroid Build Coastguard Worker */
9961*6777b538SAndroid Build Coastguard Worker nodePop(ctxt);
9962*6777b538SAndroid Build Coastguard Worker namePop(ctxt);
9963*6777b538SAndroid Build Coastguard Worker spacePop(ctxt);
9964*6777b538SAndroid Build Coastguard Worker if (nbNs > 0)
9965*6777b538SAndroid Build Coastguard Worker xmlParserNsPop(ctxt, nbNs);
9966*6777b538SAndroid Build Coastguard Worker return(-1);
9967*6777b538SAndroid Build Coastguard Worker }
9968*6777b538SAndroid Build Coastguard Worker
9969*6777b538SAndroid Build Coastguard Worker return(0);
9970*6777b538SAndroid Build Coastguard Worker }
9971*6777b538SAndroid Build Coastguard Worker
9972*6777b538SAndroid Build Coastguard Worker /**
9973*6777b538SAndroid Build Coastguard Worker * xmlParseElementEnd:
9974*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
9975*6777b538SAndroid Build Coastguard Worker *
9976*6777b538SAndroid Build Coastguard Worker * Parse the end of an XML element. Always consumes '</'.
9977*6777b538SAndroid Build Coastguard Worker */
9978*6777b538SAndroid Build Coastguard Worker static void
xmlParseElementEnd(xmlParserCtxtPtr ctxt)9979*6777b538SAndroid Build Coastguard Worker xmlParseElementEnd(xmlParserCtxtPtr ctxt) {
9980*6777b538SAndroid Build Coastguard Worker xmlNodePtr cur = ctxt->node;
9981*6777b538SAndroid Build Coastguard Worker
9982*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr <= 0) {
9983*6777b538SAndroid Build Coastguard Worker if ((RAW == '<') && (NXT(1) == '/'))
9984*6777b538SAndroid Build Coastguard Worker SKIP(2);
9985*6777b538SAndroid Build Coastguard Worker return;
9986*6777b538SAndroid Build Coastguard Worker }
9987*6777b538SAndroid Build Coastguard Worker
9988*6777b538SAndroid Build Coastguard Worker /*
9989*6777b538SAndroid Build Coastguard Worker * parse the end of tag: '</' should be here.
9990*6777b538SAndroid Build Coastguard Worker */
9991*6777b538SAndroid Build Coastguard Worker if (ctxt->sax2) {
9992*6777b538SAndroid Build Coastguard Worker xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]);
9993*6777b538SAndroid Build Coastguard Worker namePop(ctxt);
9994*6777b538SAndroid Build Coastguard Worker }
9995*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
9996*6777b538SAndroid Build Coastguard Worker else
9997*6777b538SAndroid Build Coastguard Worker xmlParseEndTag1(ctxt, 0);
9998*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
9999*6777b538SAndroid Build Coastguard Worker
10000*6777b538SAndroid Build Coastguard Worker /*
10001*6777b538SAndroid Build Coastguard Worker * Capture end position
10002*6777b538SAndroid Build Coastguard Worker */
10003*6777b538SAndroid Build Coastguard Worker if (cur != NULL && ctxt->record_info) {
10004*6777b538SAndroid Build Coastguard Worker xmlParserNodeInfoPtr node_info;
10005*6777b538SAndroid Build Coastguard Worker
10006*6777b538SAndroid Build Coastguard Worker node_info = (xmlParserNodeInfoPtr) xmlParserFindNodeInfo(ctxt, cur);
10007*6777b538SAndroid Build Coastguard Worker if (node_info != NULL) {
10008*6777b538SAndroid Build Coastguard Worker node_info->end_pos = ctxt->input->consumed +
10009*6777b538SAndroid Build Coastguard Worker (CUR_PTR - ctxt->input->base);
10010*6777b538SAndroid Build Coastguard Worker node_info->end_line = ctxt->input->line;
10011*6777b538SAndroid Build Coastguard Worker }
10012*6777b538SAndroid Build Coastguard Worker }
10013*6777b538SAndroid Build Coastguard Worker }
10014*6777b538SAndroid Build Coastguard Worker
10015*6777b538SAndroid Build Coastguard Worker /**
10016*6777b538SAndroid Build Coastguard Worker * xmlParseVersionNum:
10017*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10018*6777b538SAndroid Build Coastguard Worker *
10019*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
10020*6777b538SAndroid Build Coastguard Worker *
10021*6777b538SAndroid Build Coastguard Worker * parse the XML version value.
10022*6777b538SAndroid Build Coastguard Worker *
10023*6777b538SAndroid Build Coastguard Worker * [26] VersionNum ::= '1.' [0-9]+
10024*6777b538SAndroid Build Coastguard Worker *
10025*6777b538SAndroid Build Coastguard Worker * In practice allow [0-9].[0-9]+ at that level
10026*6777b538SAndroid Build Coastguard Worker *
10027*6777b538SAndroid Build Coastguard Worker * Returns the string giving the XML version number, or NULL
10028*6777b538SAndroid Build Coastguard Worker */
10029*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlParseVersionNum(xmlParserCtxtPtr ctxt)10030*6777b538SAndroid Build Coastguard Worker xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
10031*6777b538SAndroid Build Coastguard Worker xmlChar *buf = NULL;
10032*6777b538SAndroid Build Coastguard Worker int len = 0;
10033*6777b538SAndroid Build Coastguard Worker int size = 10;
10034*6777b538SAndroid Build Coastguard Worker xmlChar cur;
10035*6777b538SAndroid Build Coastguard Worker
10036*6777b538SAndroid Build Coastguard Worker buf = (xmlChar *) xmlMallocAtomic(size);
10037*6777b538SAndroid Build Coastguard Worker if (buf == NULL) {
10038*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
10039*6777b538SAndroid Build Coastguard Worker return(NULL);
10040*6777b538SAndroid Build Coastguard Worker }
10041*6777b538SAndroid Build Coastguard Worker cur = CUR;
10042*6777b538SAndroid Build Coastguard Worker if (!((cur >= '0') && (cur <= '9'))) {
10043*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
10044*6777b538SAndroid Build Coastguard Worker return(NULL);
10045*6777b538SAndroid Build Coastguard Worker }
10046*6777b538SAndroid Build Coastguard Worker buf[len++] = cur;
10047*6777b538SAndroid Build Coastguard Worker NEXT;
10048*6777b538SAndroid Build Coastguard Worker cur=CUR;
10049*6777b538SAndroid Build Coastguard Worker if (cur != '.') {
10050*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
10051*6777b538SAndroid Build Coastguard Worker return(NULL);
10052*6777b538SAndroid Build Coastguard Worker }
10053*6777b538SAndroid Build Coastguard Worker buf[len++] = cur;
10054*6777b538SAndroid Build Coastguard Worker NEXT;
10055*6777b538SAndroid Build Coastguard Worker cur=CUR;
10056*6777b538SAndroid Build Coastguard Worker while ((cur >= '0') && (cur <= '9')) {
10057*6777b538SAndroid Build Coastguard Worker if (len + 1 >= size) {
10058*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
10059*6777b538SAndroid Build Coastguard Worker
10060*6777b538SAndroid Build Coastguard Worker size *= 2;
10061*6777b538SAndroid Build Coastguard Worker tmp = (xmlChar *) xmlRealloc(buf, size);
10062*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
10063*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
10064*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
10065*6777b538SAndroid Build Coastguard Worker return(NULL);
10066*6777b538SAndroid Build Coastguard Worker }
10067*6777b538SAndroid Build Coastguard Worker buf = tmp;
10068*6777b538SAndroid Build Coastguard Worker }
10069*6777b538SAndroid Build Coastguard Worker buf[len++] = cur;
10070*6777b538SAndroid Build Coastguard Worker NEXT;
10071*6777b538SAndroid Build Coastguard Worker cur=CUR;
10072*6777b538SAndroid Build Coastguard Worker }
10073*6777b538SAndroid Build Coastguard Worker buf[len] = 0;
10074*6777b538SAndroid Build Coastguard Worker return(buf);
10075*6777b538SAndroid Build Coastguard Worker }
10076*6777b538SAndroid Build Coastguard Worker
10077*6777b538SAndroid Build Coastguard Worker /**
10078*6777b538SAndroid Build Coastguard Worker * xmlParseVersionInfo:
10079*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10080*6777b538SAndroid Build Coastguard Worker *
10081*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
10082*6777b538SAndroid Build Coastguard Worker *
10083*6777b538SAndroid Build Coastguard Worker * parse the XML version.
10084*6777b538SAndroid Build Coastguard Worker *
10085*6777b538SAndroid Build Coastguard Worker * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
10086*6777b538SAndroid Build Coastguard Worker *
10087*6777b538SAndroid Build Coastguard Worker * [25] Eq ::= S? '=' S?
10088*6777b538SAndroid Build Coastguard Worker *
10089*6777b538SAndroid Build Coastguard Worker * Returns the version string, e.g. "1.0"
10090*6777b538SAndroid Build Coastguard Worker */
10091*6777b538SAndroid Build Coastguard Worker
10092*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlParseVersionInfo(xmlParserCtxtPtr ctxt)10093*6777b538SAndroid Build Coastguard Worker xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
10094*6777b538SAndroid Build Coastguard Worker xmlChar *version = NULL;
10095*6777b538SAndroid Build Coastguard Worker
10096*6777b538SAndroid Build Coastguard Worker if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
10097*6777b538SAndroid Build Coastguard Worker SKIP(7);
10098*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10099*6777b538SAndroid Build Coastguard Worker if (RAW != '=') {
10100*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10101*6777b538SAndroid Build Coastguard Worker return(NULL);
10102*6777b538SAndroid Build Coastguard Worker }
10103*6777b538SAndroid Build Coastguard Worker NEXT;
10104*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10105*6777b538SAndroid Build Coastguard Worker if (RAW == '"') {
10106*6777b538SAndroid Build Coastguard Worker NEXT;
10107*6777b538SAndroid Build Coastguard Worker version = xmlParseVersionNum(ctxt);
10108*6777b538SAndroid Build Coastguard Worker if (RAW != '"') {
10109*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10110*6777b538SAndroid Build Coastguard Worker } else
10111*6777b538SAndroid Build Coastguard Worker NEXT;
10112*6777b538SAndroid Build Coastguard Worker } else if (RAW == '\''){
10113*6777b538SAndroid Build Coastguard Worker NEXT;
10114*6777b538SAndroid Build Coastguard Worker version = xmlParseVersionNum(ctxt);
10115*6777b538SAndroid Build Coastguard Worker if (RAW != '\'') {
10116*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10117*6777b538SAndroid Build Coastguard Worker } else
10118*6777b538SAndroid Build Coastguard Worker NEXT;
10119*6777b538SAndroid Build Coastguard Worker } else {
10120*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10121*6777b538SAndroid Build Coastguard Worker }
10122*6777b538SAndroid Build Coastguard Worker }
10123*6777b538SAndroid Build Coastguard Worker return(version);
10124*6777b538SAndroid Build Coastguard Worker }
10125*6777b538SAndroid Build Coastguard Worker
10126*6777b538SAndroid Build Coastguard Worker /**
10127*6777b538SAndroid Build Coastguard Worker * xmlParseEncName:
10128*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10129*6777b538SAndroid Build Coastguard Worker *
10130*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
10131*6777b538SAndroid Build Coastguard Worker *
10132*6777b538SAndroid Build Coastguard Worker * parse the XML encoding name
10133*6777b538SAndroid Build Coastguard Worker *
10134*6777b538SAndroid Build Coastguard Worker * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
10135*6777b538SAndroid Build Coastguard Worker *
10136*6777b538SAndroid Build Coastguard Worker * Returns the encoding name value or NULL
10137*6777b538SAndroid Build Coastguard Worker */
10138*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlParseEncName(xmlParserCtxtPtr ctxt)10139*6777b538SAndroid Build Coastguard Worker xmlParseEncName(xmlParserCtxtPtr ctxt) {
10140*6777b538SAndroid Build Coastguard Worker xmlChar *buf = NULL;
10141*6777b538SAndroid Build Coastguard Worker int len = 0;
10142*6777b538SAndroid Build Coastguard Worker int size = 10;
10143*6777b538SAndroid Build Coastguard Worker int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
10144*6777b538SAndroid Build Coastguard Worker XML_MAX_TEXT_LENGTH :
10145*6777b538SAndroid Build Coastguard Worker XML_MAX_NAME_LENGTH;
10146*6777b538SAndroid Build Coastguard Worker xmlChar cur;
10147*6777b538SAndroid Build Coastguard Worker
10148*6777b538SAndroid Build Coastguard Worker cur = CUR;
10149*6777b538SAndroid Build Coastguard Worker if (((cur >= 'a') && (cur <= 'z')) ||
10150*6777b538SAndroid Build Coastguard Worker ((cur >= 'A') && (cur <= 'Z'))) {
10151*6777b538SAndroid Build Coastguard Worker buf = (xmlChar *) xmlMallocAtomic(size);
10152*6777b538SAndroid Build Coastguard Worker if (buf == NULL) {
10153*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
10154*6777b538SAndroid Build Coastguard Worker return(NULL);
10155*6777b538SAndroid Build Coastguard Worker }
10156*6777b538SAndroid Build Coastguard Worker
10157*6777b538SAndroid Build Coastguard Worker buf[len++] = cur;
10158*6777b538SAndroid Build Coastguard Worker NEXT;
10159*6777b538SAndroid Build Coastguard Worker cur = CUR;
10160*6777b538SAndroid Build Coastguard Worker while (((cur >= 'a') && (cur <= 'z')) ||
10161*6777b538SAndroid Build Coastguard Worker ((cur >= 'A') && (cur <= 'Z')) ||
10162*6777b538SAndroid Build Coastguard Worker ((cur >= '0') && (cur <= '9')) ||
10163*6777b538SAndroid Build Coastguard Worker (cur == '.') || (cur == '_') ||
10164*6777b538SAndroid Build Coastguard Worker (cur == '-')) {
10165*6777b538SAndroid Build Coastguard Worker if (len + 1 >= size) {
10166*6777b538SAndroid Build Coastguard Worker xmlChar *tmp;
10167*6777b538SAndroid Build Coastguard Worker
10168*6777b538SAndroid Build Coastguard Worker size *= 2;
10169*6777b538SAndroid Build Coastguard Worker tmp = (xmlChar *) xmlRealloc(buf, size);
10170*6777b538SAndroid Build Coastguard Worker if (tmp == NULL) {
10171*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
10172*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
10173*6777b538SAndroid Build Coastguard Worker return(NULL);
10174*6777b538SAndroid Build Coastguard Worker }
10175*6777b538SAndroid Build Coastguard Worker buf = tmp;
10176*6777b538SAndroid Build Coastguard Worker }
10177*6777b538SAndroid Build Coastguard Worker buf[len++] = cur;
10178*6777b538SAndroid Build Coastguard Worker if (len > maxLength) {
10179*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "EncName");
10180*6777b538SAndroid Build Coastguard Worker xmlFree(buf);
10181*6777b538SAndroid Build Coastguard Worker return(NULL);
10182*6777b538SAndroid Build Coastguard Worker }
10183*6777b538SAndroid Build Coastguard Worker NEXT;
10184*6777b538SAndroid Build Coastguard Worker cur = CUR;
10185*6777b538SAndroid Build Coastguard Worker }
10186*6777b538SAndroid Build Coastguard Worker buf[len] = 0;
10187*6777b538SAndroid Build Coastguard Worker } else {
10188*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
10189*6777b538SAndroid Build Coastguard Worker }
10190*6777b538SAndroid Build Coastguard Worker return(buf);
10191*6777b538SAndroid Build Coastguard Worker }
10192*6777b538SAndroid Build Coastguard Worker
10193*6777b538SAndroid Build Coastguard Worker /**
10194*6777b538SAndroid Build Coastguard Worker * xmlParseEncodingDecl:
10195*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10196*6777b538SAndroid Build Coastguard Worker *
10197*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
10198*6777b538SAndroid Build Coastguard Worker *
10199*6777b538SAndroid Build Coastguard Worker * parse the XML encoding declaration
10200*6777b538SAndroid Build Coastguard Worker *
10201*6777b538SAndroid Build Coastguard Worker * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'")
10202*6777b538SAndroid Build Coastguard Worker *
10203*6777b538SAndroid Build Coastguard Worker * this setups the conversion filters.
10204*6777b538SAndroid Build Coastguard Worker *
10205*6777b538SAndroid Build Coastguard Worker * Returns the encoding value or NULL
10206*6777b538SAndroid Build Coastguard Worker */
10207*6777b538SAndroid Build Coastguard Worker
10208*6777b538SAndroid Build Coastguard Worker const xmlChar *
xmlParseEncodingDecl(xmlParserCtxtPtr ctxt)10209*6777b538SAndroid Build Coastguard Worker xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
10210*6777b538SAndroid Build Coastguard Worker xmlChar *encoding = NULL;
10211*6777b538SAndroid Build Coastguard Worker
10212*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10213*6777b538SAndroid Build Coastguard Worker if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g') == 0)
10214*6777b538SAndroid Build Coastguard Worker return(NULL);
10215*6777b538SAndroid Build Coastguard Worker
10216*6777b538SAndroid Build Coastguard Worker SKIP(8);
10217*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10218*6777b538SAndroid Build Coastguard Worker if (RAW != '=') {
10219*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10220*6777b538SAndroid Build Coastguard Worker return(NULL);
10221*6777b538SAndroid Build Coastguard Worker }
10222*6777b538SAndroid Build Coastguard Worker NEXT;
10223*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10224*6777b538SAndroid Build Coastguard Worker if (RAW == '"') {
10225*6777b538SAndroid Build Coastguard Worker NEXT;
10226*6777b538SAndroid Build Coastguard Worker encoding = xmlParseEncName(ctxt);
10227*6777b538SAndroid Build Coastguard Worker if (RAW != '"') {
10228*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10229*6777b538SAndroid Build Coastguard Worker xmlFree((xmlChar *) encoding);
10230*6777b538SAndroid Build Coastguard Worker return(NULL);
10231*6777b538SAndroid Build Coastguard Worker } else
10232*6777b538SAndroid Build Coastguard Worker NEXT;
10233*6777b538SAndroid Build Coastguard Worker } else if (RAW == '\''){
10234*6777b538SAndroid Build Coastguard Worker NEXT;
10235*6777b538SAndroid Build Coastguard Worker encoding = xmlParseEncName(ctxt);
10236*6777b538SAndroid Build Coastguard Worker if (RAW != '\'') {
10237*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10238*6777b538SAndroid Build Coastguard Worker xmlFree((xmlChar *) encoding);
10239*6777b538SAndroid Build Coastguard Worker return(NULL);
10240*6777b538SAndroid Build Coastguard Worker } else
10241*6777b538SAndroid Build Coastguard Worker NEXT;
10242*6777b538SAndroid Build Coastguard Worker } else {
10243*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10244*6777b538SAndroid Build Coastguard Worker }
10245*6777b538SAndroid Build Coastguard Worker
10246*6777b538SAndroid Build Coastguard Worker if (encoding == NULL)
10247*6777b538SAndroid Build Coastguard Worker return(NULL);
10248*6777b538SAndroid Build Coastguard Worker
10249*6777b538SAndroid Build Coastguard Worker xmlSetDeclaredEncoding(ctxt, encoding);
10250*6777b538SAndroid Build Coastguard Worker
10251*6777b538SAndroid Build Coastguard Worker return(ctxt->encoding);
10252*6777b538SAndroid Build Coastguard Worker }
10253*6777b538SAndroid Build Coastguard Worker
10254*6777b538SAndroid Build Coastguard Worker /**
10255*6777b538SAndroid Build Coastguard Worker * xmlParseSDDecl:
10256*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10257*6777b538SAndroid Build Coastguard Worker *
10258*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
10259*6777b538SAndroid Build Coastguard Worker *
10260*6777b538SAndroid Build Coastguard Worker * parse the XML standalone declaration
10261*6777b538SAndroid Build Coastguard Worker *
10262*6777b538SAndroid Build Coastguard Worker * [32] SDDecl ::= S 'standalone' Eq
10263*6777b538SAndroid Build Coastguard Worker * (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
10264*6777b538SAndroid Build Coastguard Worker *
10265*6777b538SAndroid Build Coastguard Worker * [ VC: Standalone Document Declaration ]
10266*6777b538SAndroid Build Coastguard Worker * TODO The standalone document declaration must have the value "no"
10267*6777b538SAndroid Build Coastguard Worker * if any external markup declarations contain declarations of:
10268*6777b538SAndroid Build Coastguard Worker * - attributes with default values, if elements to which these
10269*6777b538SAndroid Build Coastguard Worker * attributes apply appear in the document without specifications
10270*6777b538SAndroid Build Coastguard Worker * of values for these attributes, or
10271*6777b538SAndroid Build Coastguard Worker * - entities (other than amp, lt, gt, apos, quot), if references
10272*6777b538SAndroid Build Coastguard Worker * to those entities appear in the document, or
10273*6777b538SAndroid Build Coastguard Worker * - attributes with values subject to normalization, where the
10274*6777b538SAndroid Build Coastguard Worker * attribute appears in the document with a value which will change
10275*6777b538SAndroid Build Coastguard Worker * as a result of normalization, or
10276*6777b538SAndroid Build Coastguard Worker * - element types with element content, if white space occurs directly
10277*6777b538SAndroid Build Coastguard Worker * within any instance of those types.
10278*6777b538SAndroid Build Coastguard Worker *
10279*6777b538SAndroid Build Coastguard Worker * Returns:
10280*6777b538SAndroid Build Coastguard Worker * 1 if standalone="yes"
10281*6777b538SAndroid Build Coastguard Worker * 0 if standalone="no"
10282*6777b538SAndroid Build Coastguard Worker * -2 if standalone attribute is missing or invalid
10283*6777b538SAndroid Build Coastguard Worker * (A standalone value of -2 means that the XML declaration was found,
10284*6777b538SAndroid Build Coastguard Worker * but no value was specified for the standalone attribute).
10285*6777b538SAndroid Build Coastguard Worker */
10286*6777b538SAndroid Build Coastguard Worker
10287*6777b538SAndroid Build Coastguard Worker int
xmlParseSDDecl(xmlParserCtxtPtr ctxt)10288*6777b538SAndroid Build Coastguard Worker xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
10289*6777b538SAndroid Build Coastguard Worker int standalone = -2;
10290*6777b538SAndroid Build Coastguard Worker
10291*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10292*6777b538SAndroid Build Coastguard Worker if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
10293*6777b538SAndroid Build Coastguard Worker SKIP(10);
10294*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10295*6777b538SAndroid Build Coastguard Worker if (RAW != '=') {
10296*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10297*6777b538SAndroid Build Coastguard Worker return(standalone);
10298*6777b538SAndroid Build Coastguard Worker }
10299*6777b538SAndroid Build Coastguard Worker NEXT;
10300*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10301*6777b538SAndroid Build Coastguard Worker if (RAW == '\''){
10302*6777b538SAndroid Build Coastguard Worker NEXT;
10303*6777b538SAndroid Build Coastguard Worker if ((RAW == 'n') && (NXT(1) == 'o')) {
10304*6777b538SAndroid Build Coastguard Worker standalone = 0;
10305*6777b538SAndroid Build Coastguard Worker SKIP(2);
10306*6777b538SAndroid Build Coastguard Worker } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10307*6777b538SAndroid Build Coastguard Worker (NXT(2) == 's')) {
10308*6777b538SAndroid Build Coastguard Worker standalone = 1;
10309*6777b538SAndroid Build Coastguard Worker SKIP(3);
10310*6777b538SAndroid Build Coastguard Worker } else {
10311*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10312*6777b538SAndroid Build Coastguard Worker }
10313*6777b538SAndroid Build Coastguard Worker if (RAW != '\'') {
10314*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10315*6777b538SAndroid Build Coastguard Worker } else
10316*6777b538SAndroid Build Coastguard Worker NEXT;
10317*6777b538SAndroid Build Coastguard Worker } else if (RAW == '"'){
10318*6777b538SAndroid Build Coastguard Worker NEXT;
10319*6777b538SAndroid Build Coastguard Worker if ((RAW == 'n') && (NXT(1) == 'o')) {
10320*6777b538SAndroid Build Coastguard Worker standalone = 0;
10321*6777b538SAndroid Build Coastguard Worker SKIP(2);
10322*6777b538SAndroid Build Coastguard Worker } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10323*6777b538SAndroid Build Coastguard Worker (NXT(2) == 's')) {
10324*6777b538SAndroid Build Coastguard Worker standalone = 1;
10325*6777b538SAndroid Build Coastguard Worker SKIP(3);
10326*6777b538SAndroid Build Coastguard Worker } else {
10327*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10328*6777b538SAndroid Build Coastguard Worker }
10329*6777b538SAndroid Build Coastguard Worker if (RAW != '"') {
10330*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10331*6777b538SAndroid Build Coastguard Worker } else
10332*6777b538SAndroid Build Coastguard Worker NEXT;
10333*6777b538SAndroid Build Coastguard Worker } else {
10334*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10335*6777b538SAndroid Build Coastguard Worker }
10336*6777b538SAndroid Build Coastguard Worker }
10337*6777b538SAndroid Build Coastguard Worker return(standalone);
10338*6777b538SAndroid Build Coastguard Worker }
10339*6777b538SAndroid Build Coastguard Worker
10340*6777b538SAndroid Build Coastguard Worker /**
10341*6777b538SAndroid Build Coastguard Worker * xmlParseXMLDecl:
10342*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10343*6777b538SAndroid Build Coastguard Worker *
10344*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
10345*6777b538SAndroid Build Coastguard Worker *
10346*6777b538SAndroid Build Coastguard Worker * parse an XML declaration header
10347*6777b538SAndroid Build Coastguard Worker *
10348*6777b538SAndroid Build Coastguard Worker * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
10349*6777b538SAndroid Build Coastguard Worker */
10350*6777b538SAndroid Build Coastguard Worker
10351*6777b538SAndroid Build Coastguard Worker void
xmlParseXMLDecl(xmlParserCtxtPtr ctxt)10352*6777b538SAndroid Build Coastguard Worker xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
10353*6777b538SAndroid Build Coastguard Worker xmlChar *version;
10354*6777b538SAndroid Build Coastguard Worker
10355*6777b538SAndroid Build Coastguard Worker /*
10356*6777b538SAndroid Build Coastguard Worker * This value for standalone indicates that the document has an
10357*6777b538SAndroid Build Coastguard Worker * XML declaration but it does not have a standalone attribute.
10358*6777b538SAndroid Build Coastguard Worker * It will be overwritten later if a standalone attribute is found.
10359*6777b538SAndroid Build Coastguard Worker */
10360*6777b538SAndroid Build Coastguard Worker
10361*6777b538SAndroid Build Coastguard Worker ctxt->standalone = -2;
10362*6777b538SAndroid Build Coastguard Worker
10363*6777b538SAndroid Build Coastguard Worker /*
10364*6777b538SAndroid Build Coastguard Worker * We know that '<?xml' is here.
10365*6777b538SAndroid Build Coastguard Worker */
10366*6777b538SAndroid Build Coastguard Worker SKIP(5);
10367*6777b538SAndroid Build Coastguard Worker
10368*6777b538SAndroid Build Coastguard Worker if (!IS_BLANK_CH(RAW)) {
10369*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
10370*6777b538SAndroid Build Coastguard Worker "Blank needed after '<?xml'\n");
10371*6777b538SAndroid Build Coastguard Worker }
10372*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10373*6777b538SAndroid Build Coastguard Worker
10374*6777b538SAndroid Build Coastguard Worker /*
10375*6777b538SAndroid Build Coastguard Worker * We must have the VersionInfo here.
10376*6777b538SAndroid Build Coastguard Worker */
10377*6777b538SAndroid Build Coastguard Worker version = xmlParseVersionInfo(ctxt);
10378*6777b538SAndroid Build Coastguard Worker if (version == NULL) {
10379*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
10380*6777b538SAndroid Build Coastguard Worker } else {
10381*6777b538SAndroid Build Coastguard Worker if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
10382*6777b538SAndroid Build Coastguard Worker /*
10383*6777b538SAndroid Build Coastguard Worker * Changed here for XML-1.0 5th edition
10384*6777b538SAndroid Build Coastguard Worker */
10385*6777b538SAndroid Build Coastguard Worker if (ctxt->options & XML_PARSE_OLD10) {
10386*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10387*6777b538SAndroid Build Coastguard Worker "Unsupported version '%s'\n",
10388*6777b538SAndroid Build Coastguard Worker version);
10389*6777b538SAndroid Build Coastguard Worker } else {
10390*6777b538SAndroid Build Coastguard Worker if ((version[0] == '1') && ((version[1] == '.'))) {
10391*6777b538SAndroid Build Coastguard Worker xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
10392*6777b538SAndroid Build Coastguard Worker "Unsupported version '%s'\n",
10393*6777b538SAndroid Build Coastguard Worker version, NULL);
10394*6777b538SAndroid Build Coastguard Worker } else {
10395*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10396*6777b538SAndroid Build Coastguard Worker "Unsupported version '%s'\n",
10397*6777b538SAndroid Build Coastguard Worker version);
10398*6777b538SAndroid Build Coastguard Worker }
10399*6777b538SAndroid Build Coastguard Worker }
10400*6777b538SAndroid Build Coastguard Worker }
10401*6777b538SAndroid Build Coastguard Worker if (ctxt->version != NULL)
10402*6777b538SAndroid Build Coastguard Worker xmlFree((void *) ctxt->version);
10403*6777b538SAndroid Build Coastguard Worker ctxt->version = version;
10404*6777b538SAndroid Build Coastguard Worker }
10405*6777b538SAndroid Build Coastguard Worker
10406*6777b538SAndroid Build Coastguard Worker /*
10407*6777b538SAndroid Build Coastguard Worker * We may have the encoding declaration
10408*6777b538SAndroid Build Coastguard Worker */
10409*6777b538SAndroid Build Coastguard Worker if (!IS_BLANK_CH(RAW)) {
10410*6777b538SAndroid Build Coastguard Worker if ((RAW == '?') && (NXT(1) == '>')) {
10411*6777b538SAndroid Build Coastguard Worker SKIP(2);
10412*6777b538SAndroid Build Coastguard Worker return;
10413*6777b538SAndroid Build Coastguard Worker }
10414*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10415*6777b538SAndroid Build Coastguard Worker }
10416*6777b538SAndroid Build Coastguard Worker xmlParseEncodingDecl(ctxt);
10417*6777b538SAndroid Build Coastguard Worker
10418*6777b538SAndroid Build Coastguard Worker /*
10419*6777b538SAndroid Build Coastguard Worker * We may have the standalone status.
10420*6777b538SAndroid Build Coastguard Worker */
10421*6777b538SAndroid Build Coastguard Worker if ((ctxt->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
10422*6777b538SAndroid Build Coastguard Worker if ((RAW == '?') && (NXT(1) == '>')) {
10423*6777b538SAndroid Build Coastguard Worker SKIP(2);
10424*6777b538SAndroid Build Coastguard Worker return;
10425*6777b538SAndroid Build Coastguard Worker }
10426*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10427*6777b538SAndroid Build Coastguard Worker }
10428*6777b538SAndroid Build Coastguard Worker
10429*6777b538SAndroid Build Coastguard Worker /*
10430*6777b538SAndroid Build Coastguard Worker * We can grow the input buffer freely at that point
10431*6777b538SAndroid Build Coastguard Worker */
10432*6777b538SAndroid Build Coastguard Worker GROW;
10433*6777b538SAndroid Build Coastguard Worker
10434*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10435*6777b538SAndroid Build Coastguard Worker ctxt->standalone = xmlParseSDDecl(ctxt);
10436*6777b538SAndroid Build Coastguard Worker
10437*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10438*6777b538SAndroid Build Coastguard Worker if ((RAW == '?') && (NXT(1) == '>')) {
10439*6777b538SAndroid Build Coastguard Worker SKIP(2);
10440*6777b538SAndroid Build Coastguard Worker } else if (RAW == '>') {
10441*6777b538SAndroid Build Coastguard Worker /* Deprecated old WD ... */
10442*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10443*6777b538SAndroid Build Coastguard Worker NEXT;
10444*6777b538SAndroid Build Coastguard Worker } else {
10445*6777b538SAndroid Build Coastguard Worker int c;
10446*6777b538SAndroid Build Coastguard Worker
10447*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10448*6777b538SAndroid Build Coastguard Worker while ((PARSER_STOPPED(ctxt) == 0) &&
10449*6777b538SAndroid Build Coastguard Worker ((c = CUR) != 0)) {
10450*6777b538SAndroid Build Coastguard Worker NEXT;
10451*6777b538SAndroid Build Coastguard Worker if (c == '>')
10452*6777b538SAndroid Build Coastguard Worker break;
10453*6777b538SAndroid Build Coastguard Worker }
10454*6777b538SAndroid Build Coastguard Worker }
10455*6777b538SAndroid Build Coastguard Worker }
10456*6777b538SAndroid Build Coastguard Worker
10457*6777b538SAndroid Build Coastguard Worker /**
10458*6777b538SAndroid Build Coastguard Worker * xmlParseMisc:
10459*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10460*6777b538SAndroid Build Coastguard Worker *
10461*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Internal function, don't use.
10462*6777b538SAndroid Build Coastguard Worker *
10463*6777b538SAndroid Build Coastguard Worker * parse an XML Misc* optional field.
10464*6777b538SAndroid Build Coastguard Worker *
10465*6777b538SAndroid Build Coastguard Worker * [27] Misc ::= Comment | PI | S
10466*6777b538SAndroid Build Coastguard Worker */
10467*6777b538SAndroid Build Coastguard Worker
10468*6777b538SAndroid Build Coastguard Worker void
xmlParseMisc(xmlParserCtxtPtr ctxt)10469*6777b538SAndroid Build Coastguard Worker xmlParseMisc(xmlParserCtxtPtr ctxt) {
10470*6777b538SAndroid Build Coastguard Worker while (PARSER_STOPPED(ctxt) == 0) {
10471*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10472*6777b538SAndroid Build Coastguard Worker GROW;
10473*6777b538SAndroid Build Coastguard Worker if ((RAW == '<') && (NXT(1) == '?')) {
10474*6777b538SAndroid Build Coastguard Worker xmlParsePI(ctxt);
10475*6777b538SAndroid Build Coastguard Worker } else if (CMP4(CUR_PTR, '<', '!', '-', '-')) {
10476*6777b538SAndroid Build Coastguard Worker xmlParseComment(ctxt);
10477*6777b538SAndroid Build Coastguard Worker } else {
10478*6777b538SAndroid Build Coastguard Worker break;
10479*6777b538SAndroid Build Coastguard Worker }
10480*6777b538SAndroid Build Coastguard Worker }
10481*6777b538SAndroid Build Coastguard Worker }
10482*6777b538SAndroid Build Coastguard Worker
10483*6777b538SAndroid Build Coastguard Worker static void
xmlFinishDocument(xmlParserCtxtPtr ctxt)10484*6777b538SAndroid Build Coastguard Worker xmlFinishDocument(xmlParserCtxtPtr ctxt) {
10485*6777b538SAndroid Build Coastguard Worker xmlDocPtr doc;
10486*6777b538SAndroid Build Coastguard Worker
10487*6777b538SAndroid Build Coastguard Worker /*
10488*6777b538SAndroid Build Coastguard Worker * SAX: end of the document processing.
10489*6777b538SAndroid Build Coastguard Worker */
10490*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10491*6777b538SAndroid Build Coastguard Worker ctxt->sax->endDocument(ctxt->userData);
10492*6777b538SAndroid Build Coastguard Worker
10493*6777b538SAndroid Build Coastguard Worker doc = ctxt->myDoc;
10494*6777b538SAndroid Build Coastguard Worker if (doc != NULL) {
10495*6777b538SAndroid Build Coastguard Worker if (ctxt->wellFormed) {
10496*6777b538SAndroid Build Coastguard Worker doc->properties |= XML_DOC_WELLFORMED;
10497*6777b538SAndroid Build Coastguard Worker if (ctxt->valid)
10498*6777b538SAndroid Build Coastguard Worker doc->properties |= XML_DOC_DTDVALID;
10499*6777b538SAndroid Build Coastguard Worker if (ctxt->nsWellFormed)
10500*6777b538SAndroid Build Coastguard Worker doc->properties |= XML_DOC_NSVALID;
10501*6777b538SAndroid Build Coastguard Worker }
10502*6777b538SAndroid Build Coastguard Worker
10503*6777b538SAndroid Build Coastguard Worker if (ctxt->options & XML_PARSE_OLD10)
10504*6777b538SAndroid Build Coastguard Worker doc->properties |= XML_DOC_OLD10;
10505*6777b538SAndroid Build Coastguard Worker
10506*6777b538SAndroid Build Coastguard Worker /*
10507*6777b538SAndroid Build Coastguard Worker * Remove locally kept entity definitions if the tree was not built
10508*6777b538SAndroid Build Coastguard Worker */
10509*6777b538SAndroid Build Coastguard Worker if (xmlStrEqual(doc->version, SAX_COMPAT_MODE)) {
10510*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(doc);
10511*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = NULL;
10512*6777b538SAndroid Build Coastguard Worker }
10513*6777b538SAndroid Build Coastguard Worker }
10514*6777b538SAndroid Build Coastguard Worker }
10515*6777b538SAndroid Build Coastguard Worker
10516*6777b538SAndroid Build Coastguard Worker /**
10517*6777b538SAndroid Build Coastguard Worker * xmlParseDocument:
10518*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10519*6777b538SAndroid Build Coastguard Worker *
10520*6777b538SAndroid Build Coastguard Worker * Parse an XML document and invoke the SAX handlers. This is useful
10521*6777b538SAndroid Build Coastguard Worker * if you're only interested in custom SAX callbacks. If you want a
10522*6777b538SAndroid Build Coastguard Worker * document tree, use xmlCtxtParseDocument.
10523*6777b538SAndroid Build Coastguard Worker *
10524*6777b538SAndroid Build Coastguard Worker * Returns 0, -1 in case of error.
10525*6777b538SAndroid Build Coastguard Worker */
10526*6777b538SAndroid Build Coastguard Worker
10527*6777b538SAndroid Build Coastguard Worker int
xmlParseDocument(xmlParserCtxtPtr ctxt)10528*6777b538SAndroid Build Coastguard Worker xmlParseDocument(xmlParserCtxtPtr ctxt) {
10529*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->input == NULL))
10530*6777b538SAndroid Build Coastguard Worker return(-1);
10531*6777b538SAndroid Build Coastguard Worker
10532*6777b538SAndroid Build Coastguard Worker GROW;
10533*6777b538SAndroid Build Coastguard Worker
10534*6777b538SAndroid Build Coastguard Worker /*
10535*6777b538SAndroid Build Coastguard Worker * SAX: detecting the level.
10536*6777b538SAndroid Build Coastguard Worker */
10537*6777b538SAndroid Build Coastguard Worker xmlCtxtInitializeLate(ctxt);
10538*6777b538SAndroid Build Coastguard Worker
10539*6777b538SAndroid Build Coastguard Worker /*
10540*6777b538SAndroid Build Coastguard Worker * Document locator is unused. Only for backward compatibility.
10541*6777b538SAndroid Build Coastguard Worker */
10542*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) {
10543*6777b538SAndroid Build Coastguard Worker xmlSAXLocator copy = xmlDefaultSAXLocator;
10544*6777b538SAndroid Build Coastguard Worker ctxt->sax->setDocumentLocator(ctxt->userData, ©);
10545*6777b538SAndroid Build Coastguard Worker }
10546*6777b538SAndroid Build Coastguard Worker
10547*6777b538SAndroid Build Coastguard Worker xmlDetectEncoding(ctxt);
10548*6777b538SAndroid Build Coastguard Worker
10549*6777b538SAndroid Build Coastguard Worker if (CUR == 0) {
10550*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10551*6777b538SAndroid Build Coastguard Worker return(-1);
10552*6777b538SAndroid Build Coastguard Worker }
10553*6777b538SAndroid Build Coastguard Worker
10554*6777b538SAndroid Build Coastguard Worker GROW;
10555*6777b538SAndroid Build Coastguard Worker if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10556*6777b538SAndroid Build Coastguard Worker
10557*6777b538SAndroid Build Coastguard Worker /*
10558*6777b538SAndroid Build Coastguard Worker * Note that we will switch encoding on the fly.
10559*6777b538SAndroid Build Coastguard Worker */
10560*6777b538SAndroid Build Coastguard Worker xmlParseXMLDecl(ctxt);
10561*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10562*6777b538SAndroid Build Coastguard Worker } else {
10563*6777b538SAndroid Build Coastguard Worker ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10564*6777b538SAndroid Build Coastguard Worker if (ctxt->version == NULL) {
10565*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
10566*6777b538SAndroid Build Coastguard Worker return(-1);
10567*6777b538SAndroid Build Coastguard Worker }
10568*6777b538SAndroid Build Coastguard Worker }
10569*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10570*6777b538SAndroid Build Coastguard Worker ctxt->sax->startDocument(ctxt->userData);
10571*6777b538SAndroid Build Coastguard Worker if ((ctxt->myDoc != NULL) && (ctxt->input != NULL) &&
10572*6777b538SAndroid Build Coastguard Worker (ctxt->input->buf != NULL) && (ctxt->input->buf->compressed >= 0)) {
10573*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->compression = ctxt->input->buf->compressed;
10574*6777b538SAndroid Build Coastguard Worker }
10575*6777b538SAndroid Build Coastguard Worker
10576*6777b538SAndroid Build Coastguard Worker /*
10577*6777b538SAndroid Build Coastguard Worker * The Misc part of the Prolog
10578*6777b538SAndroid Build Coastguard Worker */
10579*6777b538SAndroid Build Coastguard Worker xmlParseMisc(ctxt);
10580*6777b538SAndroid Build Coastguard Worker
10581*6777b538SAndroid Build Coastguard Worker /*
10582*6777b538SAndroid Build Coastguard Worker * Then possibly doc type declaration(s) and more Misc
10583*6777b538SAndroid Build Coastguard Worker * (doctypedecl Misc*)?
10584*6777b538SAndroid Build Coastguard Worker */
10585*6777b538SAndroid Build Coastguard Worker GROW;
10586*6777b538SAndroid Build Coastguard Worker if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
10587*6777b538SAndroid Build Coastguard Worker
10588*6777b538SAndroid Build Coastguard Worker ctxt->inSubset = 1;
10589*6777b538SAndroid Build Coastguard Worker xmlParseDocTypeDecl(ctxt);
10590*6777b538SAndroid Build Coastguard Worker if (RAW == '[') {
10591*6777b538SAndroid Build Coastguard Worker xmlParseInternalSubset(ctxt);
10592*6777b538SAndroid Build Coastguard Worker }
10593*6777b538SAndroid Build Coastguard Worker
10594*6777b538SAndroid Build Coastguard Worker /*
10595*6777b538SAndroid Build Coastguard Worker * Create and update the external subset.
10596*6777b538SAndroid Build Coastguard Worker */
10597*6777b538SAndroid Build Coastguard Worker ctxt->inSubset = 2;
10598*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
10599*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
10600*6777b538SAndroid Build Coastguard Worker ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
10601*6777b538SAndroid Build Coastguard Worker ctxt->extSubSystem, ctxt->extSubURI);
10602*6777b538SAndroid Build Coastguard Worker ctxt->inSubset = 0;
10603*6777b538SAndroid Build Coastguard Worker
10604*6777b538SAndroid Build Coastguard Worker xmlCleanSpecialAttr(ctxt);
10605*6777b538SAndroid Build Coastguard Worker
10606*6777b538SAndroid Build Coastguard Worker xmlParseMisc(ctxt);
10607*6777b538SAndroid Build Coastguard Worker }
10608*6777b538SAndroid Build Coastguard Worker
10609*6777b538SAndroid Build Coastguard Worker /*
10610*6777b538SAndroid Build Coastguard Worker * Time to start parsing the tree itself
10611*6777b538SAndroid Build Coastguard Worker */
10612*6777b538SAndroid Build Coastguard Worker GROW;
10613*6777b538SAndroid Build Coastguard Worker if (RAW != '<') {
10614*6777b538SAndroid Build Coastguard Worker if (ctxt->wellFormed)
10615*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
10616*6777b538SAndroid Build Coastguard Worker "Start tag expected, '<' not found\n");
10617*6777b538SAndroid Build Coastguard Worker } else {
10618*6777b538SAndroid Build Coastguard Worker xmlParseElement(ctxt);
10619*6777b538SAndroid Build Coastguard Worker
10620*6777b538SAndroid Build Coastguard Worker /*
10621*6777b538SAndroid Build Coastguard Worker * The Misc part at the end
10622*6777b538SAndroid Build Coastguard Worker */
10623*6777b538SAndroid Build Coastguard Worker xmlParseMisc(ctxt);
10624*6777b538SAndroid Build Coastguard Worker
10625*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur < ctxt->input->end) {
10626*6777b538SAndroid Build Coastguard Worker if (ctxt->wellFormed)
10627*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10628*6777b538SAndroid Build Coastguard Worker } else if ((ctxt->input->buf != NULL) &&
10629*6777b538SAndroid Build Coastguard Worker (ctxt->input->buf->encoder != NULL) &&
10630*6777b538SAndroid Build Coastguard Worker (!xmlBufIsEmpty(ctxt->input->buf->raw))) {
10631*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
10632*6777b538SAndroid Build Coastguard Worker "Truncated multi-byte sequence at EOF\n");
10633*6777b538SAndroid Build Coastguard Worker }
10634*6777b538SAndroid Build Coastguard Worker }
10635*6777b538SAndroid Build Coastguard Worker
10636*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_EOF;
10637*6777b538SAndroid Build Coastguard Worker xmlFinishDocument(ctxt);
10638*6777b538SAndroid Build Coastguard Worker
10639*6777b538SAndroid Build Coastguard Worker if (! ctxt->wellFormed) {
10640*6777b538SAndroid Build Coastguard Worker ctxt->valid = 0;
10641*6777b538SAndroid Build Coastguard Worker return(-1);
10642*6777b538SAndroid Build Coastguard Worker }
10643*6777b538SAndroid Build Coastguard Worker
10644*6777b538SAndroid Build Coastguard Worker return(0);
10645*6777b538SAndroid Build Coastguard Worker }
10646*6777b538SAndroid Build Coastguard Worker
10647*6777b538SAndroid Build Coastguard Worker /**
10648*6777b538SAndroid Build Coastguard Worker * xmlParseExtParsedEnt:
10649*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10650*6777b538SAndroid Build Coastguard Worker *
10651*6777b538SAndroid Build Coastguard Worker * parse a general parsed entity
10652*6777b538SAndroid Build Coastguard Worker * An external general parsed entity is well-formed if it matches the
10653*6777b538SAndroid Build Coastguard Worker * production labeled extParsedEnt.
10654*6777b538SAndroid Build Coastguard Worker *
10655*6777b538SAndroid Build Coastguard Worker * [78] extParsedEnt ::= TextDecl? content
10656*6777b538SAndroid Build Coastguard Worker *
10657*6777b538SAndroid Build Coastguard Worker * Returns 0, -1 in case of error. the parser context is augmented
10658*6777b538SAndroid Build Coastguard Worker * as a result of the parsing.
10659*6777b538SAndroid Build Coastguard Worker */
10660*6777b538SAndroid Build Coastguard Worker
10661*6777b538SAndroid Build Coastguard Worker int
xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt)10662*6777b538SAndroid Build Coastguard Worker xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
10663*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->input == NULL))
10664*6777b538SAndroid Build Coastguard Worker return(-1);
10665*6777b538SAndroid Build Coastguard Worker
10666*6777b538SAndroid Build Coastguard Worker xmlCtxtInitializeLate(ctxt);
10667*6777b538SAndroid Build Coastguard Worker
10668*6777b538SAndroid Build Coastguard Worker /*
10669*6777b538SAndroid Build Coastguard Worker * Document locator is unused. Only for backward compatibility.
10670*6777b538SAndroid Build Coastguard Worker */
10671*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) {
10672*6777b538SAndroid Build Coastguard Worker xmlSAXLocator copy = xmlDefaultSAXLocator;
10673*6777b538SAndroid Build Coastguard Worker ctxt->sax->setDocumentLocator(ctxt->userData, ©);
10674*6777b538SAndroid Build Coastguard Worker }
10675*6777b538SAndroid Build Coastguard Worker
10676*6777b538SAndroid Build Coastguard Worker xmlDetectEncoding(ctxt);
10677*6777b538SAndroid Build Coastguard Worker
10678*6777b538SAndroid Build Coastguard Worker if (CUR == 0) {
10679*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10680*6777b538SAndroid Build Coastguard Worker }
10681*6777b538SAndroid Build Coastguard Worker
10682*6777b538SAndroid Build Coastguard Worker /*
10683*6777b538SAndroid Build Coastguard Worker * Check for the XMLDecl in the Prolog.
10684*6777b538SAndroid Build Coastguard Worker */
10685*6777b538SAndroid Build Coastguard Worker GROW;
10686*6777b538SAndroid Build Coastguard Worker if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10687*6777b538SAndroid Build Coastguard Worker
10688*6777b538SAndroid Build Coastguard Worker /*
10689*6777b538SAndroid Build Coastguard Worker * Note that we will switch encoding on the fly.
10690*6777b538SAndroid Build Coastguard Worker */
10691*6777b538SAndroid Build Coastguard Worker xmlParseXMLDecl(ctxt);
10692*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
10693*6777b538SAndroid Build Coastguard Worker } else {
10694*6777b538SAndroid Build Coastguard Worker ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10695*6777b538SAndroid Build Coastguard Worker }
10696*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10697*6777b538SAndroid Build Coastguard Worker ctxt->sax->startDocument(ctxt->userData);
10698*6777b538SAndroid Build Coastguard Worker
10699*6777b538SAndroid Build Coastguard Worker /*
10700*6777b538SAndroid Build Coastguard Worker * Doing validity checking on chunk doesn't make sense
10701*6777b538SAndroid Build Coastguard Worker */
10702*6777b538SAndroid Build Coastguard Worker ctxt->options &= ~XML_PARSE_DTDVALID;
10703*6777b538SAndroid Build Coastguard Worker ctxt->validate = 0;
10704*6777b538SAndroid Build Coastguard Worker ctxt->depth = 0;
10705*6777b538SAndroid Build Coastguard Worker
10706*6777b538SAndroid Build Coastguard Worker xmlParseContentInternal(ctxt);
10707*6777b538SAndroid Build Coastguard Worker
10708*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur < ctxt->input->end)
10709*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
10710*6777b538SAndroid Build Coastguard Worker
10711*6777b538SAndroid Build Coastguard Worker /*
10712*6777b538SAndroid Build Coastguard Worker * SAX: end of the document processing.
10713*6777b538SAndroid Build Coastguard Worker */
10714*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10715*6777b538SAndroid Build Coastguard Worker ctxt->sax->endDocument(ctxt->userData);
10716*6777b538SAndroid Build Coastguard Worker
10717*6777b538SAndroid Build Coastguard Worker if (! ctxt->wellFormed) return(-1);
10718*6777b538SAndroid Build Coastguard Worker return(0);
10719*6777b538SAndroid Build Coastguard Worker }
10720*6777b538SAndroid Build Coastguard Worker
10721*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_PUSH_ENABLED
10722*6777b538SAndroid Build Coastguard Worker /************************************************************************
10723*6777b538SAndroid Build Coastguard Worker * *
10724*6777b538SAndroid Build Coastguard Worker * Progressive parsing interfaces *
10725*6777b538SAndroid Build Coastguard Worker * *
10726*6777b538SAndroid Build Coastguard Worker ************************************************************************/
10727*6777b538SAndroid Build Coastguard Worker
10728*6777b538SAndroid Build Coastguard Worker /**
10729*6777b538SAndroid Build Coastguard Worker * xmlParseLookupChar:
10730*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10731*6777b538SAndroid Build Coastguard Worker * @c: character
10732*6777b538SAndroid Build Coastguard Worker *
10733*6777b538SAndroid Build Coastguard Worker * Check whether the input buffer contains a character.
10734*6777b538SAndroid Build Coastguard Worker */
10735*6777b538SAndroid Build Coastguard Worker static int
xmlParseLookupChar(xmlParserCtxtPtr ctxt,int c)10736*6777b538SAndroid Build Coastguard Worker xmlParseLookupChar(xmlParserCtxtPtr ctxt, int c) {
10737*6777b538SAndroid Build Coastguard Worker const xmlChar *cur;
10738*6777b538SAndroid Build Coastguard Worker
10739*6777b538SAndroid Build Coastguard Worker if (ctxt->checkIndex == 0) {
10740*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur + 1;
10741*6777b538SAndroid Build Coastguard Worker } else {
10742*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur + ctxt->checkIndex;
10743*6777b538SAndroid Build Coastguard Worker }
10744*6777b538SAndroid Build Coastguard Worker
10745*6777b538SAndroid Build Coastguard Worker if (memchr(cur, c, ctxt->input->end - cur) == NULL) {
10746*6777b538SAndroid Build Coastguard Worker size_t index = ctxt->input->end - ctxt->input->cur;
10747*6777b538SAndroid Build Coastguard Worker
10748*6777b538SAndroid Build Coastguard Worker if (index > LONG_MAX) {
10749*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10750*6777b538SAndroid Build Coastguard Worker return(1);
10751*6777b538SAndroid Build Coastguard Worker }
10752*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = index;
10753*6777b538SAndroid Build Coastguard Worker return(0);
10754*6777b538SAndroid Build Coastguard Worker } else {
10755*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10756*6777b538SAndroid Build Coastguard Worker return(1);
10757*6777b538SAndroid Build Coastguard Worker }
10758*6777b538SAndroid Build Coastguard Worker }
10759*6777b538SAndroid Build Coastguard Worker
10760*6777b538SAndroid Build Coastguard Worker /**
10761*6777b538SAndroid Build Coastguard Worker * xmlParseLookupString:
10762*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10763*6777b538SAndroid Build Coastguard Worker * @startDelta: delta to apply at the start
10764*6777b538SAndroid Build Coastguard Worker * @str: string
10765*6777b538SAndroid Build Coastguard Worker * @strLen: length of string
10766*6777b538SAndroid Build Coastguard Worker *
10767*6777b538SAndroid Build Coastguard Worker * Check whether the input buffer contains a string.
10768*6777b538SAndroid Build Coastguard Worker */
10769*6777b538SAndroid Build Coastguard Worker static const xmlChar *
xmlParseLookupString(xmlParserCtxtPtr ctxt,size_t startDelta,const char * str,size_t strLen)10770*6777b538SAndroid Build Coastguard Worker xmlParseLookupString(xmlParserCtxtPtr ctxt, size_t startDelta,
10771*6777b538SAndroid Build Coastguard Worker const char *str, size_t strLen) {
10772*6777b538SAndroid Build Coastguard Worker const xmlChar *cur, *term;
10773*6777b538SAndroid Build Coastguard Worker
10774*6777b538SAndroid Build Coastguard Worker if (ctxt->checkIndex == 0) {
10775*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur + startDelta;
10776*6777b538SAndroid Build Coastguard Worker } else {
10777*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur + ctxt->checkIndex;
10778*6777b538SAndroid Build Coastguard Worker }
10779*6777b538SAndroid Build Coastguard Worker
10780*6777b538SAndroid Build Coastguard Worker term = BAD_CAST strstr((const char *) cur, str);
10781*6777b538SAndroid Build Coastguard Worker if (term == NULL) {
10782*6777b538SAndroid Build Coastguard Worker const xmlChar *end = ctxt->input->end;
10783*6777b538SAndroid Build Coastguard Worker size_t index;
10784*6777b538SAndroid Build Coastguard Worker
10785*6777b538SAndroid Build Coastguard Worker /* Rescan (strLen - 1) characters. */
10786*6777b538SAndroid Build Coastguard Worker if ((size_t) (end - cur) < strLen)
10787*6777b538SAndroid Build Coastguard Worker end = cur;
10788*6777b538SAndroid Build Coastguard Worker else
10789*6777b538SAndroid Build Coastguard Worker end -= strLen - 1;
10790*6777b538SAndroid Build Coastguard Worker index = end - ctxt->input->cur;
10791*6777b538SAndroid Build Coastguard Worker if (index > LONG_MAX) {
10792*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10793*6777b538SAndroid Build Coastguard Worker return(ctxt->input->end - strLen);
10794*6777b538SAndroid Build Coastguard Worker }
10795*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = index;
10796*6777b538SAndroid Build Coastguard Worker } else {
10797*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10798*6777b538SAndroid Build Coastguard Worker }
10799*6777b538SAndroid Build Coastguard Worker
10800*6777b538SAndroid Build Coastguard Worker return(term);
10801*6777b538SAndroid Build Coastguard Worker }
10802*6777b538SAndroid Build Coastguard Worker
10803*6777b538SAndroid Build Coastguard Worker /**
10804*6777b538SAndroid Build Coastguard Worker * xmlParseLookupCharData:
10805*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10806*6777b538SAndroid Build Coastguard Worker *
10807*6777b538SAndroid Build Coastguard Worker * Check whether the input buffer contains terminated char data.
10808*6777b538SAndroid Build Coastguard Worker */
10809*6777b538SAndroid Build Coastguard Worker static int
xmlParseLookupCharData(xmlParserCtxtPtr ctxt)10810*6777b538SAndroid Build Coastguard Worker xmlParseLookupCharData(xmlParserCtxtPtr ctxt) {
10811*6777b538SAndroid Build Coastguard Worker const xmlChar *cur = ctxt->input->cur + ctxt->checkIndex;
10812*6777b538SAndroid Build Coastguard Worker const xmlChar *end = ctxt->input->end;
10813*6777b538SAndroid Build Coastguard Worker size_t index;
10814*6777b538SAndroid Build Coastguard Worker
10815*6777b538SAndroid Build Coastguard Worker while (cur < end) {
10816*6777b538SAndroid Build Coastguard Worker if ((*cur == '<') || (*cur == '&')) {
10817*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10818*6777b538SAndroid Build Coastguard Worker return(1);
10819*6777b538SAndroid Build Coastguard Worker }
10820*6777b538SAndroid Build Coastguard Worker cur++;
10821*6777b538SAndroid Build Coastguard Worker }
10822*6777b538SAndroid Build Coastguard Worker
10823*6777b538SAndroid Build Coastguard Worker index = cur - ctxt->input->cur;
10824*6777b538SAndroid Build Coastguard Worker if (index > LONG_MAX) {
10825*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10826*6777b538SAndroid Build Coastguard Worker return(1);
10827*6777b538SAndroid Build Coastguard Worker }
10828*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = index;
10829*6777b538SAndroid Build Coastguard Worker return(0);
10830*6777b538SAndroid Build Coastguard Worker }
10831*6777b538SAndroid Build Coastguard Worker
10832*6777b538SAndroid Build Coastguard Worker /**
10833*6777b538SAndroid Build Coastguard Worker * xmlParseLookupGt:
10834*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10835*6777b538SAndroid Build Coastguard Worker *
10836*6777b538SAndroid Build Coastguard Worker * Check whether there's enough data in the input buffer to finish parsing
10837*6777b538SAndroid Build Coastguard Worker * a start tag. This has to take quotes into account.
10838*6777b538SAndroid Build Coastguard Worker */
10839*6777b538SAndroid Build Coastguard Worker static int
xmlParseLookupGt(xmlParserCtxtPtr ctxt)10840*6777b538SAndroid Build Coastguard Worker xmlParseLookupGt(xmlParserCtxtPtr ctxt) {
10841*6777b538SAndroid Build Coastguard Worker const xmlChar *cur;
10842*6777b538SAndroid Build Coastguard Worker const xmlChar *end = ctxt->input->end;
10843*6777b538SAndroid Build Coastguard Worker int state = ctxt->endCheckState;
10844*6777b538SAndroid Build Coastguard Worker size_t index;
10845*6777b538SAndroid Build Coastguard Worker
10846*6777b538SAndroid Build Coastguard Worker if (ctxt->checkIndex == 0)
10847*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur + 1;
10848*6777b538SAndroid Build Coastguard Worker else
10849*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur + ctxt->checkIndex;
10850*6777b538SAndroid Build Coastguard Worker
10851*6777b538SAndroid Build Coastguard Worker while (cur < end) {
10852*6777b538SAndroid Build Coastguard Worker if (state) {
10853*6777b538SAndroid Build Coastguard Worker if (*cur == state)
10854*6777b538SAndroid Build Coastguard Worker state = 0;
10855*6777b538SAndroid Build Coastguard Worker } else if (*cur == '\'' || *cur == '"') {
10856*6777b538SAndroid Build Coastguard Worker state = *cur;
10857*6777b538SAndroid Build Coastguard Worker } else if (*cur == '>') {
10858*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10859*6777b538SAndroid Build Coastguard Worker ctxt->endCheckState = 0;
10860*6777b538SAndroid Build Coastguard Worker return(1);
10861*6777b538SAndroid Build Coastguard Worker }
10862*6777b538SAndroid Build Coastguard Worker cur++;
10863*6777b538SAndroid Build Coastguard Worker }
10864*6777b538SAndroid Build Coastguard Worker
10865*6777b538SAndroid Build Coastguard Worker index = cur - ctxt->input->cur;
10866*6777b538SAndroid Build Coastguard Worker if (index > LONG_MAX) {
10867*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10868*6777b538SAndroid Build Coastguard Worker ctxt->endCheckState = 0;
10869*6777b538SAndroid Build Coastguard Worker return(1);
10870*6777b538SAndroid Build Coastguard Worker }
10871*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = index;
10872*6777b538SAndroid Build Coastguard Worker ctxt->endCheckState = state;
10873*6777b538SAndroid Build Coastguard Worker return(0);
10874*6777b538SAndroid Build Coastguard Worker }
10875*6777b538SAndroid Build Coastguard Worker
10876*6777b538SAndroid Build Coastguard Worker /**
10877*6777b538SAndroid Build Coastguard Worker * xmlParseLookupInternalSubset:
10878*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
10879*6777b538SAndroid Build Coastguard Worker *
10880*6777b538SAndroid Build Coastguard Worker * Check whether there's enough data in the input buffer to finish parsing
10881*6777b538SAndroid Build Coastguard Worker * the internal subset.
10882*6777b538SAndroid Build Coastguard Worker */
10883*6777b538SAndroid Build Coastguard Worker static int
xmlParseLookupInternalSubset(xmlParserCtxtPtr ctxt)10884*6777b538SAndroid Build Coastguard Worker xmlParseLookupInternalSubset(xmlParserCtxtPtr ctxt) {
10885*6777b538SAndroid Build Coastguard Worker /*
10886*6777b538SAndroid Build Coastguard Worker * Sorry, but progressive parsing of the internal subset is not
10887*6777b538SAndroid Build Coastguard Worker * supported. We first check that the full content of the internal
10888*6777b538SAndroid Build Coastguard Worker * subset is available and parsing is launched only at that point.
10889*6777b538SAndroid Build Coastguard Worker * Internal subset ends with "']' S? '>'" in an unescaped section and
10890*6777b538SAndroid Build Coastguard Worker * not in a ']]>' sequence which are conditional sections.
10891*6777b538SAndroid Build Coastguard Worker */
10892*6777b538SAndroid Build Coastguard Worker const xmlChar *cur, *start;
10893*6777b538SAndroid Build Coastguard Worker const xmlChar *end = ctxt->input->end;
10894*6777b538SAndroid Build Coastguard Worker int state = ctxt->endCheckState;
10895*6777b538SAndroid Build Coastguard Worker size_t index;
10896*6777b538SAndroid Build Coastguard Worker
10897*6777b538SAndroid Build Coastguard Worker if (ctxt->checkIndex == 0) {
10898*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur + 1;
10899*6777b538SAndroid Build Coastguard Worker } else {
10900*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur + ctxt->checkIndex;
10901*6777b538SAndroid Build Coastguard Worker }
10902*6777b538SAndroid Build Coastguard Worker start = cur;
10903*6777b538SAndroid Build Coastguard Worker
10904*6777b538SAndroid Build Coastguard Worker while (cur < end) {
10905*6777b538SAndroid Build Coastguard Worker if (state == '-') {
10906*6777b538SAndroid Build Coastguard Worker if ((*cur == '-') &&
10907*6777b538SAndroid Build Coastguard Worker (cur[1] == '-') &&
10908*6777b538SAndroid Build Coastguard Worker (cur[2] == '>')) {
10909*6777b538SAndroid Build Coastguard Worker state = 0;
10910*6777b538SAndroid Build Coastguard Worker cur += 3;
10911*6777b538SAndroid Build Coastguard Worker start = cur;
10912*6777b538SAndroid Build Coastguard Worker continue;
10913*6777b538SAndroid Build Coastguard Worker }
10914*6777b538SAndroid Build Coastguard Worker }
10915*6777b538SAndroid Build Coastguard Worker else if (state == ']') {
10916*6777b538SAndroid Build Coastguard Worker if (*cur == '>') {
10917*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10918*6777b538SAndroid Build Coastguard Worker ctxt->endCheckState = 0;
10919*6777b538SAndroid Build Coastguard Worker return(1);
10920*6777b538SAndroid Build Coastguard Worker }
10921*6777b538SAndroid Build Coastguard Worker if (IS_BLANK_CH(*cur)) {
10922*6777b538SAndroid Build Coastguard Worker state = ' ';
10923*6777b538SAndroid Build Coastguard Worker } else if (*cur != ']') {
10924*6777b538SAndroid Build Coastguard Worker state = 0;
10925*6777b538SAndroid Build Coastguard Worker start = cur;
10926*6777b538SAndroid Build Coastguard Worker continue;
10927*6777b538SAndroid Build Coastguard Worker }
10928*6777b538SAndroid Build Coastguard Worker }
10929*6777b538SAndroid Build Coastguard Worker else if (state == ' ') {
10930*6777b538SAndroid Build Coastguard Worker if (*cur == '>') {
10931*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10932*6777b538SAndroid Build Coastguard Worker ctxt->endCheckState = 0;
10933*6777b538SAndroid Build Coastguard Worker return(1);
10934*6777b538SAndroid Build Coastguard Worker }
10935*6777b538SAndroid Build Coastguard Worker if (!IS_BLANK_CH(*cur)) {
10936*6777b538SAndroid Build Coastguard Worker state = 0;
10937*6777b538SAndroid Build Coastguard Worker start = cur;
10938*6777b538SAndroid Build Coastguard Worker continue;
10939*6777b538SAndroid Build Coastguard Worker }
10940*6777b538SAndroid Build Coastguard Worker }
10941*6777b538SAndroid Build Coastguard Worker else if (state != 0) {
10942*6777b538SAndroid Build Coastguard Worker if (*cur == state) {
10943*6777b538SAndroid Build Coastguard Worker state = 0;
10944*6777b538SAndroid Build Coastguard Worker start = cur + 1;
10945*6777b538SAndroid Build Coastguard Worker }
10946*6777b538SAndroid Build Coastguard Worker }
10947*6777b538SAndroid Build Coastguard Worker else if (*cur == '<') {
10948*6777b538SAndroid Build Coastguard Worker if ((cur[1] == '!') &&
10949*6777b538SAndroid Build Coastguard Worker (cur[2] == '-') &&
10950*6777b538SAndroid Build Coastguard Worker (cur[3] == '-')) {
10951*6777b538SAndroid Build Coastguard Worker state = '-';
10952*6777b538SAndroid Build Coastguard Worker cur += 4;
10953*6777b538SAndroid Build Coastguard Worker /* Don't treat <!--> as comment */
10954*6777b538SAndroid Build Coastguard Worker start = cur;
10955*6777b538SAndroid Build Coastguard Worker continue;
10956*6777b538SAndroid Build Coastguard Worker }
10957*6777b538SAndroid Build Coastguard Worker }
10958*6777b538SAndroid Build Coastguard Worker else if ((*cur == '"') || (*cur == '\'') || (*cur == ']')) {
10959*6777b538SAndroid Build Coastguard Worker state = *cur;
10960*6777b538SAndroid Build Coastguard Worker }
10961*6777b538SAndroid Build Coastguard Worker
10962*6777b538SAndroid Build Coastguard Worker cur++;
10963*6777b538SAndroid Build Coastguard Worker }
10964*6777b538SAndroid Build Coastguard Worker
10965*6777b538SAndroid Build Coastguard Worker /*
10966*6777b538SAndroid Build Coastguard Worker * Rescan the three last characters to detect "<!--" and "-->"
10967*6777b538SAndroid Build Coastguard Worker * split across chunks.
10968*6777b538SAndroid Build Coastguard Worker */
10969*6777b538SAndroid Build Coastguard Worker if ((state == 0) || (state == '-')) {
10970*6777b538SAndroid Build Coastguard Worker if (cur - start < 3)
10971*6777b538SAndroid Build Coastguard Worker cur = start;
10972*6777b538SAndroid Build Coastguard Worker else
10973*6777b538SAndroid Build Coastguard Worker cur -= 3;
10974*6777b538SAndroid Build Coastguard Worker }
10975*6777b538SAndroid Build Coastguard Worker index = cur - ctxt->input->cur;
10976*6777b538SAndroid Build Coastguard Worker if (index > LONG_MAX) {
10977*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
10978*6777b538SAndroid Build Coastguard Worker ctxt->endCheckState = 0;
10979*6777b538SAndroid Build Coastguard Worker return(1);
10980*6777b538SAndroid Build Coastguard Worker }
10981*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = index;
10982*6777b538SAndroid Build Coastguard Worker ctxt->endCheckState = state;
10983*6777b538SAndroid Build Coastguard Worker return(0);
10984*6777b538SAndroid Build Coastguard Worker }
10985*6777b538SAndroid Build Coastguard Worker
10986*6777b538SAndroid Build Coastguard Worker /**
10987*6777b538SAndroid Build Coastguard Worker * xmlCheckCdataPush:
10988*6777b538SAndroid Build Coastguard Worker * @cur: pointer to the block of characters
10989*6777b538SAndroid Build Coastguard Worker * @len: length of the block in bytes
10990*6777b538SAndroid Build Coastguard Worker * @complete: 1 if complete CDATA block is passed in, 0 if partial block
10991*6777b538SAndroid Build Coastguard Worker *
10992*6777b538SAndroid Build Coastguard Worker * Check that the block of characters is okay as SCdata content [20]
10993*6777b538SAndroid Build Coastguard Worker *
10994*6777b538SAndroid Build Coastguard Worker * Returns the number of bytes to pass if okay, a negative index where an
10995*6777b538SAndroid Build Coastguard Worker * UTF-8 error occurred otherwise
10996*6777b538SAndroid Build Coastguard Worker */
10997*6777b538SAndroid Build Coastguard Worker static int
xmlCheckCdataPush(const xmlChar * utf,int len,int complete)10998*6777b538SAndroid Build Coastguard Worker xmlCheckCdataPush(const xmlChar *utf, int len, int complete) {
10999*6777b538SAndroid Build Coastguard Worker int ix;
11000*6777b538SAndroid Build Coastguard Worker unsigned char c;
11001*6777b538SAndroid Build Coastguard Worker int codepoint;
11002*6777b538SAndroid Build Coastguard Worker
11003*6777b538SAndroid Build Coastguard Worker if ((utf == NULL) || (len <= 0))
11004*6777b538SAndroid Build Coastguard Worker return(0);
11005*6777b538SAndroid Build Coastguard Worker
11006*6777b538SAndroid Build Coastguard Worker for (ix = 0; ix < len;) { /* string is 0-terminated */
11007*6777b538SAndroid Build Coastguard Worker c = utf[ix];
11008*6777b538SAndroid Build Coastguard Worker if ((c & 0x80) == 0x00) { /* 1-byte code, starts with 10 */
11009*6777b538SAndroid Build Coastguard Worker if (c >= 0x20)
11010*6777b538SAndroid Build Coastguard Worker ix++;
11011*6777b538SAndroid Build Coastguard Worker else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
11012*6777b538SAndroid Build Coastguard Worker ix++;
11013*6777b538SAndroid Build Coastguard Worker else
11014*6777b538SAndroid Build Coastguard Worker return(-ix);
11015*6777b538SAndroid Build Coastguard Worker } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
11016*6777b538SAndroid Build Coastguard Worker if (ix + 2 > len) return(complete ? -ix : ix);
11017*6777b538SAndroid Build Coastguard Worker if ((utf[ix+1] & 0xc0 ) != 0x80)
11018*6777b538SAndroid Build Coastguard Worker return(-ix);
11019*6777b538SAndroid Build Coastguard Worker codepoint = (utf[ix] & 0x1f) << 6;
11020*6777b538SAndroid Build Coastguard Worker codepoint |= utf[ix+1] & 0x3f;
11021*6777b538SAndroid Build Coastguard Worker if (!xmlIsCharQ(codepoint))
11022*6777b538SAndroid Build Coastguard Worker return(-ix);
11023*6777b538SAndroid Build Coastguard Worker ix += 2;
11024*6777b538SAndroid Build Coastguard Worker } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
11025*6777b538SAndroid Build Coastguard Worker if (ix + 3 > len) return(complete ? -ix : ix);
11026*6777b538SAndroid Build Coastguard Worker if (((utf[ix+1] & 0xc0) != 0x80) ||
11027*6777b538SAndroid Build Coastguard Worker ((utf[ix+2] & 0xc0) != 0x80))
11028*6777b538SAndroid Build Coastguard Worker return(-ix);
11029*6777b538SAndroid Build Coastguard Worker codepoint = (utf[ix] & 0xf) << 12;
11030*6777b538SAndroid Build Coastguard Worker codepoint |= (utf[ix+1] & 0x3f) << 6;
11031*6777b538SAndroid Build Coastguard Worker codepoint |= utf[ix+2] & 0x3f;
11032*6777b538SAndroid Build Coastguard Worker if (!xmlIsCharQ(codepoint))
11033*6777b538SAndroid Build Coastguard Worker return(-ix);
11034*6777b538SAndroid Build Coastguard Worker ix += 3;
11035*6777b538SAndroid Build Coastguard Worker } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
11036*6777b538SAndroid Build Coastguard Worker if (ix + 4 > len) return(complete ? -ix : ix);
11037*6777b538SAndroid Build Coastguard Worker if (((utf[ix+1] & 0xc0) != 0x80) ||
11038*6777b538SAndroid Build Coastguard Worker ((utf[ix+2] & 0xc0) != 0x80) ||
11039*6777b538SAndroid Build Coastguard Worker ((utf[ix+3] & 0xc0) != 0x80))
11040*6777b538SAndroid Build Coastguard Worker return(-ix);
11041*6777b538SAndroid Build Coastguard Worker codepoint = (utf[ix] & 0x7) << 18;
11042*6777b538SAndroid Build Coastguard Worker codepoint |= (utf[ix+1] & 0x3f) << 12;
11043*6777b538SAndroid Build Coastguard Worker codepoint |= (utf[ix+2] & 0x3f) << 6;
11044*6777b538SAndroid Build Coastguard Worker codepoint |= utf[ix+3] & 0x3f;
11045*6777b538SAndroid Build Coastguard Worker if (!xmlIsCharQ(codepoint))
11046*6777b538SAndroid Build Coastguard Worker return(-ix);
11047*6777b538SAndroid Build Coastguard Worker ix += 4;
11048*6777b538SAndroid Build Coastguard Worker } else /* unknown encoding */
11049*6777b538SAndroid Build Coastguard Worker return(-ix);
11050*6777b538SAndroid Build Coastguard Worker }
11051*6777b538SAndroid Build Coastguard Worker return(ix);
11052*6777b538SAndroid Build Coastguard Worker }
11053*6777b538SAndroid Build Coastguard Worker
11054*6777b538SAndroid Build Coastguard Worker /**
11055*6777b538SAndroid Build Coastguard Worker * xmlParseTryOrFinish:
11056*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
11057*6777b538SAndroid Build Coastguard Worker * @terminate: last chunk indicator
11058*6777b538SAndroid Build Coastguard Worker *
11059*6777b538SAndroid Build Coastguard Worker * Try to progress on parsing
11060*6777b538SAndroid Build Coastguard Worker *
11061*6777b538SAndroid Build Coastguard Worker * Returns zero if no parsing was possible
11062*6777b538SAndroid Build Coastguard Worker */
11063*6777b538SAndroid Build Coastguard Worker static int
xmlParseTryOrFinish(xmlParserCtxtPtr ctxt,int terminate)11064*6777b538SAndroid Build Coastguard Worker xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
11065*6777b538SAndroid Build Coastguard Worker int ret = 0;
11066*6777b538SAndroid Build Coastguard Worker size_t avail;
11067*6777b538SAndroid Build Coastguard Worker xmlChar cur, next;
11068*6777b538SAndroid Build Coastguard Worker
11069*6777b538SAndroid Build Coastguard Worker if (ctxt->input == NULL)
11070*6777b538SAndroid Build Coastguard Worker return(0);
11071*6777b538SAndroid Build Coastguard Worker
11072*6777b538SAndroid Build Coastguard Worker if ((ctxt->input != NULL) &&
11073*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur - ctxt->input->base > 4096)) {
11074*6777b538SAndroid Build Coastguard Worker xmlParserShrink(ctxt);
11075*6777b538SAndroid Build Coastguard Worker }
11076*6777b538SAndroid Build Coastguard Worker
11077*6777b538SAndroid Build Coastguard Worker while (ctxt->disableSAX == 0) {
11078*6777b538SAndroid Build Coastguard Worker avail = ctxt->input->end - ctxt->input->cur;
11079*6777b538SAndroid Build Coastguard Worker if (avail < 1)
11080*6777b538SAndroid Build Coastguard Worker goto done;
11081*6777b538SAndroid Build Coastguard Worker switch (ctxt->instate) {
11082*6777b538SAndroid Build Coastguard Worker case XML_PARSER_EOF:
11083*6777b538SAndroid Build Coastguard Worker /*
11084*6777b538SAndroid Build Coastguard Worker * Document parsing is done !
11085*6777b538SAndroid Build Coastguard Worker */
11086*6777b538SAndroid Build Coastguard Worker goto done;
11087*6777b538SAndroid Build Coastguard Worker case XML_PARSER_START:
11088*6777b538SAndroid Build Coastguard Worker /*
11089*6777b538SAndroid Build Coastguard Worker * Very first chars read from the document flow.
11090*6777b538SAndroid Build Coastguard Worker */
11091*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 4))
11092*6777b538SAndroid Build Coastguard Worker goto done;
11093*6777b538SAndroid Build Coastguard Worker
11094*6777b538SAndroid Build Coastguard Worker /*
11095*6777b538SAndroid Build Coastguard Worker * We need more bytes to detect EBCDIC code pages.
11096*6777b538SAndroid Build Coastguard Worker * See xmlDetectEBCDIC.
11097*6777b538SAndroid Build Coastguard Worker */
11098*6777b538SAndroid Build Coastguard Worker if ((CMP4(CUR_PTR, 0x4C, 0x6F, 0xA7, 0x94)) &&
11099*6777b538SAndroid Build Coastguard Worker (!terminate) && (avail < 200))
11100*6777b538SAndroid Build Coastguard Worker goto done;
11101*6777b538SAndroid Build Coastguard Worker
11102*6777b538SAndroid Build Coastguard Worker xmlDetectEncoding(ctxt);
11103*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_XML_DECL;
11104*6777b538SAndroid Build Coastguard Worker break;
11105*6777b538SAndroid Build Coastguard Worker
11106*6777b538SAndroid Build Coastguard Worker case XML_PARSER_XML_DECL:
11107*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 2))
11108*6777b538SAndroid Build Coastguard Worker goto done;
11109*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur[0];
11110*6777b538SAndroid Build Coastguard Worker next = ctxt->input->cur[1];
11111*6777b538SAndroid Build Coastguard Worker if ((cur == '<') && (next == '?')) {
11112*6777b538SAndroid Build Coastguard Worker /* PI or XML decl */
11113*6777b538SAndroid Build Coastguard Worker if ((!terminate) &&
11114*6777b538SAndroid Build Coastguard Worker (!xmlParseLookupString(ctxt, 2, "?>", 2)))
11115*6777b538SAndroid Build Coastguard Worker goto done;
11116*6777b538SAndroid Build Coastguard Worker if ((ctxt->input->cur[2] == 'x') &&
11117*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[3] == 'm') &&
11118*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[4] == 'l') &&
11119*6777b538SAndroid Build Coastguard Worker (IS_BLANK_CH(ctxt->input->cur[5]))) {
11120*6777b538SAndroid Build Coastguard Worker ret += 5;
11121*6777b538SAndroid Build Coastguard Worker xmlParseXMLDecl(ctxt);
11122*6777b538SAndroid Build Coastguard Worker } else {
11123*6777b538SAndroid Build Coastguard Worker ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11124*6777b538SAndroid Build Coastguard Worker if (ctxt->version == NULL) {
11125*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
11126*6777b538SAndroid Build Coastguard Worker break;
11127*6777b538SAndroid Build Coastguard Worker }
11128*6777b538SAndroid Build Coastguard Worker }
11129*6777b538SAndroid Build Coastguard Worker } else {
11130*6777b538SAndroid Build Coastguard Worker ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11131*6777b538SAndroid Build Coastguard Worker if (ctxt->version == NULL) {
11132*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
11133*6777b538SAndroid Build Coastguard Worker break;
11134*6777b538SAndroid Build Coastguard Worker }
11135*6777b538SAndroid Build Coastguard Worker }
11136*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) {
11137*6777b538SAndroid Build Coastguard Worker xmlSAXLocator copy = xmlDefaultSAXLocator;
11138*6777b538SAndroid Build Coastguard Worker ctxt->sax->setDocumentLocator(ctxt->userData, ©);
11139*6777b538SAndroid Build Coastguard Worker }
11140*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11141*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
11142*6777b538SAndroid Build Coastguard Worker ctxt->sax->startDocument(ctxt->userData);
11143*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_MISC;
11144*6777b538SAndroid Build Coastguard Worker break;
11145*6777b538SAndroid Build Coastguard Worker case XML_PARSER_START_TAG: {
11146*6777b538SAndroid Build Coastguard Worker const xmlChar *name;
11147*6777b538SAndroid Build Coastguard Worker const xmlChar *prefix = NULL;
11148*6777b538SAndroid Build Coastguard Worker const xmlChar *URI = NULL;
11149*6777b538SAndroid Build Coastguard Worker int line = ctxt->input->line;
11150*6777b538SAndroid Build Coastguard Worker int nbNs = 0;
11151*6777b538SAndroid Build Coastguard Worker
11152*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 2))
11153*6777b538SAndroid Build Coastguard Worker goto done;
11154*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur[0];
11155*6777b538SAndroid Build Coastguard Worker if (cur != '<') {
11156*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
11157*6777b538SAndroid Build Coastguard Worker "Start tag expected, '<' not found");
11158*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_EOF;
11159*6777b538SAndroid Build Coastguard Worker xmlFinishDocument(ctxt);
11160*6777b538SAndroid Build Coastguard Worker goto done;
11161*6777b538SAndroid Build Coastguard Worker }
11162*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (!xmlParseLookupGt(ctxt)))
11163*6777b538SAndroid Build Coastguard Worker goto done;
11164*6777b538SAndroid Build Coastguard Worker if (ctxt->spaceNr == 0)
11165*6777b538SAndroid Build Coastguard Worker spacePush(ctxt, -1);
11166*6777b538SAndroid Build Coastguard Worker else if (*ctxt->space == -2)
11167*6777b538SAndroid Build Coastguard Worker spacePush(ctxt, -1);
11168*6777b538SAndroid Build Coastguard Worker else
11169*6777b538SAndroid Build Coastguard Worker spacePush(ctxt, *ctxt->space);
11170*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
11171*6777b538SAndroid Build Coastguard Worker if (ctxt->sax2)
11172*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
11173*6777b538SAndroid Build Coastguard Worker name = xmlParseStartTag2(ctxt, &prefix, &URI, &nbNs);
11174*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
11175*6777b538SAndroid Build Coastguard Worker else
11176*6777b538SAndroid Build Coastguard Worker name = xmlParseStartTag(ctxt);
11177*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
11178*6777b538SAndroid Build Coastguard Worker if (name == NULL) {
11179*6777b538SAndroid Build Coastguard Worker spacePop(ctxt);
11180*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_EOF;
11181*6777b538SAndroid Build Coastguard Worker xmlFinishDocument(ctxt);
11182*6777b538SAndroid Build Coastguard Worker goto done;
11183*6777b538SAndroid Build Coastguard Worker }
11184*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_VALID_ENABLED
11185*6777b538SAndroid Build Coastguard Worker /*
11186*6777b538SAndroid Build Coastguard Worker * [ VC: Root Element Type ]
11187*6777b538SAndroid Build Coastguard Worker * The Name in the document type declaration must match
11188*6777b538SAndroid Build Coastguard Worker * the element type of the root element.
11189*6777b538SAndroid Build Coastguard Worker */
11190*6777b538SAndroid Build Coastguard Worker if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
11191*6777b538SAndroid Build Coastguard Worker ctxt->node && (ctxt->node == ctxt->myDoc->children))
11192*6777b538SAndroid Build Coastguard Worker ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
11193*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_VALID_ENABLED */
11194*6777b538SAndroid Build Coastguard Worker
11195*6777b538SAndroid Build Coastguard Worker /*
11196*6777b538SAndroid Build Coastguard Worker * Check for an Empty Element.
11197*6777b538SAndroid Build Coastguard Worker */
11198*6777b538SAndroid Build Coastguard Worker if ((RAW == '/') && (NXT(1) == '>')) {
11199*6777b538SAndroid Build Coastguard Worker SKIP(2);
11200*6777b538SAndroid Build Coastguard Worker
11201*6777b538SAndroid Build Coastguard Worker if (ctxt->sax2) {
11202*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
11203*6777b538SAndroid Build Coastguard Worker (ctxt->sax->endElementNs != NULL) &&
11204*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
11205*6777b538SAndroid Build Coastguard Worker ctxt->sax->endElementNs(ctxt->userData, name,
11206*6777b538SAndroid Build Coastguard Worker prefix, URI);
11207*6777b538SAndroid Build Coastguard Worker if (nbNs > 0)
11208*6777b538SAndroid Build Coastguard Worker xmlParserNsPop(ctxt, nbNs);
11209*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
11210*6777b538SAndroid Build Coastguard Worker } else {
11211*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
11212*6777b538SAndroid Build Coastguard Worker (ctxt->sax->endElement != NULL) &&
11213*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX))
11214*6777b538SAndroid Build Coastguard Worker ctxt->sax->endElement(ctxt->userData, name);
11215*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
11216*6777b538SAndroid Build Coastguard Worker }
11217*6777b538SAndroid Build Coastguard Worker spacePop(ctxt);
11218*6777b538SAndroid Build Coastguard Worker } else if (RAW == '>') {
11219*6777b538SAndroid Build Coastguard Worker NEXT;
11220*6777b538SAndroid Build Coastguard Worker nameNsPush(ctxt, name, prefix, URI, line, nbNs);
11221*6777b538SAndroid Build Coastguard Worker } else {
11222*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
11223*6777b538SAndroid Build Coastguard Worker "Couldn't find end of Start Tag %s\n",
11224*6777b538SAndroid Build Coastguard Worker name);
11225*6777b538SAndroid Build Coastguard Worker nodePop(ctxt);
11226*6777b538SAndroid Build Coastguard Worker spacePop(ctxt);
11227*6777b538SAndroid Build Coastguard Worker if (nbNs > 0)
11228*6777b538SAndroid Build Coastguard Worker xmlParserNsPop(ctxt, nbNs);
11229*6777b538SAndroid Build Coastguard Worker }
11230*6777b538SAndroid Build Coastguard Worker
11231*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr == 0)
11232*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_EPILOG;
11233*6777b538SAndroid Build Coastguard Worker else
11234*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_CONTENT;
11235*6777b538SAndroid Build Coastguard Worker break;
11236*6777b538SAndroid Build Coastguard Worker }
11237*6777b538SAndroid Build Coastguard Worker case XML_PARSER_CONTENT: {
11238*6777b538SAndroid Build Coastguard Worker cur = ctxt->input->cur[0];
11239*6777b538SAndroid Build Coastguard Worker
11240*6777b538SAndroid Build Coastguard Worker if (cur == '<') {
11241*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 2))
11242*6777b538SAndroid Build Coastguard Worker goto done;
11243*6777b538SAndroid Build Coastguard Worker next = ctxt->input->cur[1];
11244*6777b538SAndroid Build Coastguard Worker
11245*6777b538SAndroid Build Coastguard Worker if (next == '/') {
11246*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_END_TAG;
11247*6777b538SAndroid Build Coastguard Worker break;
11248*6777b538SAndroid Build Coastguard Worker } else if (next == '?') {
11249*6777b538SAndroid Build Coastguard Worker if ((!terminate) &&
11250*6777b538SAndroid Build Coastguard Worker (!xmlParseLookupString(ctxt, 2, "?>", 2)))
11251*6777b538SAndroid Build Coastguard Worker goto done;
11252*6777b538SAndroid Build Coastguard Worker xmlParsePI(ctxt);
11253*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_CONTENT;
11254*6777b538SAndroid Build Coastguard Worker break;
11255*6777b538SAndroid Build Coastguard Worker } else if (next == '!') {
11256*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 3))
11257*6777b538SAndroid Build Coastguard Worker goto done;
11258*6777b538SAndroid Build Coastguard Worker next = ctxt->input->cur[2];
11259*6777b538SAndroid Build Coastguard Worker
11260*6777b538SAndroid Build Coastguard Worker if (next == '-') {
11261*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 4))
11262*6777b538SAndroid Build Coastguard Worker goto done;
11263*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur[3] == '-') {
11264*6777b538SAndroid Build Coastguard Worker if ((!terminate) &&
11265*6777b538SAndroid Build Coastguard Worker (!xmlParseLookupString(ctxt, 4, "-->", 3)))
11266*6777b538SAndroid Build Coastguard Worker goto done;
11267*6777b538SAndroid Build Coastguard Worker xmlParseComment(ctxt);
11268*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_CONTENT;
11269*6777b538SAndroid Build Coastguard Worker break;
11270*6777b538SAndroid Build Coastguard Worker }
11271*6777b538SAndroid Build Coastguard Worker } else if (next == '[') {
11272*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 9))
11273*6777b538SAndroid Build Coastguard Worker goto done;
11274*6777b538SAndroid Build Coastguard Worker if ((ctxt->input->cur[2] == '[') &&
11275*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[3] == 'C') &&
11276*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[4] == 'D') &&
11277*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[5] == 'A') &&
11278*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[6] == 'T') &&
11279*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[7] == 'A') &&
11280*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[8] == '[')) {
11281*6777b538SAndroid Build Coastguard Worker SKIP(9);
11282*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_CDATA_SECTION;
11283*6777b538SAndroid Build Coastguard Worker break;
11284*6777b538SAndroid Build Coastguard Worker }
11285*6777b538SAndroid Build Coastguard Worker }
11286*6777b538SAndroid Build Coastguard Worker }
11287*6777b538SAndroid Build Coastguard Worker } else if (cur == '&') {
11288*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (!xmlParseLookupChar(ctxt, ';')))
11289*6777b538SAndroid Build Coastguard Worker goto done;
11290*6777b538SAndroid Build Coastguard Worker xmlParseReference(ctxt);
11291*6777b538SAndroid Build Coastguard Worker break;
11292*6777b538SAndroid Build Coastguard Worker } else {
11293*6777b538SAndroid Build Coastguard Worker /* TODO Avoid the extra copy, handle directly !!! */
11294*6777b538SAndroid Build Coastguard Worker /*
11295*6777b538SAndroid Build Coastguard Worker * Goal of the following test is:
11296*6777b538SAndroid Build Coastguard Worker * - minimize calls to the SAX 'character' callback
11297*6777b538SAndroid Build Coastguard Worker * when they are mergeable
11298*6777b538SAndroid Build Coastguard Worker * - handle an problem for isBlank when we only parse
11299*6777b538SAndroid Build Coastguard Worker * a sequence of blank chars and the next one is
11300*6777b538SAndroid Build Coastguard Worker * not available to check against '<' presence.
11301*6777b538SAndroid Build Coastguard Worker * - tries to homogenize the differences in SAX
11302*6777b538SAndroid Build Coastguard Worker * callbacks between the push and pull versions
11303*6777b538SAndroid Build Coastguard Worker * of the parser.
11304*6777b538SAndroid Build Coastguard Worker */
11305*6777b538SAndroid Build Coastguard Worker if (avail < XML_PARSER_BIG_BUFFER_SIZE) {
11306*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (!xmlParseLookupCharData(ctxt)))
11307*6777b538SAndroid Build Coastguard Worker goto done;
11308*6777b538SAndroid Build Coastguard Worker }
11309*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
11310*6777b538SAndroid Build Coastguard Worker xmlParseCharDataInternal(ctxt, !terminate);
11311*6777b538SAndroid Build Coastguard Worker break;
11312*6777b538SAndroid Build Coastguard Worker }
11313*6777b538SAndroid Build Coastguard Worker
11314*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_START_TAG;
11315*6777b538SAndroid Build Coastguard Worker break;
11316*6777b538SAndroid Build Coastguard Worker }
11317*6777b538SAndroid Build Coastguard Worker case XML_PARSER_END_TAG:
11318*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (!xmlParseLookupChar(ctxt, '>')))
11319*6777b538SAndroid Build Coastguard Worker goto done;
11320*6777b538SAndroid Build Coastguard Worker if (ctxt->sax2) {
11321*6777b538SAndroid Build Coastguard Worker xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]);
11322*6777b538SAndroid Build Coastguard Worker nameNsPop(ctxt);
11323*6777b538SAndroid Build Coastguard Worker }
11324*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
11325*6777b538SAndroid Build Coastguard Worker else
11326*6777b538SAndroid Build Coastguard Worker xmlParseEndTag1(ctxt, 0);
11327*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
11328*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr == 0) {
11329*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_EPILOG;
11330*6777b538SAndroid Build Coastguard Worker } else {
11331*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_CONTENT;
11332*6777b538SAndroid Build Coastguard Worker }
11333*6777b538SAndroid Build Coastguard Worker break;
11334*6777b538SAndroid Build Coastguard Worker case XML_PARSER_CDATA_SECTION: {
11335*6777b538SAndroid Build Coastguard Worker /*
11336*6777b538SAndroid Build Coastguard Worker * The Push mode need to have the SAX callback for
11337*6777b538SAndroid Build Coastguard Worker * cdataBlock merge back contiguous callbacks.
11338*6777b538SAndroid Build Coastguard Worker */
11339*6777b538SAndroid Build Coastguard Worker const xmlChar *term;
11340*6777b538SAndroid Build Coastguard Worker
11341*6777b538SAndroid Build Coastguard Worker if (terminate) {
11342*6777b538SAndroid Build Coastguard Worker /*
11343*6777b538SAndroid Build Coastguard Worker * Don't call xmlParseLookupString. If 'terminate'
11344*6777b538SAndroid Build Coastguard Worker * is set, checkIndex is invalid.
11345*6777b538SAndroid Build Coastguard Worker */
11346*6777b538SAndroid Build Coastguard Worker term = BAD_CAST strstr((const char *) ctxt->input->cur,
11347*6777b538SAndroid Build Coastguard Worker "]]>");
11348*6777b538SAndroid Build Coastguard Worker } else {
11349*6777b538SAndroid Build Coastguard Worker term = xmlParseLookupString(ctxt, 0, "]]>", 3);
11350*6777b538SAndroid Build Coastguard Worker }
11351*6777b538SAndroid Build Coastguard Worker
11352*6777b538SAndroid Build Coastguard Worker if (term == NULL) {
11353*6777b538SAndroid Build Coastguard Worker int tmp, size;
11354*6777b538SAndroid Build Coastguard Worker
11355*6777b538SAndroid Build Coastguard Worker if (terminate) {
11356*6777b538SAndroid Build Coastguard Worker /* Unfinished CDATA section */
11357*6777b538SAndroid Build Coastguard Worker size = ctxt->input->end - ctxt->input->cur;
11358*6777b538SAndroid Build Coastguard Worker } else {
11359*6777b538SAndroid Build Coastguard Worker if (avail < XML_PARSER_BIG_BUFFER_SIZE + 2)
11360*6777b538SAndroid Build Coastguard Worker goto done;
11361*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
11362*6777b538SAndroid Build Coastguard Worker /* XXX: Why don't we pass the full buffer? */
11363*6777b538SAndroid Build Coastguard Worker size = XML_PARSER_BIG_BUFFER_SIZE;
11364*6777b538SAndroid Build Coastguard Worker }
11365*6777b538SAndroid Build Coastguard Worker tmp = xmlCheckCdataPush(ctxt->input->cur, size, 0);
11366*6777b538SAndroid Build Coastguard Worker if (tmp <= 0) {
11367*6777b538SAndroid Build Coastguard Worker tmp = -tmp;
11368*6777b538SAndroid Build Coastguard Worker ctxt->input->cur += tmp;
11369*6777b538SAndroid Build Coastguard Worker goto encoding_error;
11370*6777b538SAndroid Build Coastguard Worker }
11371*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
11372*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->cdataBlock != NULL)
11373*6777b538SAndroid Build Coastguard Worker ctxt->sax->cdataBlock(ctxt->userData,
11374*6777b538SAndroid Build Coastguard Worker ctxt->input->cur, tmp);
11375*6777b538SAndroid Build Coastguard Worker else if (ctxt->sax->characters != NULL)
11376*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData,
11377*6777b538SAndroid Build Coastguard Worker ctxt->input->cur, tmp);
11378*6777b538SAndroid Build Coastguard Worker }
11379*6777b538SAndroid Build Coastguard Worker SKIPL(tmp);
11380*6777b538SAndroid Build Coastguard Worker } else {
11381*6777b538SAndroid Build Coastguard Worker int base = term - CUR_PTR;
11382*6777b538SAndroid Build Coastguard Worker int tmp;
11383*6777b538SAndroid Build Coastguard Worker
11384*6777b538SAndroid Build Coastguard Worker tmp = xmlCheckCdataPush(ctxt->input->cur, base, 1);
11385*6777b538SAndroid Build Coastguard Worker if ((tmp < 0) || (tmp != base)) {
11386*6777b538SAndroid Build Coastguard Worker tmp = -tmp;
11387*6777b538SAndroid Build Coastguard Worker ctxt->input->cur += tmp;
11388*6777b538SAndroid Build Coastguard Worker goto encoding_error;
11389*6777b538SAndroid Build Coastguard Worker }
11390*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (base == 0) &&
11391*6777b538SAndroid Build Coastguard Worker (ctxt->sax->cdataBlock != NULL) &&
11392*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX)) {
11393*6777b538SAndroid Build Coastguard Worker /*
11394*6777b538SAndroid Build Coastguard Worker * Special case to provide identical behaviour
11395*6777b538SAndroid Build Coastguard Worker * between pull and push parsers on enpty CDATA
11396*6777b538SAndroid Build Coastguard Worker * sections
11397*6777b538SAndroid Build Coastguard Worker */
11398*6777b538SAndroid Build Coastguard Worker if ((ctxt->input->cur - ctxt->input->base >= 9) &&
11399*6777b538SAndroid Build Coastguard Worker (!strncmp((const char *)&ctxt->input->cur[-9],
11400*6777b538SAndroid Build Coastguard Worker "<![CDATA[", 9)))
11401*6777b538SAndroid Build Coastguard Worker ctxt->sax->cdataBlock(ctxt->userData,
11402*6777b538SAndroid Build Coastguard Worker BAD_CAST "", 0);
11403*6777b538SAndroid Build Coastguard Worker } else if ((ctxt->sax != NULL) && (base > 0) &&
11404*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX)) {
11405*6777b538SAndroid Build Coastguard Worker if (ctxt->sax->cdataBlock != NULL)
11406*6777b538SAndroid Build Coastguard Worker ctxt->sax->cdataBlock(ctxt->userData,
11407*6777b538SAndroid Build Coastguard Worker ctxt->input->cur, base);
11408*6777b538SAndroid Build Coastguard Worker else if (ctxt->sax->characters != NULL)
11409*6777b538SAndroid Build Coastguard Worker ctxt->sax->characters(ctxt->userData,
11410*6777b538SAndroid Build Coastguard Worker ctxt->input->cur, base);
11411*6777b538SAndroid Build Coastguard Worker }
11412*6777b538SAndroid Build Coastguard Worker SKIPL(base + 3);
11413*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_CONTENT;
11414*6777b538SAndroid Build Coastguard Worker }
11415*6777b538SAndroid Build Coastguard Worker break;
11416*6777b538SAndroid Build Coastguard Worker }
11417*6777b538SAndroid Build Coastguard Worker case XML_PARSER_MISC:
11418*6777b538SAndroid Build Coastguard Worker case XML_PARSER_PROLOG:
11419*6777b538SAndroid Build Coastguard Worker case XML_PARSER_EPILOG:
11420*6777b538SAndroid Build Coastguard Worker SKIP_BLANKS;
11421*6777b538SAndroid Build Coastguard Worker avail = ctxt->input->end - ctxt->input->cur;
11422*6777b538SAndroid Build Coastguard Worker if (avail < 1)
11423*6777b538SAndroid Build Coastguard Worker goto done;
11424*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur[0] == '<') {
11425*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 2))
11426*6777b538SAndroid Build Coastguard Worker goto done;
11427*6777b538SAndroid Build Coastguard Worker next = ctxt->input->cur[1];
11428*6777b538SAndroid Build Coastguard Worker if (next == '?') {
11429*6777b538SAndroid Build Coastguard Worker if ((!terminate) &&
11430*6777b538SAndroid Build Coastguard Worker (!xmlParseLookupString(ctxt, 2, "?>", 2)))
11431*6777b538SAndroid Build Coastguard Worker goto done;
11432*6777b538SAndroid Build Coastguard Worker xmlParsePI(ctxt);
11433*6777b538SAndroid Build Coastguard Worker break;
11434*6777b538SAndroid Build Coastguard Worker } else if (next == '!') {
11435*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 3))
11436*6777b538SAndroid Build Coastguard Worker goto done;
11437*6777b538SAndroid Build Coastguard Worker
11438*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur[2] == '-') {
11439*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 4))
11440*6777b538SAndroid Build Coastguard Worker goto done;
11441*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur[3] == '-') {
11442*6777b538SAndroid Build Coastguard Worker if ((!terminate) &&
11443*6777b538SAndroid Build Coastguard Worker (!xmlParseLookupString(ctxt, 4, "-->", 3)))
11444*6777b538SAndroid Build Coastguard Worker goto done;
11445*6777b538SAndroid Build Coastguard Worker xmlParseComment(ctxt);
11446*6777b538SAndroid Build Coastguard Worker break;
11447*6777b538SAndroid Build Coastguard Worker }
11448*6777b538SAndroid Build Coastguard Worker } else if (ctxt->instate == XML_PARSER_MISC) {
11449*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (avail < 9))
11450*6777b538SAndroid Build Coastguard Worker goto done;
11451*6777b538SAndroid Build Coastguard Worker if ((ctxt->input->cur[2] == 'D') &&
11452*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[3] == 'O') &&
11453*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[4] == 'C') &&
11454*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[5] == 'T') &&
11455*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[6] == 'Y') &&
11456*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[7] == 'P') &&
11457*6777b538SAndroid Build Coastguard Worker (ctxt->input->cur[8] == 'E')) {
11458*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (!xmlParseLookupGt(ctxt)))
11459*6777b538SAndroid Build Coastguard Worker goto done;
11460*6777b538SAndroid Build Coastguard Worker ctxt->inSubset = 1;
11461*6777b538SAndroid Build Coastguard Worker xmlParseDocTypeDecl(ctxt);
11462*6777b538SAndroid Build Coastguard Worker if (RAW == '[') {
11463*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_DTD;
11464*6777b538SAndroid Build Coastguard Worker } else {
11465*6777b538SAndroid Build Coastguard Worker /*
11466*6777b538SAndroid Build Coastguard Worker * Create and update the external subset.
11467*6777b538SAndroid Build Coastguard Worker */
11468*6777b538SAndroid Build Coastguard Worker ctxt->inSubset = 2;
11469*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) &&
11470*6777b538SAndroid Build Coastguard Worker (!ctxt->disableSAX) &&
11471*6777b538SAndroid Build Coastguard Worker (ctxt->sax->externalSubset != NULL))
11472*6777b538SAndroid Build Coastguard Worker ctxt->sax->externalSubset(
11473*6777b538SAndroid Build Coastguard Worker ctxt->userData,
11474*6777b538SAndroid Build Coastguard Worker ctxt->intSubName,
11475*6777b538SAndroid Build Coastguard Worker ctxt->extSubSystem,
11476*6777b538SAndroid Build Coastguard Worker ctxt->extSubURI);
11477*6777b538SAndroid Build Coastguard Worker ctxt->inSubset = 0;
11478*6777b538SAndroid Build Coastguard Worker xmlCleanSpecialAttr(ctxt);
11479*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_PROLOG;
11480*6777b538SAndroid Build Coastguard Worker }
11481*6777b538SAndroid Build Coastguard Worker break;
11482*6777b538SAndroid Build Coastguard Worker }
11483*6777b538SAndroid Build Coastguard Worker }
11484*6777b538SAndroid Build Coastguard Worker }
11485*6777b538SAndroid Build Coastguard Worker }
11486*6777b538SAndroid Build Coastguard Worker
11487*6777b538SAndroid Build Coastguard Worker if (ctxt->instate == XML_PARSER_EPILOG) {
11488*6777b538SAndroid Build Coastguard Worker if (ctxt->errNo == XML_ERR_OK)
11489*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11490*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_EOF;
11491*6777b538SAndroid Build Coastguard Worker xmlFinishDocument(ctxt);
11492*6777b538SAndroid Build Coastguard Worker } else {
11493*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_START_TAG;
11494*6777b538SAndroid Build Coastguard Worker }
11495*6777b538SAndroid Build Coastguard Worker break;
11496*6777b538SAndroid Build Coastguard Worker case XML_PARSER_DTD: {
11497*6777b538SAndroid Build Coastguard Worker if ((!terminate) && (!xmlParseLookupInternalSubset(ctxt)))
11498*6777b538SAndroid Build Coastguard Worker goto done;
11499*6777b538SAndroid Build Coastguard Worker xmlParseInternalSubset(ctxt);
11500*6777b538SAndroid Build Coastguard Worker ctxt->inSubset = 2;
11501*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11502*6777b538SAndroid Build Coastguard Worker (ctxt->sax->externalSubset != NULL))
11503*6777b538SAndroid Build Coastguard Worker ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
11504*6777b538SAndroid Build Coastguard Worker ctxt->extSubSystem, ctxt->extSubURI);
11505*6777b538SAndroid Build Coastguard Worker ctxt->inSubset = 0;
11506*6777b538SAndroid Build Coastguard Worker xmlCleanSpecialAttr(ctxt);
11507*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_PROLOG;
11508*6777b538SAndroid Build Coastguard Worker break;
11509*6777b538SAndroid Build Coastguard Worker }
11510*6777b538SAndroid Build Coastguard Worker default:
11511*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
11512*6777b538SAndroid Build Coastguard Worker "PP: internal error\n");
11513*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_EOF;
11514*6777b538SAndroid Build Coastguard Worker break;
11515*6777b538SAndroid Build Coastguard Worker }
11516*6777b538SAndroid Build Coastguard Worker }
11517*6777b538SAndroid Build Coastguard Worker done:
11518*6777b538SAndroid Build Coastguard Worker return(ret);
11519*6777b538SAndroid Build Coastguard Worker encoding_error:
11520*6777b538SAndroid Build Coastguard Worker /* Only report the first error */
11521*6777b538SAndroid Build Coastguard Worker if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
11522*6777b538SAndroid Build Coastguard Worker xmlCtxtErrIO(ctxt, XML_ERR_INVALID_ENCODING, NULL);
11523*6777b538SAndroid Build Coastguard Worker ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
11524*6777b538SAndroid Build Coastguard Worker }
11525*6777b538SAndroid Build Coastguard Worker return(0);
11526*6777b538SAndroid Build Coastguard Worker }
11527*6777b538SAndroid Build Coastguard Worker
11528*6777b538SAndroid Build Coastguard Worker /**
11529*6777b538SAndroid Build Coastguard Worker * xmlParseChunk:
11530*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
11531*6777b538SAndroid Build Coastguard Worker * @chunk: chunk of memory
11532*6777b538SAndroid Build Coastguard Worker * @size: size of chunk in bytes
11533*6777b538SAndroid Build Coastguard Worker * @terminate: last chunk indicator
11534*6777b538SAndroid Build Coastguard Worker *
11535*6777b538SAndroid Build Coastguard Worker * Parse a chunk of memory in push parser mode.
11536*6777b538SAndroid Build Coastguard Worker *
11537*6777b538SAndroid Build Coastguard Worker * Assumes that the parser context was initialized with
11538*6777b538SAndroid Build Coastguard Worker * xmlCreatePushParserCtxt.
11539*6777b538SAndroid Build Coastguard Worker *
11540*6777b538SAndroid Build Coastguard Worker * The last chunk, which will often be empty, must be marked with
11541*6777b538SAndroid Build Coastguard Worker * the @terminate flag. With the default SAX callbacks, the resulting
11542*6777b538SAndroid Build Coastguard Worker * document will be available in ctxt->myDoc. This pointer will not
11543*6777b538SAndroid Build Coastguard Worker * be freed by the library.
11544*6777b538SAndroid Build Coastguard Worker *
11545*6777b538SAndroid Build Coastguard Worker * If the document isn't well-formed, ctxt->myDoc is set to NULL.
11546*6777b538SAndroid Build Coastguard Worker * The push parser doesn't support recovery mode.
11547*6777b538SAndroid Build Coastguard Worker *
11548*6777b538SAndroid Build Coastguard Worker * Returns an xmlParserErrors code (0 on success).
11549*6777b538SAndroid Build Coastguard Worker */
11550*6777b538SAndroid Build Coastguard Worker int
xmlParseChunk(xmlParserCtxtPtr ctxt,const char * chunk,int size,int terminate)11551*6777b538SAndroid Build Coastguard Worker xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
11552*6777b538SAndroid Build Coastguard Worker int terminate) {
11553*6777b538SAndroid Build Coastguard Worker size_t curBase;
11554*6777b538SAndroid Build Coastguard Worker size_t maxLength;
11555*6777b538SAndroid Build Coastguard Worker int end_in_lf = 0;
11556*6777b538SAndroid Build Coastguard Worker
11557*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (size < 0))
11558*6777b538SAndroid Build Coastguard Worker return(XML_ERR_ARGUMENT);
11559*6777b538SAndroid Build Coastguard Worker if (ctxt->disableSAX != 0)
11560*6777b538SAndroid Build Coastguard Worker return(ctxt->errNo);
11561*6777b538SAndroid Build Coastguard Worker if (ctxt->input == NULL)
11562*6777b538SAndroid Build Coastguard Worker return(XML_ERR_INTERNAL_ERROR);
11563*6777b538SAndroid Build Coastguard Worker
11564*6777b538SAndroid Build Coastguard Worker ctxt->input->flags |= XML_INPUT_PROGRESSIVE;
11565*6777b538SAndroid Build Coastguard Worker if (ctxt->instate == XML_PARSER_START)
11566*6777b538SAndroid Build Coastguard Worker xmlCtxtInitializeLate(ctxt);
11567*6777b538SAndroid Build Coastguard Worker if ((size > 0) && (chunk != NULL) && (!terminate) &&
11568*6777b538SAndroid Build Coastguard Worker (chunk[size - 1] == '\r')) {
11569*6777b538SAndroid Build Coastguard Worker end_in_lf = 1;
11570*6777b538SAndroid Build Coastguard Worker size--;
11571*6777b538SAndroid Build Coastguard Worker }
11572*6777b538SAndroid Build Coastguard Worker
11573*6777b538SAndroid Build Coastguard Worker if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
11574*6777b538SAndroid Build Coastguard Worker (ctxt->input->buf != NULL)) {
11575*6777b538SAndroid Build Coastguard Worker size_t pos = ctxt->input->cur - ctxt->input->base;
11576*6777b538SAndroid Build Coastguard Worker int res;
11577*6777b538SAndroid Build Coastguard Worker
11578*6777b538SAndroid Build Coastguard Worker res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
11579*6777b538SAndroid Build Coastguard Worker xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
11580*6777b538SAndroid Build Coastguard Worker if (res < 0) {
11581*6777b538SAndroid Build Coastguard Worker xmlCtxtErrIO(ctxt, ctxt->input->buf->error, NULL);
11582*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
11583*6777b538SAndroid Build Coastguard Worker return(ctxt->errNo);
11584*6777b538SAndroid Build Coastguard Worker }
11585*6777b538SAndroid Build Coastguard Worker }
11586*6777b538SAndroid Build Coastguard Worker
11587*6777b538SAndroid Build Coastguard Worker xmlParseTryOrFinish(ctxt, terminate);
11588*6777b538SAndroid Build Coastguard Worker
11589*6777b538SAndroid Build Coastguard Worker curBase = ctxt->input->cur - ctxt->input->base;
11590*6777b538SAndroid Build Coastguard Worker maxLength = (ctxt->options & XML_PARSE_HUGE) ?
11591*6777b538SAndroid Build Coastguard Worker XML_MAX_HUGE_LENGTH :
11592*6777b538SAndroid Build Coastguard Worker XML_MAX_LOOKUP_LIMIT;
11593*6777b538SAndroid Build Coastguard Worker if (curBase > maxLength) {
11594*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT,
11595*6777b538SAndroid Build Coastguard Worker "Buffer size limit exceeded, try XML_PARSE_HUGE\n");
11596*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
11597*6777b538SAndroid Build Coastguard Worker }
11598*6777b538SAndroid Build Coastguard Worker
11599*6777b538SAndroid Build Coastguard Worker if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11600*6777b538SAndroid Build Coastguard Worker return(ctxt->errNo);
11601*6777b538SAndroid Build Coastguard Worker
11602*6777b538SAndroid Build Coastguard Worker if ((end_in_lf == 1) && (ctxt->input != NULL) &&
11603*6777b538SAndroid Build Coastguard Worker (ctxt->input->buf != NULL)) {
11604*6777b538SAndroid Build Coastguard Worker size_t pos = ctxt->input->cur - ctxt->input->base;
11605*6777b538SAndroid Build Coastguard Worker int res;
11606*6777b538SAndroid Build Coastguard Worker
11607*6777b538SAndroid Build Coastguard Worker res = xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
11608*6777b538SAndroid Build Coastguard Worker xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
11609*6777b538SAndroid Build Coastguard Worker if (res < 0) {
11610*6777b538SAndroid Build Coastguard Worker xmlCtxtErrIO(ctxt, ctxt->input->buf->error, NULL);
11611*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
11612*6777b538SAndroid Build Coastguard Worker return(ctxt->errNo);
11613*6777b538SAndroid Build Coastguard Worker }
11614*6777b538SAndroid Build Coastguard Worker }
11615*6777b538SAndroid Build Coastguard Worker if (terminate) {
11616*6777b538SAndroid Build Coastguard Worker /*
11617*6777b538SAndroid Build Coastguard Worker * Check for termination
11618*6777b538SAndroid Build Coastguard Worker */
11619*6777b538SAndroid Build Coastguard Worker if ((ctxt->instate != XML_PARSER_EOF) &&
11620*6777b538SAndroid Build Coastguard Worker (ctxt->instate != XML_PARSER_EPILOG)) {
11621*6777b538SAndroid Build Coastguard Worker if (ctxt->nameNr > 0) {
11622*6777b538SAndroid Build Coastguard Worker const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
11623*6777b538SAndroid Build Coastguard Worker int line = ctxt->pushTab[ctxt->nameNr - 1].line;
11624*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
11625*6777b538SAndroid Build Coastguard Worker "Premature end of data in tag %s line %d\n",
11626*6777b538SAndroid Build Coastguard Worker name, line, NULL);
11627*6777b538SAndroid Build Coastguard Worker } else if (ctxt->instate == XML_PARSER_START) {
11628*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11629*6777b538SAndroid Build Coastguard Worker } else {
11630*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
11631*6777b538SAndroid Build Coastguard Worker "Start tag expected, '<' not found\n");
11632*6777b538SAndroid Build Coastguard Worker }
11633*6777b538SAndroid Build Coastguard Worker } else if ((ctxt->input->buf != NULL) &&
11634*6777b538SAndroid Build Coastguard Worker (ctxt->input->buf->encoder != NULL) &&
11635*6777b538SAndroid Build Coastguard Worker (!xmlBufIsEmpty(ctxt->input->buf->raw))) {
11636*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
11637*6777b538SAndroid Build Coastguard Worker "Truncated multi-byte sequence at EOF\n");
11638*6777b538SAndroid Build Coastguard Worker }
11639*6777b538SAndroid Build Coastguard Worker if (ctxt->instate != XML_PARSER_EOF) {
11640*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_EOF;
11641*6777b538SAndroid Build Coastguard Worker xmlFinishDocument(ctxt);
11642*6777b538SAndroid Build Coastguard Worker }
11643*6777b538SAndroid Build Coastguard Worker }
11644*6777b538SAndroid Build Coastguard Worker if (ctxt->wellFormed == 0)
11645*6777b538SAndroid Build Coastguard Worker return((xmlParserErrors) ctxt->errNo);
11646*6777b538SAndroid Build Coastguard Worker else
11647*6777b538SAndroid Build Coastguard Worker return(0);
11648*6777b538SAndroid Build Coastguard Worker }
11649*6777b538SAndroid Build Coastguard Worker
11650*6777b538SAndroid Build Coastguard Worker /************************************************************************
11651*6777b538SAndroid Build Coastguard Worker * *
11652*6777b538SAndroid Build Coastguard Worker * I/O front end functions to the parser *
11653*6777b538SAndroid Build Coastguard Worker * *
11654*6777b538SAndroid Build Coastguard Worker ************************************************************************/
11655*6777b538SAndroid Build Coastguard Worker
11656*6777b538SAndroid Build Coastguard Worker /**
11657*6777b538SAndroid Build Coastguard Worker * xmlCreatePushParserCtxt:
11658*6777b538SAndroid Build Coastguard Worker * @sax: a SAX handler (optional)
11659*6777b538SAndroid Build Coastguard Worker * @user_data: user data for SAX callbacks (optional)
11660*6777b538SAndroid Build Coastguard Worker * @chunk: initial chunk (optional, deprecated)
11661*6777b538SAndroid Build Coastguard Worker * @size: size of initial chunk in bytes
11662*6777b538SAndroid Build Coastguard Worker * @filename: file name or URI (optional)
11663*6777b538SAndroid Build Coastguard Worker *
11664*6777b538SAndroid Build Coastguard Worker * Create a parser context for using the XML parser in push mode.
11665*6777b538SAndroid Build Coastguard Worker * See xmlParseChunk.
11666*6777b538SAndroid Build Coastguard Worker *
11667*6777b538SAndroid Build Coastguard Worker * Passing an initial chunk is useless and deprecated.
11668*6777b538SAndroid Build Coastguard Worker *
11669*6777b538SAndroid Build Coastguard Worker * @filename is used as base URI to fetch external entities and for
11670*6777b538SAndroid Build Coastguard Worker * error reports.
11671*6777b538SAndroid Build Coastguard Worker *
11672*6777b538SAndroid Build Coastguard Worker * Returns the new parser context or NULL in case of error.
11673*6777b538SAndroid Build Coastguard Worker */
11674*6777b538SAndroid Build Coastguard Worker
11675*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr
xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax,void * user_data,const char * chunk,int size,const char * filename)11676*6777b538SAndroid Build Coastguard Worker xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
11677*6777b538SAndroid Build Coastguard Worker const char *chunk, int size, const char *filename) {
11678*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
11679*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
11680*6777b538SAndroid Build Coastguard Worker
11681*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewSAXParserCtxt(sax, user_data);
11682*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
11683*6777b538SAndroid Build Coastguard Worker return(NULL);
11684*6777b538SAndroid Build Coastguard Worker
11685*6777b538SAndroid Build Coastguard Worker ctxt->options &= ~XML_PARSE_NODICT;
11686*6777b538SAndroid Build Coastguard Worker ctxt->dictNames = 1;
11687*6777b538SAndroid Build Coastguard Worker
11688*6777b538SAndroid Build Coastguard Worker input = xmlNewInputPush(ctxt, filename, chunk, size, NULL);
11689*6777b538SAndroid Build Coastguard Worker if (input == NULL) {
11690*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11691*6777b538SAndroid Build Coastguard Worker return(NULL);
11692*6777b538SAndroid Build Coastguard Worker }
11693*6777b538SAndroid Build Coastguard Worker inputPush(ctxt, input);
11694*6777b538SAndroid Build Coastguard Worker
11695*6777b538SAndroid Build Coastguard Worker return(ctxt);
11696*6777b538SAndroid Build Coastguard Worker }
11697*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_PUSH_ENABLED */
11698*6777b538SAndroid Build Coastguard Worker
11699*6777b538SAndroid Build Coastguard Worker /**
11700*6777b538SAndroid Build Coastguard Worker * xmlStopParser:
11701*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
11702*6777b538SAndroid Build Coastguard Worker *
11703*6777b538SAndroid Build Coastguard Worker * Blocks further parser processing
11704*6777b538SAndroid Build Coastguard Worker */
11705*6777b538SAndroid Build Coastguard Worker void
xmlStopParser(xmlParserCtxtPtr ctxt)11706*6777b538SAndroid Build Coastguard Worker xmlStopParser(xmlParserCtxtPtr ctxt) {
11707*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
11708*6777b538SAndroid Build Coastguard Worker return;
11709*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
11710*6777b538SAndroid Build Coastguard Worker if (ctxt->errNo != XML_ERR_NO_MEMORY)
11711*6777b538SAndroid Build Coastguard Worker ctxt->errNo = XML_ERR_USER_STOP;
11712*6777b538SAndroid Build Coastguard Worker }
11713*6777b538SAndroid Build Coastguard Worker
11714*6777b538SAndroid Build Coastguard Worker /**
11715*6777b538SAndroid Build Coastguard Worker * xmlCreateIOParserCtxt:
11716*6777b538SAndroid Build Coastguard Worker * @sax: a SAX handler (optional)
11717*6777b538SAndroid Build Coastguard Worker * @user_data: user data for SAX callbacks (optional)
11718*6777b538SAndroid Build Coastguard Worker * @ioread: an I/O read function
11719*6777b538SAndroid Build Coastguard Worker * @ioclose: an I/O close function (optional)
11720*6777b538SAndroid Build Coastguard Worker * @ioctx: an I/O handler
11721*6777b538SAndroid Build Coastguard Worker * @enc: the charset encoding if known (deprecated)
11722*6777b538SAndroid Build Coastguard Worker *
11723*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewParserCtxt and xmlCtxtReadIO.
11724*6777b538SAndroid Build Coastguard Worker *
11725*6777b538SAndroid Build Coastguard Worker * Create a parser context for using the XML parser with an existing
11726*6777b538SAndroid Build Coastguard Worker * I/O stream
11727*6777b538SAndroid Build Coastguard Worker *
11728*6777b538SAndroid Build Coastguard Worker * Returns the new parser context or NULL
11729*6777b538SAndroid Build Coastguard Worker */
11730*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr
xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax,void * user_data,xmlInputReadCallback ioread,xmlInputCloseCallback ioclose,void * ioctx,xmlCharEncoding enc)11731*6777b538SAndroid Build Coastguard Worker xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
11732*6777b538SAndroid Build Coastguard Worker xmlInputReadCallback ioread,
11733*6777b538SAndroid Build Coastguard Worker xmlInputCloseCallback ioclose,
11734*6777b538SAndroid Build Coastguard Worker void *ioctx, xmlCharEncoding enc) {
11735*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
11736*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
11737*6777b538SAndroid Build Coastguard Worker const char *encoding;
11738*6777b538SAndroid Build Coastguard Worker
11739*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewSAXParserCtxt(sax, user_data);
11740*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
11741*6777b538SAndroid Build Coastguard Worker return(NULL);
11742*6777b538SAndroid Build Coastguard Worker
11743*6777b538SAndroid Build Coastguard Worker encoding = xmlGetCharEncodingName(enc);
11744*6777b538SAndroid Build Coastguard Worker input = xmlNewInputIO(ctxt, NULL, ioread, ioclose, ioctx, encoding, 0);
11745*6777b538SAndroid Build Coastguard Worker if (input == NULL) {
11746*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11747*6777b538SAndroid Build Coastguard Worker return (NULL);
11748*6777b538SAndroid Build Coastguard Worker }
11749*6777b538SAndroid Build Coastguard Worker inputPush(ctxt, input);
11750*6777b538SAndroid Build Coastguard Worker
11751*6777b538SAndroid Build Coastguard Worker return(ctxt);
11752*6777b538SAndroid Build Coastguard Worker }
11753*6777b538SAndroid Build Coastguard Worker
11754*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_VALID_ENABLED
11755*6777b538SAndroid Build Coastguard Worker /************************************************************************
11756*6777b538SAndroid Build Coastguard Worker * *
11757*6777b538SAndroid Build Coastguard Worker * Front ends when parsing a DTD *
11758*6777b538SAndroid Build Coastguard Worker * *
11759*6777b538SAndroid Build Coastguard Worker ************************************************************************/
11760*6777b538SAndroid Build Coastguard Worker
11761*6777b538SAndroid Build Coastguard Worker /**
11762*6777b538SAndroid Build Coastguard Worker * xmlIOParseDTD:
11763*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block or NULL
11764*6777b538SAndroid Build Coastguard Worker * @input: an Input Buffer
11765*6777b538SAndroid Build Coastguard Worker * @enc: the charset encoding if known
11766*6777b538SAndroid Build Coastguard Worker *
11767*6777b538SAndroid Build Coastguard Worker * Load and parse a DTD
11768*6777b538SAndroid Build Coastguard Worker *
11769*6777b538SAndroid Build Coastguard Worker * Returns the resulting xmlDtdPtr or NULL in case of error.
11770*6777b538SAndroid Build Coastguard Worker * @input will be freed by the function in any case.
11771*6777b538SAndroid Build Coastguard Worker */
11772*6777b538SAndroid Build Coastguard Worker
11773*6777b538SAndroid Build Coastguard Worker xmlDtdPtr
xmlIOParseDTD(xmlSAXHandlerPtr sax,xmlParserInputBufferPtr input,xmlCharEncoding enc)11774*6777b538SAndroid Build Coastguard Worker xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
11775*6777b538SAndroid Build Coastguard Worker xmlCharEncoding enc) {
11776*6777b538SAndroid Build Coastguard Worker xmlDtdPtr ret = NULL;
11777*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
11778*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr pinput = NULL;
11779*6777b538SAndroid Build Coastguard Worker
11780*6777b538SAndroid Build Coastguard Worker if (input == NULL)
11781*6777b538SAndroid Build Coastguard Worker return(NULL);
11782*6777b538SAndroid Build Coastguard Worker
11783*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewSAXParserCtxt(sax, NULL);
11784*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL) {
11785*6777b538SAndroid Build Coastguard Worker xmlFreeParserInputBuffer(input);
11786*6777b538SAndroid Build Coastguard Worker return(NULL);
11787*6777b538SAndroid Build Coastguard Worker }
11788*6777b538SAndroid Build Coastguard Worker
11789*6777b538SAndroid Build Coastguard Worker /*
11790*6777b538SAndroid Build Coastguard Worker * generate a parser input from the I/O handler
11791*6777b538SAndroid Build Coastguard Worker */
11792*6777b538SAndroid Build Coastguard Worker
11793*6777b538SAndroid Build Coastguard Worker pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
11794*6777b538SAndroid Build Coastguard Worker if (pinput == NULL) {
11795*6777b538SAndroid Build Coastguard Worker xmlFreeParserInputBuffer(input);
11796*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11797*6777b538SAndroid Build Coastguard Worker return(NULL);
11798*6777b538SAndroid Build Coastguard Worker }
11799*6777b538SAndroid Build Coastguard Worker
11800*6777b538SAndroid Build Coastguard Worker /*
11801*6777b538SAndroid Build Coastguard Worker * plug some encoding conversion routines here.
11802*6777b538SAndroid Build Coastguard Worker */
11803*6777b538SAndroid Build Coastguard Worker if (xmlPushInput(ctxt, pinput) < 0) {
11804*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11805*6777b538SAndroid Build Coastguard Worker return(NULL);
11806*6777b538SAndroid Build Coastguard Worker }
11807*6777b538SAndroid Build Coastguard Worker if (enc != XML_CHAR_ENCODING_NONE) {
11808*6777b538SAndroid Build Coastguard Worker xmlSwitchEncoding(ctxt, enc);
11809*6777b538SAndroid Build Coastguard Worker }
11810*6777b538SAndroid Build Coastguard Worker
11811*6777b538SAndroid Build Coastguard Worker /*
11812*6777b538SAndroid Build Coastguard Worker * let's parse that entity knowing it's an external subset.
11813*6777b538SAndroid Build Coastguard Worker */
11814*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
11815*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc == NULL) {
11816*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
11817*6777b538SAndroid Build Coastguard Worker return(NULL);
11818*6777b538SAndroid Build Coastguard Worker }
11819*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->properties = XML_DOC_INTERNAL;
11820*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
11821*6777b538SAndroid Build Coastguard Worker BAD_CAST "none", BAD_CAST "none");
11822*6777b538SAndroid Build Coastguard Worker
11823*6777b538SAndroid Build Coastguard Worker xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
11824*6777b538SAndroid Build Coastguard Worker
11825*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc != NULL) {
11826*6777b538SAndroid Build Coastguard Worker if (ctxt->wellFormed) {
11827*6777b538SAndroid Build Coastguard Worker ret = ctxt->myDoc->extSubset;
11828*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->extSubset = NULL;
11829*6777b538SAndroid Build Coastguard Worker if (ret != NULL) {
11830*6777b538SAndroid Build Coastguard Worker xmlNodePtr tmp;
11831*6777b538SAndroid Build Coastguard Worker
11832*6777b538SAndroid Build Coastguard Worker ret->doc = NULL;
11833*6777b538SAndroid Build Coastguard Worker tmp = ret->children;
11834*6777b538SAndroid Build Coastguard Worker while (tmp != NULL) {
11835*6777b538SAndroid Build Coastguard Worker tmp->doc = NULL;
11836*6777b538SAndroid Build Coastguard Worker tmp = tmp->next;
11837*6777b538SAndroid Build Coastguard Worker }
11838*6777b538SAndroid Build Coastguard Worker }
11839*6777b538SAndroid Build Coastguard Worker } else {
11840*6777b538SAndroid Build Coastguard Worker ret = NULL;
11841*6777b538SAndroid Build Coastguard Worker }
11842*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
11843*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = NULL;
11844*6777b538SAndroid Build Coastguard Worker }
11845*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11846*6777b538SAndroid Build Coastguard Worker
11847*6777b538SAndroid Build Coastguard Worker return(ret);
11848*6777b538SAndroid Build Coastguard Worker }
11849*6777b538SAndroid Build Coastguard Worker
11850*6777b538SAndroid Build Coastguard Worker /**
11851*6777b538SAndroid Build Coastguard Worker * xmlSAXParseDTD:
11852*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block
11853*6777b538SAndroid Build Coastguard Worker * @ExternalID: a NAME* containing the External ID of the DTD
11854*6777b538SAndroid Build Coastguard Worker * @SystemID: a NAME* containing the URL to the DTD
11855*6777b538SAndroid Build Coastguard Worker *
11856*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Don't use.
11857*6777b538SAndroid Build Coastguard Worker *
11858*6777b538SAndroid Build Coastguard Worker * Load and parse an external subset.
11859*6777b538SAndroid Build Coastguard Worker *
11860*6777b538SAndroid Build Coastguard Worker * Returns the resulting xmlDtdPtr or NULL in case of error.
11861*6777b538SAndroid Build Coastguard Worker */
11862*6777b538SAndroid Build Coastguard Worker
11863*6777b538SAndroid Build Coastguard Worker xmlDtdPtr
xmlSAXParseDTD(xmlSAXHandlerPtr sax,const xmlChar * ExternalID,const xmlChar * SystemID)11864*6777b538SAndroid Build Coastguard Worker xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
11865*6777b538SAndroid Build Coastguard Worker const xmlChar *SystemID) {
11866*6777b538SAndroid Build Coastguard Worker xmlDtdPtr ret = NULL;
11867*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
11868*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input = NULL;
11869*6777b538SAndroid Build Coastguard Worker xmlChar* systemIdCanonic;
11870*6777b538SAndroid Build Coastguard Worker
11871*6777b538SAndroid Build Coastguard Worker if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
11872*6777b538SAndroid Build Coastguard Worker
11873*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewSAXParserCtxt(sax, NULL);
11874*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL) {
11875*6777b538SAndroid Build Coastguard Worker return(NULL);
11876*6777b538SAndroid Build Coastguard Worker }
11877*6777b538SAndroid Build Coastguard Worker
11878*6777b538SAndroid Build Coastguard Worker /*
11879*6777b538SAndroid Build Coastguard Worker * Canonicalise the system ID
11880*6777b538SAndroid Build Coastguard Worker */
11881*6777b538SAndroid Build Coastguard Worker systemIdCanonic = xmlCanonicPath(SystemID);
11882*6777b538SAndroid Build Coastguard Worker if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
11883*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11884*6777b538SAndroid Build Coastguard Worker return(NULL);
11885*6777b538SAndroid Build Coastguard Worker }
11886*6777b538SAndroid Build Coastguard Worker
11887*6777b538SAndroid Build Coastguard Worker /*
11888*6777b538SAndroid Build Coastguard Worker * Ask the Entity resolver to load the damn thing
11889*6777b538SAndroid Build Coastguard Worker */
11890*6777b538SAndroid Build Coastguard Worker
11891*6777b538SAndroid Build Coastguard Worker if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
11892*6777b538SAndroid Build Coastguard Worker input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
11893*6777b538SAndroid Build Coastguard Worker systemIdCanonic);
11894*6777b538SAndroid Build Coastguard Worker if (input == NULL) {
11895*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11896*6777b538SAndroid Build Coastguard Worker if (systemIdCanonic != NULL)
11897*6777b538SAndroid Build Coastguard Worker xmlFree(systemIdCanonic);
11898*6777b538SAndroid Build Coastguard Worker return(NULL);
11899*6777b538SAndroid Build Coastguard Worker }
11900*6777b538SAndroid Build Coastguard Worker
11901*6777b538SAndroid Build Coastguard Worker /*
11902*6777b538SAndroid Build Coastguard Worker * plug some encoding conversion routines here.
11903*6777b538SAndroid Build Coastguard Worker */
11904*6777b538SAndroid Build Coastguard Worker if (xmlPushInput(ctxt, input) < 0) {
11905*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11906*6777b538SAndroid Build Coastguard Worker if (systemIdCanonic != NULL)
11907*6777b538SAndroid Build Coastguard Worker xmlFree(systemIdCanonic);
11908*6777b538SAndroid Build Coastguard Worker return(NULL);
11909*6777b538SAndroid Build Coastguard Worker }
11910*6777b538SAndroid Build Coastguard Worker
11911*6777b538SAndroid Build Coastguard Worker xmlDetectEncoding(ctxt);
11912*6777b538SAndroid Build Coastguard Worker
11913*6777b538SAndroid Build Coastguard Worker if (input->filename == NULL)
11914*6777b538SAndroid Build Coastguard Worker input->filename = (char *) systemIdCanonic;
11915*6777b538SAndroid Build Coastguard Worker else
11916*6777b538SAndroid Build Coastguard Worker xmlFree(systemIdCanonic);
11917*6777b538SAndroid Build Coastguard Worker
11918*6777b538SAndroid Build Coastguard Worker /*
11919*6777b538SAndroid Build Coastguard Worker * let's parse that entity knowing it's an external subset.
11920*6777b538SAndroid Build Coastguard Worker */
11921*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
11922*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc == NULL) {
11923*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
11924*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11925*6777b538SAndroid Build Coastguard Worker return(NULL);
11926*6777b538SAndroid Build Coastguard Worker }
11927*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->properties = XML_DOC_INTERNAL;
11928*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
11929*6777b538SAndroid Build Coastguard Worker ExternalID, SystemID);
11930*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc->extSubset == NULL) {
11931*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
11932*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11933*6777b538SAndroid Build Coastguard Worker return(NULL);
11934*6777b538SAndroid Build Coastguard Worker }
11935*6777b538SAndroid Build Coastguard Worker xmlParseExternalSubset(ctxt, ExternalID, SystemID);
11936*6777b538SAndroid Build Coastguard Worker
11937*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc != NULL) {
11938*6777b538SAndroid Build Coastguard Worker if (ctxt->wellFormed) {
11939*6777b538SAndroid Build Coastguard Worker ret = ctxt->myDoc->extSubset;
11940*6777b538SAndroid Build Coastguard Worker ctxt->myDoc->extSubset = NULL;
11941*6777b538SAndroid Build Coastguard Worker if (ret != NULL) {
11942*6777b538SAndroid Build Coastguard Worker xmlNodePtr tmp;
11943*6777b538SAndroid Build Coastguard Worker
11944*6777b538SAndroid Build Coastguard Worker ret->doc = NULL;
11945*6777b538SAndroid Build Coastguard Worker tmp = ret->children;
11946*6777b538SAndroid Build Coastguard Worker while (tmp != NULL) {
11947*6777b538SAndroid Build Coastguard Worker tmp->doc = NULL;
11948*6777b538SAndroid Build Coastguard Worker tmp = tmp->next;
11949*6777b538SAndroid Build Coastguard Worker }
11950*6777b538SAndroid Build Coastguard Worker }
11951*6777b538SAndroid Build Coastguard Worker } else {
11952*6777b538SAndroid Build Coastguard Worker ret = NULL;
11953*6777b538SAndroid Build Coastguard Worker }
11954*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
11955*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = NULL;
11956*6777b538SAndroid Build Coastguard Worker }
11957*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
11958*6777b538SAndroid Build Coastguard Worker
11959*6777b538SAndroid Build Coastguard Worker return(ret);
11960*6777b538SAndroid Build Coastguard Worker }
11961*6777b538SAndroid Build Coastguard Worker
11962*6777b538SAndroid Build Coastguard Worker
11963*6777b538SAndroid Build Coastguard Worker /**
11964*6777b538SAndroid Build Coastguard Worker * xmlParseDTD:
11965*6777b538SAndroid Build Coastguard Worker * @ExternalID: a NAME* containing the External ID of the DTD
11966*6777b538SAndroid Build Coastguard Worker * @SystemID: a NAME* containing the URL to the DTD
11967*6777b538SAndroid Build Coastguard Worker *
11968*6777b538SAndroid Build Coastguard Worker * Load and parse an external subset.
11969*6777b538SAndroid Build Coastguard Worker *
11970*6777b538SAndroid Build Coastguard Worker * Returns the resulting xmlDtdPtr or NULL in case of error.
11971*6777b538SAndroid Build Coastguard Worker */
11972*6777b538SAndroid Build Coastguard Worker
11973*6777b538SAndroid Build Coastguard Worker xmlDtdPtr
xmlParseDTD(const xmlChar * ExternalID,const xmlChar * SystemID)11974*6777b538SAndroid Build Coastguard Worker xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
11975*6777b538SAndroid Build Coastguard Worker return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
11976*6777b538SAndroid Build Coastguard Worker }
11977*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_VALID_ENABLED */
11978*6777b538SAndroid Build Coastguard Worker
11979*6777b538SAndroid Build Coastguard Worker /************************************************************************
11980*6777b538SAndroid Build Coastguard Worker * *
11981*6777b538SAndroid Build Coastguard Worker * Front ends when parsing an Entity *
11982*6777b538SAndroid Build Coastguard Worker * *
11983*6777b538SAndroid Build Coastguard Worker ************************************************************************/
11984*6777b538SAndroid Build Coastguard Worker
11985*6777b538SAndroid Build Coastguard Worker static xmlNodePtr
xmlCtxtParseContent(xmlParserCtxtPtr ctxt,xmlParserInputPtr input,int hasTextDecl,int buildTree)11986*6777b538SAndroid Build Coastguard Worker xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
11987*6777b538SAndroid Build Coastguard Worker int hasTextDecl, int buildTree) {
11988*6777b538SAndroid Build Coastguard Worker xmlNodePtr root = NULL;
11989*6777b538SAndroid Build Coastguard Worker xmlNodePtr list = NULL;
11990*6777b538SAndroid Build Coastguard Worker xmlChar *rootName = BAD_CAST "#root";
11991*6777b538SAndroid Build Coastguard Worker int result;
11992*6777b538SAndroid Build Coastguard Worker
11993*6777b538SAndroid Build Coastguard Worker if (buildTree) {
11994*6777b538SAndroid Build Coastguard Worker root = xmlNewDocNode(ctxt->myDoc, NULL, rootName, NULL);
11995*6777b538SAndroid Build Coastguard Worker if (root == NULL) {
11996*6777b538SAndroid Build Coastguard Worker xmlErrMemory(ctxt);
11997*6777b538SAndroid Build Coastguard Worker goto error;
11998*6777b538SAndroid Build Coastguard Worker }
11999*6777b538SAndroid Build Coastguard Worker }
12000*6777b538SAndroid Build Coastguard Worker
12001*6777b538SAndroid Build Coastguard Worker if (xmlPushInput(ctxt, input) < 0)
12002*6777b538SAndroid Build Coastguard Worker goto error;
12003*6777b538SAndroid Build Coastguard Worker
12004*6777b538SAndroid Build Coastguard Worker nameNsPush(ctxt, rootName, NULL, NULL, 0, 0);
12005*6777b538SAndroid Build Coastguard Worker spacePush(ctxt, -1);
12006*6777b538SAndroid Build Coastguard Worker
12007*6777b538SAndroid Build Coastguard Worker if (buildTree)
12008*6777b538SAndroid Build Coastguard Worker nodePush(ctxt, root);
12009*6777b538SAndroid Build Coastguard Worker
12010*6777b538SAndroid Build Coastguard Worker if (hasTextDecl) {
12011*6777b538SAndroid Build Coastguard Worker xmlDetectEncoding(ctxt);
12012*6777b538SAndroid Build Coastguard Worker
12013*6777b538SAndroid Build Coastguard Worker /*
12014*6777b538SAndroid Build Coastguard Worker * Parse a possible text declaration first
12015*6777b538SAndroid Build Coastguard Worker */
12016*6777b538SAndroid Build Coastguard Worker if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
12017*6777b538SAndroid Build Coastguard Worker (IS_BLANK_CH(NXT(5)))) {
12018*6777b538SAndroid Build Coastguard Worker xmlParseTextDecl(ctxt);
12019*6777b538SAndroid Build Coastguard Worker /*
12020*6777b538SAndroid Build Coastguard Worker * An XML-1.0 document can't reference an entity not XML-1.0
12021*6777b538SAndroid Build Coastguard Worker */
12022*6777b538SAndroid Build Coastguard Worker if ((xmlStrEqual(ctxt->version, BAD_CAST "1.0")) &&
12023*6777b538SAndroid Build Coastguard Worker (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
12024*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
12025*6777b538SAndroid Build Coastguard Worker "Version mismatch between document and "
12026*6777b538SAndroid Build Coastguard Worker "entity\n");
12027*6777b538SAndroid Build Coastguard Worker }
12028*6777b538SAndroid Build Coastguard Worker }
12029*6777b538SAndroid Build Coastguard Worker }
12030*6777b538SAndroid Build Coastguard Worker
12031*6777b538SAndroid Build Coastguard Worker xmlParseContentInternal(ctxt);
12032*6777b538SAndroid Build Coastguard Worker
12033*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur < ctxt->input->end)
12034*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12035*6777b538SAndroid Build Coastguard Worker
12036*6777b538SAndroid Build Coastguard Worker if ((ctxt->wellFormed) ||
12037*6777b538SAndroid Build Coastguard Worker ((ctxt->recovery) && (ctxt->errNo != XML_ERR_NO_MEMORY))) {
12038*6777b538SAndroid Build Coastguard Worker if (root != NULL) {
12039*6777b538SAndroid Build Coastguard Worker xmlNodePtr cur;
12040*6777b538SAndroid Build Coastguard Worker
12041*6777b538SAndroid Build Coastguard Worker /*
12042*6777b538SAndroid Build Coastguard Worker * Return the newly created nodeset after unlinking it from
12043*6777b538SAndroid Build Coastguard Worker * its pseudo parent.
12044*6777b538SAndroid Build Coastguard Worker */
12045*6777b538SAndroid Build Coastguard Worker cur = root->children;
12046*6777b538SAndroid Build Coastguard Worker list = cur;
12047*6777b538SAndroid Build Coastguard Worker while (cur != NULL) {
12048*6777b538SAndroid Build Coastguard Worker cur->parent = NULL;
12049*6777b538SAndroid Build Coastguard Worker cur = cur->next;
12050*6777b538SAndroid Build Coastguard Worker }
12051*6777b538SAndroid Build Coastguard Worker root->children = NULL;
12052*6777b538SAndroid Build Coastguard Worker root->last = NULL;
12053*6777b538SAndroid Build Coastguard Worker }
12054*6777b538SAndroid Build Coastguard Worker }
12055*6777b538SAndroid Build Coastguard Worker
12056*6777b538SAndroid Build Coastguard Worker /*
12057*6777b538SAndroid Build Coastguard Worker * Read the rest of the stream in case of errors. We want
12058*6777b538SAndroid Build Coastguard Worker * to account for the whole entity size.
12059*6777b538SAndroid Build Coastguard Worker */
12060*6777b538SAndroid Build Coastguard Worker do {
12061*6777b538SAndroid Build Coastguard Worker ctxt->input->cur = ctxt->input->end;
12062*6777b538SAndroid Build Coastguard Worker xmlParserShrink(ctxt);
12063*6777b538SAndroid Build Coastguard Worker result = xmlParserGrow(ctxt);
12064*6777b538SAndroid Build Coastguard Worker } while (result > 0);
12065*6777b538SAndroid Build Coastguard Worker
12066*6777b538SAndroid Build Coastguard Worker if (buildTree)
12067*6777b538SAndroid Build Coastguard Worker nodePop(ctxt);
12068*6777b538SAndroid Build Coastguard Worker
12069*6777b538SAndroid Build Coastguard Worker namePop(ctxt);
12070*6777b538SAndroid Build Coastguard Worker spacePop(ctxt);
12071*6777b538SAndroid Build Coastguard Worker
12072*6777b538SAndroid Build Coastguard Worker /* xmlPopInput would free the stream */
12073*6777b538SAndroid Build Coastguard Worker inputPop(ctxt);
12074*6777b538SAndroid Build Coastguard Worker
12075*6777b538SAndroid Build Coastguard Worker error:
12076*6777b538SAndroid Build Coastguard Worker xmlFreeNode(root);
12077*6777b538SAndroid Build Coastguard Worker
12078*6777b538SAndroid Build Coastguard Worker return(list);
12079*6777b538SAndroid Build Coastguard Worker }
12080*6777b538SAndroid Build Coastguard Worker
12081*6777b538SAndroid Build Coastguard Worker static void
xmlCtxtParseEntity(xmlParserCtxtPtr ctxt,xmlEntityPtr ent)12082*6777b538SAndroid Build Coastguard Worker xmlCtxtParseEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
12083*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
12084*6777b538SAndroid Build Coastguard Worker xmlNodePtr list;
12085*6777b538SAndroid Build Coastguard Worker unsigned long consumed;
12086*6777b538SAndroid Build Coastguard Worker int isExternal;
12087*6777b538SAndroid Build Coastguard Worker int buildTree;
12088*6777b538SAndroid Build Coastguard Worker int oldMinNsIndex;
12089*6777b538SAndroid Build Coastguard Worker int oldNodelen, oldNodemem;
12090*6777b538SAndroid Build Coastguard Worker
12091*6777b538SAndroid Build Coastguard Worker isExternal = (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY);
12092*6777b538SAndroid Build Coastguard Worker buildTree = (ctxt->node != NULL);
12093*6777b538SAndroid Build Coastguard Worker
12094*6777b538SAndroid Build Coastguard Worker /*
12095*6777b538SAndroid Build Coastguard Worker * Recursion check
12096*6777b538SAndroid Build Coastguard Worker */
12097*6777b538SAndroid Build Coastguard Worker if (ent->flags & XML_ENT_EXPANDING) {
12098*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
12099*6777b538SAndroid Build Coastguard Worker xmlHaltParser(ctxt);
12100*6777b538SAndroid Build Coastguard Worker goto error;
12101*6777b538SAndroid Build Coastguard Worker }
12102*6777b538SAndroid Build Coastguard Worker
12103*6777b538SAndroid Build Coastguard Worker /*
12104*6777b538SAndroid Build Coastguard Worker * Load entity
12105*6777b538SAndroid Build Coastguard Worker */
12106*6777b538SAndroid Build Coastguard Worker input = xmlNewEntityInputStream(ctxt, ent);
12107*6777b538SAndroid Build Coastguard Worker if (input == NULL)
12108*6777b538SAndroid Build Coastguard Worker goto error;
12109*6777b538SAndroid Build Coastguard Worker
12110*6777b538SAndroid Build Coastguard Worker /*
12111*6777b538SAndroid Build Coastguard Worker * When building a tree, we need to limit the scope of namespace
12112*6777b538SAndroid Build Coastguard Worker * declarations, so that entities don't reference xmlNs structs
12113*6777b538SAndroid Build Coastguard Worker * from the parent of a reference.
12114*6777b538SAndroid Build Coastguard Worker */
12115*6777b538SAndroid Build Coastguard Worker oldMinNsIndex = ctxt->nsdb->minNsIndex;
12116*6777b538SAndroid Build Coastguard Worker if (buildTree)
12117*6777b538SAndroid Build Coastguard Worker ctxt->nsdb->minNsIndex = ctxt->nsNr;
12118*6777b538SAndroid Build Coastguard Worker
12119*6777b538SAndroid Build Coastguard Worker oldNodelen = ctxt->nodelen;
12120*6777b538SAndroid Build Coastguard Worker oldNodemem = ctxt->nodemem;
12121*6777b538SAndroid Build Coastguard Worker ctxt->nodelen = 0;
12122*6777b538SAndroid Build Coastguard Worker ctxt->nodemem = 0;
12123*6777b538SAndroid Build Coastguard Worker
12124*6777b538SAndroid Build Coastguard Worker /*
12125*6777b538SAndroid Build Coastguard Worker * Parse content
12126*6777b538SAndroid Build Coastguard Worker *
12127*6777b538SAndroid Build Coastguard Worker * This initiates a recursive call chain:
12128*6777b538SAndroid Build Coastguard Worker *
12129*6777b538SAndroid Build Coastguard Worker * - xmlCtxtParseContent
12130*6777b538SAndroid Build Coastguard Worker * - xmlParseContentInternal
12131*6777b538SAndroid Build Coastguard Worker * - xmlParseReference
12132*6777b538SAndroid Build Coastguard Worker * - xmlCtxtParseEntity
12133*6777b538SAndroid Build Coastguard Worker *
12134*6777b538SAndroid Build Coastguard Worker * The nesting depth is limited by the maximum number of inputs,
12135*6777b538SAndroid Build Coastguard Worker * see xmlPushInput.
12136*6777b538SAndroid Build Coastguard Worker *
12137*6777b538SAndroid Build Coastguard Worker * It's possible to make this non-recursive (minNsIndex must be
12138*6777b538SAndroid Build Coastguard Worker * stored in the input struct) at the expense of code readability.
12139*6777b538SAndroid Build Coastguard Worker */
12140*6777b538SAndroid Build Coastguard Worker
12141*6777b538SAndroid Build Coastguard Worker ent->flags |= XML_ENT_EXPANDING;
12142*6777b538SAndroid Build Coastguard Worker
12143*6777b538SAndroid Build Coastguard Worker list = xmlCtxtParseContent(ctxt, input, isExternal, buildTree);
12144*6777b538SAndroid Build Coastguard Worker
12145*6777b538SAndroid Build Coastguard Worker ent->flags &= ~XML_ENT_EXPANDING;
12146*6777b538SAndroid Build Coastguard Worker
12147*6777b538SAndroid Build Coastguard Worker ctxt->nsdb->minNsIndex = oldMinNsIndex;
12148*6777b538SAndroid Build Coastguard Worker ctxt->nodelen = oldNodelen;
12149*6777b538SAndroid Build Coastguard Worker ctxt->nodemem = oldNodemem;
12150*6777b538SAndroid Build Coastguard Worker
12151*6777b538SAndroid Build Coastguard Worker /*
12152*6777b538SAndroid Build Coastguard Worker * Entity size accounting
12153*6777b538SAndroid Build Coastguard Worker */
12154*6777b538SAndroid Build Coastguard Worker consumed = input->consumed;
12155*6777b538SAndroid Build Coastguard Worker xmlSaturatedAddSizeT(&consumed, input->end - input->base);
12156*6777b538SAndroid Build Coastguard Worker
12157*6777b538SAndroid Build Coastguard Worker if ((ent->flags & XML_ENT_CHECKED) == 0)
12158*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(&ent->expandedSize, consumed);
12159*6777b538SAndroid Build Coastguard Worker
12160*6777b538SAndroid Build Coastguard Worker if ((ent->flags & XML_ENT_PARSED) == 0) {
12161*6777b538SAndroid Build Coastguard Worker if (isExternal)
12162*6777b538SAndroid Build Coastguard Worker xmlSaturatedAdd(&ctxt->sizeentities, consumed);
12163*6777b538SAndroid Build Coastguard Worker
12164*6777b538SAndroid Build Coastguard Worker ent->children = list;
12165*6777b538SAndroid Build Coastguard Worker
12166*6777b538SAndroid Build Coastguard Worker while (list != NULL) {
12167*6777b538SAndroid Build Coastguard Worker list->parent = (xmlNodePtr) ent;
12168*6777b538SAndroid Build Coastguard Worker if (list->next == NULL)
12169*6777b538SAndroid Build Coastguard Worker ent->last = list;
12170*6777b538SAndroid Build Coastguard Worker list = list->next;
12171*6777b538SAndroid Build Coastguard Worker }
12172*6777b538SAndroid Build Coastguard Worker } else {
12173*6777b538SAndroid Build Coastguard Worker xmlFreeNodeList(list);
12174*6777b538SAndroid Build Coastguard Worker }
12175*6777b538SAndroid Build Coastguard Worker
12176*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(input);
12177*6777b538SAndroid Build Coastguard Worker
12178*6777b538SAndroid Build Coastguard Worker error:
12179*6777b538SAndroid Build Coastguard Worker ent->flags |= XML_ENT_PARSED | XML_ENT_CHECKED;
12180*6777b538SAndroid Build Coastguard Worker }
12181*6777b538SAndroid Build Coastguard Worker
12182*6777b538SAndroid Build Coastguard Worker /**
12183*6777b538SAndroid Build Coastguard Worker * xmlParseCtxtExternalEntity:
12184*6777b538SAndroid Build Coastguard Worker * @ctx: the existing parsing context
12185*6777b538SAndroid Build Coastguard Worker * @URL: the URL for the entity to load
12186*6777b538SAndroid Build Coastguard Worker * @ID: the System ID for the entity to load
12187*6777b538SAndroid Build Coastguard Worker * @lst: the return value for the set of parsed nodes
12188*6777b538SAndroid Build Coastguard Worker *
12189*6777b538SAndroid Build Coastguard Worker * Parse an external general entity within an existing parsing context
12190*6777b538SAndroid Build Coastguard Worker * An external general parsed entity is well-formed if it matches the
12191*6777b538SAndroid Build Coastguard Worker * production labeled extParsedEnt.
12192*6777b538SAndroid Build Coastguard Worker *
12193*6777b538SAndroid Build Coastguard Worker * [78] extParsedEnt ::= TextDecl? content
12194*6777b538SAndroid Build Coastguard Worker *
12195*6777b538SAndroid Build Coastguard Worker * Returns 0 if the entity is well formed, -1 in case of args problem and
12196*6777b538SAndroid Build Coastguard Worker * the parser error code otherwise
12197*6777b538SAndroid Build Coastguard Worker */
12198*6777b538SAndroid Build Coastguard Worker
12199*6777b538SAndroid Build Coastguard Worker int
xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctxt,const xmlChar * URL,const xmlChar * ID,xmlNodePtr * listOut)12200*6777b538SAndroid Build Coastguard Worker xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctxt, const xmlChar *URL,
12201*6777b538SAndroid Build Coastguard Worker const xmlChar *ID, xmlNodePtr *listOut) {
12202*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
12203*6777b538SAndroid Build Coastguard Worker xmlNodePtr list;
12204*6777b538SAndroid Build Coastguard Worker
12205*6777b538SAndroid Build Coastguard Worker if (listOut != NULL)
12206*6777b538SAndroid Build Coastguard Worker *listOut = NULL;
12207*6777b538SAndroid Build Coastguard Worker
12208*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
12209*6777b538SAndroid Build Coastguard Worker return(XML_ERR_ARGUMENT);
12210*6777b538SAndroid Build Coastguard Worker
12211*6777b538SAndroid Build Coastguard Worker input = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
12212*6777b538SAndroid Build Coastguard Worker if (input == NULL)
12213*6777b538SAndroid Build Coastguard Worker return(ctxt->errNo);
12214*6777b538SAndroid Build Coastguard Worker
12215*6777b538SAndroid Build Coastguard Worker xmlCtxtInitializeLate(ctxt);
12216*6777b538SAndroid Build Coastguard Worker
12217*6777b538SAndroid Build Coastguard Worker list = xmlCtxtParseContent(ctxt, input, /* hasTextDecl */ 1, 1);
12218*6777b538SAndroid Build Coastguard Worker if (*listOut != NULL)
12219*6777b538SAndroid Build Coastguard Worker *listOut = list;
12220*6777b538SAndroid Build Coastguard Worker else
12221*6777b538SAndroid Build Coastguard Worker xmlFreeNodeList(list);
12222*6777b538SAndroid Build Coastguard Worker
12223*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(input);
12224*6777b538SAndroid Build Coastguard Worker return(ctxt->errNo);
12225*6777b538SAndroid Build Coastguard Worker }
12226*6777b538SAndroid Build Coastguard Worker
12227*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
12228*6777b538SAndroid Build Coastguard Worker /**
12229*6777b538SAndroid Build Coastguard Worker * xmlParseExternalEntity:
12230*6777b538SAndroid Build Coastguard Worker * @doc: the document the chunk pertains to
12231*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block (possibly NULL)
12232*6777b538SAndroid Build Coastguard Worker * @user_data: The user data returned on SAX callbacks (possibly NULL)
12233*6777b538SAndroid Build Coastguard Worker * @depth: Used for loop detection, use 0
12234*6777b538SAndroid Build Coastguard Worker * @URL: the URL for the entity to load
12235*6777b538SAndroid Build Coastguard Worker * @ID: the System ID for the entity to load
12236*6777b538SAndroid Build Coastguard Worker * @lst: the return value for the set of parsed nodes
12237*6777b538SAndroid Build Coastguard Worker *
12238*6777b538SAndroid Build Coastguard Worker * Parse an external general entity
12239*6777b538SAndroid Build Coastguard Worker * An external general parsed entity is well-formed if it matches the
12240*6777b538SAndroid Build Coastguard Worker * production labeled extParsedEnt.
12241*6777b538SAndroid Build Coastguard Worker *
12242*6777b538SAndroid Build Coastguard Worker * [78] extParsedEnt ::= TextDecl? content
12243*6777b538SAndroid Build Coastguard Worker *
12244*6777b538SAndroid Build Coastguard Worker * Returns 0 if the entity is well formed, -1 in case of args problem and
12245*6777b538SAndroid Build Coastguard Worker * the parser error code otherwise
12246*6777b538SAndroid Build Coastguard Worker */
12247*6777b538SAndroid Build Coastguard Worker
12248*6777b538SAndroid Build Coastguard Worker int
xmlParseExternalEntity(xmlDocPtr doc,xmlSAXHandlerPtr sax,void * user_data,int depth,const xmlChar * URL,const xmlChar * ID,xmlNodePtr * list)12249*6777b538SAndroid Build Coastguard Worker xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
12250*6777b538SAndroid Build Coastguard Worker int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *list) {
12251*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
12252*6777b538SAndroid Build Coastguard Worker int ret;
12253*6777b538SAndroid Build Coastguard Worker
12254*6777b538SAndroid Build Coastguard Worker if (list != NULL)
12255*6777b538SAndroid Build Coastguard Worker *list = NULL;
12256*6777b538SAndroid Build Coastguard Worker
12257*6777b538SAndroid Build Coastguard Worker if (doc == NULL)
12258*6777b538SAndroid Build Coastguard Worker return(XML_ERR_ARGUMENT);
12259*6777b538SAndroid Build Coastguard Worker
12260*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewSAXParserCtxt(sax, user_data);
12261*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
12262*6777b538SAndroid Build Coastguard Worker return(XML_ERR_NO_MEMORY);
12263*6777b538SAndroid Build Coastguard Worker
12264*6777b538SAndroid Build Coastguard Worker ctxt->depth = depth;
12265*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = doc;
12266*6777b538SAndroid Build Coastguard Worker ret = xmlParseCtxtExternalEntity(ctxt, URL, ID, list);
12267*6777b538SAndroid Build Coastguard Worker
12268*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
12269*6777b538SAndroid Build Coastguard Worker return(ret);
12270*6777b538SAndroid Build Coastguard Worker }
12271*6777b538SAndroid Build Coastguard Worker
12272*6777b538SAndroid Build Coastguard Worker /**
12273*6777b538SAndroid Build Coastguard Worker * xmlParseBalancedChunkMemory:
12274*6777b538SAndroid Build Coastguard Worker * @doc: the document the chunk pertains to (must not be NULL)
12275*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block (possibly NULL)
12276*6777b538SAndroid Build Coastguard Worker * @user_data: The user data returned on SAX callbacks (possibly NULL)
12277*6777b538SAndroid Build Coastguard Worker * @depth: Used for loop detection, use 0
12278*6777b538SAndroid Build Coastguard Worker * @string: the input string in UTF8 or ISO-Latin (zero terminated)
12279*6777b538SAndroid Build Coastguard Worker * @lst: the return value for the set of parsed nodes
12280*6777b538SAndroid Build Coastguard Worker *
12281*6777b538SAndroid Build Coastguard Worker * Parse a well-balanced chunk of an XML document
12282*6777b538SAndroid Build Coastguard Worker * called by the parser
12283*6777b538SAndroid Build Coastguard Worker * The allowed sequence for the Well Balanced Chunk is the one defined by
12284*6777b538SAndroid Build Coastguard Worker * the content production in the XML grammar:
12285*6777b538SAndroid Build Coastguard Worker *
12286*6777b538SAndroid Build Coastguard Worker * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12287*6777b538SAndroid Build Coastguard Worker *
12288*6777b538SAndroid Build Coastguard Worker * Returns 0 if the chunk is well balanced, -1 in case of args problem and
12289*6777b538SAndroid Build Coastguard Worker * the parser error code otherwise
12290*6777b538SAndroid Build Coastguard Worker */
12291*6777b538SAndroid Build Coastguard Worker
12292*6777b538SAndroid Build Coastguard Worker int
xmlParseBalancedChunkMemory(xmlDocPtr doc,xmlSAXHandlerPtr sax,void * user_data,int depth,const xmlChar * string,xmlNodePtr * lst)12293*6777b538SAndroid Build Coastguard Worker xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
12294*6777b538SAndroid Build Coastguard Worker void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
12295*6777b538SAndroid Build Coastguard Worker return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
12296*6777b538SAndroid Build Coastguard Worker depth, string, lst, 0 );
12297*6777b538SAndroid Build Coastguard Worker }
12298*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
12299*6777b538SAndroid Build Coastguard Worker
12300*6777b538SAndroid Build Coastguard Worker /**
12301*6777b538SAndroid Build Coastguard Worker * xmlParseInNodeContext:
12302*6777b538SAndroid Build Coastguard Worker * @node: the context node
12303*6777b538SAndroid Build Coastguard Worker * @data: the input string
12304*6777b538SAndroid Build Coastguard Worker * @datalen: the input string length in bytes
12305*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
12306*6777b538SAndroid Build Coastguard Worker * @lst: the return value for the set of parsed nodes
12307*6777b538SAndroid Build Coastguard Worker *
12308*6777b538SAndroid Build Coastguard Worker * Parse a well-balanced chunk of an XML document
12309*6777b538SAndroid Build Coastguard Worker * within the context (DTD, namespaces, etc ...) of the given node.
12310*6777b538SAndroid Build Coastguard Worker *
12311*6777b538SAndroid Build Coastguard Worker * The allowed sequence for the data is a Well Balanced Chunk defined by
12312*6777b538SAndroid Build Coastguard Worker * the content production in the XML grammar:
12313*6777b538SAndroid Build Coastguard Worker *
12314*6777b538SAndroid Build Coastguard Worker * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12315*6777b538SAndroid Build Coastguard Worker *
12316*6777b538SAndroid Build Coastguard Worker * Returns XML_ERR_OK if the chunk is well balanced, and the parser
12317*6777b538SAndroid Build Coastguard Worker * error code otherwise
12318*6777b538SAndroid Build Coastguard Worker */
12319*6777b538SAndroid Build Coastguard Worker xmlParserErrors
xmlParseInNodeContext(xmlNodePtr node,const char * data,int datalen,int options,xmlNodePtr * lst)12320*6777b538SAndroid Build Coastguard Worker xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
12321*6777b538SAndroid Build Coastguard Worker int options, xmlNodePtr *lst) {
12322*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
12323*6777b538SAndroid Build Coastguard Worker xmlDocPtr doc = NULL;
12324*6777b538SAndroid Build Coastguard Worker xmlNodePtr fake, cur;
12325*6777b538SAndroid Build Coastguard Worker int nsnr = 0;
12326*6777b538SAndroid Build Coastguard Worker
12327*6777b538SAndroid Build Coastguard Worker xmlParserErrors ret = XML_ERR_OK;
12328*6777b538SAndroid Build Coastguard Worker
12329*6777b538SAndroid Build Coastguard Worker /*
12330*6777b538SAndroid Build Coastguard Worker * check all input parameters, grab the document
12331*6777b538SAndroid Build Coastguard Worker */
12332*6777b538SAndroid Build Coastguard Worker if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
12333*6777b538SAndroid Build Coastguard Worker return(XML_ERR_ARGUMENT);
12334*6777b538SAndroid Build Coastguard Worker switch (node->type) {
12335*6777b538SAndroid Build Coastguard Worker case XML_ELEMENT_NODE:
12336*6777b538SAndroid Build Coastguard Worker case XML_ATTRIBUTE_NODE:
12337*6777b538SAndroid Build Coastguard Worker case XML_TEXT_NODE:
12338*6777b538SAndroid Build Coastguard Worker case XML_CDATA_SECTION_NODE:
12339*6777b538SAndroid Build Coastguard Worker case XML_ENTITY_REF_NODE:
12340*6777b538SAndroid Build Coastguard Worker case XML_PI_NODE:
12341*6777b538SAndroid Build Coastguard Worker case XML_COMMENT_NODE:
12342*6777b538SAndroid Build Coastguard Worker case XML_DOCUMENT_NODE:
12343*6777b538SAndroid Build Coastguard Worker case XML_HTML_DOCUMENT_NODE:
12344*6777b538SAndroid Build Coastguard Worker break;
12345*6777b538SAndroid Build Coastguard Worker default:
12346*6777b538SAndroid Build Coastguard Worker return(XML_ERR_INTERNAL_ERROR);
12347*6777b538SAndroid Build Coastguard Worker
12348*6777b538SAndroid Build Coastguard Worker }
12349*6777b538SAndroid Build Coastguard Worker while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
12350*6777b538SAndroid Build Coastguard Worker (node->type != XML_DOCUMENT_NODE) &&
12351*6777b538SAndroid Build Coastguard Worker (node->type != XML_HTML_DOCUMENT_NODE))
12352*6777b538SAndroid Build Coastguard Worker node = node->parent;
12353*6777b538SAndroid Build Coastguard Worker if (node == NULL)
12354*6777b538SAndroid Build Coastguard Worker return(XML_ERR_INTERNAL_ERROR);
12355*6777b538SAndroid Build Coastguard Worker if (node->type == XML_ELEMENT_NODE)
12356*6777b538SAndroid Build Coastguard Worker doc = node->doc;
12357*6777b538SAndroid Build Coastguard Worker else
12358*6777b538SAndroid Build Coastguard Worker doc = (xmlDocPtr) node;
12359*6777b538SAndroid Build Coastguard Worker if (doc == NULL)
12360*6777b538SAndroid Build Coastguard Worker return(XML_ERR_INTERNAL_ERROR);
12361*6777b538SAndroid Build Coastguard Worker
12362*6777b538SAndroid Build Coastguard Worker /*
12363*6777b538SAndroid Build Coastguard Worker * allocate a context and set-up everything not related to the
12364*6777b538SAndroid Build Coastguard Worker * node position in the tree
12365*6777b538SAndroid Build Coastguard Worker */
12366*6777b538SAndroid Build Coastguard Worker if (doc->type == XML_DOCUMENT_NODE)
12367*6777b538SAndroid Build Coastguard Worker ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
12368*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
12369*6777b538SAndroid Build Coastguard Worker else if (doc->type == XML_HTML_DOCUMENT_NODE) {
12370*6777b538SAndroid Build Coastguard Worker ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
12371*6777b538SAndroid Build Coastguard Worker /*
12372*6777b538SAndroid Build Coastguard Worker * When parsing in context, it makes no sense to add implied
12373*6777b538SAndroid Build Coastguard Worker * elements like html/body/etc...
12374*6777b538SAndroid Build Coastguard Worker */
12375*6777b538SAndroid Build Coastguard Worker options |= HTML_PARSE_NOIMPLIED;
12376*6777b538SAndroid Build Coastguard Worker }
12377*6777b538SAndroid Build Coastguard Worker #endif
12378*6777b538SAndroid Build Coastguard Worker else
12379*6777b538SAndroid Build Coastguard Worker return(XML_ERR_INTERNAL_ERROR);
12380*6777b538SAndroid Build Coastguard Worker
12381*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
12382*6777b538SAndroid Build Coastguard Worker return(XML_ERR_NO_MEMORY);
12383*6777b538SAndroid Build Coastguard Worker
12384*6777b538SAndroid Build Coastguard Worker /*
12385*6777b538SAndroid Build Coastguard Worker * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
12386*6777b538SAndroid Build Coastguard Worker * We need a dictionary for xmlCtxtInitializeLate, so if there's no doc dict
12387*6777b538SAndroid Build Coastguard Worker * we must wait until the last moment to free the original one.
12388*6777b538SAndroid Build Coastguard Worker */
12389*6777b538SAndroid Build Coastguard Worker if (doc->dict != NULL) {
12390*6777b538SAndroid Build Coastguard Worker if (ctxt->dict != NULL)
12391*6777b538SAndroid Build Coastguard Worker xmlDictFree(ctxt->dict);
12392*6777b538SAndroid Build Coastguard Worker ctxt->dict = doc->dict;
12393*6777b538SAndroid Build Coastguard Worker } else {
12394*6777b538SAndroid Build Coastguard Worker options |= XML_PARSE_NODICT;
12395*6777b538SAndroid Build Coastguard Worker ctxt->dictNames = 0;
12396*6777b538SAndroid Build Coastguard Worker }
12397*6777b538SAndroid Build Coastguard Worker
12398*6777b538SAndroid Build Coastguard Worker if (doc->encoding != NULL)
12399*6777b538SAndroid Build Coastguard Worker xmlSwitchEncodingName(ctxt, (const char *) doc->encoding);
12400*6777b538SAndroid Build Coastguard Worker
12401*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
12402*6777b538SAndroid Build Coastguard Worker xmlCtxtInitializeLate(ctxt);
12403*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = doc;
12404*6777b538SAndroid Build Coastguard Worker /* parsing in context, i.e. as within existing content */
12405*6777b538SAndroid Build Coastguard Worker ctxt->input_id = 2;
12406*6777b538SAndroid Build Coastguard Worker
12407*6777b538SAndroid Build Coastguard Worker /*
12408*6777b538SAndroid Build Coastguard Worker * TODO: Use xmlCtxtParseContent
12409*6777b538SAndroid Build Coastguard Worker */
12410*6777b538SAndroid Build Coastguard Worker
12411*6777b538SAndroid Build Coastguard Worker fake = xmlNewDocComment(node->doc, NULL);
12412*6777b538SAndroid Build Coastguard Worker if (fake == NULL) {
12413*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
12414*6777b538SAndroid Build Coastguard Worker return(XML_ERR_NO_MEMORY);
12415*6777b538SAndroid Build Coastguard Worker }
12416*6777b538SAndroid Build Coastguard Worker xmlAddChild(node, fake);
12417*6777b538SAndroid Build Coastguard Worker
12418*6777b538SAndroid Build Coastguard Worker if (node->type == XML_ELEMENT_NODE)
12419*6777b538SAndroid Build Coastguard Worker nodePush(ctxt, node);
12420*6777b538SAndroid Build Coastguard Worker
12421*6777b538SAndroid Build Coastguard Worker if ((ctxt->html == 0) && (node->type == XML_ELEMENT_NODE)) {
12422*6777b538SAndroid Build Coastguard Worker /*
12423*6777b538SAndroid Build Coastguard Worker * initialize the SAX2 namespaces stack
12424*6777b538SAndroid Build Coastguard Worker */
12425*6777b538SAndroid Build Coastguard Worker cur = node;
12426*6777b538SAndroid Build Coastguard Worker while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
12427*6777b538SAndroid Build Coastguard Worker xmlNsPtr ns = cur->nsDef;
12428*6777b538SAndroid Build Coastguard Worker xmlHashedString hprefix, huri;
12429*6777b538SAndroid Build Coastguard Worker
12430*6777b538SAndroid Build Coastguard Worker while (ns != NULL) {
12431*6777b538SAndroid Build Coastguard Worker hprefix = xmlDictLookupHashed(ctxt->dict, ns->prefix, -1);
12432*6777b538SAndroid Build Coastguard Worker huri = xmlDictLookupHashed(ctxt->dict, ns->href, -1);
12433*6777b538SAndroid Build Coastguard Worker if (xmlParserNsPush(ctxt, &hprefix, &huri, ns, 1) > 0)
12434*6777b538SAndroid Build Coastguard Worker nsnr++;
12435*6777b538SAndroid Build Coastguard Worker ns = ns->next;
12436*6777b538SAndroid Build Coastguard Worker }
12437*6777b538SAndroid Build Coastguard Worker cur = cur->parent;
12438*6777b538SAndroid Build Coastguard Worker }
12439*6777b538SAndroid Build Coastguard Worker }
12440*6777b538SAndroid Build Coastguard Worker
12441*6777b538SAndroid Build Coastguard Worker if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
12442*6777b538SAndroid Build Coastguard Worker /*
12443*6777b538SAndroid Build Coastguard Worker * ID/IDREF registration will be done in xmlValidateElement below
12444*6777b538SAndroid Build Coastguard Worker */
12445*6777b538SAndroid Build Coastguard Worker ctxt->loadsubset |= XML_SKIP_IDS;
12446*6777b538SAndroid Build Coastguard Worker }
12447*6777b538SAndroid Build Coastguard Worker
12448*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
12449*6777b538SAndroid Build Coastguard Worker if (doc->type == XML_HTML_DOCUMENT_NODE)
12450*6777b538SAndroid Build Coastguard Worker __htmlParseContent(ctxt);
12451*6777b538SAndroid Build Coastguard Worker else
12452*6777b538SAndroid Build Coastguard Worker #endif
12453*6777b538SAndroid Build Coastguard Worker xmlParseContentInternal(ctxt);
12454*6777b538SAndroid Build Coastguard Worker
12455*6777b538SAndroid Build Coastguard Worker if (ctxt->input->cur < ctxt->input->end)
12456*6777b538SAndroid Build Coastguard Worker xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12457*6777b538SAndroid Build Coastguard Worker
12458*6777b538SAndroid Build Coastguard Worker xmlParserNsPop(ctxt, nsnr);
12459*6777b538SAndroid Build Coastguard Worker
12460*6777b538SAndroid Build Coastguard Worker if ((ctxt->wellFormed) ||
12461*6777b538SAndroid Build Coastguard Worker ((ctxt->recovery) && (ctxt->errNo != XML_ERR_NO_MEMORY))) {
12462*6777b538SAndroid Build Coastguard Worker ret = XML_ERR_OK;
12463*6777b538SAndroid Build Coastguard Worker } else {
12464*6777b538SAndroid Build Coastguard Worker ret = (xmlParserErrors) ctxt->errNo;
12465*6777b538SAndroid Build Coastguard Worker }
12466*6777b538SAndroid Build Coastguard Worker
12467*6777b538SAndroid Build Coastguard Worker /*
12468*6777b538SAndroid Build Coastguard Worker * Return the newly created nodeset after unlinking it from
12469*6777b538SAndroid Build Coastguard Worker * the pseudo sibling.
12470*6777b538SAndroid Build Coastguard Worker */
12471*6777b538SAndroid Build Coastguard Worker
12472*6777b538SAndroid Build Coastguard Worker cur = fake->next;
12473*6777b538SAndroid Build Coastguard Worker fake->next = NULL;
12474*6777b538SAndroid Build Coastguard Worker node->last = fake;
12475*6777b538SAndroid Build Coastguard Worker
12476*6777b538SAndroid Build Coastguard Worker if (cur != NULL) {
12477*6777b538SAndroid Build Coastguard Worker cur->prev = NULL;
12478*6777b538SAndroid Build Coastguard Worker }
12479*6777b538SAndroid Build Coastguard Worker
12480*6777b538SAndroid Build Coastguard Worker *lst = cur;
12481*6777b538SAndroid Build Coastguard Worker
12482*6777b538SAndroid Build Coastguard Worker while (cur != NULL) {
12483*6777b538SAndroid Build Coastguard Worker cur->parent = NULL;
12484*6777b538SAndroid Build Coastguard Worker cur = cur->next;
12485*6777b538SAndroid Build Coastguard Worker }
12486*6777b538SAndroid Build Coastguard Worker
12487*6777b538SAndroid Build Coastguard Worker xmlUnlinkNode(fake);
12488*6777b538SAndroid Build Coastguard Worker xmlFreeNode(fake);
12489*6777b538SAndroid Build Coastguard Worker
12490*6777b538SAndroid Build Coastguard Worker
12491*6777b538SAndroid Build Coastguard Worker if (ret != XML_ERR_OK) {
12492*6777b538SAndroid Build Coastguard Worker xmlFreeNodeList(*lst);
12493*6777b538SAndroid Build Coastguard Worker *lst = NULL;
12494*6777b538SAndroid Build Coastguard Worker }
12495*6777b538SAndroid Build Coastguard Worker
12496*6777b538SAndroid Build Coastguard Worker if (doc->dict != NULL)
12497*6777b538SAndroid Build Coastguard Worker ctxt->dict = NULL;
12498*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
12499*6777b538SAndroid Build Coastguard Worker
12500*6777b538SAndroid Build Coastguard Worker return(ret);
12501*6777b538SAndroid Build Coastguard Worker }
12502*6777b538SAndroid Build Coastguard Worker
12503*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
12504*6777b538SAndroid Build Coastguard Worker /**
12505*6777b538SAndroid Build Coastguard Worker * xmlParseBalancedChunkMemoryRecover:
12506*6777b538SAndroid Build Coastguard Worker * @doc: the document the chunk pertains to (must not be NULL)
12507*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block (possibly NULL)
12508*6777b538SAndroid Build Coastguard Worker * @user_data: The user data returned on SAX callbacks (possibly NULL)
12509*6777b538SAndroid Build Coastguard Worker * @depth: Used for loop detection, use 0
12510*6777b538SAndroid Build Coastguard Worker * @string: the input string in UTF8 or ISO-Latin (zero terminated)
12511*6777b538SAndroid Build Coastguard Worker * @list: the return value for the set of parsed nodes
12512*6777b538SAndroid Build Coastguard Worker * @recover: return nodes even if the data is broken (use 0)
12513*6777b538SAndroid Build Coastguard Worker *
12514*6777b538SAndroid Build Coastguard Worker * Parse a well-balanced chunk of an XML document
12515*6777b538SAndroid Build Coastguard Worker *
12516*6777b538SAndroid Build Coastguard Worker * The allowed sequence for the Well Balanced Chunk is the one defined by
12517*6777b538SAndroid Build Coastguard Worker * the content production in the XML grammar:
12518*6777b538SAndroid Build Coastguard Worker *
12519*6777b538SAndroid Build Coastguard Worker * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12520*6777b538SAndroid Build Coastguard Worker *
12521*6777b538SAndroid Build Coastguard Worker * Returns 0 if the chunk is well balanced, or thehe parser error code
12522*6777b538SAndroid Build Coastguard Worker * otherwise.
12523*6777b538SAndroid Build Coastguard Worker *
12524*6777b538SAndroid Build Coastguard Worker * In case recover is set to 1, the nodelist will not be empty even if
12525*6777b538SAndroid Build Coastguard Worker * the parsed chunk is not well balanced, assuming the parsing succeeded to
12526*6777b538SAndroid Build Coastguard Worker * some extent.
12527*6777b538SAndroid Build Coastguard Worker */
12528*6777b538SAndroid Build Coastguard Worker int
xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc,xmlSAXHandlerPtr sax,void * user_data,int depth,const xmlChar * string,xmlNodePtr * listOut,int recover)12529*6777b538SAndroid Build Coastguard Worker xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
12530*6777b538SAndroid Build Coastguard Worker void *user_data, int depth, const xmlChar *string, xmlNodePtr *listOut,
12531*6777b538SAndroid Build Coastguard Worker int recover) {
12532*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
12533*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
12534*6777b538SAndroid Build Coastguard Worker xmlNodePtr list;
12535*6777b538SAndroid Build Coastguard Worker int ret;
12536*6777b538SAndroid Build Coastguard Worker
12537*6777b538SAndroid Build Coastguard Worker if (listOut != NULL)
12538*6777b538SAndroid Build Coastguard Worker *listOut = NULL;
12539*6777b538SAndroid Build Coastguard Worker
12540*6777b538SAndroid Build Coastguard Worker if (string == NULL)
12541*6777b538SAndroid Build Coastguard Worker return(XML_ERR_ARGUMENT);
12542*6777b538SAndroid Build Coastguard Worker
12543*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewSAXParserCtxt(sax, user_data);
12544*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
12545*6777b538SAndroid Build Coastguard Worker return(XML_ERR_NO_MEMORY);
12546*6777b538SAndroid Build Coastguard Worker
12547*6777b538SAndroid Build Coastguard Worker xmlCtxtInitializeLate(ctxt);
12548*6777b538SAndroid Build Coastguard Worker
12549*6777b538SAndroid Build Coastguard Worker ctxt->depth = depth;
12550*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = doc;
12551*6777b538SAndroid Build Coastguard Worker if (recover) {
12552*6777b538SAndroid Build Coastguard Worker ctxt->options |= XML_PARSE_RECOVER;
12553*6777b538SAndroid Build Coastguard Worker ctxt->recovery = 1;
12554*6777b538SAndroid Build Coastguard Worker }
12555*6777b538SAndroid Build Coastguard Worker
12556*6777b538SAndroid Build Coastguard Worker input = xmlNewStringInputStream(ctxt, string);
12557*6777b538SAndroid Build Coastguard Worker if (input == NULL)
12558*6777b538SAndroid Build Coastguard Worker return(ctxt->errNo);
12559*6777b538SAndroid Build Coastguard Worker
12560*6777b538SAndroid Build Coastguard Worker list = xmlCtxtParseContent(ctxt, input, /* hasTextDecl */ 0, 1);
12561*6777b538SAndroid Build Coastguard Worker if (listOut != NULL)
12562*6777b538SAndroid Build Coastguard Worker *listOut = list;
12563*6777b538SAndroid Build Coastguard Worker else
12564*6777b538SAndroid Build Coastguard Worker xmlFreeNodeList(list);
12565*6777b538SAndroid Build Coastguard Worker
12566*6777b538SAndroid Build Coastguard Worker ret = ctxt->errNo;
12567*6777b538SAndroid Build Coastguard Worker
12568*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(input);
12569*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
12570*6777b538SAndroid Build Coastguard Worker return(ret);
12571*6777b538SAndroid Build Coastguard Worker }
12572*6777b538SAndroid Build Coastguard Worker
12573*6777b538SAndroid Build Coastguard Worker /**
12574*6777b538SAndroid Build Coastguard Worker * xmlSAXParseEntity:
12575*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block
12576*6777b538SAndroid Build Coastguard Worker * @filename: the filename
12577*6777b538SAndroid Build Coastguard Worker *
12578*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Don't use.
12579*6777b538SAndroid Build Coastguard Worker *
12580*6777b538SAndroid Build Coastguard Worker * parse an XML external entity out of context and build a tree.
12581*6777b538SAndroid Build Coastguard Worker * It use the given SAX function block to handle the parsing callback.
12582*6777b538SAndroid Build Coastguard Worker * If sax is NULL, fallback to the default DOM tree building routines.
12583*6777b538SAndroid Build Coastguard Worker *
12584*6777b538SAndroid Build Coastguard Worker * [78] extParsedEnt ::= TextDecl? content
12585*6777b538SAndroid Build Coastguard Worker *
12586*6777b538SAndroid Build Coastguard Worker * This correspond to a "Well Balanced" chunk
12587*6777b538SAndroid Build Coastguard Worker *
12588*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
12589*6777b538SAndroid Build Coastguard Worker */
12590*6777b538SAndroid Build Coastguard Worker
12591*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlSAXParseEntity(xmlSAXHandlerPtr sax,const char * filename)12592*6777b538SAndroid Build Coastguard Worker xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
12593*6777b538SAndroid Build Coastguard Worker xmlDocPtr ret;
12594*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
12595*6777b538SAndroid Build Coastguard Worker
12596*6777b538SAndroid Build Coastguard Worker ctxt = xmlCreateFileParserCtxt(filename);
12597*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL) {
12598*6777b538SAndroid Build Coastguard Worker return(NULL);
12599*6777b538SAndroid Build Coastguard Worker }
12600*6777b538SAndroid Build Coastguard Worker if (sax != NULL) {
12601*6777b538SAndroid Build Coastguard Worker if (sax->initialized == XML_SAX2_MAGIC) {
12602*6777b538SAndroid Build Coastguard Worker *ctxt->sax = *sax;
12603*6777b538SAndroid Build Coastguard Worker } else {
12604*6777b538SAndroid Build Coastguard Worker memset(ctxt->sax, 0, sizeof(*ctxt->sax));
12605*6777b538SAndroid Build Coastguard Worker memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12606*6777b538SAndroid Build Coastguard Worker }
12607*6777b538SAndroid Build Coastguard Worker ctxt->userData = NULL;
12608*6777b538SAndroid Build Coastguard Worker }
12609*6777b538SAndroid Build Coastguard Worker
12610*6777b538SAndroid Build Coastguard Worker xmlParseExtParsedEnt(ctxt);
12611*6777b538SAndroid Build Coastguard Worker
12612*6777b538SAndroid Build Coastguard Worker if (ctxt->wellFormed) {
12613*6777b538SAndroid Build Coastguard Worker ret = ctxt->myDoc;
12614*6777b538SAndroid Build Coastguard Worker } else {
12615*6777b538SAndroid Build Coastguard Worker ret = NULL;
12616*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
12617*6777b538SAndroid Build Coastguard Worker }
12618*6777b538SAndroid Build Coastguard Worker
12619*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
12620*6777b538SAndroid Build Coastguard Worker
12621*6777b538SAndroid Build Coastguard Worker return(ret);
12622*6777b538SAndroid Build Coastguard Worker }
12623*6777b538SAndroid Build Coastguard Worker
12624*6777b538SAndroid Build Coastguard Worker /**
12625*6777b538SAndroid Build Coastguard Worker * xmlParseEntity:
12626*6777b538SAndroid Build Coastguard Worker * @filename: the filename
12627*6777b538SAndroid Build Coastguard Worker *
12628*6777b538SAndroid Build Coastguard Worker * parse an XML external entity out of context and build a tree.
12629*6777b538SAndroid Build Coastguard Worker *
12630*6777b538SAndroid Build Coastguard Worker * [78] extParsedEnt ::= TextDecl? content
12631*6777b538SAndroid Build Coastguard Worker *
12632*6777b538SAndroid Build Coastguard Worker * This correspond to a "Well Balanced" chunk
12633*6777b538SAndroid Build Coastguard Worker *
12634*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
12635*6777b538SAndroid Build Coastguard Worker */
12636*6777b538SAndroid Build Coastguard Worker
12637*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlParseEntity(const char * filename)12638*6777b538SAndroid Build Coastguard Worker xmlParseEntity(const char *filename) {
12639*6777b538SAndroid Build Coastguard Worker return(xmlSAXParseEntity(NULL, filename));
12640*6777b538SAndroid Build Coastguard Worker }
12641*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
12642*6777b538SAndroid Build Coastguard Worker
12643*6777b538SAndroid Build Coastguard Worker /**
12644*6777b538SAndroid Build Coastguard Worker * xmlCreateEntityParserCtxt:
12645*6777b538SAndroid Build Coastguard Worker * @URL: the entity URL
12646*6777b538SAndroid Build Coastguard Worker * @ID: the entity PUBLIC ID
12647*6777b538SAndroid Build Coastguard Worker * @base: a possible base for the target URI
12648*6777b538SAndroid Build Coastguard Worker *
12649*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewInputURL.
12650*6777b538SAndroid Build Coastguard Worker *
12651*6777b538SAndroid Build Coastguard Worker * Create a parser context for an external entity
12652*6777b538SAndroid Build Coastguard Worker * Automatic support for ZLIB/Compress compressed document is provided
12653*6777b538SAndroid Build Coastguard Worker * by default if found at compile-time.
12654*6777b538SAndroid Build Coastguard Worker *
12655*6777b538SAndroid Build Coastguard Worker * Returns the new parser context or NULL
12656*6777b538SAndroid Build Coastguard Worker */
12657*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr
xmlCreateEntityParserCtxt(const xmlChar * URL,const xmlChar * ID,const xmlChar * base)12658*6777b538SAndroid Build Coastguard Worker xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
12659*6777b538SAndroid Build Coastguard Worker const xmlChar *base) {
12660*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
12661*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
12662*6777b538SAndroid Build Coastguard Worker xmlChar *uri = NULL;
12663*6777b538SAndroid Build Coastguard Worker
12664*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
12665*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
12666*6777b538SAndroid Build Coastguard Worker return(NULL);
12667*6777b538SAndroid Build Coastguard Worker
12668*6777b538SAndroid Build Coastguard Worker if (base != NULL) {
12669*6777b538SAndroid Build Coastguard Worker if (xmlBuildURISafe(URL, base, &uri) < 0)
12670*6777b538SAndroid Build Coastguard Worker goto error;
12671*6777b538SAndroid Build Coastguard Worker if (uri != NULL)
12672*6777b538SAndroid Build Coastguard Worker URL = uri;
12673*6777b538SAndroid Build Coastguard Worker }
12674*6777b538SAndroid Build Coastguard Worker
12675*6777b538SAndroid Build Coastguard Worker input = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
12676*6777b538SAndroid Build Coastguard Worker if (input == NULL)
12677*6777b538SAndroid Build Coastguard Worker goto error;
12678*6777b538SAndroid Build Coastguard Worker
12679*6777b538SAndroid Build Coastguard Worker if (inputPush(ctxt, input) < 0)
12680*6777b538SAndroid Build Coastguard Worker goto error;
12681*6777b538SAndroid Build Coastguard Worker
12682*6777b538SAndroid Build Coastguard Worker xmlFree(uri);
12683*6777b538SAndroid Build Coastguard Worker return(ctxt);
12684*6777b538SAndroid Build Coastguard Worker
12685*6777b538SAndroid Build Coastguard Worker error:
12686*6777b538SAndroid Build Coastguard Worker xmlFree(uri);
12687*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
12688*6777b538SAndroid Build Coastguard Worker return(NULL);
12689*6777b538SAndroid Build Coastguard Worker }
12690*6777b538SAndroid Build Coastguard Worker
12691*6777b538SAndroid Build Coastguard Worker /************************************************************************
12692*6777b538SAndroid Build Coastguard Worker * *
12693*6777b538SAndroid Build Coastguard Worker * Front ends when parsing from a file *
12694*6777b538SAndroid Build Coastguard Worker * *
12695*6777b538SAndroid Build Coastguard Worker ************************************************************************/
12696*6777b538SAndroid Build Coastguard Worker
12697*6777b538SAndroid Build Coastguard Worker /**
12698*6777b538SAndroid Build Coastguard Worker * xmlCreateURLParserCtxt:
12699*6777b538SAndroid Build Coastguard Worker * @filename: the filename or URL
12700*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
12701*6777b538SAndroid Build Coastguard Worker *
12702*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewParserCtxt and xmlCtxtReadFile.
12703*6777b538SAndroid Build Coastguard Worker *
12704*6777b538SAndroid Build Coastguard Worker * Create a parser context for a file or URL content.
12705*6777b538SAndroid Build Coastguard Worker * Automatic support for ZLIB/Compress compressed document is provided
12706*6777b538SAndroid Build Coastguard Worker * by default if found at compile-time and for file accesses
12707*6777b538SAndroid Build Coastguard Worker *
12708*6777b538SAndroid Build Coastguard Worker * Returns the new parser context or NULL
12709*6777b538SAndroid Build Coastguard Worker */
12710*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr
xmlCreateURLParserCtxt(const char * filename,int options)12711*6777b538SAndroid Build Coastguard Worker xmlCreateURLParserCtxt(const char *filename, int options)
12712*6777b538SAndroid Build Coastguard Worker {
12713*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
12714*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
12715*6777b538SAndroid Build Coastguard Worker
12716*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
12717*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
12718*6777b538SAndroid Build Coastguard Worker return(NULL);
12719*6777b538SAndroid Build Coastguard Worker
12720*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
12721*6777b538SAndroid Build Coastguard Worker ctxt->linenumbers = 1;
12722*6777b538SAndroid Build Coastguard Worker
12723*6777b538SAndroid Build Coastguard Worker input = xmlLoadExternalEntity(filename, NULL, ctxt);
12724*6777b538SAndroid Build Coastguard Worker if (input == NULL) {
12725*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
12726*6777b538SAndroid Build Coastguard Worker return(NULL);
12727*6777b538SAndroid Build Coastguard Worker }
12728*6777b538SAndroid Build Coastguard Worker inputPush(ctxt, input);
12729*6777b538SAndroid Build Coastguard Worker
12730*6777b538SAndroid Build Coastguard Worker return(ctxt);
12731*6777b538SAndroid Build Coastguard Worker }
12732*6777b538SAndroid Build Coastguard Worker
12733*6777b538SAndroid Build Coastguard Worker /**
12734*6777b538SAndroid Build Coastguard Worker * xmlCreateFileParserCtxt:
12735*6777b538SAndroid Build Coastguard Worker * @filename: the filename
12736*6777b538SAndroid Build Coastguard Worker *
12737*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewParserCtxt and xmlCtxtReadFile.
12738*6777b538SAndroid Build Coastguard Worker *
12739*6777b538SAndroid Build Coastguard Worker * Create a parser context for a file content.
12740*6777b538SAndroid Build Coastguard Worker * Automatic support for ZLIB/Compress compressed document is provided
12741*6777b538SAndroid Build Coastguard Worker * by default if found at compile-time.
12742*6777b538SAndroid Build Coastguard Worker *
12743*6777b538SAndroid Build Coastguard Worker * Returns the new parser context or NULL
12744*6777b538SAndroid Build Coastguard Worker */
12745*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr
xmlCreateFileParserCtxt(const char * filename)12746*6777b538SAndroid Build Coastguard Worker xmlCreateFileParserCtxt(const char *filename)
12747*6777b538SAndroid Build Coastguard Worker {
12748*6777b538SAndroid Build Coastguard Worker return(xmlCreateURLParserCtxt(filename, 0));
12749*6777b538SAndroid Build Coastguard Worker }
12750*6777b538SAndroid Build Coastguard Worker
12751*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
12752*6777b538SAndroid Build Coastguard Worker /**
12753*6777b538SAndroid Build Coastguard Worker * xmlSAXParseFileWithData:
12754*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block
12755*6777b538SAndroid Build Coastguard Worker * @filename: the filename
12756*6777b538SAndroid Build Coastguard Worker * @recovery: work in recovery mode, i.e. tries to read no Well Formed
12757*6777b538SAndroid Build Coastguard Worker * documents
12758*6777b538SAndroid Build Coastguard Worker * @data: the userdata
12759*6777b538SAndroid Build Coastguard Worker *
12760*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadFile.
12761*6777b538SAndroid Build Coastguard Worker *
12762*6777b538SAndroid Build Coastguard Worker * parse an XML file and build a tree. Automatic support for ZLIB/Compress
12763*6777b538SAndroid Build Coastguard Worker * compressed document is provided by default if found at compile-time.
12764*6777b538SAndroid Build Coastguard Worker * It use the given SAX function block to handle the parsing callback.
12765*6777b538SAndroid Build Coastguard Worker * If sax is NULL, fallback to the default DOM tree building routines.
12766*6777b538SAndroid Build Coastguard Worker *
12767*6777b538SAndroid Build Coastguard Worker * User data (void *) is stored within the parser context in the
12768*6777b538SAndroid Build Coastguard Worker * context's _private member, so it is available nearly everywhere in libxml
12769*6777b538SAndroid Build Coastguard Worker *
12770*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
12771*6777b538SAndroid Build Coastguard Worker */
12772*6777b538SAndroid Build Coastguard Worker
12773*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlSAXParseFileWithData(xmlSAXHandlerPtr sax,const char * filename,int recovery,void * data)12774*6777b538SAndroid Build Coastguard Worker xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
12775*6777b538SAndroid Build Coastguard Worker int recovery, void *data) {
12776*6777b538SAndroid Build Coastguard Worker xmlDocPtr ret;
12777*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
12778*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
12779*6777b538SAndroid Build Coastguard Worker
12780*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewSAXParserCtxt(sax, NULL);
12781*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
12782*6777b538SAndroid Build Coastguard Worker return(NULL);
12783*6777b538SAndroid Build Coastguard Worker
12784*6777b538SAndroid Build Coastguard Worker if (data != NULL)
12785*6777b538SAndroid Build Coastguard Worker ctxt->_private = data;
12786*6777b538SAndroid Build Coastguard Worker
12787*6777b538SAndroid Build Coastguard Worker if (recovery) {
12788*6777b538SAndroid Build Coastguard Worker ctxt->options |= XML_PARSE_RECOVER;
12789*6777b538SAndroid Build Coastguard Worker ctxt->recovery = 1;
12790*6777b538SAndroid Build Coastguard Worker }
12791*6777b538SAndroid Build Coastguard Worker
12792*6777b538SAndroid Build Coastguard Worker input = xmlNewInputURL(ctxt, filename, NULL, NULL, 0);
12793*6777b538SAndroid Build Coastguard Worker
12794*6777b538SAndroid Build Coastguard Worker ret = xmlCtxtParseDocument(ctxt, input);
12795*6777b538SAndroid Build Coastguard Worker
12796*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
12797*6777b538SAndroid Build Coastguard Worker return(ret);
12798*6777b538SAndroid Build Coastguard Worker }
12799*6777b538SAndroid Build Coastguard Worker
12800*6777b538SAndroid Build Coastguard Worker /**
12801*6777b538SAndroid Build Coastguard Worker * xmlSAXParseFile:
12802*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block
12803*6777b538SAndroid Build Coastguard Worker * @filename: the filename
12804*6777b538SAndroid Build Coastguard Worker * @recovery: work in recovery mode, i.e. tries to read no Well Formed
12805*6777b538SAndroid Build Coastguard Worker * documents
12806*6777b538SAndroid Build Coastguard Worker *
12807*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadFile.
12808*6777b538SAndroid Build Coastguard Worker *
12809*6777b538SAndroid Build Coastguard Worker * parse an XML file and build a tree. Automatic support for ZLIB/Compress
12810*6777b538SAndroid Build Coastguard Worker * compressed document is provided by default if found at compile-time.
12811*6777b538SAndroid Build Coastguard Worker * It use the given SAX function block to handle the parsing callback.
12812*6777b538SAndroid Build Coastguard Worker * If sax is NULL, fallback to the default DOM tree building routines.
12813*6777b538SAndroid Build Coastguard Worker *
12814*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
12815*6777b538SAndroid Build Coastguard Worker */
12816*6777b538SAndroid Build Coastguard Worker
12817*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlSAXParseFile(xmlSAXHandlerPtr sax,const char * filename,int recovery)12818*6777b538SAndroid Build Coastguard Worker xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
12819*6777b538SAndroid Build Coastguard Worker int recovery) {
12820*6777b538SAndroid Build Coastguard Worker return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
12821*6777b538SAndroid Build Coastguard Worker }
12822*6777b538SAndroid Build Coastguard Worker
12823*6777b538SAndroid Build Coastguard Worker /**
12824*6777b538SAndroid Build Coastguard Worker * xmlRecoverDoc:
12825*6777b538SAndroid Build Coastguard Worker * @cur: a pointer to an array of xmlChar
12826*6777b538SAndroid Build Coastguard Worker *
12827*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlReadDoc with XML_PARSE_RECOVER.
12828*6777b538SAndroid Build Coastguard Worker *
12829*6777b538SAndroid Build Coastguard Worker * parse an XML in-memory document and build a tree.
12830*6777b538SAndroid Build Coastguard Worker * In the case the document is not Well Formed, a attempt to build a
12831*6777b538SAndroid Build Coastguard Worker * tree is tried anyway
12832*6777b538SAndroid Build Coastguard Worker *
12833*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree or NULL in case of failure
12834*6777b538SAndroid Build Coastguard Worker */
12835*6777b538SAndroid Build Coastguard Worker
12836*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlRecoverDoc(const xmlChar * cur)12837*6777b538SAndroid Build Coastguard Worker xmlRecoverDoc(const xmlChar *cur) {
12838*6777b538SAndroid Build Coastguard Worker return(xmlSAXParseDoc(NULL, cur, 1));
12839*6777b538SAndroid Build Coastguard Worker }
12840*6777b538SAndroid Build Coastguard Worker
12841*6777b538SAndroid Build Coastguard Worker /**
12842*6777b538SAndroid Build Coastguard Worker * xmlParseFile:
12843*6777b538SAndroid Build Coastguard Worker * @filename: the filename
12844*6777b538SAndroid Build Coastguard Worker *
12845*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlReadFile.
12846*6777b538SAndroid Build Coastguard Worker *
12847*6777b538SAndroid Build Coastguard Worker * parse an XML file and build a tree. Automatic support for ZLIB/Compress
12848*6777b538SAndroid Build Coastguard Worker * compressed document is provided by default if found at compile-time.
12849*6777b538SAndroid Build Coastguard Worker *
12850*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree if the file was wellformed,
12851*6777b538SAndroid Build Coastguard Worker * NULL otherwise.
12852*6777b538SAndroid Build Coastguard Worker */
12853*6777b538SAndroid Build Coastguard Worker
12854*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlParseFile(const char * filename)12855*6777b538SAndroid Build Coastguard Worker xmlParseFile(const char *filename) {
12856*6777b538SAndroid Build Coastguard Worker return(xmlSAXParseFile(NULL, filename, 0));
12857*6777b538SAndroid Build Coastguard Worker }
12858*6777b538SAndroid Build Coastguard Worker
12859*6777b538SAndroid Build Coastguard Worker /**
12860*6777b538SAndroid Build Coastguard Worker * xmlRecoverFile:
12861*6777b538SAndroid Build Coastguard Worker * @filename: the filename
12862*6777b538SAndroid Build Coastguard Worker *
12863*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlReadFile with XML_PARSE_RECOVER.
12864*6777b538SAndroid Build Coastguard Worker *
12865*6777b538SAndroid Build Coastguard Worker * parse an XML file and build a tree. Automatic support for ZLIB/Compress
12866*6777b538SAndroid Build Coastguard Worker * compressed document is provided by default if found at compile-time.
12867*6777b538SAndroid Build Coastguard Worker * In the case the document is not Well Formed, it attempts to build
12868*6777b538SAndroid Build Coastguard Worker * a tree anyway
12869*6777b538SAndroid Build Coastguard Worker *
12870*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree or NULL in case of failure
12871*6777b538SAndroid Build Coastguard Worker */
12872*6777b538SAndroid Build Coastguard Worker
12873*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlRecoverFile(const char * filename)12874*6777b538SAndroid Build Coastguard Worker xmlRecoverFile(const char *filename) {
12875*6777b538SAndroid Build Coastguard Worker return(xmlSAXParseFile(NULL, filename, 1));
12876*6777b538SAndroid Build Coastguard Worker }
12877*6777b538SAndroid Build Coastguard Worker
12878*6777b538SAndroid Build Coastguard Worker
12879*6777b538SAndroid Build Coastguard Worker /**
12880*6777b538SAndroid Build Coastguard Worker * xmlSetupParserForBuffer:
12881*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
12882*6777b538SAndroid Build Coastguard Worker * @buffer: a xmlChar * buffer
12883*6777b538SAndroid Build Coastguard Worker * @filename: a file name
12884*6777b538SAndroid Build Coastguard Worker *
12885*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Don't use.
12886*6777b538SAndroid Build Coastguard Worker *
12887*6777b538SAndroid Build Coastguard Worker * Setup the parser context to parse a new buffer; Clears any prior
12888*6777b538SAndroid Build Coastguard Worker * contents from the parser context. The buffer parameter must not be
12889*6777b538SAndroid Build Coastguard Worker * NULL, but the filename parameter can be
12890*6777b538SAndroid Build Coastguard Worker */
12891*6777b538SAndroid Build Coastguard Worker void
xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt,const xmlChar * buffer,const char * filename)12892*6777b538SAndroid Build Coastguard Worker xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
12893*6777b538SAndroid Build Coastguard Worker const char* filename)
12894*6777b538SAndroid Build Coastguard Worker {
12895*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
12896*6777b538SAndroid Build Coastguard Worker
12897*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (buffer == NULL))
12898*6777b538SAndroid Build Coastguard Worker return;
12899*6777b538SAndroid Build Coastguard Worker
12900*6777b538SAndroid Build Coastguard Worker xmlClearParserCtxt(ctxt);
12901*6777b538SAndroid Build Coastguard Worker
12902*6777b538SAndroid Build Coastguard Worker input = xmlNewInputString(ctxt, filename, (const char *) buffer, NULL, 0);
12903*6777b538SAndroid Build Coastguard Worker if (input == NULL)
12904*6777b538SAndroid Build Coastguard Worker return;
12905*6777b538SAndroid Build Coastguard Worker inputPush(ctxt, input);
12906*6777b538SAndroid Build Coastguard Worker }
12907*6777b538SAndroid Build Coastguard Worker
12908*6777b538SAndroid Build Coastguard Worker /**
12909*6777b538SAndroid Build Coastguard Worker * xmlSAXUserParseFile:
12910*6777b538SAndroid Build Coastguard Worker * @sax: a SAX handler
12911*6777b538SAndroid Build Coastguard Worker * @user_data: The user data returned on SAX callbacks
12912*6777b538SAndroid Build Coastguard Worker * @filename: a file name
12913*6777b538SAndroid Build Coastguard Worker *
12914*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadFile.
12915*6777b538SAndroid Build Coastguard Worker *
12916*6777b538SAndroid Build Coastguard Worker * parse an XML file and call the given SAX handler routines.
12917*6777b538SAndroid Build Coastguard Worker * Automatic support for ZLIB/Compress compressed document is provided
12918*6777b538SAndroid Build Coastguard Worker *
12919*6777b538SAndroid Build Coastguard Worker * Returns 0 in case of success or a error number otherwise
12920*6777b538SAndroid Build Coastguard Worker */
12921*6777b538SAndroid Build Coastguard Worker int
xmlSAXUserParseFile(xmlSAXHandlerPtr sax,void * user_data,const char * filename)12922*6777b538SAndroid Build Coastguard Worker xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
12923*6777b538SAndroid Build Coastguard Worker const char *filename) {
12924*6777b538SAndroid Build Coastguard Worker int ret = 0;
12925*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
12926*6777b538SAndroid Build Coastguard Worker
12927*6777b538SAndroid Build Coastguard Worker ctxt = xmlCreateFileParserCtxt(filename);
12928*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL) return -1;
12929*6777b538SAndroid Build Coastguard Worker if (sax != NULL) {
12930*6777b538SAndroid Build Coastguard Worker if (sax->initialized == XML_SAX2_MAGIC) {
12931*6777b538SAndroid Build Coastguard Worker *ctxt->sax = *sax;
12932*6777b538SAndroid Build Coastguard Worker } else {
12933*6777b538SAndroid Build Coastguard Worker memset(ctxt->sax, 0, sizeof(*ctxt->sax));
12934*6777b538SAndroid Build Coastguard Worker memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12935*6777b538SAndroid Build Coastguard Worker }
12936*6777b538SAndroid Build Coastguard Worker ctxt->userData = user_data;
12937*6777b538SAndroid Build Coastguard Worker }
12938*6777b538SAndroid Build Coastguard Worker
12939*6777b538SAndroid Build Coastguard Worker xmlParseDocument(ctxt);
12940*6777b538SAndroid Build Coastguard Worker
12941*6777b538SAndroid Build Coastguard Worker if (ctxt->wellFormed)
12942*6777b538SAndroid Build Coastguard Worker ret = 0;
12943*6777b538SAndroid Build Coastguard Worker else {
12944*6777b538SAndroid Build Coastguard Worker if (ctxt->errNo != 0)
12945*6777b538SAndroid Build Coastguard Worker ret = ctxt->errNo;
12946*6777b538SAndroid Build Coastguard Worker else
12947*6777b538SAndroid Build Coastguard Worker ret = -1;
12948*6777b538SAndroid Build Coastguard Worker }
12949*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc != NULL) {
12950*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
12951*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = NULL;
12952*6777b538SAndroid Build Coastguard Worker }
12953*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
12954*6777b538SAndroid Build Coastguard Worker
12955*6777b538SAndroid Build Coastguard Worker return ret;
12956*6777b538SAndroid Build Coastguard Worker }
12957*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
12958*6777b538SAndroid Build Coastguard Worker
12959*6777b538SAndroid Build Coastguard Worker /************************************************************************
12960*6777b538SAndroid Build Coastguard Worker * *
12961*6777b538SAndroid Build Coastguard Worker * Front ends when parsing from memory *
12962*6777b538SAndroid Build Coastguard Worker * *
12963*6777b538SAndroid Build Coastguard Worker ************************************************************************/
12964*6777b538SAndroid Build Coastguard Worker
12965*6777b538SAndroid Build Coastguard Worker /**
12966*6777b538SAndroid Build Coastguard Worker * xmlCreateMemoryParserCtxt:
12967*6777b538SAndroid Build Coastguard Worker * @buffer: a pointer to a char array
12968*6777b538SAndroid Build Coastguard Worker * @size: the size of the array
12969*6777b538SAndroid Build Coastguard Worker *
12970*6777b538SAndroid Build Coastguard Worker * Create a parser context for an XML in-memory document. The input buffer
12971*6777b538SAndroid Build Coastguard Worker * must not contain a terminating null byte.
12972*6777b538SAndroid Build Coastguard Worker *
12973*6777b538SAndroid Build Coastguard Worker * Returns the new parser context or NULL
12974*6777b538SAndroid Build Coastguard Worker */
12975*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr
xmlCreateMemoryParserCtxt(const char * buffer,int size)12976*6777b538SAndroid Build Coastguard Worker xmlCreateMemoryParserCtxt(const char *buffer, int size) {
12977*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
12978*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
12979*6777b538SAndroid Build Coastguard Worker
12980*6777b538SAndroid Build Coastguard Worker if (size < 0)
12981*6777b538SAndroid Build Coastguard Worker return(NULL);
12982*6777b538SAndroid Build Coastguard Worker
12983*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
12984*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
12985*6777b538SAndroid Build Coastguard Worker return(NULL);
12986*6777b538SAndroid Build Coastguard Worker
12987*6777b538SAndroid Build Coastguard Worker input = xmlNewInputMemory(ctxt, NULL, buffer, size, NULL, 0);
12988*6777b538SAndroid Build Coastguard Worker if (input == NULL) {
12989*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
12990*6777b538SAndroid Build Coastguard Worker return(NULL);
12991*6777b538SAndroid Build Coastguard Worker }
12992*6777b538SAndroid Build Coastguard Worker inputPush(ctxt, input);
12993*6777b538SAndroid Build Coastguard Worker
12994*6777b538SAndroid Build Coastguard Worker return(ctxt);
12995*6777b538SAndroid Build Coastguard Worker }
12996*6777b538SAndroid Build Coastguard Worker
12997*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
12998*6777b538SAndroid Build Coastguard Worker /**
12999*6777b538SAndroid Build Coastguard Worker * xmlSAXParseMemoryWithData:
13000*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block
13001*6777b538SAndroid Build Coastguard Worker * @buffer: an pointer to a char array
13002*6777b538SAndroid Build Coastguard Worker * @size: the size of the array
13003*6777b538SAndroid Build Coastguard Worker * @recovery: work in recovery mode, i.e. tries to read no Well Formed
13004*6777b538SAndroid Build Coastguard Worker * documents
13005*6777b538SAndroid Build Coastguard Worker * @data: the userdata
13006*6777b538SAndroid Build Coastguard Worker *
13007*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadMemory.
13008*6777b538SAndroid Build Coastguard Worker *
13009*6777b538SAndroid Build Coastguard Worker * parse an XML in-memory block and use the given SAX function block
13010*6777b538SAndroid Build Coastguard Worker * to handle the parsing callback. If sax is NULL, fallback to the default
13011*6777b538SAndroid Build Coastguard Worker * DOM tree building routines.
13012*6777b538SAndroid Build Coastguard Worker *
13013*6777b538SAndroid Build Coastguard Worker * User data (void *) is stored within the parser context in the
13014*6777b538SAndroid Build Coastguard Worker * context's _private member, so it is available nearly everywhere in libxml
13015*6777b538SAndroid Build Coastguard Worker *
13016*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13017*6777b538SAndroid Build Coastguard Worker */
13018*6777b538SAndroid Build Coastguard Worker
13019*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax,const char * buffer,int size,int recovery,void * data)13020*6777b538SAndroid Build Coastguard Worker xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
13021*6777b538SAndroid Build Coastguard Worker int size, int recovery, void *data) {
13022*6777b538SAndroid Build Coastguard Worker xmlDocPtr ret;
13023*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
13024*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13025*6777b538SAndroid Build Coastguard Worker
13026*6777b538SAndroid Build Coastguard Worker if (size < 0)
13027*6777b538SAndroid Build Coastguard Worker return(NULL);
13028*6777b538SAndroid Build Coastguard Worker
13029*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewSAXParserCtxt(sax, NULL);
13030*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13031*6777b538SAndroid Build Coastguard Worker return(NULL);
13032*6777b538SAndroid Build Coastguard Worker
13033*6777b538SAndroid Build Coastguard Worker if (data != NULL)
13034*6777b538SAndroid Build Coastguard Worker ctxt->_private=data;
13035*6777b538SAndroid Build Coastguard Worker
13036*6777b538SAndroid Build Coastguard Worker if (recovery) {
13037*6777b538SAndroid Build Coastguard Worker ctxt->options |= XML_PARSE_RECOVER;
13038*6777b538SAndroid Build Coastguard Worker ctxt->recovery = 1;
13039*6777b538SAndroid Build Coastguard Worker }
13040*6777b538SAndroid Build Coastguard Worker
13041*6777b538SAndroid Build Coastguard Worker input = xmlNewInputMemory(ctxt, NULL, buffer, size, NULL,
13042*6777b538SAndroid Build Coastguard Worker XML_INPUT_BUF_STATIC);
13043*6777b538SAndroid Build Coastguard Worker
13044*6777b538SAndroid Build Coastguard Worker ret = xmlCtxtParseDocument(ctxt, input);
13045*6777b538SAndroid Build Coastguard Worker
13046*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
13047*6777b538SAndroid Build Coastguard Worker return(ret);
13048*6777b538SAndroid Build Coastguard Worker }
13049*6777b538SAndroid Build Coastguard Worker
13050*6777b538SAndroid Build Coastguard Worker /**
13051*6777b538SAndroid Build Coastguard Worker * xmlSAXParseMemory:
13052*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block
13053*6777b538SAndroid Build Coastguard Worker * @buffer: an pointer to a char array
13054*6777b538SAndroid Build Coastguard Worker * @size: the size of the array
13055*6777b538SAndroid Build Coastguard Worker * @recovery: work in recovery mode, i.e. tries to read not Well Formed
13056*6777b538SAndroid Build Coastguard Worker * documents
13057*6777b538SAndroid Build Coastguard Worker *
13058*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadMemory.
13059*6777b538SAndroid Build Coastguard Worker *
13060*6777b538SAndroid Build Coastguard Worker * parse an XML in-memory block and use the given SAX function block
13061*6777b538SAndroid Build Coastguard Worker * to handle the parsing callback. If sax is NULL, fallback to the default
13062*6777b538SAndroid Build Coastguard Worker * DOM tree building routines.
13063*6777b538SAndroid Build Coastguard Worker *
13064*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13065*6777b538SAndroid Build Coastguard Worker */
13066*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlSAXParseMemory(xmlSAXHandlerPtr sax,const char * buffer,int size,int recovery)13067*6777b538SAndroid Build Coastguard Worker xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
13068*6777b538SAndroid Build Coastguard Worker int size, int recovery) {
13069*6777b538SAndroid Build Coastguard Worker return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
13070*6777b538SAndroid Build Coastguard Worker }
13071*6777b538SAndroid Build Coastguard Worker
13072*6777b538SAndroid Build Coastguard Worker /**
13073*6777b538SAndroid Build Coastguard Worker * xmlParseMemory:
13074*6777b538SAndroid Build Coastguard Worker * @buffer: an pointer to a char array
13075*6777b538SAndroid Build Coastguard Worker * @size: the size of the array
13076*6777b538SAndroid Build Coastguard Worker *
13077*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlReadMemory.
13078*6777b538SAndroid Build Coastguard Worker *
13079*6777b538SAndroid Build Coastguard Worker * parse an XML in-memory block and build a tree.
13080*6777b538SAndroid Build Coastguard Worker *
13081*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13082*6777b538SAndroid Build Coastguard Worker */
13083*6777b538SAndroid Build Coastguard Worker
xmlParseMemory(const char * buffer,int size)13084*6777b538SAndroid Build Coastguard Worker xmlDocPtr xmlParseMemory(const char *buffer, int size) {
13085*6777b538SAndroid Build Coastguard Worker return(xmlSAXParseMemory(NULL, buffer, size, 0));
13086*6777b538SAndroid Build Coastguard Worker }
13087*6777b538SAndroid Build Coastguard Worker
13088*6777b538SAndroid Build Coastguard Worker /**
13089*6777b538SAndroid Build Coastguard Worker * xmlRecoverMemory:
13090*6777b538SAndroid Build Coastguard Worker * @buffer: an pointer to a char array
13091*6777b538SAndroid Build Coastguard Worker * @size: the size of the array
13092*6777b538SAndroid Build Coastguard Worker *
13093*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlReadMemory with XML_PARSE_RECOVER.
13094*6777b538SAndroid Build Coastguard Worker *
13095*6777b538SAndroid Build Coastguard Worker * parse an XML in-memory block and build a tree.
13096*6777b538SAndroid Build Coastguard Worker * In the case the document is not Well Formed, an attempt to
13097*6777b538SAndroid Build Coastguard Worker * build a tree is tried anyway
13098*6777b538SAndroid Build Coastguard Worker *
13099*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree or NULL in case of error
13100*6777b538SAndroid Build Coastguard Worker */
13101*6777b538SAndroid Build Coastguard Worker
xmlRecoverMemory(const char * buffer,int size)13102*6777b538SAndroid Build Coastguard Worker xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
13103*6777b538SAndroid Build Coastguard Worker return(xmlSAXParseMemory(NULL, buffer, size, 1));
13104*6777b538SAndroid Build Coastguard Worker }
13105*6777b538SAndroid Build Coastguard Worker
13106*6777b538SAndroid Build Coastguard Worker /**
13107*6777b538SAndroid Build Coastguard Worker * xmlSAXUserParseMemory:
13108*6777b538SAndroid Build Coastguard Worker * @sax: a SAX handler
13109*6777b538SAndroid Build Coastguard Worker * @user_data: The user data returned on SAX callbacks
13110*6777b538SAndroid Build Coastguard Worker * @buffer: an in-memory XML document input
13111*6777b538SAndroid Build Coastguard Worker * @size: the length of the XML document in bytes
13112*6777b538SAndroid Build Coastguard Worker *
13113*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadMemory.
13114*6777b538SAndroid Build Coastguard Worker *
13115*6777b538SAndroid Build Coastguard Worker * parse an XML in-memory buffer and call the given SAX handler routines.
13116*6777b538SAndroid Build Coastguard Worker *
13117*6777b538SAndroid Build Coastguard Worker * Returns 0 in case of success or a error number otherwise
13118*6777b538SAndroid Build Coastguard Worker */
xmlSAXUserParseMemory(xmlSAXHandlerPtr sax,void * user_data,const char * buffer,int size)13119*6777b538SAndroid Build Coastguard Worker int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
13120*6777b538SAndroid Build Coastguard Worker const char *buffer, int size) {
13121*6777b538SAndroid Build Coastguard Worker int ret = 0;
13122*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
13123*6777b538SAndroid Build Coastguard Worker
13124*6777b538SAndroid Build Coastguard Worker ctxt = xmlCreateMemoryParserCtxt(buffer, size);
13125*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL) return -1;
13126*6777b538SAndroid Build Coastguard Worker if (sax != NULL) {
13127*6777b538SAndroid Build Coastguard Worker if (sax->initialized == XML_SAX2_MAGIC) {
13128*6777b538SAndroid Build Coastguard Worker *ctxt->sax = *sax;
13129*6777b538SAndroid Build Coastguard Worker } else {
13130*6777b538SAndroid Build Coastguard Worker memset(ctxt->sax, 0, sizeof(*ctxt->sax));
13131*6777b538SAndroid Build Coastguard Worker memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
13132*6777b538SAndroid Build Coastguard Worker }
13133*6777b538SAndroid Build Coastguard Worker ctxt->userData = user_data;
13134*6777b538SAndroid Build Coastguard Worker }
13135*6777b538SAndroid Build Coastguard Worker
13136*6777b538SAndroid Build Coastguard Worker xmlParseDocument(ctxt);
13137*6777b538SAndroid Build Coastguard Worker
13138*6777b538SAndroid Build Coastguard Worker if (ctxt->wellFormed)
13139*6777b538SAndroid Build Coastguard Worker ret = 0;
13140*6777b538SAndroid Build Coastguard Worker else {
13141*6777b538SAndroid Build Coastguard Worker if (ctxt->errNo != 0)
13142*6777b538SAndroid Build Coastguard Worker ret = ctxt->errNo;
13143*6777b538SAndroid Build Coastguard Worker else
13144*6777b538SAndroid Build Coastguard Worker ret = -1;
13145*6777b538SAndroid Build Coastguard Worker }
13146*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc != NULL) {
13147*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
13148*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = NULL;
13149*6777b538SAndroid Build Coastguard Worker }
13150*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
13151*6777b538SAndroid Build Coastguard Worker
13152*6777b538SAndroid Build Coastguard Worker return ret;
13153*6777b538SAndroid Build Coastguard Worker }
13154*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
13155*6777b538SAndroid Build Coastguard Worker
13156*6777b538SAndroid Build Coastguard Worker /**
13157*6777b538SAndroid Build Coastguard Worker * xmlCreateDocParserCtxt:
13158*6777b538SAndroid Build Coastguard Worker * @str: a pointer to an array of xmlChar
13159*6777b538SAndroid Build Coastguard Worker *
13160*6777b538SAndroid Build Coastguard Worker * Creates a parser context for an XML in-memory document.
13161*6777b538SAndroid Build Coastguard Worker *
13162*6777b538SAndroid Build Coastguard Worker * Returns the new parser context or NULL
13163*6777b538SAndroid Build Coastguard Worker */
13164*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr
xmlCreateDocParserCtxt(const xmlChar * str)13165*6777b538SAndroid Build Coastguard Worker xmlCreateDocParserCtxt(const xmlChar *str) {
13166*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
13167*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13168*6777b538SAndroid Build Coastguard Worker
13169*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
13170*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13171*6777b538SAndroid Build Coastguard Worker return(NULL);
13172*6777b538SAndroid Build Coastguard Worker
13173*6777b538SAndroid Build Coastguard Worker input = xmlNewInputString(ctxt, NULL, (const char *) str, NULL, 0);
13174*6777b538SAndroid Build Coastguard Worker if (input == NULL) {
13175*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
13176*6777b538SAndroid Build Coastguard Worker return(NULL);
13177*6777b538SAndroid Build Coastguard Worker }
13178*6777b538SAndroid Build Coastguard Worker inputPush(ctxt, input);
13179*6777b538SAndroid Build Coastguard Worker
13180*6777b538SAndroid Build Coastguard Worker return(ctxt);
13181*6777b538SAndroid Build Coastguard Worker }
13182*6777b538SAndroid Build Coastguard Worker
13183*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
13184*6777b538SAndroid Build Coastguard Worker /**
13185*6777b538SAndroid Build Coastguard Worker * xmlSAXParseDoc:
13186*6777b538SAndroid Build Coastguard Worker * @sax: the SAX handler block
13187*6777b538SAndroid Build Coastguard Worker * @cur: a pointer to an array of xmlChar
13188*6777b538SAndroid Build Coastguard Worker * @recovery: work in recovery mode, i.e. tries to read no Well Formed
13189*6777b538SAndroid Build Coastguard Worker * documents
13190*6777b538SAndroid Build Coastguard Worker *
13191*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadDoc.
13192*6777b538SAndroid Build Coastguard Worker *
13193*6777b538SAndroid Build Coastguard Worker * parse an XML in-memory document and build a tree.
13194*6777b538SAndroid Build Coastguard Worker * It use the given SAX function block to handle the parsing callback.
13195*6777b538SAndroid Build Coastguard Worker * If sax is NULL, fallback to the default DOM tree building routines.
13196*6777b538SAndroid Build Coastguard Worker *
13197*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13198*6777b538SAndroid Build Coastguard Worker */
13199*6777b538SAndroid Build Coastguard Worker
13200*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlSAXParseDoc(xmlSAXHandlerPtr sax,const xmlChar * cur,int recovery)13201*6777b538SAndroid Build Coastguard Worker xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
13202*6777b538SAndroid Build Coastguard Worker xmlDocPtr ret;
13203*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
13204*6777b538SAndroid Build Coastguard Worker xmlSAXHandlerPtr oldsax = NULL;
13205*6777b538SAndroid Build Coastguard Worker
13206*6777b538SAndroid Build Coastguard Worker if (cur == NULL) return(NULL);
13207*6777b538SAndroid Build Coastguard Worker
13208*6777b538SAndroid Build Coastguard Worker
13209*6777b538SAndroid Build Coastguard Worker ctxt = xmlCreateDocParserCtxt(cur);
13210*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL) return(NULL);
13211*6777b538SAndroid Build Coastguard Worker if (sax != NULL) {
13212*6777b538SAndroid Build Coastguard Worker oldsax = ctxt->sax;
13213*6777b538SAndroid Build Coastguard Worker ctxt->sax = sax;
13214*6777b538SAndroid Build Coastguard Worker ctxt->userData = NULL;
13215*6777b538SAndroid Build Coastguard Worker }
13216*6777b538SAndroid Build Coastguard Worker
13217*6777b538SAndroid Build Coastguard Worker xmlParseDocument(ctxt);
13218*6777b538SAndroid Build Coastguard Worker if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
13219*6777b538SAndroid Build Coastguard Worker else {
13220*6777b538SAndroid Build Coastguard Worker ret = NULL;
13221*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
13222*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = NULL;
13223*6777b538SAndroid Build Coastguard Worker }
13224*6777b538SAndroid Build Coastguard Worker if (sax != NULL)
13225*6777b538SAndroid Build Coastguard Worker ctxt->sax = oldsax;
13226*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
13227*6777b538SAndroid Build Coastguard Worker
13228*6777b538SAndroid Build Coastguard Worker return(ret);
13229*6777b538SAndroid Build Coastguard Worker }
13230*6777b538SAndroid Build Coastguard Worker
13231*6777b538SAndroid Build Coastguard Worker /**
13232*6777b538SAndroid Build Coastguard Worker * xmlParseDoc:
13233*6777b538SAndroid Build Coastguard Worker * @cur: a pointer to an array of xmlChar
13234*6777b538SAndroid Build Coastguard Worker *
13235*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlReadDoc.
13236*6777b538SAndroid Build Coastguard Worker *
13237*6777b538SAndroid Build Coastguard Worker * parse an XML in-memory document and build a tree.
13238*6777b538SAndroid Build Coastguard Worker *
13239*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13240*6777b538SAndroid Build Coastguard Worker */
13241*6777b538SAndroid Build Coastguard Worker
13242*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlParseDoc(const xmlChar * cur)13243*6777b538SAndroid Build Coastguard Worker xmlParseDoc(const xmlChar *cur) {
13244*6777b538SAndroid Build Coastguard Worker return(xmlSAXParseDoc(NULL, cur, 0));
13245*6777b538SAndroid Build Coastguard Worker }
13246*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
13247*6777b538SAndroid Build Coastguard Worker
13248*6777b538SAndroid Build Coastguard Worker /************************************************************************
13249*6777b538SAndroid Build Coastguard Worker * *
13250*6777b538SAndroid Build Coastguard Worker * New set (2.6.0) of simpler and more flexible APIs *
13251*6777b538SAndroid Build Coastguard Worker * *
13252*6777b538SAndroid Build Coastguard Worker ************************************************************************/
13253*6777b538SAndroid Build Coastguard Worker
13254*6777b538SAndroid Build Coastguard Worker /**
13255*6777b538SAndroid Build Coastguard Worker * DICT_FREE:
13256*6777b538SAndroid Build Coastguard Worker * @str: a string
13257*6777b538SAndroid Build Coastguard Worker *
13258*6777b538SAndroid Build Coastguard Worker * Free a string if it is not owned by the "dict" dictionary in the
13259*6777b538SAndroid Build Coastguard Worker * current scope
13260*6777b538SAndroid Build Coastguard Worker */
13261*6777b538SAndroid Build Coastguard Worker #define DICT_FREE(str) \
13262*6777b538SAndroid Build Coastguard Worker if ((str) && ((!dict) || \
13263*6777b538SAndroid Build Coastguard Worker (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
13264*6777b538SAndroid Build Coastguard Worker xmlFree((char *)(str));
13265*6777b538SAndroid Build Coastguard Worker
13266*6777b538SAndroid Build Coastguard Worker /**
13267*6777b538SAndroid Build Coastguard Worker * xmlCtxtReset:
13268*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
13269*6777b538SAndroid Build Coastguard Worker *
13270*6777b538SAndroid Build Coastguard Worker * Reset a parser context
13271*6777b538SAndroid Build Coastguard Worker */
13272*6777b538SAndroid Build Coastguard Worker void
xmlCtxtReset(xmlParserCtxtPtr ctxt)13273*6777b538SAndroid Build Coastguard Worker xmlCtxtReset(xmlParserCtxtPtr ctxt)
13274*6777b538SAndroid Build Coastguard Worker {
13275*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13276*6777b538SAndroid Build Coastguard Worker xmlDictPtr dict;
13277*6777b538SAndroid Build Coastguard Worker
13278*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13279*6777b538SAndroid Build Coastguard Worker return;
13280*6777b538SAndroid Build Coastguard Worker
13281*6777b538SAndroid Build Coastguard Worker dict = ctxt->dict;
13282*6777b538SAndroid Build Coastguard Worker
13283*6777b538SAndroid Build Coastguard Worker while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
13284*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(input);
13285*6777b538SAndroid Build Coastguard Worker }
13286*6777b538SAndroid Build Coastguard Worker ctxt->inputNr = 0;
13287*6777b538SAndroid Build Coastguard Worker ctxt->input = NULL;
13288*6777b538SAndroid Build Coastguard Worker
13289*6777b538SAndroid Build Coastguard Worker ctxt->spaceNr = 0;
13290*6777b538SAndroid Build Coastguard Worker if (ctxt->spaceTab != NULL) {
13291*6777b538SAndroid Build Coastguard Worker ctxt->spaceTab[0] = -1;
13292*6777b538SAndroid Build Coastguard Worker ctxt->space = &ctxt->spaceTab[0];
13293*6777b538SAndroid Build Coastguard Worker } else {
13294*6777b538SAndroid Build Coastguard Worker ctxt->space = NULL;
13295*6777b538SAndroid Build Coastguard Worker }
13296*6777b538SAndroid Build Coastguard Worker
13297*6777b538SAndroid Build Coastguard Worker
13298*6777b538SAndroid Build Coastguard Worker ctxt->nodeNr = 0;
13299*6777b538SAndroid Build Coastguard Worker ctxt->node = NULL;
13300*6777b538SAndroid Build Coastguard Worker
13301*6777b538SAndroid Build Coastguard Worker ctxt->nameNr = 0;
13302*6777b538SAndroid Build Coastguard Worker ctxt->name = NULL;
13303*6777b538SAndroid Build Coastguard Worker
13304*6777b538SAndroid Build Coastguard Worker ctxt->nsNr = 0;
13305*6777b538SAndroid Build Coastguard Worker xmlParserNsReset(ctxt->nsdb);
13306*6777b538SAndroid Build Coastguard Worker
13307*6777b538SAndroid Build Coastguard Worker DICT_FREE(ctxt->version);
13308*6777b538SAndroid Build Coastguard Worker ctxt->version = NULL;
13309*6777b538SAndroid Build Coastguard Worker DICT_FREE(ctxt->encoding);
13310*6777b538SAndroid Build Coastguard Worker ctxt->encoding = NULL;
13311*6777b538SAndroid Build Coastguard Worker DICT_FREE(ctxt->extSubURI);
13312*6777b538SAndroid Build Coastguard Worker ctxt->extSubURI = NULL;
13313*6777b538SAndroid Build Coastguard Worker DICT_FREE(ctxt->extSubSystem);
13314*6777b538SAndroid Build Coastguard Worker ctxt->extSubSystem = NULL;
13315*6777b538SAndroid Build Coastguard Worker if (ctxt->myDoc != NULL)
13316*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
13317*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = NULL;
13318*6777b538SAndroid Build Coastguard Worker
13319*6777b538SAndroid Build Coastguard Worker ctxt->standalone = -1;
13320*6777b538SAndroid Build Coastguard Worker ctxt->hasExternalSubset = 0;
13321*6777b538SAndroid Build Coastguard Worker ctxt->hasPErefs = 0;
13322*6777b538SAndroid Build Coastguard Worker ctxt->html = 0;
13323*6777b538SAndroid Build Coastguard Worker ctxt->instate = XML_PARSER_START;
13324*6777b538SAndroid Build Coastguard Worker
13325*6777b538SAndroid Build Coastguard Worker ctxt->wellFormed = 1;
13326*6777b538SAndroid Build Coastguard Worker ctxt->nsWellFormed = 1;
13327*6777b538SAndroid Build Coastguard Worker ctxt->disableSAX = 0;
13328*6777b538SAndroid Build Coastguard Worker ctxt->valid = 1;
13329*6777b538SAndroid Build Coastguard Worker #if 0
13330*6777b538SAndroid Build Coastguard Worker ctxt->vctxt.userData = ctxt;
13331*6777b538SAndroid Build Coastguard Worker ctxt->vctxt.error = xmlParserValidityError;
13332*6777b538SAndroid Build Coastguard Worker ctxt->vctxt.warning = xmlParserValidityWarning;
13333*6777b538SAndroid Build Coastguard Worker #endif
13334*6777b538SAndroid Build Coastguard Worker ctxt->record_info = 0;
13335*6777b538SAndroid Build Coastguard Worker ctxt->checkIndex = 0;
13336*6777b538SAndroid Build Coastguard Worker ctxt->endCheckState = 0;
13337*6777b538SAndroid Build Coastguard Worker ctxt->inSubset = 0;
13338*6777b538SAndroid Build Coastguard Worker ctxt->errNo = XML_ERR_OK;
13339*6777b538SAndroid Build Coastguard Worker ctxt->depth = 0;
13340*6777b538SAndroid Build Coastguard Worker ctxt->catalogs = NULL;
13341*6777b538SAndroid Build Coastguard Worker ctxt->sizeentities = 0;
13342*6777b538SAndroid Build Coastguard Worker ctxt->sizeentcopy = 0;
13343*6777b538SAndroid Build Coastguard Worker xmlInitNodeInfoSeq(&ctxt->node_seq);
13344*6777b538SAndroid Build Coastguard Worker
13345*6777b538SAndroid Build Coastguard Worker if (ctxt->attsDefault != NULL) {
13346*6777b538SAndroid Build Coastguard Worker xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator);
13347*6777b538SAndroid Build Coastguard Worker ctxt->attsDefault = NULL;
13348*6777b538SAndroid Build Coastguard Worker }
13349*6777b538SAndroid Build Coastguard Worker if (ctxt->attsSpecial != NULL) {
13350*6777b538SAndroid Build Coastguard Worker xmlHashFree(ctxt->attsSpecial, NULL);
13351*6777b538SAndroid Build Coastguard Worker ctxt->attsSpecial = NULL;
13352*6777b538SAndroid Build Coastguard Worker }
13353*6777b538SAndroid Build Coastguard Worker
13354*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
13355*6777b538SAndroid Build Coastguard Worker if (ctxt->catalogs != NULL)
13356*6777b538SAndroid Build Coastguard Worker xmlCatalogFreeLocal(ctxt->catalogs);
13357*6777b538SAndroid Build Coastguard Worker #endif
13358*6777b538SAndroid Build Coastguard Worker ctxt->nbErrors = 0;
13359*6777b538SAndroid Build Coastguard Worker ctxt->nbWarnings = 0;
13360*6777b538SAndroid Build Coastguard Worker if (ctxt->lastError.code != XML_ERR_OK)
13361*6777b538SAndroid Build Coastguard Worker xmlResetError(&ctxt->lastError);
13362*6777b538SAndroid Build Coastguard Worker }
13363*6777b538SAndroid Build Coastguard Worker
13364*6777b538SAndroid Build Coastguard Worker /**
13365*6777b538SAndroid Build Coastguard Worker * xmlCtxtResetPush:
13366*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
13367*6777b538SAndroid Build Coastguard Worker * @chunk: a pointer to an array of chars
13368*6777b538SAndroid Build Coastguard Worker * @size: number of chars in the array
13369*6777b538SAndroid Build Coastguard Worker * @filename: an optional file name or URI
13370*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding, or NULL
13371*6777b538SAndroid Build Coastguard Worker *
13372*6777b538SAndroid Build Coastguard Worker * Reset a push parser context
13373*6777b538SAndroid Build Coastguard Worker *
13374*6777b538SAndroid Build Coastguard Worker * Returns 0 in case of success and 1 in case of error
13375*6777b538SAndroid Build Coastguard Worker */
13376*6777b538SAndroid Build Coastguard Worker int
xmlCtxtResetPush(xmlParserCtxtPtr ctxt,const char * chunk,int size,const char * filename,const char * encoding)13377*6777b538SAndroid Build Coastguard Worker xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
13378*6777b538SAndroid Build Coastguard Worker int size, const char *filename, const char *encoding)
13379*6777b538SAndroid Build Coastguard Worker {
13380*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13381*6777b538SAndroid Build Coastguard Worker
13382*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13383*6777b538SAndroid Build Coastguard Worker return(1);
13384*6777b538SAndroid Build Coastguard Worker
13385*6777b538SAndroid Build Coastguard Worker xmlCtxtReset(ctxt);
13386*6777b538SAndroid Build Coastguard Worker
13387*6777b538SAndroid Build Coastguard Worker input = xmlNewInputPush(ctxt, filename, chunk, size, encoding);
13388*6777b538SAndroid Build Coastguard Worker if (input == NULL)
13389*6777b538SAndroid Build Coastguard Worker return(1);
13390*6777b538SAndroid Build Coastguard Worker inputPush(ctxt, input);
13391*6777b538SAndroid Build Coastguard Worker
13392*6777b538SAndroid Build Coastguard Worker return(0);
13393*6777b538SAndroid Build Coastguard Worker }
13394*6777b538SAndroid Build Coastguard Worker
13395*6777b538SAndroid Build Coastguard Worker static int
xmlCtxtSetOptionsInternal(xmlParserCtxtPtr ctxt,int options,int keepMask)13396*6777b538SAndroid Build Coastguard Worker xmlCtxtSetOptionsInternal(xmlParserCtxtPtr ctxt, int options, int keepMask)
13397*6777b538SAndroid Build Coastguard Worker {
13398*6777b538SAndroid Build Coastguard Worker int allMask;
13399*6777b538SAndroid Build Coastguard Worker
13400*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13401*6777b538SAndroid Build Coastguard Worker return(-1);
13402*6777b538SAndroid Build Coastguard Worker
13403*6777b538SAndroid Build Coastguard Worker /*
13404*6777b538SAndroid Build Coastguard Worker * XInclude options aren't handled by the parser.
13405*6777b538SAndroid Build Coastguard Worker *
13406*6777b538SAndroid Build Coastguard Worker * XML_PARSE_XINCLUDE
13407*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NOXINCNODE
13408*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NOBASEFIX
13409*6777b538SAndroid Build Coastguard Worker */
13410*6777b538SAndroid Build Coastguard Worker allMask = XML_PARSE_RECOVER |
13411*6777b538SAndroid Build Coastguard Worker XML_PARSE_NOENT |
13412*6777b538SAndroid Build Coastguard Worker XML_PARSE_DTDLOAD |
13413*6777b538SAndroid Build Coastguard Worker XML_PARSE_DTDATTR |
13414*6777b538SAndroid Build Coastguard Worker XML_PARSE_DTDVALID |
13415*6777b538SAndroid Build Coastguard Worker XML_PARSE_NOERROR |
13416*6777b538SAndroid Build Coastguard Worker XML_PARSE_NOWARNING |
13417*6777b538SAndroid Build Coastguard Worker XML_PARSE_PEDANTIC |
13418*6777b538SAndroid Build Coastguard Worker XML_PARSE_NOBLANKS |
13419*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
13420*6777b538SAndroid Build Coastguard Worker XML_PARSE_SAX1 |
13421*6777b538SAndroid Build Coastguard Worker #endif
13422*6777b538SAndroid Build Coastguard Worker XML_PARSE_NONET |
13423*6777b538SAndroid Build Coastguard Worker XML_PARSE_NODICT |
13424*6777b538SAndroid Build Coastguard Worker XML_PARSE_NSCLEAN |
13425*6777b538SAndroid Build Coastguard Worker XML_PARSE_NOCDATA |
13426*6777b538SAndroid Build Coastguard Worker XML_PARSE_COMPACT |
13427*6777b538SAndroid Build Coastguard Worker XML_PARSE_OLD10 |
13428*6777b538SAndroid Build Coastguard Worker XML_PARSE_HUGE |
13429*6777b538SAndroid Build Coastguard Worker XML_PARSE_OLDSAX |
13430*6777b538SAndroid Build Coastguard Worker XML_PARSE_IGNORE_ENC |
13431*6777b538SAndroid Build Coastguard Worker XML_PARSE_BIG_LINES |
13432*6777b538SAndroid Build Coastguard Worker XML_PARSE_NO_XXE;
13433*6777b538SAndroid Build Coastguard Worker
13434*6777b538SAndroid Build Coastguard Worker ctxt->options = (ctxt->options & keepMask) | (options & allMask);
13435*6777b538SAndroid Build Coastguard Worker
13436*6777b538SAndroid Build Coastguard Worker /*
13437*6777b538SAndroid Build Coastguard Worker * For some options, struct members are historically the source
13438*6777b538SAndroid Build Coastguard Worker * of truth. The values are initalized from global variables and
13439*6777b538SAndroid Build Coastguard Worker * old code could also modify them directly. Several older API
13440*6777b538SAndroid Build Coastguard Worker * functions that don't take an options argument rely on these
13441*6777b538SAndroid Build Coastguard Worker * deprecated mechanisms.
13442*6777b538SAndroid Build Coastguard Worker *
13443*6777b538SAndroid Build Coastguard Worker * Once public access to struct members and the globals are
13444*6777b538SAndroid Build Coastguard Worker * disabled, we can use the options bitmask as source of
13445*6777b538SAndroid Build Coastguard Worker * truth, making all these struct members obsolete.
13446*6777b538SAndroid Build Coastguard Worker *
13447*6777b538SAndroid Build Coastguard Worker * The XML_DETECT_IDS flags is misnamed. It simply enables
13448*6777b538SAndroid Build Coastguard Worker * loading of the external subset.
13449*6777b538SAndroid Build Coastguard Worker */
13450*6777b538SAndroid Build Coastguard Worker ctxt->recovery = (options & XML_PARSE_RECOVER) ? 1 : 0;
13451*6777b538SAndroid Build Coastguard Worker ctxt->replaceEntities = (options & XML_PARSE_NOENT) ? 1 : 0;
13452*6777b538SAndroid Build Coastguard Worker ctxt->loadsubset = (options & XML_PARSE_DTDLOAD) ? XML_DETECT_IDS : 0;
13453*6777b538SAndroid Build Coastguard Worker ctxt->loadsubset |= (options & XML_PARSE_DTDATTR) ? XML_COMPLETE_ATTRS : 0;
13454*6777b538SAndroid Build Coastguard Worker ctxt->validate = (options & XML_PARSE_DTDVALID) ? 1 : 0;
13455*6777b538SAndroid Build Coastguard Worker ctxt->pedantic = (options & XML_PARSE_PEDANTIC) ? 1 : 0;
13456*6777b538SAndroid Build Coastguard Worker ctxt->keepBlanks = (options & XML_PARSE_NOBLANKS) ? 0 : 1;
13457*6777b538SAndroid Build Coastguard Worker ctxt->dictNames = (options & XML_PARSE_NODICT) ? 0 : 1;
13458*6777b538SAndroid Build Coastguard Worker
13459*6777b538SAndroid Build Coastguard Worker /*
13460*6777b538SAndroid Build Coastguard Worker * Changing SAX callbacks is a bad idea. This should be fixed.
13461*6777b538SAndroid Build Coastguard Worker */
13462*6777b538SAndroid Build Coastguard Worker if (options & XML_PARSE_NOBLANKS) {
13463*6777b538SAndroid Build Coastguard Worker ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
13464*6777b538SAndroid Build Coastguard Worker }
13465*6777b538SAndroid Build Coastguard Worker if (options & XML_PARSE_NOCDATA) {
13466*6777b538SAndroid Build Coastguard Worker ctxt->sax->cdataBlock = NULL;
13467*6777b538SAndroid Build Coastguard Worker }
13468*6777b538SAndroid Build Coastguard Worker if (options & XML_PARSE_HUGE) {
13469*6777b538SAndroid Build Coastguard Worker if (ctxt->dict != NULL)
13470*6777b538SAndroid Build Coastguard Worker xmlDictSetLimit(ctxt->dict, 0);
13471*6777b538SAndroid Build Coastguard Worker }
13472*6777b538SAndroid Build Coastguard Worker
13473*6777b538SAndroid Build Coastguard Worker ctxt->linenumbers = 1;
13474*6777b538SAndroid Build Coastguard Worker
13475*6777b538SAndroid Build Coastguard Worker return(options & ~allMask);
13476*6777b538SAndroid Build Coastguard Worker }
13477*6777b538SAndroid Build Coastguard Worker
13478*6777b538SAndroid Build Coastguard Worker /**
13479*6777b538SAndroid Build Coastguard Worker * xmlCtxtSetOptions:
13480*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
13481*6777b538SAndroid Build Coastguard Worker * @options: a bitmask of xmlParserOption values
13482*6777b538SAndroid Build Coastguard Worker *
13483*6777b538SAndroid Build Coastguard Worker * Applies the options to the parser context. Unset options are
13484*6777b538SAndroid Build Coastguard Worker * cleared.
13485*6777b538SAndroid Build Coastguard Worker *
13486*6777b538SAndroid Build Coastguard Worker * Available since 2.13.0. With older versions, you can use
13487*6777b538SAndroid Build Coastguard Worker * xmlCtxtUseOptions.
13488*6777b538SAndroid Build Coastguard Worker *
13489*6777b538SAndroid Build Coastguard Worker * XML_PARSE_RECOVER
13490*6777b538SAndroid Build Coastguard Worker *
13491*6777b538SAndroid Build Coastguard Worker * Enable "recovery" mode which allows non-wellformed documents.
13492*6777b538SAndroid Build Coastguard Worker * How this mode behaves exactly is unspecified and may change
13493*6777b538SAndroid Build Coastguard Worker * without further notice. Use of this feature is DISCOURAGED.
13494*6777b538SAndroid Build Coastguard Worker *
13495*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NOENT
13496*6777b538SAndroid Build Coastguard Worker *
13497*6777b538SAndroid Build Coastguard Worker * Despite the confusing name, this option enables substitution
13498*6777b538SAndroid Build Coastguard Worker * of entities. The resulting tree won't contain any entity
13499*6777b538SAndroid Build Coastguard Worker * reference nodes.
13500*6777b538SAndroid Build Coastguard Worker *
13501*6777b538SAndroid Build Coastguard Worker * This option also enables loading of external entities (both
13502*6777b538SAndroid Build Coastguard Worker * general and parameter entities) which is dangerous. If you
13503*6777b538SAndroid Build Coastguard Worker * process untrusted data, it's recommended to set the
13504*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NO_XXE option to disable loading of external
13505*6777b538SAndroid Build Coastguard Worker * entities.
13506*6777b538SAndroid Build Coastguard Worker *
13507*6777b538SAndroid Build Coastguard Worker * XML_PARSE_DTDLOAD
13508*6777b538SAndroid Build Coastguard Worker *
13509*6777b538SAndroid Build Coastguard Worker * Enables loading of an external DTD and the loading and
13510*6777b538SAndroid Build Coastguard Worker * substitution of external parameter entities. Has no effect
13511*6777b538SAndroid Build Coastguard Worker * if XML_PARSE_NO_XXE is set.
13512*6777b538SAndroid Build Coastguard Worker *
13513*6777b538SAndroid Build Coastguard Worker * XML_PARSE_DTDATTR
13514*6777b538SAndroid Build Coastguard Worker *
13515*6777b538SAndroid Build Coastguard Worker * Adds default attributes from the DTD to the result document.
13516*6777b538SAndroid Build Coastguard Worker *
13517*6777b538SAndroid Build Coastguard Worker * Implies XML_PARSE_DTDLOAD, but loading of external content
13518*6777b538SAndroid Build Coastguard Worker * can be disabled with XML_PARSE_NO_XXE.
13519*6777b538SAndroid Build Coastguard Worker *
13520*6777b538SAndroid Build Coastguard Worker * XML_PARSE_DTDVALID
13521*6777b538SAndroid Build Coastguard Worker *
13522*6777b538SAndroid Build Coastguard Worker * This option enables DTD validation which requires to load
13523*6777b538SAndroid Build Coastguard Worker * external DTDs and external entities (both general and
13524*6777b538SAndroid Build Coastguard Worker * parameter entities) unless XML_PARSE_NO_XXE was set.
13525*6777b538SAndroid Build Coastguard Worker *
13526*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NO_XXE
13527*6777b538SAndroid Build Coastguard Worker *
13528*6777b538SAndroid Build Coastguard Worker * Disables loading of external DTDs or entities.
13529*6777b538SAndroid Build Coastguard Worker *
13530*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NOERROR
13531*6777b538SAndroid Build Coastguard Worker *
13532*6777b538SAndroid Build Coastguard Worker * Disable error and warning reports to the error handlers.
13533*6777b538SAndroid Build Coastguard Worker * Errors are still accessible with xmlCtxtGetLastError.
13534*6777b538SAndroid Build Coastguard Worker *
13535*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NOWARNING
13536*6777b538SAndroid Build Coastguard Worker *
13537*6777b538SAndroid Build Coastguard Worker * Disable warning reports.
13538*6777b538SAndroid Build Coastguard Worker *
13539*6777b538SAndroid Build Coastguard Worker * XML_PARSE_PEDANTIC
13540*6777b538SAndroid Build Coastguard Worker *
13541*6777b538SAndroid Build Coastguard Worker * Enable some pedantic warnings.
13542*6777b538SAndroid Build Coastguard Worker *
13543*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NOBLANKS
13544*6777b538SAndroid Build Coastguard Worker *
13545*6777b538SAndroid Build Coastguard Worker * Remove some text nodes containing only whitespace from the
13546*6777b538SAndroid Build Coastguard Worker * result document. Which nodes are removed depends on DTD
13547*6777b538SAndroid Build Coastguard Worker * element declarations or a conservative heuristic. The
13548*6777b538SAndroid Build Coastguard Worker * reindenting feature of the serialization code relies on this
13549*6777b538SAndroid Build Coastguard Worker * option to be set when parsing. Use of this option is
13550*6777b538SAndroid Build Coastguard Worker * DISCOURAGED.
13551*6777b538SAndroid Build Coastguard Worker *
13552*6777b538SAndroid Build Coastguard Worker * XML_PARSE_SAX1
13553*6777b538SAndroid Build Coastguard Worker *
13554*6777b538SAndroid Build Coastguard Worker * Always invoke the deprecated SAX1 startElement and endElement
13555*6777b538SAndroid Build Coastguard Worker * handlers. This option is DEPRECATED.
13556*6777b538SAndroid Build Coastguard Worker *
13557*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NONET
13558*6777b538SAndroid Build Coastguard Worker *
13559*6777b538SAndroid Build Coastguard Worker * Disable network access with the builtin HTTP and FTP clients.
13560*6777b538SAndroid Build Coastguard Worker *
13561*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NODICT
13562*6777b538SAndroid Build Coastguard Worker *
13563*6777b538SAndroid Build Coastguard Worker * Create a document without interned strings, making all
13564*6777b538SAndroid Build Coastguard Worker * strings separate memory allocations.
13565*6777b538SAndroid Build Coastguard Worker *
13566*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NSCLEAN
13567*6777b538SAndroid Build Coastguard Worker *
13568*6777b538SAndroid Build Coastguard Worker * Remove redundant namespace declarations from the result
13569*6777b538SAndroid Build Coastguard Worker * document.
13570*6777b538SAndroid Build Coastguard Worker *
13571*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NOCDATA
13572*6777b538SAndroid Build Coastguard Worker *
13573*6777b538SAndroid Build Coastguard Worker * Output normal text nodes instead of CDATA nodes.
13574*6777b538SAndroid Build Coastguard Worker *
13575*6777b538SAndroid Build Coastguard Worker * XML_PARSE_COMPACT
13576*6777b538SAndroid Build Coastguard Worker *
13577*6777b538SAndroid Build Coastguard Worker * Store small strings directly in the node struct to save
13578*6777b538SAndroid Build Coastguard Worker * memory.
13579*6777b538SAndroid Build Coastguard Worker *
13580*6777b538SAndroid Build Coastguard Worker * XML_PARSE_OLD10
13581*6777b538SAndroid Build Coastguard Worker *
13582*6777b538SAndroid Build Coastguard Worker * Use old Name productions from before XML 1.0 Fifth Edition.
13583*6777b538SAndroid Build Coastguard Worker * This options is DEPRECATED.
13584*6777b538SAndroid Build Coastguard Worker *
13585*6777b538SAndroid Build Coastguard Worker * XML_PARSE_HUGE
13586*6777b538SAndroid Build Coastguard Worker *
13587*6777b538SAndroid Build Coastguard Worker * Relax some internal limits.
13588*6777b538SAndroid Build Coastguard Worker *
13589*6777b538SAndroid Build Coastguard Worker * Maximum size of text nodes, tags, comments, processing instructions,
13590*6777b538SAndroid Build Coastguard Worker * CDATA sections, entity values
13591*6777b538SAndroid Build Coastguard Worker *
13592*6777b538SAndroid Build Coastguard Worker * normal: 10M
13593*6777b538SAndroid Build Coastguard Worker * huge: 1B
13594*6777b538SAndroid Build Coastguard Worker *
13595*6777b538SAndroid Build Coastguard Worker * Maximum size of names, system literals, pubid literals
13596*6777b538SAndroid Build Coastguard Worker *
13597*6777b538SAndroid Build Coastguard Worker * normal: 50K
13598*6777b538SAndroid Build Coastguard Worker * huge: 10M
13599*6777b538SAndroid Build Coastguard Worker *
13600*6777b538SAndroid Build Coastguard Worker * Maximum nesting depth of elements
13601*6777b538SAndroid Build Coastguard Worker *
13602*6777b538SAndroid Build Coastguard Worker * normal: 256
13603*6777b538SAndroid Build Coastguard Worker * huge: 2048
13604*6777b538SAndroid Build Coastguard Worker *
13605*6777b538SAndroid Build Coastguard Worker * Maximum nesting depth of entities
13606*6777b538SAndroid Build Coastguard Worker *
13607*6777b538SAndroid Build Coastguard Worker * normal: 20
13608*6777b538SAndroid Build Coastguard Worker * huge: 40
13609*6777b538SAndroid Build Coastguard Worker *
13610*6777b538SAndroid Build Coastguard Worker * XML_PARSE_OLDSAX
13611*6777b538SAndroid Build Coastguard Worker *
13612*6777b538SAndroid Build Coastguard Worker * Enable an unspecified legacy mode for SAX parsers. This
13613*6777b538SAndroid Build Coastguard Worker * option is DEPRECATED.
13614*6777b538SAndroid Build Coastguard Worker *
13615*6777b538SAndroid Build Coastguard Worker * XML_PARSE_IGNORE_ENC
13616*6777b538SAndroid Build Coastguard Worker *
13617*6777b538SAndroid Build Coastguard Worker * Ignore the encoding in the XML declaration. This option is
13618*6777b538SAndroid Build Coastguard Worker * mostly unneeded these days. The only effect is to enforce
13619*6777b538SAndroid Build Coastguard Worker * UTF-8 decoding of ASCII-like data.
13620*6777b538SAndroid Build Coastguard Worker *
13621*6777b538SAndroid Build Coastguard Worker * XML_PARSE_BIG_LINES
13622*6777b538SAndroid Build Coastguard Worker *
13623*6777b538SAndroid Build Coastguard Worker * Enable reporting of line numbers larger than 65535.
13624*6777b538SAndroid Build Coastguard Worker *
13625*6777b538SAndroid Build Coastguard Worker * Returns 0 in case of success, the set of unknown or unimplemented options
13626*6777b538SAndroid Build Coastguard Worker * in case of error.
13627*6777b538SAndroid Build Coastguard Worker */
13628*6777b538SAndroid Build Coastguard Worker int
xmlCtxtSetOptions(xmlParserCtxtPtr ctxt,int options)13629*6777b538SAndroid Build Coastguard Worker xmlCtxtSetOptions(xmlParserCtxtPtr ctxt, int options)
13630*6777b538SAndroid Build Coastguard Worker {
13631*6777b538SAndroid Build Coastguard Worker return(xmlCtxtSetOptionsInternal(ctxt, options, 0));
13632*6777b538SAndroid Build Coastguard Worker }
13633*6777b538SAndroid Build Coastguard Worker
13634*6777b538SAndroid Build Coastguard Worker /**
13635*6777b538SAndroid Build Coastguard Worker * xmlCtxtUseOptions:
13636*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
13637*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
13638*6777b538SAndroid Build Coastguard Worker *
13639*6777b538SAndroid Build Coastguard Worker * DEPRECATED: Use xmlCtxtSetOptions.
13640*6777b538SAndroid Build Coastguard Worker *
13641*6777b538SAndroid Build Coastguard Worker * Applies the options to the parser context. The following options
13642*6777b538SAndroid Build Coastguard Worker * are never cleared and can only be enabled:
13643*6777b538SAndroid Build Coastguard Worker *
13644*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NOERROR
13645*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NOWARNING
13646*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NONET
13647*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NSCLEAN
13648*6777b538SAndroid Build Coastguard Worker * XML_PARSE_NOCDATA
13649*6777b538SAndroid Build Coastguard Worker * XML_PARSE_COMPACT
13650*6777b538SAndroid Build Coastguard Worker * XML_PARSE_OLD10
13651*6777b538SAndroid Build Coastguard Worker * XML_PARSE_HUGE
13652*6777b538SAndroid Build Coastguard Worker * XML_PARSE_OLDSAX
13653*6777b538SAndroid Build Coastguard Worker * XML_PARSE_IGNORE_ENC
13654*6777b538SAndroid Build Coastguard Worker * XML_PARSE_BIG_LINES
13655*6777b538SAndroid Build Coastguard Worker *
13656*6777b538SAndroid Build Coastguard Worker * Returns 0 in case of success, the set of unknown or unimplemented options
13657*6777b538SAndroid Build Coastguard Worker * in case of error.
13658*6777b538SAndroid Build Coastguard Worker */
13659*6777b538SAndroid Build Coastguard Worker int
xmlCtxtUseOptions(xmlParserCtxtPtr ctxt,int options)13660*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
13661*6777b538SAndroid Build Coastguard Worker {
13662*6777b538SAndroid Build Coastguard Worker int keepMask;
13663*6777b538SAndroid Build Coastguard Worker
13664*6777b538SAndroid Build Coastguard Worker /*
13665*6777b538SAndroid Build Coastguard Worker * For historic reasons, some options can only be enabled.
13666*6777b538SAndroid Build Coastguard Worker */
13667*6777b538SAndroid Build Coastguard Worker keepMask = XML_PARSE_NOERROR |
13668*6777b538SAndroid Build Coastguard Worker XML_PARSE_NOWARNING |
13669*6777b538SAndroid Build Coastguard Worker XML_PARSE_NONET |
13670*6777b538SAndroid Build Coastguard Worker XML_PARSE_NSCLEAN |
13671*6777b538SAndroid Build Coastguard Worker XML_PARSE_NOCDATA |
13672*6777b538SAndroid Build Coastguard Worker XML_PARSE_COMPACT |
13673*6777b538SAndroid Build Coastguard Worker XML_PARSE_OLD10 |
13674*6777b538SAndroid Build Coastguard Worker XML_PARSE_HUGE |
13675*6777b538SAndroid Build Coastguard Worker XML_PARSE_OLDSAX |
13676*6777b538SAndroid Build Coastguard Worker XML_PARSE_IGNORE_ENC |
13677*6777b538SAndroid Build Coastguard Worker XML_PARSE_BIG_LINES;
13678*6777b538SAndroid Build Coastguard Worker
13679*6777b538SAndroid Build Coastguard Worker return(xmlCtxtSetOptionsInternal(ctxt, options, keepMask));
13680*6777b538SAndroid Build Coastguard Worker }
13681*6777b538SAndroid Build Coastguard Worker
13682*6777b538SAndroid Build Coastguard Worker /**
13683*6777b538SAndroid Build Coastguard Worker * xmlCtxtSetMaxAmplification:
13684*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
13685*6777b538SAndroid Build Coastguard Worker * @maxAmpl: maximum amplification factor
13686*6777b538SAndroid Build Coastguard Worker *
13687*6777b538SAndroid Build Coastguard Worker * To protect against exponential entity expansion ("billion laughs"), the
13688*6777b538SAndroid Build Coastguard Worker * size of serialized output is (roughly) limited to the input size
13689*6777b538SAndroid Build Coastguard Worker * multiplied by this factor. The default value is 5.
13690*6777b538SAndroid Build Coastguard Worker *
13691*6777b538SAndroid Build Coastguard Worker * When working with documents making heavy use of entity expansion, it can
13692*6777b538SAndroid Build Coastguard Worker * be necessary to increase the value. For security reasons, this should only
13693*6777b538SAndroid Build Coastguard Worker * be considered when processing trusted input.
13694*6777b538SAndroid Build Coastguard Worker */
13695*6777b538SAndroid Build Coastguard Worker void
xmlCtxtSetMaxAmplification(xmlParserCtxtPtr ctxt,unsigned maxAmpl)13696*6777b538SAndroid Build Coastguard Worker xmlCtxtSetMaxAmplification(xmlParserCtxtPtr ctxt, unsigned maxAmpl)
13697*6777b538SAndroid Build Coastguard Worker {
13698*6777b538SAndroid Build Coastguard Worker ctxt->maxAmpl = maxAmpl;
13699*6777b538SAndroid Build Coastguard Worker }
13700*6777b538SAndroid Build Coastguard Worker
13701*6777b538SAndroid Build Coastguard Worker /**
13702*6777b538SAndroid Build Coastguard Worker * xmlCtxtParseDocument:
13703*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
13704*6777b538SAndroid Build Coastguard Worker * @input: parser input
13705*6777b538SAndroid Build Coastguard Worker *
13706*6777b538SAndroid Build Coastguard Worker * Parse an XML document and return the resulting document tree.
13707*6777b538SAndroid Build Coastguard Worker * Takes ownership of the input object.
13708*6777b538SAndroid Build Coastguard Worker *
13709*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree or NULL
13710*6777b538SAndroid Build Coastguard Worker */
13711*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlCtxtParseDocument(xmlParserCtxtPtr ctxt,xmlParserInputPtr input)13712*6777b538SAndroid Build Coastguard Worker xmlCtxtParseDocument(xmlParserCtxtPtr ctxt, xmlParserInputPtr input)
13713*6777b538SAndroid Build Coastguard Worker {
13714*6777b538SAndroid Build Coastguard Worker xmlDocPtr ret = NULL;
13715*6777b538SAndroid Build Coastguard Worker
13716*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (input == NULL))
13717*6777b538SAndroid Build Coastguard Worker return(NULL);
13718*6777b538SAndroid Build Coastguard Worker
13719*6777b538SAndroid Build Coastguard Worker /* assert(ctxt->inputNr == 0); */
13720*6777b538SAndroid Build Coastguard Worker while (ctxt->inputNr > 0)
13721*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(inputPop(ctxt));
13722*6777b538SAndroid Build Coastguard Worker
13723*6777b538SAndroid Build Coastguard Worker if (inputPush(ctxt, input) < 0) {
13724*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(input);
13725*6777b538SAndroid Build Coastguard Worker return(NULL);
13726*6777b538SAndroid Build Coastguard Worker }
13727*6777b538SAndroid Build Coastguard Worker
13728*6777b538SAndroid Build Coastguard Worker xmlParseDocument(ctxt);
13729*6777b538SAndroid Build Coastguard Worker
13730*6777b538SAndroid Build Coastguard Worker if ((ctxt->wellFormed) ||
13731*6777b538SAndroid Build Coastguard Worker ((ctxt->recovery) && (ctxt->errNo != XML_ERR_NO_MEMORY))) {
13732*6777b538SAndroid Build Coastguard Worker ret = ctxt->myDoc;
13733*6777b538SAndroid Build Coastguard Worker } else {
13734*6777b538SAndroid Build Coastguard Worker if (ctxt->errNo == XML_ERR_OK)
13735*6777b538SAndroid Build Coastguard Worker xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, "unknown error\n");
13736*6777b538SAndroid Build Coastguard Worker
13737*6777b538SAndroid Build Coastguard Worker ret = NULL;
13738*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
13739*6777b538SAndroid Build Coastguard Worker }
13740*6777b538SAndroid Build Coastguard Worker ctxt->myDoc = NULL;
13741*6777b538SAndroid Build Coastguard Worker
13742*6777b538SAndroid Build Coastguard Worker /* assert(ctxt->inputNr == 1); */
13743*6777b538SAndroid Build Coastguard Worker while (ctxt->inputNr > 0)
13744*6777b538SAndroid Build Coastguard Worker xmlFreeInputStream(inputPop(ctxt));
13745*6777b538SAndroid Build Coastguard Worker
13746*6777b538SAndroid Build Coastguard Worker return(ret);
13747*6777b538SAndroid Build Coastguard Worker }
13748*6777b538SAndroid Build Coastguard Worker
13749*6777b538SAndroid Build Coastguard Worker /**
13750*6777b538SAndroid Build Coastguard Worker * xmlReadDoc:
13751*6777b538SAndroid Build Coastguard Worker * @cur: a pointer to a zero terminated string
13752*6777b538SAndroid Build Coastguard Worker * @URL: base URL (optional)
13753*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding (optional)
13754*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
13755*6777b538SAndroid Build Coastguard Worker *
13756*6777b538SAndroid Build Coastguard Worker * Convenience function to parse an XML document from a
13757*6777b538SAndroid Build Coastguard Worker * zero-terminated string.
13758*6777b538SAndroid Build Coastguard Worker *
13759*6777b538SAndroid Build Coastguard Worker * See xmlCtxtReadDoc for details.
13760*6777b538SAndroid Build Coastguard Worker *
13761*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13762*6777b538SAndroid Build Coastguard Worker */
13763*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlReadDoc(const xmlChar * cur,const char * URL,const char * encoding,int options)13764*6777b538SAndroid Build Coastguard Worker xmlReadDoc(const xmlChar *cur, const char *URL, const char *encoding,
13765*6777b538SAndroid Build Coastguard Worker int options)
13766*6777b538SAndroid Build Coastguard Worker {
13767*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
13768*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13769*6777b538SAndroid Build Coastguard Worker xmlDocPtr doc;
13770*6777b538SAndroid Build Coastguard Worker
13771*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
13772*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13773*6777b538SAndroid Build Coastguard Worker return(NULL);
13774*6777b538SAndroid Build Coastguard Worker
13775*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
13776*6777b538SAndroid Build Coastguard Worker
13777*6777b538SAndroid Build Coastguard Worker input = xmlNewInputString(ctxt, URL, (const char *) cur, encoding,
13778*6777b538SAndroid Build Coastguard Worker XML_INPUT_BUF_STATIC);
13779*6777b538SAndroid Build Coastguard Worker
13780*6777b538SAndroid Build Coastguard Worker doc = xmlCtxtParseDocument(ctxt, input);
13781*6777b538SAndroid Build Coastguard Worker
13782*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
13783*6777b538SAndroid Build Coastguard Worker return(doc);
13784*6777b538SAndroid Build Coastguard Worker }
13785*6777b538SAndroid Build Coastguard Worker
13786*6777b538SAndroid Build Coastguard Worker /**
13787*6777b538SAndroid Build Coastguard Worker * xmlReadFile:
13788*6777b538SAndroid Build Coastguard Worker * @filename: a file or URL
13789*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding (optional)
13790*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
13791*6777b538SAndroid Build Coastguard Worker *
13792*6777b538SAndroid Build Coastguard Worker * Convenience function to parse an XML file from the filesystem,
13793*6777b538SAndroid Build Coastguard Worker * the network or a global user-define resource loader.
13794*6777b538SAndroid Build Coastguard Worker *
13795*6777b538SAndroid Build Coastguard Worker * See xmlCtxtReadFile for details.
13796*6777b538SAndroid Build Coastguard Worker *
13797*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13798*6777b538SAndroid Build Coastguard Worker */
13799*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlReadFile(const char * filename,const char * encoding,int options)13800*6777b538SAndroid Build Coastguard Worker xmlReadFile(const char *filename, const char *encoding, int options)
13801*6777b538SAndroid Build Coastguard Worker {
13802*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
13803*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13804*6777b538SAndroid Build Coastguard Worker xmlDocPtr doc;
13805*6777b538SAndroid Build Coastguard Worker
13806*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
13807*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13808*6777b538SAndroid Build Coastguard Worker return(NULL);
13809*6777b538SAndroid Build Coastguard Worker
13810*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
13811*6777b538SAndroid Build Coastguard Worker
13812*6777b538SAndroid Build Coastguard Worker input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0);
13813*6777b538SAndroid Build Coastguard Worker
13814*6777b538SAndroid Build Coastguard Worker doc = xmlCtxtParseDocument(ctxt, input);
13815*6777b538SAndroid Build Coastguard Worker
13816*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
13817*6777b538SAndroid Build Coastguard Worker return(doc);
13818*6777b538SAndroid Build Coastguard Worker }
13819*6777b538SAndroid Build Coastguard Worker
13820*6777b538SAndroid Build Coastguard Worker /**
13821*6777b538SAndroid Build Coastguard Worker * xmlReadMemory:
13822*6777b538SAndroid Build Coastguard Worker * @buffer: a pointer to a char array
13823*6777b538SAndroid Build Coastguard Worker * @size: the size of the array
13824*6777b538SAndroid Build Coastguard Worker * @url: base URL (optional)
13825*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding (optional)
13826*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
13827*6777b538SAndroid Build Coastguard Worker *
13828*6777b538SAndroid Build Coastguard Worker * Parse an XML in-memory document and build a tree. The input buffer must
13829*6777b538SAndroid Build Coastguard Worker * not contain a terminating null byte.
13830*6777b538SAndroid Build Coastguard Worker *
13831*6777b538SAndroid Build Coastguard Worker * See xmlCtxtReadMemory for details.
13832*6777b538SAndroid Build Coastguard Worker *
13833*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13834*6777b538SAndroid Build Coastguard Worker */
13835*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlReadMemory(const char * buffer,int size,const char * url,const char * encoding,int options)13836*6777b538SAndroid Build Coastguard Worker xmlReadMemory(const char *buffer, int size, const char *url,
13837*6777b538SAndroid Build Coastguard Worker const char *encoding, int options)
13838*6777b538SAndroid Build Coastguard Worker {
13839*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
13840*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13841*6777b538SAndroid Build Coastguard Worker xmlDocPtr doc;
13842*6777b538SAndroid Build Coastguard Worker
13843*6777b538SAndroid Build Coastguard Worker if (size < 0)
13844*6777b538SAndroid Build Coastguard Worker return(NULL);
13845*6777b538SAndroid Build Coastguard Worker
13846*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
13847*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13848*6777b538SAndroid Build Coastguard Worker return(NULL);
13849*6777b538SAndroid Build Coastguard Worker
13850*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
13851*6777b538SAndroid Build Coastguard Worker
13852*6777b538SAndroid Build Coastguard Worker input = xmlNewInputMemory(ctxt, url, buffer, size, encoding,
13853*6777b538SAndroid Build Coastguard Worker XML_INPUT_BUF_STATIC);
13854*6777b538SAndroid Build Coastguard Worker
13855*6777b538SAndroid Build Coastguard Worker doc = xmlCtxtParseDocument(ctxt, input);
13856*6777b538SAndroid Build Coastguard Worker
13857*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
13858*6777b538SAndroid Build Coastguard Worker return(doc);
13859*6777b538SAndroid Build Coastguard Worker }
13860*6777b538SAndroid Build Coastguard Worker
13861*6777b538SAndroid Build Coastguard Worker /**
13862*6777b538SAndroid Build Coastguard Worker * xmlReadFd:
13863*6777b538SAndroid Build Coastguard Worker * @fd: an open file descriptor
13864*6777b538SAndroid Build Coastguard Worker * @URL: base URL (optional)
13865*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding (optional)
13866*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
13867*6777b538SAndroid Build Coastguard Worker *
13868*6777b538SAndroid Build Coastguard Worker * Parse an XML from a file descriptor and build a tree.
13869*6777b538SAndroid Build Coastguard Worker *
13870*6777b538SAndroid Build Coastguard Worker * See xmlCtxtReadFd for details.
13871*6777b538SAndroid Build Coastguard Worker *
13872*6777b538SAndroid Build Coastguard Worker * NOTE that the file descriptor will not be closed when the
13873*6777b538SAndroid Build Coastguard Worker * context is freed or reset.
13874*6777b538SAndroid Build Coastguard Worker *
13875*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13876*6777b538SAndroid Build Coastguard Worker */
13877*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlReadFd(int fd,const char * URL,const char * encoding,int options)13878*6777b538SAndroid Build Coastguard Worker xmlReadFd(int fd, const char *URL, const char *encoding, int options)
13879*6777b538SAndroid Build Coastguard Worker {
13880*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
13881*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13882*6777b538SAndroid Build Coastguard Worker xmlDocPtr doc;
13883*6777b538SAndroid Build Coastguard Worker
13884*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
13885*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13886*6777b538SAndroid Build Coastguard Worker return(NULL);
13887*6777b538SAndroid Build Coastguard Worker
13888*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
13889*6777b538SAndroid Build Coastguard Worker
13890*6777b538SAndroid Build Coastguard Worker input = xmlNewInputFd(ctxt, URL, fd, encoding, 0);
13891*6777b538SAndroid Build Coastguard Worker input->buf->closecallback = NULL;
13892*6777b538SAndroid Build Coastguard Worker
13893*6777b538SAndroid Build Coastguard Worker doc = xmlCtxtParseDocument(ctxt, input);
13894*6777b538SAndroid Build Coastguard Worker
13895*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
13896*6777b538SAndroid Build Coastguard Worker return(doc);
13897*6777b538SAndroid Build Coastguard Worker }
13898*6777b538SAndroid Build Coastguard Worker
13899*6777b538SAndroid Build Coastguard Worker /**
13900*6777b538SAndroid Build Coastguard Worker * xmlReadIO:
13901*6777b538SAndroid Build Coastguard Worker * @ioread: an I/O read function
13902*6777b538SAndroid Build Coastguard Worker * @ioclose: an I/O close function (optional)
13903*6777b538SAndroid Build Coastguard Worker * @ioctx: an I/O handler
13904*6777b538SAndroid Build Coastguard Worker * @URL: base URL (optional)
13905*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding (optional)
13906*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
13907*6777b538SAndroid Build Coastguard Worker *
13908*6777b538SAndroid Build Coastguard Worker * Parse an XML document from I/O functions and context and build a tree.
13909*6777b538SAndroid Build Coastguard Worker *
13910*6777b538SAndroid Build Coastguard Worker * See xmlCtxtReadIO for details.
13911*6777b538SAndroid Build Coastguard Worker *
13912*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13913*6777b538SAndroid Build Coastguard Worker */
13914*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlReadIO(xmlInputReadCallback ioread,xmlInputCloseCallback ioclose,void * ioctx,const char * URL,const char * encoding,int options)13915*6777b538SAndroid Build Coastguard Worker xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
13916*6777b538SAndroid Build Coastguard Worker void *ioctx, const char *URL, const char *encoding, int options)
13917*6777b538SAndroid Build Coastguard Worker {
13918*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
13919*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13920*6777b538SAndroid Build Coastguard Worker xmlDocPtr doc;
13921*6777b538SAndroid Build Coastguard Worker
13922*6777b538SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
13923*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13924*6777b538SAndroid Build Coastguard Worker return(NULL);
13925*6777b538SAndroid Build Coastguard Worker
13926*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
13927*6777b538SAndroid Build Coastguard Worker
13928*6777b538SAndroid Build Coastguard Worker input = xmlNewInputIO(ctxt, URL, ioread, ioclose, ioctx, encoding, 0);
13929*6777b538SAndroid Build Coastguard Worker
13930*6777b538SAndroid Build Coastguard Worker doc = xmlCtxtParseDocument(ctxt, input);
13931*6777b538SAndroid Build Coastguard Worker
13932*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
13933*6777b538SAndroid Build Coastguard Worker return(doc);
13934*6777b538SAndroid Build Coastguard Worker }
13935*6777b538SAndroid Build Coastguard Worker
13936*6777b538SAndroid Build Coastguard Worker /**
13937*6777b538SAndroid Build Coastguard Worker * xmlCtxtReadDoc:
13938*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
13939*6777b538SAndroid Build Coastguard Worker * @str: a pointer to a zero terminated string
13940*6777b538SAndroid Build Coastguard Worker * @URL: base URL (optional)
13941*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding (optional)
13942*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
13943*6777b538SAndroid Build Coastguard Worker *
13944*6777b538SAndroid Build Coastguard Worker * Parse an XML in-memory document and build a tree.
13945*6777b538SAndroid Build Coastguard Worker *
13946*6777b538SAndroid Build Coastguard Worker * @URL is used as base to resolve external entities and for error
13947*6777b538SAndroid Build Coastguard Worker * reporting.
13948*6777b538SAndroid Build Coastguard Worker *
13949*6777b538SAndroid Build Coastguard Worker * See xmlCtxtUseOptions for details.
13950*6777b538SAndroid Build Coastguard Worker *
13951*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13952*6777b538SAndroid Build Coastguard Worker */
13953*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlCtxtReadDoc(xmlParserCtxtPtr ctxt,const xmlChar * str,const char * URL,const char * encoding,int options)13954*6777b538SAndroid Build Coastguard Worker xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar *str,
13955*6777b538SAndroid Build Coastguard Worker const char *URL, const char *encoding, int options)
13956*6777b538SAndroid Build Coastguard Worker {
13957*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13958*6777b538SAndroid Build Coastguard Worker
13959*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13960*6777b538SAndroid Build Coastguard Worker return(NULL);
13961*6777b538SAndroid Build Coastguard Worker
13962*6777b538SAndroid Build Coastguard Worker xmlCtxtReset(ctxt);
13963*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
13964*6777b538SAndroid Build Coastguard Worker
13965*6777b538SAndroid Build Coastguard Worker input = xmlNewInputString(ctxt, URL, (const char *) str, encoding,
13966*6777b538SAndroid Build Coastguard Worker XML_INPUT_BUF_STATIC);
13967*6777b538SAndroid Build Coastguard Worker
13968*6777b538SAndroid Build Coastguard Worker return(xmlCtxtParseDocument(ctxt, input));
13969*6777b538SAndroid Build Coastguard Worker }
13970*6777b538SAndroid Build Coastguard Worker
13971*6777b538SAndroid Build Coastguard Worker /**
13972*6777b538SAndroid Build Coastguard Worker * xmlCtxtReadFile:
13973*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
13974*6777b538SAndroid Build Coastguard Worker * @filename: a file or URL
13975*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding (optional)
13976*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
13977*6777b538SAndroid Build Coastguard Worker *
13978*6777b538SAndroid Build Coastguard Worker * Parse an XML file from the filesystem, the network or a user-defined
13979*6777b538SAndroid Build Coastguard Worker * resource loader.
13980*6777b538SAndroid Build Coastguard Worker *
13981*6777b538SAndroid Build Coastguard Worker * See xmlNewInputURL and xmlCtxtUseOptions for details.
13982*6777b538SAndroid Build Coastguard Worker *
13983*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
13984*6777b538SAndroid Build Coastguard Worker */
13985*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlCtxtReadFile(xmlParserCtxtPtr ctxt,const char * filename,const char * encoding,int options)13986*6777b538SAndroid Build Coastguard Worker xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
13987*6777b538SAndroid Build Coastguard Worker const char *encoding, int options)
13988*6777b538SAndroid Build Coastguard Worker {
13989*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
13990*6777b538SAndroid Build Coastguard Worker
13991*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
13992*6777b538SAndroid Build Coastguard Worker return(NULL);
13993*6777b538SAndroid Build Coastguard Worker
13994*6777b538SAndroid Build Coastguard Worker xmlCtxtReset(ctxt);
13995*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
13996*6777b538SAndroid Build Coastguard Worker
13997*6777b538SAndroid Build Coastguard Worker input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0);
13998*6777b538SAndroid Build Coastguard Worker
13999*6777b538SAndroid Build Coastguard Worker return(xmlCtxtParseDocument(ctxt, input));
14000*6777b538SAndroid Build Coastguard Worker }
14001*6777b538SAndroid Build Coastguard Worker
14002*6777b538SAndroid Build Coastguard Worker /**
14003*6777b538SAndroid Build Coastguard Worker * xmlCtxtReadMemory:
14004*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
14005*6777b538SAndroid Build Coastguard Worker * @buffer: a pointer to a char array
14006*6777b538SAndroid Build Coastguard Worker * @size: the size of the array
14007*6777b538SAndroid Build Coastguard Worker * @URL: base URL (optional)
14008*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding (optional)
14009*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
14010*6777b538SAndroid Build Coastguard Worker *
14011*6777b538SAndroid Build Coastguard Worker * Parse an XML in-memory document and build a tree. The input buffer must
14012*6777b538SAndroid Build Coastguard Worker * not contain a terminating null byte.
14013*6777b538SAndroid Build Coastguard Worker *
14014*6777b538SAndroid Build Coastguard Worker * @URL is used as base to resolve external entities and for error
14015*6777b538SAndroid Build Coastguard Worker * reporting.
14016*6777b538SAndroid Build Coastguard Worker *
14017*6777b538SAndroid Build Coastguard Worker * See xmlCtxtUseOptions for details.
14018*6777b538SAndroid Build Coastguard Worker *
14019*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
14020*6777b538SAndroid Build Coastguard Worker */
14021*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlCtxtReadMemory(xmlParserCtxtPtr ctxt,const char * buffer,int size,const char * URL,const char * encoding,int options)14022*6777b538SAndroid Build Coastguard Worker xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
14023*6777b538SAndroid Build Coastguard Worker const char *URL, const char *encoding, int options)
14024*6777b538SAndroid Build Coastguard Worker {
14025*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
14026*6777b538SAndroid Build Coastguard Worker
14027*6777b538SAndroid Build Coastguard Worker if ((ctxt == NULL) || (size < 0))
14028*6777b538SAndroid Build Coastguard Worker return(NULL);
14029*6777b538SAndroid Build Coastguard Worker
14030*6777b538SAndroid Build Coastguard Worker xmlCtxtReset(ctxt);
14031*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
14032*6777b538SAndroid Build Coastguard Worker
14033*6777b538SAndroid Build Coastguard Worker input = xmlNewInputMemory(ctxt, URL, buffer, size, encoding,
14034*6777b538SAndroid Build Coastguard Worker XML_INPUT_BUF_STATIC);
14035*6777b538SAndroid Build Coastguard Worker
14036*6777b538SAndroid Build Coastguard Worker return(xmlCtxtParseDocument(ctxt, input));
14037*6777b538SAndroid Build Coastguard Worker }
14038*6777b538SAndroid Build Coastguard Worker
14039*6777b538SAndroid Build Coastguard Worker /**
14040*6777b538SAndroid Build Coastguard Worker * xmlCtxtReadFd:
14041*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
14042*6777b538SAndroid Build Coastguard Worker * @fd: an open file descriptor
14043*6777b538SAndroid Build Coastguard Worker * @URL: base URL (optional)
14044*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding (optional)
14045*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
14046*6777b538SAndroid Build Coastguard Worker *
14047*6777b538SAndroid Build Coastguard Worker * Parse an XML document from a file descriptor and build a tree.
14048*6777b538SAndroid Build Coastguard Worker *
14049*6777b538SAndroid Build Coastguard Worker * NOTE that the file descriptor will not be closed when the
14050*6777b538SAndroid Build Coastguard Worker * context is freed or reset.
14051*6777b538SAndroid Build Coastguard Worker *
14052*6777b538SAndroid Build Coastguard Worker * @URL is used as base to resolve external entities and for error
14053*6777b538SAndroid Build Coastguard Worker * reporting.
14054*6777b538SAndroid Build Coastguard Worker *
14055*6777b538SAndroid Build Coastguard Worker * See xmlCtxtUseOptions for details.
14056*6777b538SAndroid Build Coastguard Worker *
14057*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
14058*6777b538SAndroid Build Coastguard Worker */
14059*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlCtxtReadFd(xmlParserCtxtPtr ctxt,int fd,const char * URL,const char * encoding,int options)14060*6777b538SAndroid Build Coastguard Worker xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
14061*6777b538SAndroid Build Coastguard Worker const char *URL, const char *encoding, int options)
14062*6777b538SAndroid Build Coastguard Worker {
14063*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
14064*6777b538SAndroid Build Coastguard Worker
14065*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
14066*6777b538SAndroid Build Coastguard Worker return(NULL);
14067*6777b538SAndroid Build Coastguard Worker
14068*6777b538SAndroid Build Coastguard Worker xmlCtxtReset(ctxt);
14069*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
14070*6777b538SAndroid Build Coastguard Worker
14071*6777b538SAndroid Build Coastguard Worker input = xmlNewInputFd(ctxt, URL, fd, encoding, 0);
14072*6777b538SAndroid Build Coastguard Worker input->buf->closecallback = NULL;
14073*6777b538SAndroid Build Coastguard Worker
14074*6777b538SAndroid Build Coastguard Worker return(xmlCtxtParseDocument(ctxt, input));
14075*6777b538SAndroid Build Coastguard Worker }
14076*6777b538SAndroid Build Coastguard Worker
14077*6777b538SAndroid Build Coastguard Worker /**
14078*6777b538SAndroid Build Coastguard Worker * xmlCtxtReadIO:
14079*6777b538SAndroid Build Coastguard Worker * @ctxt: an XML parser context
14080*6777b538SAndroid Build Coastguard Worker * @ioread: an I/O read function
14081*6777b538SAndroid Build Coastguard Worker * @ioclose: an I/O close function
14082*6777b538SAndroid Build Coastguard Worker * @ioctx: an I/O handler
14083*6777b538SAndroid Build Coastguard Worker * @URL: the base URL to use for the document
14084*6777b538SAndroid Build Coastguard Worker * @encoding: the document encoding, or NULL
14085*6777b538SAndroid Build Coastguard Worker * @options: a combination of xmlParserOption
14086*6777b538SAndroid Build Coastguard Worker *
14087*6777b538SAndroid Build Coastguard Worker * parse an XML document from I/O functions and source and build a tree.
14088*6777b538SAndroid Build Coastguard Worker * This reuses the existing @ctxt parser context
14089*6777b538SAndroid Build Coastguard Worker *
14090*6777b538SAndroid Build Coastguard Worker * @URL is used as base to resolve external entities and for error
14091*6777b538SAndroid Build Coastguard Worker * reporting.
14092*6777b538SAndroid Build Coastguard Worker *
14093*6777b538SAndroid Build Coastguard Worker * See xmlCtxtUseOptions for details.
14094*6777b538SAndroid Build Coastguard Worker *
14095*6777b538SAndroid Build Coastguard Worker * Returns the resulting document tree
14096*6777b538SAndroid Build Coastguard Worker */
14097*6777b538SAndroid Build Coastguard Worker xmlDocPtr
xmlCtxtReadIO(xmlParserCtxtPtr ctxt,xmlInputReadCallback ioread,xmlInputCloseCallback ioclose,void * ioctx,const char * URL,const char * encoding,int options)14098*6777b538SAndroid Build Coastguard Worker xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
14099*6777b538SAndroid Build Coastguard Worker xmlInputCloseCallback ioclose, void *ioctx,
14100*6777b538SAndroid Build Coastguard Worker const char *URL,
14101*6777b538SAndroid Build Coastguard Worker const char *encoding, int options)
14102*6777b538SAndroid Build Coastguard Worker {
14103*6777b538SAndroid Build Coastguard Worker xmlParserInputPtr input;
14104*6777b538SAndroid Build Coastguard Worker
14105*6777b538SAndroid Build Coastguard Worker if (ctxt == NULL)
14106*6777b538SAndroid Build Coastguard Worker return(NULL);
14107*6777b538SAndroid Build Coastguard Worker
14108*6777b538SAndroid Build Coastguard Worker xmlCtxtReset(ctxt);
14109*6777b538SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, options);
14110*6777b538SAndroid Build Coastguard Worker
14111*6777b538SAndroid Build Coastguard Worker input = xmlNewInputIO(ctxt, URL, ioread, ioclose, ioctx, encoding, 0);
14112*6777b538SAndroid Build Coastguard Worker
14113*6777b538SAndroid Build Coastguard Worker return(xmlCtxtParseDocument(ctxt, input));
14114*6777b538SAndroid Build Coastguard Worker }
14115*6777b538SAndroid Build Coastguard Worker
14116