xref: /aosp_15_r20/external/libxml2/parserInternals.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /*
2*7c568831SAndroid Build Coastguard Worker  * parserInternals.c : Internal routines (and obsolete ones) needed for the
3*7c568831SAndroid Build Coastguard Worker  *                     XML and HTML parsers.
4*7c568831SAndroid Build Coastguard Worker  *
5*7c568831SAndroid Build Coastguard Worker  * See Copyright for the status of this software.
6*7c568831SAndroid Build Coastguard Worker  *
7*7c568831SAndroid Build Coastguard Worker  * [email protected]
8*7c568831SAndroid Build Coastguard Worker  */
9*7c568831SAndroid Build Coastguard Worker 
10*7c568831SAndroid Build Coastguard Worker #define IN_LIBXML
11*7c568831SAndroid Build Coastguard Worker #include "libxml.h"
12*7c568831SAndroid Build Coastguard Worker 
13*7c568831SAndroid Build Coastguard Worker #if defined(_WIN32)
14*7c568831SAndroid Build Coastguard Worker #define XML_DIR_SEP '\\'
15*7c568831SAndroid Build Coastguard Worker #else
16*7c568831SAndroid Build Coastguard Worker #define XML_DIR_SEP '/'
17*7c568831SAndroid Build Coastguard Worker #endif
18*7c568831SAndroid Build Coastguard Worker 
19*7c568831SAndroid Build Coastguard Worker #include <string.h>
20*7c568831SAndroid Build Coastguard Worker #include <ctype.h>
21*7c568831SAndroid Build Coastguard Worker #include <stdlib.h>
22*7c568831SAndroid Build Coastguard Worker 
23*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlmemory.h>
24*7c568831SAndroid Build Coastguard Worker #include <libxml/tree.h>
25*7c568831SAndroid Build Coastguard Worker #include <libxml/parser.h>
26*7c568831SAndroid Build Coastguard Worker #include <libxml/parserInternals.h>
27*7c568831SAndroid Build Coastguard Worker #include <libxml/entities.h>
28*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlerror.h>
29*7c568831SAndroid Build Coastguard Worker #include <libxml/encoding.h>
30*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlIO.h>
31*7c568831SAndroid Build Coastguard Worker #include <libxml/uri.h>
32*7c568831SAndroid Build Coastguard Worker #include <libxml/dict.h>
33*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlsave.h>
34*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
35*7c568831SAndroid Build Coastguard Worker #include <libxml/catalog.h>
36*7c568831SAndroid Build Coastguard Worker #endif
37*7c568831SAndroid Build Coastguard Worker #include <libxml/chvalid.h>
38*7c568831SAndroid Build Coastguard Worker #include <libxml/nanohttp.h>
39*7c568831SAndroid Build Coastguard Worker 
40*7c568831SAndroid Build Coastguard Worker #define CUR(ctxt) ctxt->input->cur
41*7c568831SAndroid Build Coastguard Worker #define END(ctxt) ctxt->input->end
42*7c568831SAndroid Build Coastguard Worker 
43*7c568831SAndroid Build Coastguard Worker #include "private/buf.h"
44*7c568831SAndroid Build Coastguard Worker #include "private/enc.h"
45*7c568831SAndroid Build Coastguard Worker #include "private/error.h"
46*7c568831SAndroid Build Coastguard Worker #include "private/io.h"
47*7c568831SAndroid Build Coastguard Worker #include "private/parser.h"
48*7c568831SAndroid Build Coastguard Worker 
49*7c568831SAndroid Build Coastguard Worker #define XML_MAX_ERRORS 100
50*7c568831SAndroid Build Coastguard Worker 
51*7c568831SAndroid Build Coastguard Worker /*
52*7c568831SAndroid Build Coastguard Worker  * XML_MAX_AMPLIFICATION_DEFAULT is the default maximum allowed amplification
53*7c568831SAndroid Build Coastguard Worker  * factor of serialized output after entity expansion.
54*7c568831SAndroid Build Coastguard Worker  */
55*7c568831SAndroid Build Coastguard Worker #define XML_MAX_AMPLIFICATION_DEFAULT 5
56*7c568831SAndroid Build Coastguard Worker 
57*7c568831SAndroid Build Coastguard Worker /*
58*7c568831SAndroid Build Coastguard Worker  * Various global defaults for parsing
59*7c568831SAndroid Build Coastguard Worker  */
60*7c568831SAndroid Build Coastguard Worker 
61*7c568831SAndroid Build Coastguard Worker /**
62*7c568831SAndroid Build Coastguard Worker  * xmlCheckVersion:
63*7c568831SAndroid Build Coastguard Worker  * @version: the include version number
64*7c568831SAndroid Build Coastguard Worker  *
65*7c568831SAndroid Build Coastguard Worker  * check the compiled lib version against the include one.
66*7c568831SAndroid Build Coastguard Worker  */
67*7c568831SAndroid Build Coastguard Worker void
xmlCheckVersion(int version)68*7c568831SAndroid Build Coastguard Worker xmlCheckVersion(int version) {
69*7c568831SAndroid Build Coastguard Worker     int myversion = LIBXML_VERSION;
70*7c568831SAndroid Build Coastguard Worker 
71*7c568831SAndroid Build Coastguard Worker     xmlInitParser();
72*7c568831SAndroid Build Coastguard Worker 
73*7c568831SAndroid Build Coastguard Worker     if ((myversion / 10000) != (version / 10000)) {
74*7c568831SAndroid Build Coastguard Worker 	xmlPrintErrorMessage(
75*7c568831SAndroid Build Coastguard Worker 		"Fatal: program compiled against libxml %d using libxml %d\n",
76*7c568831SAndroid Build Coastguard Worker 		(version / 10000), (myversion / 10000));
77*7c568831SAndroid Build Coastguard Worker     } else if ((myversion / 100) < (version / 100)) {
78*7c568831SAndroid Build Coastguard Worker 	xmlPrintErrorMessage(
79*7c568831SAndroid Build Coastguard Worker 		"Warning: program compiled against libxml %d using older %d\n",
80*7c568831SAndroid Build Coastguard Worker 		(version / 100), (myversion / 100));
81*7c568831SAndroid Build Coastguard Worker     }
82*7c568831SAndroid Build Coastguard Worker }
83*7c568831SAndroid Build Coastguard Worker 
84*7c568831SAndroid Build Coastguard Worker 
85*7c568831SAndroid Build Coastguard Worker /************************************************************************
86*7c568831SAndroid Build Coastguard Worker  *									*
87*7c568831SAndroid Build Coastguard Worker  *		Some factorized error routines				*
88*7c568831SAndroid Build Coastguard Worker  *									*
89*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
90*7c568831SAndroid Build Coastguard Worker 
91*7c568831SAndroid Build Coastguard Worker 
92*7c568831SAndroid Build Coastguard Worker /**
93*7c568831SAndroid Build Coastguard Worker  * xmlCtxtSetErrorHandler:
94*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
95*7c568831SAndroid Build Coastguard Worker  * @handler:  error handler
96*7c568831SAndroid Build Coastguard Worker  * @data:  data for error handler
97*7c568831SAndroid Build Coastguard Worker  *
98*7c568831SAndroid Build Coastguard Worker  * Register a callback function that will be called on errors and
99*7c568831SAndroid Build Coastguard Worker  * warnings. If handler is NULL, the error handler will be deactivated.
100*7c568831SAndroid Build Coastguard Worker  *
101*7c568831SAndroid Build Coastguard Worker  * This is the recommended way to collect errors from the parser and
102*7c568831SAndroid Build Coastguard Worker  * takes precedence over all other error reporting mechanisms.
103*7c568831SAndroid Build Coastguard Worker  * These are (in order of precedence):
104*7c568831SAndroid Build Coastguard Worker  *
105*7c568831SAndroid Build Coastguard Worker  * - per-context structured handler (xmlCtxtSetErrorHandler)
106*7c568831SAndroid Build Coastguard Worker  * - per-context structured "serror" SAX handler
107*7c568831SAndroid Build Coastguard Worker  * - global structured handler (xmlSetStructuredErrorFunc)
108*7c568831SAndroid Build Coastguard Worker  * - per-context generic "error" and "warning" SAX handlers
109*7c568831SAndroid Build Coastguard Worker  * - global generic handler (xmlSetGenericErrorFunc)
110*7c568831SAndroid Build Coastguard Worker  * - print to stderr
111*7c568831SAndroid Build Coastguard Worker  *
112*7c568831SAndroid Build Coastguard Worker  * Available since 2.13.0.
113*7c568831SAndroid Build Coastguard Worker  */
114*7c568831SAndroid Build Coastguard Worker void
xmlCtxtSetErrorHandler(xmlParserCtxtPtr ctxt,xmlStructuredErrorFunc handler,void * data)115*7c568831SAndroid Build Coastguard Worker xmlCtxtSetErrorHandler(xmlParserCtxtPtr ctxt, xmlStructuredErrorFunc handler,
116*7c568831SAndroid Build Coastguard Worker                        void *data)
117*7c568831SAndroid Build Coastguard Worker {
118*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
119*7c568831SAndroid Build Coastguard Worker         return;
120*7c568831SAndroid Build Coastguard Worker     ctxt->errorHandler = handler;
121*7c568831SAndroid Build Coastguard Worker     ctxt->errorCtxt = data;
122*7c568831SAndroid Build Coastguard Worker }
123*7c568831SAndroid Build Coastguard Worker 
124*7c568831SAndroid Build Coastguard Worker /**
125*7c568831SAndroid Build Coastguard Worker  * xmlCtxtGetLastError:
126*7c568831SAndroid Build Coastguard Worker  * @ctx:  an XML parser context
127*7c568831SAndroid Build Coastguard Worker  *
128*7c568831SAndroid Build Coastguard Worker  * Get the last parsing error registered.
129*7c568831SAndroid Build Coastguard Worker  *
130*7c568831SAndroid Build Coastguard Worker  * Returns NULL if no error occurred or a pointer to the error
131*7c568831SAndroid Build Coastguard Worker  */
132*7c568831SAndroid Build Coastguard Worker const xmlError *
xmlCtxtGetLastError(void * ctx)133*7c568831SAndroid Build Coastguard Worker xmlCtxtGetLastError(void *ctx)
134*7c568831SAndroid Build Coastguard Worker {
135*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
136*7c568831SAndroid Build Coastguard Worker 
137*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
138*7c568831SAndroid Build Coastguard Worker         return (NULL);
139*7c568831SAndroid Build Coastguard Worker     if (ctxt->lastError.code == XML_ERR_OK)
140*7c568831SAndroid Build Coastguard Worker         return (NULL);
141*7c568831SAndroid Build Coastguard Worker     return (&ctxt->lastError);
142*7c568831SAndroid Build Coastguard Worker }
143*7c568831SAndroid Build Coastguard Worker 
144*7c568831SAndroid Build Coastguard Worker /**
145*7c568831SAndroid Build Coastguard Worker  * xmlCtxtResetLastError:
146*7c568831SAndroid Build Coastguard Worker  * @ctx:  an XML parser context
147*7c568831SAndroid Build Coastguard Worker  *
148*7c568831SAndroid Build Coastguard Worker  * Cleanup the last global error registered. For parsing error
149*7c568831SAndroid Build Coastguard Worker  * this does not change the well-formedness result.
150*7c568831SAndroid Build Coastguard Worker  */
151*7c568831SAndroid Build Coastguard Worker void
xmlCtxtResetLastError(void * ctx)152*7c568831SAndroid Build Coastguard Worker xmlCtxtResetLastError(void *ctx)
153*7c568831SAndroid Build Coastguard Worker {
154*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
155*7c568831SAndroid Build Coastguard Worker 
156*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
157*7c568831SAndroid Build Coastguard Worker         return;
158*7c568831SAndroid Build Coastguard Worker     ctxt->errNo = XML_ERR_OK;
159*7c568831SAndroid Build Coastguard Worker     if (ctxt->lastError.code == XML_ERR_OK)
160*7c568831SAndroid Build Coastguard Worker         return;
161*7c568831SAndroid Build Coastguard Worker     xmlResetError(&ctxt->lastError);
162*7c568831SAndroid Build Coastguard Worker }
163*7c568831SAndroid Build Coastguard Worker 
164*7c568831SAndroid Build Coastguard Worker /**
165*7c568831SAndroid Build Coastguard Worker  * xmlCtxtErrMemory:
166*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
167*7c568831SAndroid Build Coastguard Worker  *
168*7c568831SAndroid Build Coastguard Worker  * Handle an out-of-memory error.
169*7c568831SAndroid Build Coastguard Worker  *
170*7c568831SAndroid Build Coastguard Worker  * Available since 2.13.0.
171*7c568831SAndroid Build Coastguard Worker  */
172*7c568831SAndroid Build Coastguard Worker void
xmlCtxtErrMemory(xmlParserCtxtPtr ctxt)173*7c568831SAndroid Build Coastguard Worker xmlCtxtErrMemory(xmlParserCtxtPtr ctxt)
174*7c568831SAndroid Build Coastguard Worker {
175*7c568831SAndroid Build Coastguard Worker     xmlStructuredErrorFunc schannel = NULL;
176*7c568831SAndroid Build Coastguard Worker     xmlGenericErrorFunc channel = NULL;
177*7c568831SAndroid Build Coastguard Worker     void *data;
178*7c568831SAndroid Build Coastguard Worker 
179*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
180*7c568831SAndroid Build Coastguard Worker         return;
181*7c568831SAndroid Build Coastguard Worker 
182*7c568831SAndroid Build Coastguard Worker     ctxt->errNo = XML_ERR_NO_MEMORY;
183*7c568831SAndroid Build Coastguard Worker     ctxt->instate = XML_PARSER_EOF; /* TODO: Remove after refactoring */
184*7c568831SAndroid Build Coastguard Worker     ctxt->wellFormed = 0;
185*7c568831SAndroid Build Coastguard Worker     ctxt->disableSAX = 2;
186*7c568831SAndroid Build Coastguard Worker 
187*7c568831SAndroid Build Coastguard Worker     if (ctxt->errorHandler) {
188*7c568831SAndroid Build Coastguard Worker         schannel = ctxt->errorHandler;
189*7c568831SAndroid Build Coastguard Worker         data = ctxt->errorCtxt;
190*7c568831SAndroid Build Coastguard Worker     } else if ((ctxt->sax->initialized == XML_SAX2_MAGIC) &&
191*7c568831SAndroid Build Coastguard Worker         (ctxt->sax->serror != NULL)) {
192*7c568831SAndroid Build Coastguard Worker         schannel = ctxt->sax->serror;
193*7c568831SAndroid Build Coastguard Worker         data = ctxt->userData;
194*7c568831SAndroid Build Coastguard Worker     } else {
195*7c568831SAndroid Build Coastguard Worker         channel = ctxt->sax->error;
196*7c568831SAndroid Build Coastguard Worker         data = ctxt->userData;
197*7c568831SAndroid Build Coastguard Worker     }
198*7c568831SAndroid Build Coastguard Worker 
199*7c568831SAndroid Build Coastguard Worker     xmlRaiseMemoryError(schannel, channel, data, XML_FROM_PARSER,
200*7c568831SAndroid Build Coastguard Worker                         &ctxt->lastError);
201*7c568831SAndroid Build Coastguard Worker }
202*7c568831SAndroid Build Coastguard Worker 
203*7c568831SAndroid Build Coastguard Worker /**
204*7c568831SAndroid Build Coastguard Worker  * xmlCtxtErrIO:
205*7c568831SAndroid Build Coastguard Worker  * @ctxt:  parser context
206*7c568831SAndroid Build Coastguard Worker  * @code:  xmlParserErrors code
207*7c568831SAndroid Build Coastguard Worker  * @uri:  filename or URI (optional)
208*7c568831SAndroid Build Coastguard Worker  *
209*7c568831SAndroid Build Coastguard Worker  * If filename is empty, use the one from context input if available.
210*7c568831SAndroid Build Coastguard Worker  *
211*7c568831SAndroid Build Coastguard Worker  * Report an IO error to the parser context.
212*7c568831SAndroid Build Coastguard Worker  */
213*7c568831SAndroid Build Coastguard Worker void
xmlCtxtErrIO(xmlParserCtxtPtr ctxt,int code,const char * uri)214*7c568831SAndroid Build Coastguard Worker xmlCtxtErrIO(xmlParserCtxtPtr ctxt, int code, const char *uri)
215*7c568831SAndroid Build Coastguard Worker {
216*7c568831SAndroid Build Coastguard Worker     const char *errstr, *msg, *str1, *str2;
217*7c568831SAndroid Build Coastguard Worker     xmlErrorLevel level;
218*7c568831SAndroid Build Coastguard Worker 
219*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
220*7c568831SAndroid Build Coastguard Worker         return;
221*7c568831SAndroid Build Coastguard Worker 
222*7c568831SAndroid Build Coastguard Worker     if (((code == XML_IO_ENOENT) ||
223*7c568831SAndroid Build Coastguard Worker          (code == XML_IO_UNKNOWN))) {
224*7c568831SAndroid Build Coastguard Worker         /*
225*7c568831SAndroid Build Coastguard Worker          * Only report a warning if a file could not be found. This should
226*7c568831SAndroid Build Coastguard Worker          * only be done for external entities, but the external entity loader
227*7c568831SAndroid Build Coastguard Worker          * of xsltproc can try multiple paths and assumes that ENOENT doesn't
228*7c568831SAndroid Build Coastguard Worker          * raise an error and aborts parsing.
229*7c568831SAndroid Build Coastguard Worker          */
230*7c568831SAndroid Build Coastguard Worker         if (ctxt->validate == 0)
231*7c568831SAndroid Build Coastguard Worker             level = XML_ERR_WARNING;
232*7c568831SAndroid Build Coastguard Worker         else
233*7c568831SAndroid Build Coastguard Worker             level = XML_ERR_ERROR;
234*7c568831SAndroid Build Coastguard Worker     } else if (code == XML_IO_NETWORK_ATTEMPT) {
235*7c568831SAndroid Build Coastguard Worker         level = XML_ERR_ERROR;
236*7c568831SAndroid Build Coastguard Worker     } else {
237*7c568831SAndroid Build Coastguard Worker         level = XML_ERR_FATAL;
238*7c568831SAndroid Build Coastguard Worker     }
239*7c568831SAndroid Build Coastguard Worker 
240*7c568831SAndroid Build Coastguard Worker     errstr = xmlErrString(code);
241*7c568831SAndroid Build Coastguard Worker 
242*7c568831SAndroid Build Coastguard Worker     if (uri == NULL) {
243*7c568831SAndroid Build Coastguard Worker         msg = "%s\n";
244*7c568831SAndroid Build Coastguard Worker         str1 = errstr;
245*7c568831SAndroid Build Coastguard Worker         str2 = NULL;
246*7c568831SAndroid Build Coastguard Worker     } else {
247*7c568831SAndroid Build Coastguard Worker         msg = "failed to load \"%s\": %s\n";
248*7c568831SAndroid Build Coastguard Worker         str1 = uri;
249*7c568831SAndroid Build Coastguard Worker         str2 = errstr;
250*7c568831SAndroid Build Coastguard Worker     }
251*7c568831SAndroid Build Coastguard Worker 
252*7c568831SAndroid Build Coastguard Worker     xmlCtxtErr(ctxt, NULL, XML_FROM_IO, code, level,
253*7c568831SAndroid Build Coastguard Worker                (const xmlChar *) uri, NULL, NULL, 0,
254*7c568831SAndroid Build Coastguard Worker                msg, str1, str2);
255*7c568831SAndroid Build Coastguard Worker }
256*7c568831SAndroid Build Coastguard Worker 
257*7c568831SAndroid Build Coastguard Worker static int
xmlCtxtIsCatastrophicError(xmlParserCtxtPtr ctxt)258*7c568831SAndroid Build Coastguard Worker xmlCtxtIsCatastrophicError(xmlParserCtxtPtr ctxt) {
259*7c568831SAndroid Build Coastguard Worker     int fatal = 0;
260*7c568831SAndroid Build Coastguard Worker     int code;
261*7c568831SAndroid Build Coastguard Worker 
262*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
263*7c568831SAndroid Build Coastguard Worker         return(1);
264*7c568831SAndroid Build Coastguard Worker 
265*7c568831SAndroid Build Coastguard Worker     if (ctxt->lastError.level != XML_ERR_FATAL)
266*7c568831SAndroid Build Coastguard Worker         return(0);
267*7c568831SAndroid Build Coastguard Worker 
268*7c568831SAndroid Build Coastguard Worker     code = ctxt->lastError.code;
269*7c568831SAndroid Build Coastguard Worker 
270*7c568831SAndroid Build Coastguard Worker     switch (code) {
271*7c568831SAndroid Build Coastguard Worker         case XML_ERR_NO_MEMORY:
272*7c568831SAndroid Build Coastguard Worker         case XML_ERR_RESOURCE_LIMIT:
273*7c568831SAndroid Build Coastguard Worker         case XML_ERR_SYSTEM:
274*7c568831SAndroid Build Coastguard Worker         case XML_ERR_ARGUMENT:
275*7c568831SAndroid Build Coastguard Worker         case XML_ERR_INTERNAL_ERROR:
276*7c568831SAndroid Build Coastguard Worker             fatal = 1;
277*7c568831SAndroid Build Coastguard Worker             break;
278*7c568831SAndroid Build Coastguard Worker         default:
279*7c568831SAndroid Build Coastguard Worker             if ((code >= 1500) && (code <= 1599))
280*7c568831SAndroid Build Coastguard Worker                 fatal = 1;
281*7c568831SAndroid Build Coastguard Worker             break;
282*7c568831SAndroid Build Coastguard Worker     }
283*7c568831SAndroid Build Coastguard Worker 
284*7c568831SAndroid Build Coastguard Worker     return(fatal);
285*7c568831SAndroid Build Coastguard Worker }
286*7c568831SAndroid Build Coastguard Worker 
287*7c568831SAndroid Build Coastguard Worker /**
288*7c568831SAndroid Build Coastguard Worker  * xmlCtxtVErr:
289*7c568831SAndroid Build Coastguard Worker  * @ctxt:  a parser context
290*7c568831SAndroid Build Coastguard Worker  * @node: the current node or NULL
291*7c568831SAndroid Build Coastguard Worker  * @domain: the domain for the error
292*7c568831SAndroid Build Coastguard Worker  * @code: the code for the error
293*7c568831SAndroid Build Coastguard Worker  * @level: the xmlErrorLevel for the error
294*7c568831SAndroid Build Coastguard Worker  * @str1: extra string info
295*7c568831SAndroid Build Coastguard Worker  * @str2: extra string info
296*7c568831SAndroid Build Coastguard Worker  * @str3: extra string info
297*7c568831SAndroid Build Coastguard Worker  * @int1: extra int info
298*7c568831SAndroid Build Coastguard Worker  * @msg:  the message to display/transmit
299*7c568831SAndroid Build Coastguard Worker  * @ap:  extra parameters for the message display
300*7c568831SAndroid Build Coastguard Worker  *
301*7c568831SAndroid Build Coastguard Worker  * Raise a parser error.
302*7c568831SAndroid Build Coastguard Worker  */
303*7c568831SAndroid Build Coastguard Worker void
xmlCtxtVErr(xmlParserCtxtPtr ctxt,xmlNodePtr node,xmlErrorDomain domain,xmlParserErrors code,xmlErrorLevel level,const xmlChar * str1,const xmlChar * str2,const xmlChar * str3,int int1,const char * msg,va_list ap)304*7c568831SAndroid Build Coastguard Worker xmlCtxtVErr(xmlParserCtxtPtr ctxt, xmlNodePtr node, xmlErrorDomain domain,
305*7c568831SAndroid Build Coastguard Worker             xmlParserErrors code, xmlErrorLevel level,
306*7c568831SAndroid Build Coastguard Worker             const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
307*7c568831SAndroid Build Coastguard Worker             int int1, const char *msg, va_list ap)
308*7c568831SAndroid Build Coastguard Worker {
309*7c568831SAndroid Build Coastguard Worker     xmlStructuredErrorFunc schannel = NULL;
310*7c568831SAndroid Build Coastguard Worker     xmlGenericErrorFunc channel = NULL;
311*7c568831SAndroid Build Coastguard Worker     void *data = NULL;
312*7c568831SAndroid Build Coastguard Worker     const char *file = NULL;
313*7c568831SAndroid Build Coastguard Worker     int line = 0;
314*7c568831SAndroid Build Coastguard Worker     int col = 0;
315*7c568831SAndroid Build Coastguard Worker     int res;
316*7c568831SAndroid Build Coastguard Worker 
317*7c568831SAndroid Build Coastguard Worker     if (code == XML_ERR_NO_MEMORY) {
318*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrMemory(ctxt);
319*7c568831SAndroid Build Coastguard Worker         return;
320*7c568831SAndroid Build Coastguard Worker     }
321*7c568831SAndroid Build Coastguard Worker 
322*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
323*7c568831SAndroid Build Coastguard Worker         return;
324*7c568831SAndroid Build Coastguard Worker 
325*7c568831SAndroid Build Coastguard Worker     if (PARSER_STOPPED(ctxt))
326*7c568831SAndroid Build Coastguard Worker 	return;
327*7c568831SAndroid Build Coastguard Worker 
328*7c568831SAndroid Build Coastguard Worker     if (level == XML_ERR_WARNING) {
329*7c568831SAndroid Build Coastguard Worker         if (ctxt->nbWarnings >= XML_MAX_ERRORS)
330*7c568831SAndroid Build Coastguard Worker             goto done;
331*7c568831SAndroid Build Coastguard Worker         ctxt->nbWarnings += 1;
332*7c568831SAndroid Build Coastguard Worker     } else {
333*7c568831SAndroid Build Coastguard Worker         /* Report at least one fatal error. */
334*7c568831SAndroid Build Coastguard Worker         if ((ctxt->nbErrors >= XML_MAX_ERRORS) &&
335*7c568831SAndroid Build Coastguard Worker             ((level < XML_ERR_FATAL) || (ctxt->wellFormed == 0)))
336*7c568831SAndroid Build Coastguard Worker             goto done;
337*7c568831SAndroid Build Coastguard Worker         ctxt->nbErrors += 1;
338*7c568831SAndroid Build Coastguard Worker     }
339*7c568831SAndroid Build Coastguard Worker 
340*7c568831SAndroid Build Coastguard Worker     if (((ctxt->options & XML_PARSE_NOERROR) == 0) &&
341*7c568831SAndroid Build Coastguard Worker         ((level != XML_ERR_WARNING) ||
342*7c568831SAndroid Build Coastguard Worker          ((ctxt->options & XML_PARSE_NOWARNING) == 0))) {
343*7c568831SAndroid Build Coastguard Worker         if (ctxt->errorHandler) {
344*7c568831SAndroid Build Coastguard Worker             schannel = ctxt->errorHandler;
345*7c568831SAndroid Build Coastguard Worker             data = ctxt->errorCtxt;
346*7c568831SAndroid Build Coastguard Worker         } else if ((ctxt->sax->initialized == XML_SAX2_MAGIC) &&
347*7c568831SAndroid Build Coastguard Worker             (ctxt->sax->serror != NULL)) {
348*7c568831SAndroid Build Coastguard Worker             schannel = ctxt->sax->serror;
349*7c568831SAndroid Build Coastguard Worker             data = ctxt->userData;
350*7c568831SAndroid Build Coastguard Worker         } else if ((domain == XML_FROM_VALID) || (domain == XML_FROM_DTD)) {
351*7c568831SAndroid Build Coastguard Worker             if (level == XML_ERR_WARNING)
352*7c568831SAndroid Build Coastguard Worker                 channel = ctxt->vctxt.warning;
353*7c568831SAndroid Build Coastguard Worker             else
354*7c568831SAndroid Build Coastguard Worker                 channel = ctxt->vctxt.error;
355*7c568831SAndroid Build Coastguard Worker             data = ctxt->vctxt.userData;
356*7c568831SAndroid Build Coastguard Worker         } else {
357*7c568831SAndroid Build Coastguard Worker             if (level == XML_ERR_WARNING)
358*7c568831SAndroid Build Coastguard Worker                 channel = ctxt->sax->warning;
359*7c568831SAndroid Build Coastguard Worker             else
360*7c568831SAndroid Build Coastguard Worker                 channel = ctxt->sax->error;
361*7c568831SAndroid Build Coastguard Worker             data = ctxt->userData;
362*7c568831SAndroid Build Coastguard Worker         }
363*7c568831SAndroid Build Coastguard Worker     }
364*7c568831SAndroid Build Coastguard Worker 
365*7c568831SAndroid Build Coastguard Worker     if (ctxt->input != NULL) {
366*7c568831SAndroid Build Coastguard Worker         xmlParserInputPtr input = ctxt->input;
367*7c568831SAndroid Build Coastguard Worker 
368*7c568831SAndroid Build Coastguard Worker         if ((input->filename == NULL) &&
369*7c568831SAndroid Build Coastguard Worker             (ctxt->inputNr > 1)) {
370*7c568831SAndroid Build Coastguard Worker             input = ctxt->inputTab[ctxt->inputNr - 2];
371*7c568831SAndroid Build Coastguard Worker         }
372*7c568831SAndroid Build Coastguard Worker         file = input->filename;
373*7c568831SAndroid Build Coastguard Worker         line = input->line;
374*7c568831SAndroid Build Coastguard Worker         col = input->col;
375*7c568831SAndroid Build Coastguard Worker     }
376*7c568831SAndroid Build Coastguard Worker 
377*7c568831SAndroid Build Coastguard Worker     res = xmlVRaiseError(schannel, channel, data, ctxt, node, domain, code,
378*7c568831SAndroid Build Coastguard Worker                          level, file, line, (const char *) str1,
379*7c568831SAndroid Build Coastguard Worker                          (const char *) str2, (const char *) str3, int1, col,
380*7c568831SAndroid Build Coastguard Worker                          msg, ap);
381*7c568831SAndroid Build Coastguard Worker 
382*7c568831SAndroid Build Coastguard Worker     if (res < 0) {
383*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrMemory(ctxt);
384*7c568831SAndroid Build Coastguard Worker         return;
385*7c568831SAndroid Build Coastguard Worker     }
386*7c568831SAndroid Build Coastguard Worker 
387*7c568831SAndroid Build Coastguard Worker done:
388*7c568831SAndroid Build Coastguard Worker     if (level >= XML_ERR_ERROR)
389*7c568831SAndroid Build Coastguard Worker         ctxt->errNo = code;
390*7c568831SAndroid Build Coastguard Worker     if (level == XML_ERR_FATAL) {
391*7c568831SAndroid Build Coastguard Worker         ctxt->wellFormed = 0;
392*7c568831SAndroid Build Coastguard Worker 
393*7c568831SAndroid Build Coastguard Worker         if (xmlCtxtIsCatastrophicError(ctxt))
394*7c568831SAndroid Build Coastguard Worker             ctxt->disableSAX = 2; /* stop parser */
395*7c568831SAndroid Build Coastguard Worker         else if (ctxt->recovery == 0)
396*7c568831SAndroid Build Coastguard Worker             ctxt->disableSAX = 1;
397*7c568831SAndroid Build Coastguard Worker     }
398*7c568831SAndroid Build Coastguard Worker }
399*7c568831SAndroid Build Coastguard Worker 
400*7c568831SAndroid Build Coastguard Worker /**
401*7c568831SAndroid Build Coastguard Worker  * xmlCtxtErr:
402*7c568831SAndroid Build Coastguard Worker  * @ctxt:  a parser context
403*7c568831SAndroid Build Coastguard Worker  * @node: the current node or NULL
404*7c568831SAndroid Build Coastguard Worker  * @domain: the domain for the error
405*7c568831SAndroid Build Coastguard Worker  * @code: the code for the error
406*7c568831SAndroid Build Coastguard Worker  * @level: the xmlErrorLevel for the error
407*7c568831SAndroid Build Coastguard Worker  * @str1: extra string info
408*7c568831SAndroid Build Coastguard Worker  * @str2: extra string info
409*7c568831SAndroid Build Coastguard Worker  * @str3: extra string info
410*7c568831SAndroid Build Coastguard Worker  * @int1: extra int info
411*7c568831SAndroid Build Coastguard Worker  * @msg:  the message to display/transmit
412*7c568831SAndroid Build Coastguard Worker  * @...:  extra parameters for the message display
413*7c568831SAndroid Build Coastguard Worker  *
414*7c568831SAndroid Build Coastguard Worker  * Raise a parser error.
415*7c568831SAndroid Build Coastguard Worker  */
416*7c568831SAndroid Build Coastguard Worker void
xmlCtxtErr(xmlParserCtxtPtr ctxt,xmlNodePtr node,xmlErrorDomain domain,xmlParserErrors code,xmlErrorLevel level,const xmlChar * str1,const xmlChar * str2,const xmlChar * str3,int int1,const char * msg,...)417*7c568831SAndroid Build Coastguard Worker xmlCtxtErr(xmlParserCtxtPtr ctxt, xmlNodePtr node, xmlErrorDomain domain,
418*7c568831SAndroid Build Coastguard Worker            xmlParserErrors code, xmlErrorLevel level,
419*7c568831SAndroid Build Coastguard Worker            const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
420*7c568831SAndroid Build Coastguard Worker            int int1, const char *msg, ...)
421*7c568831SAndroid Build Coastguard Worker {
422*7c568831SAndroid Build Coastguard Worker     va_list ap;
423*7c568831SAndroid Build Coastguard Worker 
424*7c568831SAndroid Build Coastguard Worker     va_start(ap, msg);
425*7c568831SAndroid Build Coastguard Worker     xmlCtxtVErr(ctxt, node, domain, code, level,
426*7c568831SAndroid Build Coastguard Worker                 str1, str2, str3, int1, msg, ap);
427*7c568831SAndroid Build Coastguard Worker     va_end(ap);
428*7c568831SAndroid Build Coastguard Worker }
429*7c568831SAndroid Build Coastguard Worker 
430*7c568831SAndroid Build Coastguard Worker /**
431*7c568831SAndroid Build Coastguard Worker  * xmlCtxtGetStatus:
432*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
433*7c568831SAndroid Build Coastguard Worker  *
434*7c568831SAndroid Build Coastguard Worker  * Get well-formedness and validation status after parsing. Also
435*7c568831SAndroid Build Coastguard Worker  * reports catastrophic errors which are not related to parsing
436*7c568831SAndroid Build Coastguard Worker  * like out-of-memory, I/O or other errors.
437*7c568831SAndroid Build Coastguard Worker  *
438*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
439*7c568831SAndroid Build Coastguard Worker  *
440*7c568831SAndroid Build Coastguard Worker  * Returns a bitmask of XML_STATUS_* flags ORed together.
441*7c568831SAndroid Build Coastguard Worker  */
442*7c568831SAndroid Build Coastguard Worker int
xmlCtxtGetStatus(xmlParserCtxt * ctxt)443*7c568831SAndroid Build Coastguard Worker xmlCtxtGetStatus(xmlParserCtxt *ctxt) {
444*7c568831SAndroid Build Coastguard Worker     int bits = 0;
445*7c568831SAndroid Build Coastguard Worker 
446*7c568831SAndroid Build Coastguard Worker     if (xmlCtxtIsCatastrophicError(ctxt)) {
447*7c568831SAndroid Build Coastguard Worker         bits |= XML_STATUS_CATASTROPHIC_ERROR |
448*7c568831SAndroid Build Coastguard Worker                 XML_STATUS_NOT_WELL_FORMED |
449*7c568831SAndroid Build Coastguard Worker                 XML_STATUS_NOT_NS_WELL_FORMED;
450*7c568831SAndroid Build Coastguard Worker         if ((ctxt != NULL) && (ctxt->validate))
451*7c568831SAndroid Build Coastguard Worker             bits |= XML_STATUS_DTD_VALIDATION_FAILED;
452*7c568831SAndroid Build Coastguard Worker 
453*7c568831SAndroid Build Coastguard Worker         return(bits);
454*7c568831SAndroid Build Coastguard Worker     }
455*7c568831SAndroid Build Coastguard Worker 
456*7c568831SAndroid Build Coastguard Worker     if (!ctxt->wellFormed)
457*7c568831SAndroid Build Coastguard Worker         bits |= XML_STATUS_NOT_WELL_FORMED;
458*7c568831SAndroid Build Coastguard Worker     if (!ctxt->nsWellFormed)
459*7c568831SAndroid Build Coastguard Worker         bits |= XML_STATUS_NOT_NS_WELL_FORMED;
460*7c568831SAndroid Build Coastguard Worker     if ((ctxt->validate) && (!ctxt->valid))
461*7c568831SAndroid Build Coastguard Worker         bits |= XML_STATUS_DTD_VALIDATION_FAILED;
462*7c568831SAndroid Build Coastguard Worker 
463*7c568831SAndroid Build Coastguard Worker     return(bits);
464*7c568831SAndroid Build Coastguard Worker }
465*7c568831SAndroid Build Coastguard Worker 
466*7c568831SAndroid Build Coastguard Worker /**
467*7c568831SAndroid Build Coastguard Worker  * xmlFatalErr:
468*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
469*7c568831SAndroid Build Coastguard Worker  * @code:  the error number
470*7c568831SAndroid Build Coastguard Worker  * @info:  extra information string
471*7c568831SAndroid Build Coastguard Worker  *
472*7c568831SAndroid Build Coastguard Worker  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
473*7c568831SAndroid Build Coastguard Worker  */
474*7c568831SAndroid Build Coastguard Worker void
xmlFatalErr(xmlParserCtxtPtr ctxt,xmlParserErrors code,const char * info)475*7c568831SAndroid Build Coastguard Worker xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors code, const char *info)
476*7c568831SAndroid Build Coastguard Worker {
477*7c568831SAndroid Build Coastguard Worker     const char *errmsg;
478*7c568831SAndroid Build Coastguard Worker 
479*7c568831SAndroid Build Coastguard Worker     errmsg = xmlErrString(code);
480*7c568831SAndroid Build Coastguard Worker 
481*7c568831SAndroid Build Coastguard Worker     if (info == NULL) {
482*7c568831SAndroid Build Coastguard Worker         xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, code, XML_ERR_FATAL,
483*7c568831SAndroid Build Coastguard Worker                    NULL, NULL, NULL, 0, "%s\n", errmsg);
484*7c568831SAndroid Build Coastguard Worker     } else {
485*7c568831SAndroid Build Coastguard Worker         xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, code, XML_ERR_FATAL,
486*7c568831SAndroid Build Coastguard Worker                    (const xmlChar *) info, NULL, NULL, 0,
487*7c568831SAndroid Build Coastguard Worker                    "%s: %s\n", errmsg, info);
488*7c568831SAndroid Build Coastguard Worker     }
489*7c568831SAndroid Build Coastguard Worker }
490*7c568831SAndroid Build Coastguard Worker 
491*7c568831SAndroid Build Coastguard Worker /**
492*7c568831SAndroid Build Coastguard Worker  * xmlIsLetter:
493*7c568831SAndroid Build Coastguard Worker  * @c:  an unicode character (int)
494*7c568831SAndroid Build Coastguard Worker  *
495*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Internal function, don't use.
496*7c568831SAndroid Build Coastguard Worker  *
497*7c568831SAndroid Build Coastguard Worker  * Check whether the character is allowed by the production
498*7c568831SAndroid Build Coastguard Worker  * [84] Letter ::= BaseChar | Ideographic
499*7c568831SAndroid Build Coastguard Worker  *
500*7c568831SAndroid Build Coastguard Worker  * Returns 0 if not, non-zero otherwise
501*7c568831SAndroid Build Coastguard Worker  */
502*7c568831SAndroid Build Coastguard Worker int
xmlIsLetter(int c)503*7c568831SAndroid Build Coastguard Worker xmlIsLetter(int c) {
504*7c568831SAndroid Build Coastguard Worker     return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
505*7c568831SAndroid Build Coastguard Worker }
506*7c568831SAndroid Build Coastguard Worker 
507*7c568831SAndroid Build Coastguard Worker /************************************************************************
508*7c568831SAndroid Build Coastguard Worker  *									*
509*7c568831SAndroid Build Coastguard Worker  *		Input handling functions for progressive parsing	*
510*7c568831SAndroid Build Coastguard Worker  *									*
511*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
512*7c568831SAndroid Build Coastguard Worker 
513*7c568831SAndroid Build Coastguard Worker /* we need to keep enough input to show errors in context */
514*7c568831SAndroid Build Coastguard Worker #define LINE_LEN        80
515*7c568831SAndroid Build Coastguard Worker 
516*7c568831SAndroid Build Coastguard Worker /**
517*7c568831SAndroid Build Coastguard Worker  * xmlHaltParser:
518*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
519*7c568831SAndroid Build Coastguard Worker  *
520*7c568831SAndroid Build Coastguard Worker  * Blocks further parser processing don't override error
521*7c568831SAndroid Build Coastguard Worker  * for internal use
522*7c568831SAndroid Build Coastguard Worker  */
523*7c568831SAndroid Build Coastguard Worker void
xmlHaltParser(xmlParserCtxtPtr ctxt)524*7c568831SAndroid Build Coastguard Worker xmlHaltParser(xmlParserCtxtPtr ctxt) {
525*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
526*7c568831SAndroid Build Coastguard Worker         return;
527*7c568831SAndroid Build Coastguard Worker     ctxt->instate = XML_PARSER_EOF; /* TODO: Remove after refactoring */
528*7c568831SAndroid Build Coastguard Worker     ctxt->disableSAX = 2;
529*7c568831SAndroid Build Coastguard Worker }
530*7c568831SAndroid Build Coastguard Worker 
531*7c568831SAndroid Build Coastguard Worker /**
532*7c568831SAndroid Build Coastguard Worker  * xmlParserInputRead:
533*7c568831SAndroid Build Coastguard Worker  * @in:  an XML parser input
534*7c568831SAndroid Build Coastguard Worker  * @len:  an indicative size for the lookahead
535*7c568831SAndroid Build Coastguard Worker  *
536*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: This function was internal and is deprecated.
537*7c568831SAndroid Build Coastguard Worker  *
538*7c568831SAndroid Build Coastguard Worker  * Returns -1 as this is an error to use it.
539*7c568831SAndroid Build Coastguard Worker  */
540*7c568831SAndroid Build Coastguard Worker int
xmlParserInputRead(xmlParserInputPtr in ATTRIBUTE_UNUSED,int len ATTRIBUTE_UNUSED)541*7c568831SAndroid Build Coastguard Worker xmlParserInputRead(xmlParserInputPtr in ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) {
542*7c568831SAndroid Build Coastguard Worker     return(-1);
543*7c568831SAndroid Build Coastguard Worker }
544*7c568831SAndroid Build Coastguard Worker 
545*7c568831SAndroid Build Coastguard Worker /**
546*7c568831SAndroid Build Coastguard Worker  * xmlParserGrow:
547*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
548*7c568831SAndroid Build Coastguard Worker  *
549*7c568831SAndroid Build Coastguard Worker  * Grow the input buffer.
550*7c568831SAndroid Build Coastguard Worker  *
551*7c568831SAndroid Build Coastguard Worker  * Returns the number of bytes read or -1 in case of error.
552*7c568831SAndroid Build Coastguard Worker  */
553*7c568831SAndroid Build Coastguard Worker int
xmlParserGrow(xmlParserCtxtPtr ctxt)554*7c568831SAndroid Build Coastguard Worker xmlParserGrow(xmlParserCtxtPtr ctxt) {
555*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr in = ctxt->input;
556*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr buf = in->buf;
557*7c568831SAndroid Build Coastguard Worker     size_t curEnd = in->end - in->cur;
558*7c568831SAndroid Build Coastguard Worker     size_t curBase = in->cur - in->base;
559*7c568831SAndroid Build Coastguard Worker     size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
560*7c568831SAndroid Build Coastguard Worker                        XML_MAX_HUGE_LENGTH :
561*7c568831SAndroid Build Coastguard Worker                        XML_MAX_LOOKUP_LIMIT;
562*7c568831SAndroid Build Coastguard Worker     int ret;
563*7c568831SAndroid Build Coastguard Worker 
564*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
565*7c568831SAndroid Build Coastguard Worker         return(0);
566*7c568831SAndroid Build Coastguard Worker     /* Don't grow push parser buffer. */
567*7c568831SAndroid Build Coastguard Worker     if (PARSER_PROGRESSIVE(ctxt))
568*7c568831SAndroid Build Coastguard Worker         return(0);
569*7c568831SAndroid Build Coastguard Worker     /* Don't grow memory buffers. */
570*7c568831SAndroid Build Coastguard Worker     if ((buf->encoder == NULL) && (buf->readcallback == NULL))
571*7c568831SAndroid Build Coastguard Worker         return(0);
572*7c568831SAndroid Build Coastguard Worker     if (buf->error != 0)
573*7c568831SAndroid Build Coastguard Worker         return(-1);
574*7c568831SAndroid Build Coastguard Worker 
575*7c568831SAndroid Build Coastguard Worker     if (curBase > maxLength) {
576*7c568831SAndroid Build Coastguard Worker         xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT,
577*7c568831SAndroid Build Coastguard Worker                     "Buffer size limit exceeded, try XML_PARSE_HUGE\n");
578*7c568831SAndroid Build Coastguard Worker         xmlHaltParser(ctxt);
579*7c568831SAndroid Build Coastguard Worker 	return(-1);
580*7c568831SAndroid Build Coastguard Worker     }
581*7c568831SAndroid Build Coastguard Worker 
582*7c568831SAndroid Build Coastguard Worker     if (curEnd >= INPUT_CHUNK)
583*7c568831SAndroid Build Coastguard Worker         return(0);
584*7c568831SAndroid Build Coastguard Worker 
585*7c568831SAndroid Build Coastguard Worker     ret = xmlParserInputBufferGrow(buf, INPUT_CHUNK);
586*7c568831SAndroid Build Coastguard Worker     xmlBufUpdateInput(buf->buffer, in, curBase);
587*7c568831SAndroid Build Coastguard Worker 
588*7c568831SAndroid Build Coastguard Worker     if (ret < 0) {
589*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrIO(ctxt, buf->error, NULL);
590*7c568831SAndroid Build Coastguard Worker     }
591*7c568831SAndroid Build Coastguard Worker 
592*7c568831SAndroid Build Coastguard Worker     return(ret);
593*7c568831SAndroid Build Coastguard Worker }
594*7c568831SAndroid Build Coastguard Worker 
595*7c568831SAndroid Build Coastguard Worker /**
596*7c568831SAndroid Build Coastguard Worker  * xmlParserInputGrow:
597*7c568831SAndroid Build Coastguard Worker  * @in:  an XML parser input
598*7c568831SAndroid Build Coastguard Worker  * @len:  an indicative size for the lookahead
599*7c568831SAndroid Build Coastguard Worker  *
600*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
601*7c568831SAndroid Build Coastguard Worker  *
602*7c568831SAndroid Build Coastguard Worker  * This function increase the input for the parser. It tries to
603*7c568831SAndroid Build Coastguard Worker  * preserve pointers to the input buffer, and keep already read data
604*7c568831SAndroid Build Coastguard Worker  *
605*7c568831SAndroid Build Coastguard Worker  * Returns the amount of char read, or -1 in case of error, 0 indicate the
606*7c568831SAndroid Build Coastguard Worker  * end of this entity
607*7c568831SAndroid Build Coastguard Worker  */
608*7c568831SAndroid Build Coastguard Worker int
xmlParserInputGrow(xmlParserInputPtr in,int len)609*7c568831SAndroid Build Coastguard Worker xmlParserInputGrow(xmlParserInputPtr in, int len) {
610*7c568831SAndroid Build Coastguard Worker     int ret;
611*7c568831SAndroid Build Coastguard Worker     size_t indx;
612*7c568831SAndroid Build Coastguard Worker 
613*7c568831SAndroid Build Coastguard Worker     if ((in == NULL) || (len < 0)) return(-1);
614*7c568831SAndroid Build Coastguard Worker     if (in->buf == NULL) return(-1);
615*7c568831SAndroid Build Coastguard Worker     if (in->base == NULL) return(-1);
616*7c568831SAndroid Build Coastguard Worker     if (in->cur == NULL) return(-1);
617*7c568831SAndroid Build Coastguard Worker     if (in->buf->buffer == NULL) return(-1);
618*7c568831SAndroid Build Coastguard Worker 
619*7c568831SAndroid Build Coastguard Worker     /* Don't grow memory buffers. */
620*7c568831SAndroid Build Coastguard Worker     if ((in->buf->encoder == NULL) && (in->buf->readcallback == NULL))
621*7c568831SAndroid Build Coastguard Worker         return(0);
622*7c568831SAndroid Build Coastguard Worker 
623*7c568831SAndroid Build Coastguard Worker     indx = in->cur - in->base;
624*7c568831SAndroid Build Coastguard Worker     if (xmlBufUse(in->buf->buffer) > (unsigned int) indx + INPUT_CHUNK) {
625*7c568831SAndroid Build Coastguard Worker         return(0);
626*7c568831SAndroid Build Coastguard Worker     }
627*7c568831SAndroid Build Coastguard Worker     ret = xmlParserInputBufferGrow(in->buf, len);
628*7c568831SAndroid Build Coastguard Worker 
629*7c568831SAndroid Build Coastguard Worker     in->base = xmlBufContent(in->buf->buffer);
630*7c568831SAndroid Build Coastguard Worker     if (in->base == NULL) {
631*7c568831SAndroid Build Coastguard Worker         in->base = BAD_CAST "";
632*7c568831SAndroid Build Coastguard Worker         in->cur = in->base;
633*7c568831SAndroid Build Coastguard Worker         in->end = in->base;
634*7c568831SAndroid Build Coastguard Worker         return(-1);
635*7c568831SAndroid Build Coastguard Worker     }
636*7c568831SAndroid Build Coastguard Worker     in->cur = in->base + indx;
637*7c568831SAndroid Build Coastguard Worker     in->end = xmlBufEnd(in->buf->buffer);
638*7c568831SAndroid Build Coastguard Worker 
639*7c568831SAndroid Build Coastguard Worker     return(ret);
640*7c568831SAndroid Build Coastguard Worker }
641*7c568831SAndroid Build Coastguard Worker 
642*7c568831SAndroid Build Coastguard Worker /**
643*7c568831SAndroid Build Coastguard Worker  * xmlParserShrink:
644*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
645*7c568831SAndroid Build Coastguard Worker  *
646*7c568831SAndroid Build Coastguard Worker  * Shrink the input buffer.
647*7c568831SAndroid Build Coastguard Worker  */
648*7c568831SAndroid Build Coastguard Worker void
xmlParserShrink(xmlParserCtxtPtr ctxt)649*7c568831SAndroid Build Coastguard Worker xmlParserShrink(xmlParserCtxtPtr ctxt) {
650*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr in = ctxt->input;
651*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr buf = in->buf;
652*7c568831SAndroid Build Coastguard Worker     size_t used, res;
653*7c568831SAndroid Build Coastguard Worker 
654*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
655*7c568831SAndroid Build Coastguard Worker         return;
656*7c568831SAndroid Build Coastguard Worker 
657*7c568831SAndroid Build Coastguard Worker     used = in->cur - in->base;
658*7c568831SAndroid Build Coastguard Worker 
659*7c568831SAndroid Build Coastguard Worker     if (used > LINE_LEN) {
660*7c568831SAndroid Build Coastguard Worker         res = xmlBufShrink(buf->buffer, used - LINE_LEN);
661*7c568831SAndroid Build Coastguard Worker 
662*7c568831SAndroid Build Coastguard Worker         if (res > 0) {
663*7c568831SAndroid Build Coastguard Worker             used -= res;
664*7c568831SAndroid Build Coastguard Worker             if ((res > ULONG_MAX) ||
665*7c568831SAndroid Build Coastguard Worker                 (in->consumed > ULONG_MAX - (unsigned long)res))
666*7c568831SAndroid Build Coastguard Worker                 in->consumed = ULONG_MAX;
667*7c568831SAndroid Build Coastguard Worker             else
668*7c568831SAndroid Build Coastguard Worker                 in->consumed += res;
669*7c568831SAndroid Build Coastguard Worker         }
670*7c568831SAndroid Build Coastguard Worker 
671*7c568831SAndroid Build Coastguard Worker         xmlBufUpdateInput(buf->buffer, in, used);
672*7c568831SAndroid Build Coastguard Worker     }
673*7c568831SAndroid Build Coastguard Worker }
674*7c568831SAndroid Build Coastguard Worker 
675*7c568831SAndroid Build Coastguard Worker /**
676*7c568831SAndroid Build Coastguard Worker  * xmlParserInputShrink:
677*7c568831SAndroid Build Coastguard Worker  * @in:  an XML parser input
678*7c568831SAndroid Build Coastguard Worker  *
679*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
680*7c568831SAndroid Build Coastguard Worker  *
681*7c568831SAndroid Build Coastguard Worker  * This function removes used input for the parser.
682*7c568831SAndroid Build Coastguard Worker  */
683*7c568831SAndroid Build Coastguard Worker void
xmlParserInputShrink(xmlParserInputPtr in)684*7c568831SAndroid Build Coastguard Worker xmlParserInputShrink(xmlParserInputPtr in) {
685*7c568831SAndroid Build Coastguard Worker     size_t used;
686*7c568831SAndroid Build Coastguard Worker     size_t ret;
687*7c568831SAndroid Build Coastguard Worker 
688*7c568831SAndroid Build Coastguard Worker     if (in == NULL) return;
689*7c568831SAndroid Build Coastguard Worker     if (in->buf == NULL) return;
690*7c568831SAndroid Build Coastguard Worker     if (in->base == NULL) return;
691*7c568831SAndroid Build Coastguard Worker     if (in->cur == NULL) return;
692*7c568831SAndroid Build Coastguard Worker     if (in->buf->buffer == NULL) return;
693*7c568831SAndroid Build Coastguard Worker 
694*7c568831SAndroid Build Coastguard Worker     used = in->cur - in->base;
695*7c568831SAndroid Build Coastguard Worker 
696*7c568831SAndroid Build Coastguard Worker     if (used > LINE_LEN) {
697*7c568831SAndroid Build Coastguard Worker 	ret = xmlBufShrink(in->buf->buffer, used - LINE_LEN);
698*7c568831SAndroid Build Coastguard Worker 	if (ret > 0) {
699*7c568831SAndroid Build Coastguard Worker             used -= ret;
700*7c568831SAndroid Build Coastguard Worker             if ((ret > ULONG_MAX) ||
701*7c568831SAndroid Build Coastguard Worker                 (in->consumed > ULONG_MAX - (unsigned long)ret))
702*7c568831SAndroid Build Coastguard Worker                 in->consumed = ULONG_MAX;
703*7c568831SAndroid Build Coastguard Worker             else
704*7c568831SAndroid Build Coastguard Worker                 in->consumed += ret;
705*7c568831SAndroid Build Coastguard Worker 	}
706*7c568831SAndroid Build Coastguard Worker 
707*7c568831SAndroid Build Coastguard Worker         xmlBufUpdateInput(in->buf->buffer, in, used);
708*7c568831SAndroid Build Coastguard Worker     }
709*7c568831SAndroid Build Coastguard Worker }
710*7c568831SAndroid Build Coastguard Worker 
711*7c568831SAndroid Build Coastguard Worker /************************************************************************
712*7c568831SAndroid Build Coastguard Worker  *									*
713*7c568831SAndroid Build Coastguard Worker  *		UTF8 character input and related functions		*
714*7c568831SAndroid Build Coastguard Worker  *									*
715*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
716*7c568831SAndroid Build Coastguard Worker 
717*7c568831SAndroid Build Coastguard Worker /**
718*7c568831SAndroid Build Coastguard Worker  * xmlNextChar:
719*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the XML parser context
720*7c568831SAndroid Build Coastguard Worker  *
721*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Internal function, do not use.
722*7c568831SAndroid Build Coastguard Worker  *
723*7c568831SAndroid Build Coastguard Worker  * Skip to the next char input char.
724*7c568831SAndroid Build Coastguard Worker  */
725*7c568831SAndroid Build Coastguard Worker 
726*7c568831SAndroid Build Coastguard Worker void
xmlNextChar(xmlParserCtxtPtr ctxt)727*7c568831SAndroid Build Coastguard Worker xmlNextChar(xmlParserCtxtPtr ctxt)
728*7c568831SAndroid Build Coastguard Worker {
729*7c568831SAndroid Build Coastguard Worker     const unsigned char *cur;
730*7c568831SAndroid Build Coastguard Worker     size_t avail;
731*7c568831SAndroid Build Coastguard Worker     int c;
732*7c568831SAndroid Build Coastguard Worker 
733*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->input == NULL))
734*7c568831SAndroid Build Coastguard Worker         return;
735*7c568831SAndroid Build Coastguard Worker 
736*7c568831SAndroid Build Coastguard Worker     avail = ctxt->input->end - ctxt->input->cur;
737*7c568831SAndroid Build Coastguard Worker 
738*7c568831SAndroid Build Coastguard Worker     if (avail < INPUT_CHUNK) {
739*7c568831SAndroid Build Coastguard Worker         xmlParserGrow(ctxt);
740*7c568831SAndroid Build Coastguard Worker         if (ctxt->input->cur >= ctxt->input->end)
741*7c568831SAndroid Build Coastguard Worker             return;
742*7c568831SAndroid Build Coastguard Worker         avail = ctxt->input->end - ctxt->input->cur;
743*7c568831SAndroid Build Coastguard Worker     }
744*7c568831SAndroid Build Coastguard Worker 
745*7c568831SAndroid Build Coastguard Worker     cur = ctxt->input->cur;
746*7c568831SAndroid Build Coastguard Worker     c = *cur;
747*7c568831SAndroid Build Coastguard Worker 
748*7c568831SAndroid Build Coastguard Worker     if (c < 0x80) {
749*7c568831SAndroid Build Coastguard Worker         if (c == '\n') {
750*7c568831SAndroid Build Coastguard Worker             ctxt->input->cur++;
751*7c568831SAndroid Build Coastguard Worker             ctxt->input->line++;
752*7c568831SAndroid Build Coastguard Worker             ctxt->input->col = 1;
753*7c568831SAndroid Build Coastguard Worker         } else if (c == '\r') {
754*7c568831SAndroid Build Coastguard Worker             /*
755*7c568831SAndroid Build Coastguard Worker              *   2.11 End-of-Line Handling
756*7c568831SAndroid Build Coastguard Worker              *   the literal two-character sequence "#xD#xA" or a standalone
757*7c568831SAndroid Build Coastguard Worker              *   literal #xD, an XML processor must pass to the application
758*7c568831SAndroid Build Coastguard Worker              *   the single character #xA.
759*7c568831SAndroid Build Coastguard Worker              */
760*7c568831SAndroid Build Coastguard Worker             ctxt->input->cur += ((cur[1] == '\n') ? 2 : 1);
761*7c568831SAndroid Build Coastguard Worker             ctxt->input->line++;
762*7c568831SAndroid Build Coastguard Worker             ctxt->input->col = 1;
763*7c568831SAndroid Build Coastguard Worker             return;
764*7c568831SAndroid Build Coastguard Worker         } else {
765*7c568831SAndroid Build Coastguard Worker             ctxt->input->cur++;
766*7c568831SAndroid Build Coastguard Worker             ctxt->input->col++;
767*7c568831SAndroid Build Coastguard Worker         }
768*7c568831SAndroid Build Coastguard Worker     } else {
769*7c568831SAndroid Build Coastguard Worker         ctxt->input->col++;
770*7c568831SAndroid Build Coastguard Worker 
771*7c568831SAndroid Build Coastguard Worker         if ((avail < 2) || (cur[1] & 0xc0) != 0x80)
772*7c568831SAndroid Build Coastguard Worker             goto encoding_error;
773*7c568831SAndroid Build Coastguard Worker 
774*7c568831SAndroid Build Coastguard Worker         if (c < 0xe0) {
775*7c568831SAndroid Build Coastguard Worker             /* 2-byte code */
776*7c568831SAndroid Build Coastguard Worker             if (c < 0xc2)
777*7c568831SAndroid Build Coastguard Worker                 goto encoding_error;
778*7c568831SAndroid Build Coastguard Worker             ctxt->input->cur += 2;
779*7c568831SAndroid Build Coastguard Worker         } else {
780*7c568831SAndroid Build Coastguard Worker             unsigned int val = (c << 8) | cur[1];
781*7c568831SAndroid Build Coastguard Worker 
782*7c568831SAndroid Build Coastguard Worker             if ((avail < 3) || (cur[2] & 0xc0) != 0x80)
783*7c568831SAndroid Build Coastguard Worker                 goto encoding_error;
784*7c568831SAndroid Build Coastguard Worker 
785*7c568831SAndroid Build Coastguard Worker             if (c < 0xf0) {
786*7c568831SAndroid Build Coastguard Worker                 /* 3-byte code */
787*7c568831SAndroid Build Coastguard Worker                 if ((val < 0xe0a0) || ((val >= 0xeda0) && (val < 0xee00)))
788*7c568831SAndroid Build Coastguard Worker                     goto encoding_error;
789*7c568831SAndroid Build Coastguard Worker                 ctxt->input->cur += 3;
790*7c568831SAndroid Build Coastguard Worker             } else {
791*7c568831SAndroid Build Coastguard Worker                 if ((avail < 4) || ((cur[3] & 0xc0) != 0x80))
792*7c568831SAndroid Build Coastguard Worker                     goto encoding_error;
793*7c568831SAndroid Build Coastguard Worker 
794*7c568831SAndroid Build Coastguard Worker                 /* 4-byte code */
795*7c568831SAndroid Build Coastguard Worker                 if ((val < 0xf090) || (val >= 0xf490))
796*7c568831SAndroid Build Coastguard Worker                     goto encoding_error;
797*7c568831SAndroid Build Coastguard Worker                 ctxt->input->cur += 4;
798*7c568831SAndroid Build Coastguard Worker             }
799*7c568831SAndroid Build Coastguard Worker         }
800*7c568831SAndroid Build Coastguard Worker     }
801*7c568831SAndroid Build Coastguard Worker 
802*7c568831SAndroid Build Coastguard Worker     return;
803*7c568831SAndroid Build Coastguard Worker 
804*7c568831SAndroid Build Coastguard Worker encoding_error:
805*7c568831SAndroid Build Coastguard Worker     /* Only report the first error */
806*7c568831SAndroid Build Coastguard Worker     if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
807*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrIO(ctxt, XML_ERR_INVALID_ENCODING, NULL);
808*7c568831SAndroid Build Coastguard Worker         ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
809*7c568831SAndroid Build Coastguard Worker     }
810*7c568831SAndroid Build Coastguard Worker     ctxt->input->cur++;
811*7c568831SAndroid Build Coastguard Worker }
812*7c568831SAndroid Build Coastguard Worker 
813*7c568831SAndroid Build Coastguard Worker /**
814*7c568831SAndroid Build Coastguard Worker  * xmlCurrentChar:
815*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the XML parser context
816*7c568831SAndroid Build Coastguard Worker  * @len:  pointer to the length of the char read
817*7c568831SAndroid Build Coastguard Worker  *
818*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Internal function, do not use.
819*7c568831SAndroid Build Coastguard Worker  *
820*7c568831SAndroid Build Coastguard Worker  * The current char value, if using UTF-8 this may actually span multiple
821*7c568831SAndroid Build Coastguard Worker  * bytes in the input buffer. Implement the end of line normalization:
822*7c568831SAndroid Build Coastguard Worker  * 2.11 End-of-Line Handling
823*7c568831SAndroid Build Coastguard Worker  * Wherever an external parsed entity or the literal entity value
824*7c568831SAndroid Build Coastguard Worker  * of an internal parsed entity contains either the literal two-character
825*7c568831SAndroid Build Coastguard Worker  * sequence "#xD#xA" or a standalone literal #xD, an XML processor
826*7c568831SAndroid Build Coastguard Worker  * must pass to the application the single character #xA.
827*7c568831SAndroid Build Coastguard Worker  * This behavior can conveniently be produced by normalizing all
828*7c568831SAndroid Build Coastguard Worker  * line breaks to #xA on input, before parsing.)
829*7c568831SAndroid Build Coastguard Worker  *
830*7c568831SAndroid Build Coastguard Worker  * Returns the current char value and its length
831*7c568831SAndroid Build Coastguard Worker  */
832*7c568831SAndroid Build Coastguard Worker 
833*7c568831SAndroid Build Coastguard Worker int
xmlCurrentChar(xmlParserCtxtPtr ctxt,int * len)834*7c568831SAndroid Build Coastguard Worker xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
835*7c568831SAndroid Build Coastguard Worker     const unsigned char *cur;
836*7c568831SAndroid Build Coastguard Worker     size_t avail;
837*7c568831SAndroid Build Coastguard Worker     int c;
838*7c568831SAndroid Build Coastguard Worker 
839*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (len == NULL) || (ctxt->input == NULL)) return(0);
840*7c568831SAndroid Build Coastguard Worker 
841*7c568831SAndroid Build Coastguard Worker     avail = ctxt->input->end - ctxt->input->cur;
842*7c568831SAndroid Build Coastguard Worker 
843*7c568831SAndroid Build Coastguard Worker     if (avail < INPUT_CHUNK) {
844*7c568831SAndroid Build Coastguard Worker         xmlParserGrow(ctxt);
845*7c568831SAndroid Build Coastguard Worker         avail = ctxt->input->end - ctxt->input->cur;
846*7c568831SAndroid Build Coastguard Worker     }
847*7c568831SAndroid Build Coastguard Worker 
848*7c568831SAndroid Build Coastguard Worker     cur = ctxt->input->cur;
849*7c568831SAndroid Build Coastguard Worker     c = *cur;
850*7c568831SAndroid Build Coastguard Worker 
851*7c568831SAndroid Build Coastguard Worker     if (c < 0x80) {
852*7c568831SAndroid Build Coastguard Worker 	/* 1-byte code */
853*7c568831SAndroid Build Coastguard Worker         if (c < 0x20) {
854*7c568831SAndroid Build Coastguard Worker             /*
855*7c568831SAndroid Build Coastguard Worker              *   2.11 End-of-Line Handling
856*7c568831SAndroid Build Coastguard Worker              *   the literal two-character sequence "#xD#xA" or a standalone
857*7c568831SAndroid Build Coastguard Worker              *   literal #xD, an XML processor must pass to the application
858*7c568831SAndroid Build Coastguard Worker              *   the single character #xA.
859*7c568831SAndroid Build Coastguard Worker              */
860*7c568831SAndroid Build Coastguard Worker             if (c == '\r') {
861*7c568831SAndroid Build Coastguard Worker                 /*
862*7c568831SAndroid Build Coastguard Worker                  * TODO: This function shouldn't change the 'cur' pointer
863*7c568831SAndroid Build Coastguard Worker                  * as side effect, but the NEXTL macro in parser.c relies
864*7c568831SAndroid Build Coastguard Worker                  * on this behavior when incrementing line numbers.
865*7c568831SAndroid Build Coastguard Worker                  */
866*7c568831SAndroid Build Coastguard Worker                 if (cur[1] == '\n')
867*7c568831SAndroid Build Coastguard Worker                     ctxt->input->cur++;
868*7c568831SAndroid Build Coastguard Worker                 *len = 1;
869*7c568831SAndroid Build Coastguard Worker                 c = '\n';
870*7c568831SAndroid Build Coastguard Worker             } else if (c == 0) {
871*7c568831SAndroid Build Coastguard Worker                 if (ctxt->input->cur >= ctxt->input->end) {
872*7c568831SAndroid Build Coastguard Worker                     *len = 0;
873*7c568831SAndroid Build Coastguard Worker                 } else {
874*7c568831SAndroid Build Coastguard Worker                     *len = 1;
875*7c568831SAndroid Build Coastguard Worker                     /*
876*7c568831SAndroid Build Coastguard Worker                      * TODO: Null bytes should be handled by callers,
877*7c568831SAndroid Build Coastguard Worker                      * but this can be tricky.
878*7c568831SAndroid Build Coastguard Worker                      */
879*7c568831SAndroid Build Coastguard Worker                     xmlFatalErr(ctxt, XML_ERR_INVALID_CHAR,
880*7c568831SAndroid Build Coastguard Worker                             "Char 0x0 out of allowed range\n");
881*7c568831SAndroid Build Coastguard Worker                 }
882*7c568831SAndroid Build Coastguard Worker             } else {
883*7c568831SAndroid Build Coastguard Worker                 *len = 1;
884*7c568831SAndroid Build Coastguard Worker             }
885*7c568831SAndroid Build Coastguard Worker         } else {
886*7c568831SAndroid Build Coastguard Worker             *len = 1;
887*7c568831SAndroid Build Coastguard Worker         }
888*7c568831SAndroid Build Coastguard Worker 
889*7c568831SAndroid Build Coastguard Worker         return(c);
890*7c568831SAndroid Build Coastguard Worker     } else {
891*7c568831SAndroid Build Coastguard Worker         int val;
892*7c568831SAndroid Build Coastguard Worker 
893*7c568831SAndroid Build Coastguard Worker         if (avail < 2)
894*7c568831SAndroid Build Coastguard Worker             goto incomplete_sequence;
895*7c568831SAndroid Build Coastguard Worker         if ((cur[1] & 0xc0) != 0x80)
896*7c568831SAndroid Build Coastguard Worker             goto encoding_error;
897*7c568831SAndroid Build Coastguard Worker 
898*7c568831SAndroid Build Coastguard Worker         if (c < 0xe0) {
899*7c568831SAndroid Build Coastguard Worker             /* 2-byte code */
900*7c568831SAndroid Build Coastguard Worker             if (c < 0xc2)
901*7c568831SAndroid Build Coastguard Worker                 goto encoding_error;
902*7c568831SAndroid Build Coastguard Worker             val = (c & 0x1f) << 6;
903*7c568831SAndroid Build Coastguard Worker             val |= cur[1] & 0x3f;
904*7c568831SAndroid Build Coastguard Worker             *len = 2;
905*7c568831SAndroid Build Coastguard Worker         } else {
906*7c568831SAndroid Build Coastguard Worker             if (avail < 3)
907*7c568831SAndroid Build Coastguard Worker                 goto incomplete_sequence;
908*7c568831SAndroid Build Coastguard Worker             if ((cur[2] & 0xc0) != 0x80)
909*7c568831SAndroid Build Coastguard Worker                 goto encoding_error;
910*7c568831SAndroid Build Coastguard Worker 
911*7c568831SAndroid Build Coastguard Worker             if (c < 0xf0) {
912*7c568831SAndroid Build Coastguard Worker                 /* 3-byte code */
913*7c568831SAndroid Build Coastguard Worker                 val = (c & 0xf) << 12;
914*7c568831SAndroid Build Coastguard Worker                 val |= (cur[1] & 0x3f) << 6;
915*7c568831SAndroid Build Coastguard Worker                 val |= cur[2] & 0x3f;
916*7c568831SAndroid Build Coastguard Worker                 if ((val < 0x800) || ((val >= 0xd800) && (val < 0xe000)))
917*7c568831SAndroid Build Coastguard Worker                     goto encoding_error;
918*7c568831SAndroid Build Coastguard Worker                 *len = 3;
919*7c568831SAndroid Build Coastguard Worker             } else {
920*7c568831SAndroid Build Coastguard Worker                 if (avail < 4)
921*7c568831SAndroid Build Coastguard Worker                     goto incomplete_sequence;
922*7c568831SAndroid Build Coastguard Worker                 if ((cur[3] & 0xc0) != 0x80)
923*7c568831SAndroid Build Coastguard Worker                     goto encoding_error;
924*7c568831SAndroid Build Coastguard Worker 
925*7c568831SAndroid Build Coastguard Worker                 /* 4-byte code */
926*7c568831SAndroid Build Coastguard Worker                 val = (c & 0x0f) << 18;
927*7c568831SAndroid Build Coastguard Worker                 val |= (cur[1] & 0x3f) << 12;
928*7c568831SAndroid Build Coastguard Worker                 val |= (cur[2] & 0x3f) << 6;
929*7c568831SAndroid Build Coastguard Worker                 val |= cur[3] & 0x3f;
930*7c568831SAndroid Build Coastguard Worker                 if ((val < 0x10000) || (val >= 0x110000))
931*7c568831SAndroid Build Coastguard Worker                     goto encoding_error;
932*7c568831SAndroid Build Coastguard Worker                 *len = 4;
933*7c568831SAndroid Build Coastguard Worker             }
934*7c568831SAndroid Build Coastguard Worker         }
935*7c568831SAndroid Build Coastguard Worker 
936*7c568831SAndroid Build Coastguard Worker         return(val);
937*7c568831SAndroid Build Coastguard Worker     }
938*7c568831SAndroid Build Coastguard Worker 
939*7c568831SAndroid Build Coastguard Worker encoding_error:
940*7c568831SAndroid Build Coastguard Worker     /* Only report the first error */
941*7c568831SAndroid Build Coastguard Worker     if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
942*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrIO(ctxt, XML_ERR_INVALID_ENCODING, NULL);
943*7c568831SAndroid Build Coastguard Worker         ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
944*7c568831SAndroid Build Coastguard Worker     }
945*7c568831SAndroid Build Coastguard Worker     *len = 1;
946*7c568831SAndroid Build Coastguard Worker     return(XML_INVALID_CHAR);
947*7c568831SAndroid Build Coastguard Worker 
948*7c568831SAndroid Build Coastguard Worker incomplete_sequence:
949*7c568831SAndroid Build Coastguard Worker     /*
950*7c568831SAndroid Build Coastguard Worker      * An encoding problem may arise from a truncated input buffer
951*7c568831SAndroid Build Coastguard Worker      * splitting a character in the middle. In that case do not raise
952*7c568831SAndroid Build Coastguard Worker      * an error but return 0. This should only happen when push parsing
953*7c568831SAndroid Build Coastguard Worker      * char data.
954*7c568831SAndroid Build Coastguard Worker      */
955*7c568831SAndroid Build Coastguard Worker     *len = 0;
956*7c568831SAndroid Build Coastguard Worker     return(0);
957*7c568831SAndroid Build Coastguard Worker }
958*7c568831SAndroid Build Coastguard Worker 
959*7c568831SAndroid Build Coastguard Worker /**
960*7c568831SAndroid Build Coastguard Worker  * xmlStringCurrentChar:
961*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the XML parser context
962*7c568831SAndroid Build Coastguard Worker  * @cur:  pointer to the beginning of the char
963*7c568831SAndroid Build Coastguard Worker  * @len:  pointer to the length of the char read
964*7c568831SAndroid Build Coastguard Worker  *
965*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Internal function, do not use.
966*7c568831SAndroid Build Coastguard Worker  *
967*7c568831SAndroid Build Coastguard Worker  * The current char value, if using UTF-8 this may actually span multiple
968*7c568831SAndroid Build Coastguard Worker  * bytes in the input buffer.
969*7c568831SAndroid Build Coastguard Worker  *
970*7c568831SAndroid Build Coastguard Worker  * Returns the current char value and its length
971*7c568831SAndroid Build Coastguard Worker  */
972*7c568831SAndroid Build Coastguard Worker 
973*7c568831SAndroid Build Coastguard Worker int
xmlStringCurrentChar(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,const xmlChar * cur,int * len)974*7c568831SAndroid Build Coastguard Worker xmlStringCurrentChar(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
975*7c568831SAndroid Build Coastguard Worker                      const xmlChar *cur, int *len) {
976*7c568831SAndroid Build Coastguard Worker     int c;
977*7c568831SAndroid Build Coastguard Worker 
978*7c568831SAndroid Build Coastguard Worker     if ((cur == NULL) || (len == NULL))
979*7c568831SAndroid Build Coastguard Worker         return(0);
980*7c568831SAndroid Build Coastguard Worker 
981*7c568831SAndroid Build Coastguard Worker     /* cur is zero-terminated, so we can lie about its length. */
982*7c568831SAndroid Build Coastguard Worker     *len = 4;
983*7c568831SAndroid Build Coastguard Worker     c = xmlGetUTF8Char(cur, len);
984*7c568831SAndroid Build Coastguard Worker 
985*7c568831SAndroid Build Coastguard Worker     return((c < 0) ? 0 : c);
986*7c568831SAndroid Build Coastguard Worker }
987*7c568831SAndroid Build Coastguard Worker 
988*7c568831SAndroid Build Coastguard Worker /**
989*7c568831SAndroid Build Coastguard Worker  * xmlCopyCharMultiByte:
990*7c568831SAndroid Build Coastguard Worker  * @out:  pointer to an array of xmlChar
991*7c568831SAndroid Build Coastguard Worker  * @val:  the char value
992*7c568831SAndroid Build Coastguard Worker  *
993*7c568831SAndroid Build Coastguard Worker  * append the char value in the array
994*7c568831SAndroid Build Coastguard Worker  *
995*7c568831SAndroid Build Coastguard Worker  * Returns the number of xmlChar written
996*7c568831SAndroid Build Coastguard Worker  */
997*7c568831SAndroid Build Coastguard Worker int
xmlCopyCharMultiByte(xmlChar * out,int val)998*7c568831SAndroid Build Coastguard Worker xmlCopyCharMultiByte(xmlChar *out, int val) {
999*7c568831SAndroid Build Coastguard Worker     if ((out == NULL) || (val < 0)) return(0);
1000*7c568831SAndroid Build Coastguard Worker     /*
1001*7c568831SAndroid Build Coastguard Worker      * We are supposed to handle UTF8, check it's valid
1002*7c568831SAndroid Build Coastguard Worker      * From rfc2044: encoding of the Unicode values on UTF-8:
1003*7c568831SAndroid Build Coastguard Worker      *
1004*7c568831SAndroid Build Coastguard Worker      * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
1005*7c568831SAndroid Build Coastguard Worker      * 0000 0000-0000 007F   0xxxxxxx
1006*7c568831SAndroid Build Coastguard Worker      * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
1007*7c568831SAndroid Build Coastguard Worker      * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
1008*7c568831SAndroid Build Coastguard Worker      */
1009*7c568831SAndroid Build Coastguard Worker     if  (val >= 0x80) {
1010*7c568831SAndroid Build Coastguard Worker 	xmlChar *savedout = out;
1011*7c568831SAndroid Build Coastguard Worker 	int bits;
1012*7c568831SAndroid Build Coastguard Worker 	if (val <   0x800) { *out++= (val >>  6) | 0xC0;  bits=  0; }
1013*7c568831SAndroid Build Coastguard Worker 	else if (val < 0x10000) { *out++= (val >> 12) | 0xE0;  bits=  6;}
1014*7c568831SAndroid Build Coastguard Worker 	else if (val < 0x110000)  { *out++= (val >> 18) | 0xF0;  bits=  12; }
1015*7c568831SAndroid Build Coastguard Worker 	else {
1016*7c568831SAndroid Build Coastguard Worker #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1017*7c568831SAndroid Build Coastguard Worker             xmlAbort("xmlCopyCharMultiByte: codepoint out of range\n");
1018*7c568831SAndroid Build Coastguard Worker #endif
1019*7c568831SAndroid Build Coastguard Worker 	    return(0);
1020*7c568831SAndroid Build Coastguard Worker 	}
1021*7c568831SAndroid Build Coastguard Worker 	for ( ; bits >= 0; bits-= 6)
1022*7c568831SAndroid Build Coastguard Worker 	    *out++= ((val >> bits) & 0x3F) | 0x80 ;
1023*7c568831SAndroid Build Coastguard Worker 	return (out - savedout);
1024*7c568831SAndroid Build Coastguard Worker     }
1025*7c568831SAndroid Build Coastguard Worker     *out = val;
1026*7c568831SAndroid Build Coastguard Worker     return 1;
1027*7c568831SAndroid Build Coastguard Worker }
1028*7c568831SAndroid Build Coastguard Worker 
1029*7c568831SAndroid Build Coastguard Worker /**
1030*7c568831SAndroid Build Coastguard Worker  * xmlCopyChar:
1031*7c568831SAndroid Build Coastguard Worker  * @len:  Ignored, compatibility
1032*7c568831SAndroid Build Coastguard Worker  * @out:  pointer to an array of xmlChar
1033*7c568831SAndroid Build Coastguard Worker  * @val:  the char value
1034*7c568831SAndroid Build Coastguard Worker  *
1035*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
1036*7c568831SAndroid Build Coastguard Worker  *
1037*7c568831SAndroid Build Coastguard Worker  * append the char value in the array
1038*7c568831SAndroid Build Coastguard Worker  *
1039*7c568831SAndroid Build Coastguard Worker  * Returns the number of xmlChar written
1040*7c568831SAndroid Build Coastguard Worker  */
1041*7c568831SAndroid Build Coastguard Worker 
1042*7c568831SAndroid Build Coastguard Worker int
xmlCopyChar(int len ATTRIBUTE_UNUSED,xmlChar * out,int val)1043*7c568831SAndroid Build Coastguard Worker xmlCopyChar(int len ATTRIBUTE_UNUSED, xmlChar *out, int val) {
1044*7c568831SAndroid Build Coastguard Worker     if ((out == NULL) || (val < 0)) return(0);
1045*7c568831SAndroid Build Coastguard Worker     /* the len parameter is ignored */
1046*7c568831SAndroid Build Coastguard Worker     if  (val >= 0x80) {
1047*7c568831SAndroid Build Coastguard Worker 	return(xmlCopyCharMultiByte (out, val));
1048*7c568831SAndroid Build Coastguard Worker     }
1049*7c568831SAndroid Build Coastguard Worker     *out = val;
1050*7c568831SAndroid Build Coastguard Worker     return 1;
1051*7c568831SAndroid Build Coastguard Worker }
1052*7c568831SAndroid Build Coastguard Worker 
1053*7c568831SAndroid Build Coastguard Worker /************************************************************************
1054*7c568831SAndroid Build Coastguard Worker  *									*
1055*7c568831SAndroid Build Coastguard Worker  *		Commodity functions to switch encodings			*
1056*7c568831SAndroid Build Coastguard Worker  *									*
1057*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
1058*7c568831SAndroid Build Coastguard Worker 
1059*7c568831SAndroid Build Coastguard Worker /**
1060*7c568831SAndroid Build Coastguard Worker  * xmlCtxtSetCharEncConvImpl:
1061*7c568831SAndroid Build Coastguard Worker  * @ctxt:  parser context
1062*7c568831SAndroid Build Coastguard Worker  * @impl:  callback
1063*7c568831SAndroid Build Coastguard Worker  * @vctxt:  user data
1064*7c568831SAndroid Build Coastguard Worker  *
1065*7c568831SAndroid Build Coastguard Worker  * Installs a custom implementation to convert between character
1066*7c568831SAndroid Build Coastguard Worker  * encodings.
1067*7c568831SAndroid Build Coastguard Worker  *
1068*7c568831SAndroid Build Coastguard Worker  * This bypasses legacy feature like global encoding handlers or
1069*7c568831SAndroid Build Coastguard Worker  * encoding aliases.
1070*7c568831SAndroid Build Coastguard Worker  *
1071*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
1072*7c568831SAndroid Build Coastguard Worker  */
1073*7c568831SAndroid Build Coastguard Worker void
xmlCtxtSetCharEncConvImpl(xmlParserCtxtPtr ctxt,xmlCharEncConvImpl impl,void * vctxt)1074*7c568831SAndroid Build Coastguard Worker xmlCtxtSetCharEncConvImpl(xmlParserCtxtPtr ctxt, xmlCharEncConvImpl impl,
1075*7c568831SAndroid Build Coastguard Worker                           void *vctxt) {
1076*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
1077*7c568831SAndroid Build Coastguard Worker         return;
1078*7c568831SAndroid Build Coastguard Worker 
1079*7c568831SAndroid Build Coastguard Worker     ctxt->convImpl = impl;
1080*7c568831SAndroid Build Coastguard Worker     ctxt->convCtxt = vctxt;
1081*7c568831SAndroid Build Coastguard Worker }
1082*7c568831SAndroid Build Coastguard Worker 
1083*7c568831SAndroid Build Coastguard Worker static int
xmlDetectEBCDIC(xmlParserCtxtPtr ctxt,xmlCharEncodingHandlerPtr * hout)1084*7c568831SAndroid Build Coastguard Worker xmlDetectEBCDIC(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr *hout) {
1085*7c568831SAndroid Build Coastguard Worker     xmlChar out[200];
1086*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input = ctxt->input;
1087*7c568831SAndroid Build Coastguard Worker     xmlCharEncodingHandlerPtr handler;
1088*7c568831SAndroid Build Coastguard Worker     int inlen, outlen, res, i;
1089*7c568831SAndroid Build Coastguard Worker 
1090*7c568831SAndroid Build Coastguard Worker     *hout = NULL;
1091*7c568831SAndroid Build Coastguard Worker 
1092*7c568831SAndroid Build Coastguard Worker     /*
1093*7c568831SAndroid Build Coastguard Worker      * To detect the EBCDIC code page, we convert the first 200 bytes
1094*7c568831SAndroid Build Coastguard Worker      * to IBM037 (EBCDIC-US) and try to find the encoding declaration.
1095*7c568831SAndroid Build Coastguard Worker      */
1096*7c568831SAndroid Build Coastguard Worker     res = xmlCreateCharEncodingHandler("IBM037", /* output */ 0,
1097*7c568831SAndroid Build Coastguard Worker             ctxt->convImpl, ctxt->convCtxt, &handler);
1098*7c568831SAndroid Build Coastguard Worker     if (res != 0)
1099*7c568831SAndroid Build Coastguard Worker         return(res);
1100*7c568831SAndroid Build Coastguard Worker     outlen = sizeof(out) - 1;
1101*7c568831SAndroid Build Coastguard Worker     inlen = input->end - input->cur;
1102*7c568831SAndroid Build Coastguard Worker     res = xmlEncInputChunk(handler, out, &outlen, input->cur, &inlen);
1103*7c568831SAndroid Build Coastguard Worker     /*
1104*7c568831SAndroid Build Coastguard Worker      * Return the EBCDIC handler if decoding failed. The error will
1105*7c568831SAndroid Build Coastguard Worker      * be reported later.
1106*7c568831SAndroid Build Coastguard Worker      */
1107*7c568831SAndroid Build Coastguard Worker     if (res < 0)
1108*7c568831SAndroid Build Coastguard Worker         goto done;
1109*7c568831SAndroid Build Coastguard Worker     out[outlen] = 0;
1110*7c568831SAndroid Build Coastguard Worker 
1111*7c568831SAndroid Build Coastguard Worker     for (i = 0; i < outlen; i++) {
1112*7c568831SAndroid Build Coastguard Worker         if (out[i] == '>')
1113*7c568831SAndroid Build Coastguard Worker             break;
1114*7c568831SAndroid Build Coastguard Worker         if ((out[i] == 'e') &&
1115*7c568831SAndroid Build Coastguard Worker             (xmlStrncmp(out + i, BAD_CAST "encoding", 8) == 0)) {
1116*7c568831SAndroid Build Coastguard Worker             int start, cur, quote;
1117*7c568831SAndroid Build Coastguard Worker 
1118*7c568831SAndroid Build Coastguard Worker             i += 8;
1119*7c568831SAndroid Build Coastguard Worker             while (IS_BLANK_CH(out[i]))
1120*7c568831SAndroid Build Coastguard Worker                 i += 1;
1121*7c568831SAndroid Build Coastguard Worker             if (out[i++] != '=')
1122*7c568831SAndroid Build Coastguard Worker                 break;
1123*7c568831SAndroid Build Coastguard Worker             while (IS_BLANK_CH(out[i]))
1124*7c568831SAndroid Build Coastguard Worker                 i += 1;
1125*7c568831SAndroid Build Coastguard Worker             quote = out[i++];
1126*7c568831SAndroid Build Coastguard Worker             if ((quote != '\'') && (quote != '"'))
1127*7c568831SAndroid Build Coastguard Worker                 break;
1128*7c568831SAndroid Build Coastguard Worker             start = i;
1129*7c568831SAndroid Build Coastguard Worker             cur = out[i];
1130*7c568831SAndroid Build Coastguard Worker             while (((cur >= 'a') && (cur <= 'z')) ||
1131*7c568831SAndroid Build Coastguard Worker                    ((cur >= 'A') && (cur <= 'Z')) ||
1132*7c568831SAndroid Build Coastguard Worker                    ((cur >= '0') && (cur <= '9')) ||
1133*7c568831SAndroid Build Coastguard Worker                    (cur == '.') || (cur == '_') ||
1134*7c568831SAndroid Build Coastguard Worker                    (cur == '-'))
1135*7c568831SAndroid Build Coastguard Worker                 cur = out[++i];
1136*7c568831SAndroid Build Coastguard Worker             if (cur != quote)
1137*7c568831SAndroid Build Coastguard Worker                 break;
1138*7c568831SAndroid Build Coastguard Worker             out[i] = 0;
1139*7c568831SAndroid Build Coastguard Worker             xmlCharEncCloseFunc(handler);
1140*7c568831SAndroid Build Coastguard Worker             res = xmlCreateCharEncodingHandler((char *) out + start,
1141*7c568831SAndroid Build Coastguard Worker                     /* output */ 0, ctxt->convImpl, ctxt->convCtxt,
1142*7c568831SAndroid Build Coastguard Worker                     &handler);
1143*7c568831SAndroid Build Coastguard Worker             if (res != 0)
1144*7c568831SAndroid Build Coastguard Worker                 return(res);
1145*7c568831SAndroid Build Coastguard Worker             *hout = handler;
1146*7c568831SAndroid Build Coastguard Worker             return(0);
1147*7c568831SAndroid Build Coastguard Worker         }
1148*7c568831SAndroid Build Coastguard Worker     }
1149*7c568831SAndroid Build Coastguard Worker 
1150*7c568831SAndroid Build Coastguard Worker done:
1151*7c568831SAndroid Build Coastguard Worker     /*
1152*7c568831SAndroid Build Coastguard Worker      * Encoding handlers are stateful, so we have to recreate them.
1153*7c568831SAndroid Build Coastguard Worker      */
1154*7c568831SAndroid Build Coastguard Worker     xmlCharEncCloseFunc(handler);
1155*7c568831SAndroid Build Coastguard Worker     res = xmlCreateCharEncodingHandler("IBM037", /* output */ 0,
1156*7c568831SAndroid Build Coastguard Worker             ctxt->convImpl, ctxt->convCtxt, &handler);
1157*7c568831SAndroid Build Coastguard Worker     if (res != 0)
1158*7c568831SAndroid Build Coastguard Worker         return(res);
1159*7c568831SAndroid Build Coastguard Worker     *hout = handler;
1160*7c568831SAndroid Build Coastguard Worker     return(0);
1161*7c568831SAndroid Build Coastguard Worker }
1162*7c568831SAndroid Build Coastguard Worker 
1163*7c568831SAndroid Build Coastguard Worker /**
1164*7c568831SAndroid Build Coastguard Worker  * xmlSwitchEncoding:
1165*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the parser context
1166*7c568831SAndroid Build Coastguard Worker  * @enc:  the encoding value (number)
1167*7c568831SAndroid Build Coastguard Worker  *
1168*7c568831SAndroid Build Coastguard Worker  * Use encoding specified by enum to decode input data. This overrides
1169*7c568831SAndroid Build Coastguard Worker  * the encoding found in the XML declaration.
1170*7c568831SAndroid Build Coastguard Worker  *
1171*7c568831SAndroid Build Coastguard Worker  * This function can also be used to override the encoding of chunks
1172*7c568831SAndroid Build Coastguard Worker  * passed to xmlParseChunk.
1173*7c568831SAndroid Build Coastguard Worker  *
1174*7c568831SAndroid Build Coastguard Worker  * Returns 0 in case of success, -1 otherwise
1175*7c568831SAndroid Build Coastguard Worker  */
1176*7c568831SAndroid Build Coastguard Worker int
xmlSwitchEncoding(xmlParserCtxtPtr ctxt,xmlCharEncoding enc)1177*7c568831SAndroid Build Coastguard Worker xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
1178*7c568831SAndroid Build Coastguard Worker {
1179*7c568831SAndroid Build Coastguard Worker     xmlCharEncodingHandlerPtr handler = NULL;
1180*7c568831SAndroid Build Coastguard Worker     int ret;
1181*7c568831SAndroid Build Coastguard Worker     int res;
1182*7c568831SAndroid Build Coastguard Worker 
1183*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->input == NULL))
1184*7c568831SAndroid Build Coastguard Worker         return(-1);
1185*7c568831SAndroid Build Coastguard Worker 
1186*7c568831SAndroid Build Coastguard Worker     res = xmlLookupCharEncodingHandler(enc, &handler);
1187*7c568831SAndroid Build Coastguard Worker     if (res != 0) {
1188*7c568831SAndroid Build Coastguard Worker         xmlFatalErr(ctxt, res, NULL);
1189*7c568831SAndroid Build Coastguard Worker         return(-1);
1190*7c568831SAndroid Build Coastguard Worker     }
1191*7c568831SAndroid Build Coastguard Worker 
1192*7c568831SAndroid Build Coastguard Worker     ret = xmlSwitchToEncoding(ctxt, handler);
1193*7c568831SAndroid Build Coastguard Worker 
1194*7c568831SAndroid Build Coastguard Worker     if ((ret >= 0) && (enc == XML_CHAR_ENCODING_NONE)) {
1195*7c568831SAndroid Build Coastguard Worker         ctxt->input->flags &= ~XML_INPUT_HAS_ENCODING;
1196*7c568831SAndroid Build Coastguard Worker     }
1197*7c568831SAndroid Build Coastguard Worker 
1198*7c568831SAndroid Build Coastguard Worker     return(ret);
1199*7c568831SAndroid Build Coastguard Worker }
1200*7c568831SAndroid Build Coastguard Worker 
1201*7c568831SAndroid Build Coastguard Worker /**
1202*7c568831SAndroid Build Coastguard Worker  * xmlSwitchInputEncodingName:
1203*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the parser context
1204*7c568831SAndroid Build Coastguard Worker  * @input:  the input strea,
1205*7c568831SAndroid Build Coastguard Worker  * @encoding:  the encoding name
1206*7c568831SAndroid Build Coastguard Worker  *
1207*7c568831SAndroid Build Coastguard Worker  * Returns 0 in case of success, -1 otherwise
1208*7c568831SAndroid Build Coastguard Worker  */
1209*7c568831SAndroid Build Coastguard Worker static int
xmlSwitchInputEncodingName(xmlParserCtxtPtr ctxt,xmlParserInputPtr input,const char * encoding)1210*7c568831SAndroid Build Coastguard Worker xmlSwitchInputEncodingName(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
1211*7c568831SAndroid Build Coastguard Worker                            const char *encoding) {
1212*7c568831SAndroid Build Coastguard Worker     xmlCharEncodingHandlerPtr handler;
1213*7c568831SAndroid Build Coastguard Worker     int res;
1214*7c568831SAndroid Build Coastguard Worker 
1215*7c568831SAndroid Build Coastguard Worker     if (encoding == NULL)
1216*7c568831SAndroid Build Coastguard Worker         return(-1);
1217*7c568831SAndroid Build Coastguard Worker 
1218*7c568831SAndroid Build Coastguard Worker     res = xmlCreateCharEncodingHandler(encoding, /* output */ 0,
1219*7c568831SAndroid Build Coastguard Worker             ctxt->convImpl, ctxt->convCtxt, &handler);
1220*7c568831SAndroid Build Coastguard Worker     if (res == XML_ERR_UNSUPPORTED_ENCODING) {
1221*7c568831SAndroid Build Coastguard Worker         xmlWarningMsg(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1222*7c568831SAndroid Build Coastguard Worker                       "Unsupported encoding: %s\n", BAD_CAST encoding, NULL);
1223*7c568831SAndroid Build Coastguard Worker         return(-1);
1224*7c568831SAndroid Build Coastguard Worker     } else if (res != XML_ERR_OK) {
1225*7c568831SAndroid Build Coastguard Worker         xmlFatalErr(ctxt, res, encoding);
1226*7c568831SAndroid Build Coastguard Worker         return(-1);
1227*7c568831SAndroid Build Coastguard Worker     }
1228*7c568831SAndroid Build Coastguard Worker 
1229*7c568831SAndroid Build Coastguard Worker     res  = xmlInputSetEncodingHandler(input, handler);
1230*7c568831SAndroid Build Coastguard Worker     if (res != XML_ERR_OK) {
1231*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrIO(ctxt, res, NULL);
1232*7c568831SAndroid Build Coastguard Worker         return(-1);
1233*7c568831SAndroid Build Coastguard Worker     }
1234*7c568831SAndroid Build Coastguard Worker 
1235*7c568831SAndroid Build Coastguard Worker     return(0);
1236*7c568831SAndroid Build Coastguard Worker }
1237*7c568831SAndroid Build Coastguard Worker 
1238*7c568831SAndroid Build Coastguard Worker /**
1239*7c568831SAndroid Build Coastguard Worker  * xmlSwitchEncodingName:
1240*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the parser context
1241*7c568831SAndroid Build Coastguard Worker  * @encoding:  the encoding name
1242*7c568831SAndroid Build Coastguard Worker  *
1243*7c568831SAndroid Build Coastguard Worker  * Use specified encoding to decode input data. This overrides the
1244*7c568831SAndroid Build Coastguard Worker  * encoding found in the XML declaration.
1245*7c568831SAndroid Build Coastguard Worker  *
1246*7c568831SAndroid Build Coastguard Worker  * This function can also be used to override the encoding of chunks
1247*7c568831SAndroid Build Coastguard Worker  * passed to xmlParseChunk.
1248*7c568831SAndroid Build Coastguard Worker  *
1249*7c568831SAndroid Build Coastguard Worker  * Available since 2.13.0.
1250*7c568831SAndroid Build Coastguard Worker  *
1251*7c568831SAndroid Build Coastguard Worker  * Returns 0 in case of success, -1 otherwise
1252*7c568831SAndroid Build Coastguard Worker  */
1253*7c568831SAndroid Build Coastguard Worker int
xmlSwitchEncodingName(xmlParserCtxtPtr ctxt,const char * encoding)1254*7c568831SAndroid Build Coastguard Worker xmlSwitchEncodingName(xmlParserCtxtPtr ctxt, const char *encoding) {
1255*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
1256*7c568831SAndroid Build Coastguard Worker         return(-1);
1257*7c568831SAndroid Build Coastguard Worker 
1258*7c568831SAndroid Build Coastguard Worker     return(xmlSwitchInputEncodingName(ctxt, ctxt->input, encoding));
1259*7c568831SAndroid Build Coastguard Worker }
1260*7c568831SAndroid Build Coastguard Worker 
1261*7c568831SAndroid Build Coastguard Worker /**
1262*7c568831SAndroid Build Coastguard Worker  * xmlInputSetEncodingHandler:
1263*7c568831SAndroid Build Coastguard Worker  * @input:  the input stream
1264*7c568831SAndroid Build Coastguard Worker  * @handler:  the encoding handler
1265*7c568831SAndroid Build Coastguard Worker  *
1266*7c568831SAndroid Build Coastguard Worker  * Use encoding handler to decode input data.
1267*7c568831SAndroid Build Coastguard Worker  *
1268*7c568831SAndroid Build Coastguard Worker  * Closes the handler on error.
1269*7c568831SAndroid Build Coastguard Worker  *
1270*7c568831SAndroid Build Coastguard Worker  * Returns an xmlParserErrors code.
1271*7c568831SAndroid Build Coastguard Worker  */
1272*7c568831SAndroid Build Coastguard Worker int
xmlInputSetEncodingHandler(xmlParserInputPtr input,xmlCharEncodingHandlerPtr handler)1273*7c568831SAndroid Build Coastguard Worker xmlInputSetEncodingHandler(xmlParserInputPtr input,
1274*7c568831SAndroid Build Coastguard Worker                            xmlCharEncodingHandlerPtr handler) {
1275*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr in;
1276*7c568831SAndroid Build Coastguard Worker     xmlBufPtr buf;
1277*7c568831SAndroid Build Coastguard Worker     int code = XML_ERR_OK;
1278*7c568831SAndroid Build Coastguard Worker 
1279*7c568831SAndroid Build Coastguard Worker     if ((input == NULL) || (input->buf == NULL)) {
1280*7c568831SAndroid Build Coastguard Worker         xmlCharEncCloseFunc(handler);
1281*7c568831SAndroid Build Coastguard Worker 	return(XML_ERR_ARGUMENT);
1282*7c568831SAndroid Build Coastguard Worker     }
1283*7c568831SAndroid Build Coastguard Worker     in = input->buf;
1284*7c568831SAndroid Build Coastguard Worker 
1285*7c568831SAndroid Build Coastguard Worker     input->flags |= XML_INPUT_HAS_ENCODING;
1286*7c568831SAndroid Build Coastguard Worker 
1287*7c568831SAndroid Build Coastguard Worker     /*
1288*7c568831SAndroid Build Coastguard Worker      * UTF-8 requires no encoding handler.
1289*7c568831SAndroid Build Coastguard Worker      */
1290*7c568831SAndroid Build Coastguard Worker     if ((handler != NULL) &&
1291*7c568831SAndroid Build Coastguard Worker         (xmlStrcasecmp(BAD_CAST handler->name, BAD_CAST "UTF-8") == 0)) {
1292*7c568831SAndroid Build Coastguard Worker         xmlCharEncCloseFunc(handler);
1293*7c568831SAndroid Build Coastguard Worker         handler = NULL;
1294*7c568831SAndroid Build Coastguard Worker     }
1295*7c568831SAndroid Build Coastguard Worker 
1296*7c568831SAndroid Build Coastguard Worker     if (in->encoder == handler)
1297*7c568831SAndroid Build Coastguard Worker         return(XML_ERR_OK);
1298*7c568831SAndroid Build Coastguard Worker 
1299*7c568831SAndroid Build Coastguard Worker     if (in->encoder != NULL) {
1300*7c568831SAndroid Build Coastguard Worker         /*
1301*7c568831SAndroid Build Coastguard Worker          * Switching encodings during parsing is a really bad idea,
1302*7c568831SAndroid Build Coastguard Worker          * but Chromium can switch between ISO-8859-1 and UTF-16 before
1303*7c568831SAndroid Build Coastguard Worker          * separate calls to xmlParseChunk.
1304*7c568831SAndroid Build Coastguard Worker          *
1305*7c568831SAndroid Build Coastguard Worker          * TODO: We should check whether the "raw" input buffer is empty and
1306*7c568831SAndroid Build Coastguard Worker          * convert the old content using the old encoder.
1307*7c568831SAndroid Build Coastguard Worker          */
1308*7c568831SAndroid Build Coastguard Worker 
1309*7c568831SAndroid Build Coastguard Worker         xmlCharEncCloseFunc(in->encoder);
1310*7c568831SAndroid Build Coastguard Worker         in->encoder = handler;
1311*7c568831SAndroid Build Coastguard Worker         return(XML_ERR_OK);
1312*7c568831SAndroid Build Coastguard Worker     }
1313*7c568831SAndroid Build Coastguard Worker 
1314*7c568831SAndroid Build Coastguard Worker     buf = xmlBufCreate(XML_IO_BUFFER_SIZE);
1315*7c568831SAndroid Build Coastguard Worker     if (buf == NULL) {
1316*7c568831SAndroid Build Coastguard Worker         xmlCharEncCloseFunc(handler);
1317*7c568831SAndroid Build Coastguard Worker         return(XML_ERR_NO_MEMORY);
1318*7c568831SAndroid Build Coastguard Worker     }
1319*7c568831SAndroid Build Coastguard Worker 
1320*7c568831SAndroid Build Coastguard Worker     in->encoder = handler;
1321*7c568831SAndroid Build Coastguard Worker     in->raw = in->buffer;
1322*7c568831SAndroid Build Coastguard Worker     in->buffer = buf;
1323*7c568831SAndroid Build Coastguard Worker 
1324*7c568831SAndroid Build Coastguard Worker     /*
1325*7c568831SAndroid Build Coastguard Worker      * Is there already some content down the pipe to convert ?
1326*7c568831SAndroid Build Coastguard Worker      */
1327*7c568831SAndroid Build Coastguard Worker     if (input->end > input->base) {
1328*7c568831SAndroid Build Coastguard Worker         size_t processed;
1329*7c568831SAndroid Build Coastguard Worker         size_t nbchars;
1330*7c568831SAndroid Build Coastguard Worker         int res;
1331*7c568831SAndroid Build Coastguard Worker 
1332*7c568831SAndroid Build Coastguard Worker         /*
1333*7c568831SAndroid Build Coastguard Worker          * Shrink the current input buffer.
1334*7c568831SAndroid Build Coastguard Worker          * Move it as the raw buffer and create a new input buffer
1335*7c568831SAndroid Build Coastguard Worker          */
1336*7c568831SAndroid Build Coastguard Worker         processed = input->cur - input->base;
1337*7c568831SAndroid Build Coastguard Worker         xmlBufShrink(in->raw, processed);
1338*7c568831SAndroid Build Coastguard Worker         input->consumed += processed;
1339*7c568831SAndroid Build Coastguard Worker         in->rawconsumed = processed;
1340*7c568831SAndroid Build Coastguard Worker 
1341*7c568831SAndroid Build Coastguard Worker         nbchars = 4000 /* MINLEN */;
1342*7c568831SAndroid Build Coastguard Worker         res = xmlCharEncInput(in, &nbchars);
1343*7c568831SAndroid Build Coastguard Worker         if (res < 0)
1344*7c568831SAndroid Build Coastguard Worker             code = in->error;
1345*7c568831SAndroid Build Coastguard Worker     }
1346*7c568831SAndroid Build Coastguard Worker 
1347*7c568831SAndroid Build Coastguard Worker     xmlBufResetInput(in->buffer, input);
1348*7c568831SAndroid Build Coastguard Worker 
1349*7c568831SAndroid Build Coastguard Worker     return(code);
1350*7c568831SAndroid Build Coastguard Worker }
1351*7c568831SAndroid Build Coastguard Worker 
1352*7c568831SAndroid Build Coastguard Worker /**
1353*7c568831SAndroid Build Coastguard Worker  * xmlSwitchInputEncoding:
1354*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the parser context, only for error reporting
1355*7c568831SAndroid Build Coastguard Worker  * @input:  the input stream
1356*7c568831SAndroid Build Coastguard Worker  * @handler:  the encoding handler
1357*7c568831SAndroid Build Coastguard Worker  *
1358*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Internal function, don't use.
1359*7c568831SAndroid Build Coastguard Worker  *
1360*7c568831SAndroid Build Coastguard Worker  * Use encoding handler to decode input data.
1361*7c568831SAndroid Build Coastguard Worker  *
1362*7c568831SAndroid Build Coastguard Worker  * Returns 0 in case of success, -1 otherwise
1363*7c568831SAndroid Build Coastguard Worker  */
1364*7c568831SAndroid Build Coastguard Worker int
xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt,xmlParserInputPtr input,xmlCharEncodingHandlerPtr handler)1365*7c568831SAndroid Build Coastguard Worker xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
1366*7c568831SAndroid Build Coastguard Worker                        xmlCharEncodingHandlerPtr handler) {
1367*7c568831SAndroid Build Coastguard Worker     int code = xmlInputSetEncodingHandler(input, handler);
1368*7c568831SAndroid Build Coastguard Worker 
1369*7c568831SAndroid Build Coastguard Worker     if (code != XML_ERR_OK) {
1370*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrIO(ctxt, code, NULL);
1371*7c568831SAndroid Build Coastguard Worker         return(-1);
1372*7c568831SAndroid Build Coastguard Worker     }
1373*7c568831SAndroid Build Coastguard Worker 
1374*7c568831SAndroid Build Coastguard Worker     return(0);
1375*7c568831SAndroid Build Coastguard Worker }
1376*7c568831SAndroid Build Coastguard Worker 
1377*7c568831SAndroid Build Coastguard Worker /**
1378*7c568831SAndroid Build Coastguard Worker  * xmlSwitchToEncoding:
1379*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the parser context
1380*7c568831SAndroid Build Coastguard Worker  * @handler:  the encoding handler
1381*7c568831SAndroid Build Coastguard Worker  *
1382*7c568831SAndroid Build Coastguard Worker  * Use encoding handler to decode input data.
1383*7c568831SAndroid Build Coastguard Worker  *
1384*7c568831SAndroid Build Coastguard Worker  * This function can be used to enforce the encoding of chunks passed
1385*7c568831SAndroid Build Coastguard Worker  * to xmlParseChunk.
1386*7c568831SAndroid Build Coastguard Worker  *
1387*7c568831SAndroid Build Coastguard Worker  * Returns 0 in case of success, -1 otherwise
1388*7c568831SAndroid Build Coastguard Worker  */
1389*7c568831SAndroid Build Coastguard Worker int
xmlSwitchToEncoding(xmlParserCtxtPtr ctxt,xmlCharEncodingHandlerPtr handler)1390*7c568831SAndroid Build Coastguard Worker xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
1391*7c568831SAndroid Build Coastguard Worker {
1392*7c568831SAndroid Build Coastguard Worker     int code;
1393*7c568831SAndroid Build Coastguard Worker 
1394*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
1395*7c568831SAndroid Build Coastguard Worker         return(-1);
1396*7c568831SAndroid Build Coastguard Worker 
1397*7c568831SAndroid Build Coastguard Worker     code = xmlInputSetEncodingHandler(ctxt->input, handler);
1398*7c568831SAndroid Build Coastguard Worker     if (code != XML_ERR_OK) {
1399*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrIO(ctxt, code, NULL);
1400*7c568831SAndroid Build Coastguard Worker         return(-1);
1401*7c568831SAndroid Build Coastguard Worker     }
1402*7c568831SAndroid Build Coastguard Worker 
1403*7c568831SAndroid Build Coastguard Worker     return(0);
1404*7c568831SAndroid Build Coastguard Worker }
1405*7c568831SAndroid Build Coastguard Worker 
1406*7c568831SAndroid Build Coastguard Worker /**
1407*7c568831SAndroid Build Coastguard Worker  * xmlDetectEncoding:
1408*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the parser context
1409*7c568831SAndroid Build Coastguard Worker  *
1410*7c568831SAndroid Build Coastguard Worker  * Handle optional BOM, detect and switch to encoding.
1411*7c568831SAndroid Build Coastguard Worker  *
1412*7c568831SAndroid Build Coastguard Worker  * Assumes that there are at least four bytes in the input buffer.
1413*7c568831SAndroid Build Coastguard Worker  */
1414*7c568831SAndroid Build Coastguard Worker void
xmlDetectEncoding(xmlParserCtxtPtr ctxt)1415*7c568831SAndroid Build Coastguard Worker xmlDetectEncoding(xmlParserCtxtPtr ctxt) {
1416*7c568831SAndroid Build Coastguard Worker     const xmlChar *in;
1417*7c568831SAndroid Build Coastguard Worker     xmlCharEncoding enc;
1418*7c568831SAndroid Build Coastguard Worker     int bomSize;
1419*7c568831SAndroid Build Coastguard Worker     int autoFlag = 0;
1420*7c568831SAndroid Build Coastguard Worker 
1421*7c568831SAndroid Build Coastguard Worker     if (xmlParserGrow(ctxt) < 0)
1422*7c568831SAndroid Build Coastguard Worker         return;
1423*7c568831SAndroid Build Coastguard Worker     in = ctxt->input->cur;
1424*7c568831SAndroid Build Coastguard Worker     if (ctxt->input->end - in < 4)
1425*7c568831SAndroid Build Coastguard Worker         return;
1426*7c568831SAndroid Build Coastguard Worker 
1427*7c568831SAndroid Build Coastguard Worker     if (ctxt->input->flags & XML_INPUT_HAS_ENCODING) {
1428*7c568831SAndroid Build Coastguard Worker         /*
1429*7c568831SAndroid Build Coastguard Worker          * If the encoding was already set, only skip the BOM which was
1430*7c568831SAndroid Build Coastguard Worker          * possibly decoded to UTF-8.
1431*7c568831SAndroid Build Coastguard Worker          */
1432*7c568831SAndroid Build Coastguard Worker         if ((in[0] == 0xEF) && (in[1] == 0xBB) && (in[2] == 0xBF)) {
1433*7c568831SAndroid Build Coastguard Worker             ctxt->input->cur += 3;
1434*7c568831SAndroid Build Coastguard Worker         }
1435*7c568831SAndroid Build Coastguard Worker 
1436*7c568831SAndroid Build Coastguard Worker         return;
1437*7c568831SAndroid Build Coastguard Worker     }
1438*7c568831SAndroid Build Coastguard Worker 
1439*7c568831SAndroid Build Coastguard Worker     enc = XML_CHAR_ENCODING_NONE;
1440*7c568831SAndroid Build Coastguard Worker     bomSize = 0;
1441*7c568831SAndroid Build Coastguard Worker 
1442*7c568831SAndroid Build Coastguard Worker     switch (in[0]) {
1443*7c568831SAndroid Build Coastguard Worker         case 0x00:
1444*7c568831SAndroid Build Coastguard Worker             if ((in[1] == 0x00) && (in[2] == 0x00) && (in[3] == 0x3C)) {
1445*7c568831SAndroid Build Coastguard Worker                 enc = XML_CHAR_ENCODING_UCS4BE;
1446*7c568831SAndroid Build Coastguard Worker                 autoFlag = XML_INPUT_AUTO_OTHER;
1447*7c568831SAndroid Build Coastguard Worker             } else if ((in[1] == 0x3C) && (in[2] == 0x00) && (in[3] == 0x3F)) {
1448*7c568831SAndroid Build Coastguard Worker                 enc = XML_CHAR_ENCODING_UTF16BE;
1449*7c568831SAndroid Build Coastguard Worker                 autoFlag = XML_INPUT_AUTO_UTF16BE;
1450*7c568831SAndroid Build Coastguard Worker             }
1451*7c568831SAndroid Build Coastguard Worker             break;
1452*7c568831SAndroid Build Coastguard Worker 
1453*7c568831SAndroid Build Coastguard Worker         case 0x3C:
1454*7c568831SAndroid Build Coastguard Worker             if (in[1] == 0x00) {
1455*7c568831SAndroid Build Coastguard Worker                 if ((in[2] == 0x00) && (in[3] == 0x00)) {
1456*7c568831SAndroid Build Coastguard Worker                     enc = XML_CHAR_ENCODING_UCS4LE;
1457*7c568831SAndroid Build Coastguard Worker                     autoFlag = XML_INPUT_AUTO_OTHER;
1458*7c568831SAndroid Build Coastguard Worker                 } else if ((in[2] == 0x3F) && (in[3] == 0x00)) {
1459*7c568831SAndroid Build Coastguard Worker                     enc = XML_CHAR_ENCODING_UTF16LE;
1460*7c568831SAndroid Build Coastguard Worker                     autoFlag = XML_INPUT_AUTO_UTF16LE;
1461*7c568831SAndroid Build Coastguard Worker                 }
1462*7c568831SAndroid Build Coastguard Worker             }
1463*7c568831SAndroid Build Coastguard Worker             break;
1464*7c568831SAndroid Build Coastguard Worker 
1465*7c568831SAndroid Build Coastguard Worker         case 0x4C:
1466*7c568831SAndroid Build Coastguard Worker 	    if ((in[1] == 0x6F) && (in[2] == 0xA7) && (in[3] == 0x94)) {
1467*7c568831SAndroid Build Coastguard Worker 	        enc = XML_CHAR_ENCODING_EBCDIC;
1468*7c568831SAndroid Build Coastguard Worker                 autoFlag = XML_INPUT_AUTO_OTHER;
1469*7c568831SAndroid Build Coastguard Worker             }
1470*7c568831SAndroid Build Coastguard Worker             break;
1471*7c568831SAndroid Build Coastguard Worker 
1472*7c568831SAndroid Build Coastguard Worker         case 0xEF:
1473*7c568831SAndroid Build Coastguard Worker             if ((in[1] == 0xBB) && (in[2] == 0xBF)) {
1474*7c568831SAndroid Build Coastguard Worker                 enc = XML_CHAR_ENCODING_UTF8;
1475*7c568831SAndroid Build Coastguard Worker                 autoFlag = XML_INPUT_AUTO_UTF8;
1476*7c568831SAndroid Build Coastguard Worker                 bomSize = 3;
1477*7c568831SAndroid Build Coastguard Worker             }
1478*7c568831SAndroid Build Coastguard Worker             break;
1479*7c568831SAndroid Build Coastguard Worker 
1480*7c568831SAndroid Build Coastguard Worker         case 0xFE:
1481*7c568831SAndroid Build Coastguard Worker             if (in[1] == 0xFF) {
1482*7c568831SAndroid Build Coastguard Worker                 enc = XML_CHAR_ENCODING_UTF16BE;
1483*7c568831SAndroid Build Coastguard Worker                 autoFlag = XML_INPUT_AUTO_UTF16BE;
1484*7c568831SAndroid Build Coastguard Worker                 bomSize = 2;
1485*7c568831SAndroid Build Coastguard Worker             }
1486*7c568831SAndroid Build Coastguard Worker             break;
1487*7c568831SAndroid Build Coastguard Worker 
1488*7c568831SAndroid Build Coastguard Worker         case 0xFF:
1489*7c568831SAndroid Build Coastguard Worker             if (in[1] == 0xFE) {
1490*7c568831SAndroid Build Coastguard Worker                 enc = XML_CHAR_ENCODING_UTF16LE;
1491*7c568831SAndroid Build Coastguard Worker                 autoFlag = XML_INPUT_AUTO_UTF16LE;
1492*7c568831SAndroid Build Coastguard Worker                 bomSize = 2;
1493*7c568831SAndroid Build Coastguard Worker             }
1494*7c568831SAndroid Build Coastguard Worker             break;
1495*7c568831SAndroid Build Coastguard Worker     }
1496*7c568831SAndroid Build Coastguard Worker 
1497*7c568831SAndroid Build Coastguard Worker     if (bomSize > 0) {
1498*7c568831SAndroid Build Coastguard Worker         ctxt->input->cur += bomSize;
1499*7c568831SAndroid Build Coastguard Worker     }
1500*7c568831SAndroid Build Coastguard Worker 
1501*7c568831SAndroid Build Coastguard Worker     if (enc != XML_CHAR_ENCODING_NONE) {
1502*7c568831SAndroid Build Coastguard Worker         ctxt->input->flags |= autoFlag;
1503*7c568831SAndroid Build Coastguard Worker 
1504*7c568831SAndroid Build Coastguard Worker         if (enc == XML_CHAR_ENCODING_EBCDIC) {
1505*7c568831SAndroid Build Coastguard Worker             xmlCharEncodingHandlerPtr handler;
1506*7c568831SAndroid Build Coastguard Worker             int res;
1507*7c568831SAndroid Build Coastguard Worker 
1508*7c568831SAndroid Build Coastguard Worker             res = xmlDetectEBCDIC(ctxt, &handler);
1509*7c568831SAndroid Build Coastguard Worker             if (res != XML_ERR_OK) {
1510*7c568831SAndroid Build Coastguard Worker                 xmlFatalErr(ctxt, res, "detecting EBCDIC\n");
1511*7c568831SAndroid Build Coastguard Worker             } else {
1512*7c568831SAndroid Build Coastguard Worker                 xmlSwitchToEncoding(ctxt, handler);
1513*7c568831SAndroid Build Coastguard Worker             }
1514*7c568831SAndroid Build Coastguard Worker         } else {
1515*7c568831SAndroid Build Coastguard Worker             xmlSwitchEncoding(ctxt, enc);
1516*7c568831SAndroid Build Coastguard Worker         }
1517*7c568831SAndroid Build Coastguard Worker     }
1518*7c568831SAndroid Build Coastguard Worker }
1519*7c568831SAndroid Build Coastguard Worker 
1520*7c568831SAndroid Build Coastguard Worker /**
1521*7c568831SAndroid Build Coastguard Worker  * xmlSetDeclaredEncoding:
1522*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the parser context
1523*7c568831SAndroid Build Coastguard Worker  * @encoding:  declared encoding
1524*7c568831SAndroid Build Coastguard Worker  *
1525*7c568831SAndroid Build Coastguard Worker  * Set the encoding from a declaration in the document.
1526*7c568831SAndroid Build Coastguard Worker  *
1527*7c568831SAndroid Build Coastguard Worker  * If no encoding was set yet, switch the encoding. Otherwise, only warn
1528*7c568831SAndroid Build Coastguard Worker  * about encoding mismatches.
1529*7c568831SAndroid Build Coastguard Worker  *
1530*7c568831SAndroid Build Coastguard Worker  * Takes ownership of 'encoding'.
1531*7c568831SAndroid Build Coastguard Worker  */
1532*7c568831SAndroid Build Coastguard Worker void
xmlSetDeclaredEncoding(xmlParserCtxtPtr ctxt,xmlChar * encoding)1533*7c568831SAndroid Build Coastguard Worker xmlSetDeclaredEncoding(xmlParserCtxtPtr ctxt, xmlChar *encoding) {
1534*7c568831SAndroid Build Coastguard Worker     if (((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0) &&
1535*7c568831SAndroid Build Coastguard Worker         ((ctxt->options & XML_PARSE_IGNORE_ENC) == 0)) {
1536*7c568831SAndroid Build Coastguard Worker         xmlCharEncodingHandlerPtr handler;
1537*7c568831SAndroid Build Coastguard Worker         int res;
1538*7c568831SAndroid Build Coastguard Worker 
1539*7c568831SAndroid Build Coastguard Worker         /*
1540*7c568831SAndroid Build Coastguard Worker          * xmlSwitchEncodingName treats unsupported encodings as
1541*7c568831SAndroid Build Coastguard Worker          * warnings, but we want it to be an error in an encoding
1542*7c568831SAndroid Build Coastguard Worker          * declaration.
1543*7c568831SAndroid Build Coastguard Worker          */
1544*7c568831SAndroid Build Coastguard Worker         res = xmlCreateCharEncodingHandler((const char *) encoding,
1545*7c568831SAndroid Build Coastguard Worker                 /* output */ 0, ctxt->convImpl, ctxt->convCtxt, &handler);
1546*7c568831SAndroid Build Coastguard Worker         if (res != XML_ERR_OK) {
1547*7c568831SAndroid Build Coastguard Worker             xmlFatalErr(ctxt, res, (const char *) encoding);
1548*7c568831SAndroid Build Coastguard Worker             xmlFree(encoding);
1549*7c568831SAndroid Build Coastguard Worker             return;
1550*7c568831SAndroid Build Coastguard Worker         }
1551*7c568831SAndroid Build Coastguard Worker 
1552*7c568831SAndroid Build Coastguard Worker         res  = xmlInputSetEncodingHandler(ctxt->input, handler);
1553*7c568831SAndroid Build Coastguard Worker         if (res != XML_ERR_OK) {
1554*7c568831SAndroid Build Coastguard Worker             xmlCtxtErrIO(ctxt, res, NULL);
1555*7c568831SAndroid Build Coastguard Worker             xmlFree(encoding);
1556*7c568831SAndroid Build Coastguard Worker             return;
1557*7c568831SAndroid Build Coastguard Worker         }
1558*7c568831SAndroid Build Coastguard Worker 
1559*7c568831SAndroid Build Coastguard Worker         ctxt->input->flags |= XML_INPUT_USES_ENC_DECL;
1560*7c568831SAndroid Build Coastguard Worker     } else if (ctxt->input->flags & XML_INPUT_AUTO_ENCODING) {
1561*7c568831SAndroid Build Coastguard Worker         static const char *allowedUTF8[] = {
1562*7c568831SAndroid Build Coastguard Worker             "UTF-8", "UTF8", NULL
1563*7c568831SAndroid Build Coastguard Worker         };
1564*7c568831SAndroid Build Coastguard Worker         static const char *allowedUTF16LE[] = {
1565*7c568831SAndroid Build Coastguard Worker             "UTF-16", "UTF-16LE", "UTF16", NULL
1566*7c568831SAndroid Build Coastguard Worker         };
1567*7c568831SAndroid Build Coastguard Worker         static const char *allowedUTF16BE[] = {
1568*7c568831SAndroid Build Coastguard Worker             "UTF-16", "UTF-16BE", "UTF16", NULL
1569*7c568831SAndroid Build Coastguard Worker         };
1570*7c568831SAndroid Build Coastguard Worker         const char **allowed = NULL;
1571*7c568831SAndroid Build Coastguard Worker         const char *autoEnc = NULL;
1572*7c568831SAndroid Build Coastguard Worker 
1573*7c568831SAndroid Build Coastguard Worker         switch (ctxt->input->flags & XML_INPUT_AUTO_ENCODING) {
1574*7c568831SAndroid Build Coastguard Worker             case XML_INPUT_AUTO_UTF8:
1575*7c568831SAndroid Build Coastguard Worker                 allowed = allowedUTF8;
1576*7c568831SAndroid Build Coastguard Worker                 autoEnc = "UTF-8";
1577*7c568831SAndroid Build Coastguard Worker                 break;
1578*7c568831SAndroid Build Coastguard Worker             case XML_INPUT_AUTO_UTF16LE:
1579*7c568831SAndroid Build Coastguard Worker                 allowed = allowedUTF16LE;
1580*7c568831SAndroid Build Coastguard Worker                 autoEnc = "UTF-16LE";
1581*7c568831SAndroid Build Coastguard Worker                 break;
1582*7c568831SAndroid Build Coastguard Worker             case XML_INPUT_AUTO_UTF16BE:
1583*7c568831SAndroid Build Coastguard Worker                 allowed = allowedUTF16BE;
1584*7c568831SAndroid Build Coastguard Worker                 autoEnc = "UTF-16BE";
1585*7c568831SAndroid Build Coastguard Worker                 break;
1586*7c568831SAndroid Build Coastguard Worker         }
1587*7c568831SAndroid Build Coastguard Worker 
1588*7c568831SAndroid Build Coastguard Worker         if (allowed != NULL) {
1589*7c568831SAndroid Build Coastguard Worker             const char **p;
1590*7c568831SAndroid Build Coastguard Worker             int match = 0;
1591*7c568831SAndroid Build Coastguard Worker 
1592*7c568831SAndroid Build Coastguard Worker             for (p = allowed; *p != NULL; p++) {
1593*7c568831SAndroid Build Coastguard Worker                 if (xmlStrcasecmp(encoding, BAD_CAST *p) == 0) {
1594*7c568831SAndroid Build Coastguard Worker                     match = 1;
1595*7c568831SAndroid Build Coastguard Worker                     break;
1596*7c568831SAndroid Build Coastguard Worker                 }
1597*7c568831SAndroid Build Coastguard Worker             }
1598*7c568831SAndroid Build Coastguard Worker 
1599*7c568831SAndroid Build Coastguard Worker             if (match == 0) {
1600*7c568831SAndroid Build Coastguard Worker                 xmlWarningMsg(ctxt, XML_WAR_ENCODING_MISMATCH,
1601*7c568831SAndroid Build Coastguard Worker                               "Encoding '%s' doesn't match "
1602*7c568831SAndroid Build Coastguard Worker                               "auto-detected '%s'\n",
1603*7c568831SAndroid Build Coastguard Worker                               encoding, BAD_CAST autoEnc);
1604*7c568831SAndroid Build Coastguard Worker                 xmlFree(encoding);
1605*7c568831SAndroid Build Coastguard Worker                 encoding = xmlStrdup(BAD_CAST autoEnc);
1606*7c568831SAndroid Build Coastguard Worker                 if (encoding == NULL)
1607*7c568831SAndroid Build Coastguard Worker                     xmlCtxtErrMemory(ctxt);
1608*7c568831SAndroid Build Coastguard Worker             }
1609*7c568831SAndroid Build Coastguard Worker         }
1610*7c568831SAndroid Build Coastguard Worker     }
1611*7c568831SAndroid Build Coastguard Worker 
1612*7c568831SAndroid Build Coastguard Worker     if (ctxt->encoding != NULL)
1613*7c568831SAndroid Build Coastguard Worker         xmlFree((xmlChar *) ctxt->encoding);
1614*7c568831SAndroid Build Coastguard Worker     ctxt->encoding = encoding;
1615*7c568831SAndroid Build Coastguard Worker }
1616*7c568831SAndroid Build Coastguard Worker 
1617*7c568831SAndroid Build Coastguard Worker /**
1618*7c568831SAndroid Build Coastguard Worker  * xmlCtxtGetDeclaredEncoding:
1619*7c568831SAndroid Build Coastguard Worker  * ctxt:  parser context
1620*7c568831SAndroid Build Coastguard Worker  *
1621*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
1622*7c568831SAndroid Build Coastguard Worker  *
1623*7c568831SAndroid Build Coastguard Worker  * Returns the encoding from the encoding declaration. This can differ
1624*7c568831SAndroid Build Coastguard Worker  * from the actual encoding.
1625*7c568831SAndroid Build Coastguard Worker  */
1626*7c568831SAndroid Build Coastguard Worker const xmlChar *
xmlCtxtGetDeclaredEncoding(xmlParserCtxtPtr ctxt)1627*7c568831SAndroid Build Coastguard Worker xmlCtxtGetDeclaredEncoding(xmlParserCtxtPtr ctxt) {
1628*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
1629*7c568831SAndroid Build Coastguard Worker         return(NULL);
1630*7c568831SAndroid Build Coastguard Worker 
1631*7c568831SAndroid Build Coastguard Worker     return(ctxt->encoding);
1632*7c568831SAndroid Build Coastguard Worker }
1633*7c568831SAndroid Build Coastguard Worker 
1634*7c568831SAndroid Build Coastguard Worker /**
1635*7c568831SAndroid Build Coastguard Worker  * xmlGetActualEncoding:
1636*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the parser context
1637*7c568831SAndroid Build Coastguard Worker  *
1638*7c568831SAndroid Build Coastguard Worker  * Returns the actual used to parse the document. This can differ from
1639*7c568831SAndroid Build Coastguard Worker  * the declared encoding.
1640*7c568831SAndroid Build Coastguard Worker  */
1641*7c568831SAndroid Build Coastguard Worker const xmlChar *
xmlGetActualEncoding(xmlParserCtxtPtr ctxt)1642*7c568831SAndroid Build Coastguard Worker xmlGetActualEncoding(xmlParserCtxtPtr ctxt) {
1643*7c568831SAndroid Build Coastguard Worker     const xmlChar *encoding = NULL;
1644*7c568831SAndroid Build Coastguard Worker 
1645*7c568831SAndroid Build Coastguard Worker     if ((ctxt->input->flags & XML_INPUT_USES_ENC_DECL) ||
1646*7c568831SAndroid Build Coastguard Worker         (ctxt->input->flags & XML_INPUT_AUTO_ENCODING)) {
1647*7c568831SAndroid Build Coastguard Worker         /* Preserve encoding exactly */
1648*7c568831SAndroid Build Coastguard Worker         encoding = ctxt->encoding;
1649*7c568831SAndroid Build Coastguard Worker     } else if ((ctxt->input->buf) && (ctxt->input->buf->encoder)) {
1650*7c568831SAndroid Build Coastguard Worker         encoding = BAD_CAST ctxt->input->buf->encoder->name;
1651*7c568831SAndroid Build Coastguard Worker     } else if (ctxt->input->flags & XML_INPUT_HAS_ENCODING) {
1652*7c568831SAndroid Build Coastguard Worker         encoding = BAD_CAST "UTF-8";
1653*7c568831SAndroid Build Coastguard Worker     }
1654*7c568831SAndroid Build Coastguard Worker 
1655*7c568831SAndroid Build Coastguard Worker     return(encoding);
1656*7c568831SAndroid Build Coastguard Worker }
1657*7c568831SAndroid Build Coastguard Worker 
1658*7c568831SAndroid Build Coastguard Worker /************************************************************************
1659*7c568831SAndroid Build Coastguard Worker  *									*
1660*7c568831SAndroid Build Coastguard Worker  *	Commodity functions to handle entities processing		*
1661*7c568831SAndroid Build Coastguard Worker  *									*
1662*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
1663*7c568831SAndroid Build Coastguard Worker 
1664*7c568831SAndroid Build Coastguard Worker /**
1665*7c568831SAndroid Build Coastguard Worker  * xmlFreeInputStream:
1666*7c568831SAndroid Build Coastguard Worker  * @input:  an xmlParserInputPtr
1667*7c568831SAndroid Build Coastguard Worker  *
1668*7c568831SAndroid Build Coastguard Worker  * Free up an input stream.
1669*7c568831SAndroid Build Coastguard Worker  */
1670*7c568831SAndroid Build Coastguard Worker void
xmlFreeInputStream(xmlParserInputPtr input)1671*7c568831SAndroid Build Coastguard Worker xmlFreeInputStream(xmlParserInputPtr input) {
1672*7c568831SAndroid Build Coastguard Worker     if (input == NULL) return;
1673*7c568831SAndroid Build Coastguard Worker 
1674*7c568831SAndroid Build Coastguard Worker     if (input->filename != NULL) xmlFree((char *) input->filename);
1675*7c568831SAndroid Build Coastguard Worker     if (input->version != NULL) xmlFree((char *) input->version);
1676*7c568831SAndroid Build Coastguard Worker     if ((input->free != NULL) && (input->base != NULL))
1677*7c568831SAndroid Build Coastguard Worker         input->free((xmlChar *) input->base);
1678*7c568831SAndroid Build Coastguard Worker     if (input->buf != NULL)
1679*7c568831SAndroid Build Coastguard Worker         xmlFreeParserInputBuffer(input->buf);
1680*7c568831SAndroid Build Coastguard Worker     xmlFree(input);
1681*7c568831SAndroid Build Coastguard Worker }
1682*7c568831SAndroid Build Coastguard Worker 
1683*7c568831SAndroid Build Coastguard Worker /**
1684*7c568831SAndroid Build Coastguard Worker  * xmlNewInputStream:
1685*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
1686*7c568831SAndroid Build Coastguard Worker  *
1687*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Use xmlNewInputFromUrl or similar functions.
1688*7c568831SAndroid Build Coastguard Worker  *
1689*7c568831SAndroid Build Coastguard Worker  * Create a new input stream structure.
1690*7c568831SAndroid Build Coastguard Worker  *
1691*7c568831SAndroid Build Coastguard Worker  * Returns the new input stream or NULL
1692*7c568831SAndroid Build Coastguard Worker  */
1693*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNewInputStream(xmlParserCtxtPtr ctxt)1694*7c568831SAndroid Build Coastguard Worker xmlNewInputStream(xmlParserCtxtPtr ctxt) {
1695*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
1696*7c568831SAndroid Build Coastguard Worker 
1697*7c568831SAndroid Build Coastguard Worker     input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
1698*7c568831SAndroid Build Coastguard Worker     if (input == NULL) {
1699*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrMemory(ctxt);
1700*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1701*7c568831SAndroid Build Coastguard Worker     }
1702*7c568831SAndroid Build Coastguard Worker     memset(input, 0, sizeof(xmlParserInput));
1703*7c568831SAndroid Build Coastguard Worker     input->line = 1;
1704*7c568831SAndroid Build Coastguard Worker     input->col = 1;
1705*7c568831SAndroid Build Coastguard Worker 
1706*7c568831SAndroid Build Coastguard Worker     return(input);
1707*7c568831SAndroid Build Coastguard Worker }
1708*7c568831SAndroid Build Coastguard Worker 
1709*7c568831SAndroid Build Coastguard Worker /**
1710*7c568831SAndroid Build Coastguard Worker  * xmlCtxtNewInputFromUrl:
1711*7c568831SAndroid Build Coastguard Worker  * @ctxt:  parser context
1712*7c568831SAndroid Build Coastguard Worker  * @url:  filename or URL
1713*7c568831SAndroid Build Coastguard Worker  * @publicId:  publid ID from doctype (optional)
1714*7c568831SAndroid Build Coastguard Worker  * @encoding:  character encoding (optional)
1715*7c568831SAndroid Build Coastguard Worker  * @flags:  unused, pass 0
1716*7c568831SAndroid Build Coastguard Worker  *
1717*7c568831SAndroid Build Coastguard Worker  * Creates a new parser input from the filesystem, the network or
1718*7c568831SAndroid Build Coastguard Worker  * a user-defined resource loader.
1719*7c568831SAndroid Build Coastguard Worker  *
1720*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input.
1721*7c568831SAndroid Build Coastguard Worker  */
1722*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlCtxtNewInputFromUrl(xmlParserCtxtPtr ctxt,const char * url,const char * publicId,const char * encoding,int flags ATTRIBUTE_UNUSED)1723*7c568831SAndroid Build Coastguard Worker xmlCtxtNewInputFromUrl(xmlParserCtxtPtr ctxt, const char *url,
1724*7c568831SAndroid Build Coastguard Worker                        const char *publicId, const char *encoding,
1725*7c568831SAndroid Build Coastguard Worker                        int flags ATTRIBUTE_UNUSED) {
1726*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
1727*7c568831SAndroid Build Coastguard Worker 
1728*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (url == NULL))
1729*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1730*7c568831SAndroid Build Coastguard Worker 
1731*7c568831SAndroid Build Coastguard Worker     input = xmlLoadResource(ctxt, url, publicId, XML_RESOURCE_MAIN_DOCUMENT);
1732*7c568831SAndroid Build Coastguard Worker     if (input == NULL)
1733*7c568831SAndroid Build Coastguard Worker         return(NULL);
1734*7c568831SAndroid Build Coastguard Worker 
1735*7c568831SAndroid Build Coastguard Worker     if (encoding != NULL)
1736*7c568831SAndroid Build Coastguard Worker         xmlSwitchInputEncodingName(ctxt, input, encoding);
1737*7c568831SAndroid Build Coastguard Worker 
1738*7c568831SAndroid Build Coastguard Worker     return(input);
1739*7c568831SAndroid Build Coastguard Worker }
1740*7c568831SAndroid Build Coastguard Worker 
1741*7c568831SAndroid Build Coastguard Worker /**
1742*7c568831SAndroid Build Coastguard Worker  * xmlNewInputInternal:
1743*7c568831SAndroid Build Coastguard Worker  * @buf:  parser input buffer
1744*7c568831SAndroid Build Coastguard Worker  * @filename:  filename or URL
1745*7c568831SAndroid Build Coastguard Worker  *
1746*7c568831SAndroid Build Coastguard Worker  * Internal helper function.
1747*7c568831SAndroid Build Coastguard Worker  *
1748*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input.
1749*7c568831SAndroid Build Coastguard Worker  */
1750*7c568831SAndroid Build Coastguard Worker static xmlParserInputPtr
xmlNewInputInternal(xmlParserInputBufferPtr buf,const char * filename)1751*7c568831SAndroid Build Coastguard Worker xmlNewInputInternal(xmlParserInputBufferPtr buf, const char *filename) {
1752*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
1753*7c568831SAndroid Build Coastguard Worker 
1754*7c568831SAndroid Build Coastguard Worker     input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
1755*7c568831SAndroid Build Coastguard Worker     if (input == NULL) {
1756*7c568831SAndroid Build Coastguard Worker 	xmlFreeParserInputBuffer(buf);
1757*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1758*7c568831SAndroid Build Coastguard Worker     }
1759*7c568831SAndroid Build Coastguard Worker     memset(input, 0, sizeof(xmlParserInput));
1760*7c568831SAndroid Build Coastguard Worker     input->line = 1;
1761*7c568831SAndroid Build Coastguard Worker     input->col = 1;
1762*7c568831SAndroid Build Coastguard Worker 
1763*7c568831SAndroid Build Coastguard Worker     input->buf = buf;
1764*7c568831SAndroid Build Coastguard Worker     xmlBufResetInput(input->buf->buffer, input);
1765*7c568831SAndroid Build Coastguard Worker 
1766*7c568831SAndroid Build Coastguard Worker     if (filename != NULL) {
1767*7c568831SAndroid Build Coastguard Worker         input->filename = xmlMemStrdup(filename);
1768*7c568831SAndroid Build Coastguard Worker         if (input->filename == NULL) {
1769*7c568831SAndroid Build Coastguard Worker             xmlFreeInputStream(input);
1770*7c568831SAndroid Build Coastguard Worker             return(NULL);
1771*7c568831SAndroid Build Coastguard Worker         }
1772*7c568831SAndroid Build Coastguard Worker     }
1773*7c568831SAndroid Build Coastguard Worker 
1774*7c568831SAndroid Build Coastguard Worker     return(input);
1775*7c568831SAndroid Build Coastguard Worker }
1776*7c568831SAndroid Build Coastguard Worker 
1777*7c568831SAndroid Build Coastguard Worker /**
1778*7c568831SAndroid Build Coastguard Worker  * xmlNewInputFromMemory:
1779*7c568831SAndroid Build Coastguard Worker  * @url:  base URL (optional)
1780*7c568831SAndroid Build Coastguard Worker  * @mem:  pointer to char array
1781*7c568831SAndroid Build Coastguard Worker  * @size:  size of array
1782*7c568831SAndroid Build Coastguard Worker  * @flags:  optimization hints
1783*7c568831SAndroid Build Coastguard Worker  *
1784*7c568831SAndroid Build Coastguard Worker  * Creates a new parser input to read from a memory area.
1785*7c568831SAndroid Build Coastguard Worker  *
1786*7c568831SAndroid Build Coastguard Worker  * @url is used as base to resolve external entities and for
1787*7c568831SAndroid Build Coastguard Worker  * error reporting.
1788*7c568831SAndroid Build Coastguard Worker  *
1789*7c568831SAndroid Build Coastguard Worker  * If the XML_INPUT_BUF_STATIC flag is set, the memory area must
1790*7c568831SAndroid Build Coastguard Worker  * stay unchanged until parsing has finished. This can avoid
1791*7c568831SAndroid Build Coastguard Worker  * temporary copies.
1792*7c568831SAndroid Build Coastguard Worker  *
1793*7c568831SAndroid Build Coastguard Worker  * If the XML_INPUT_BUF_ZERO_TERMINATED flag is set, the memory
1794*7c568831SAndroid Build Coastguard Worker  * area must contain a zero byte after the buffer at position @size.
1795*7c568831SAndroid Build Coastguard Worker  * This can avoid temporary copies.
1796*7c568831SAndroid Build Coastguard Worker  *
1797*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
1798*7c568831SAndroid Build Coastguard Worker  *
1799*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input or NULL if a memory allocation failed.
1800*7c568831SAndroid Build Coastguard Worker  */
1801*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNewInputFromMemory(const char * url,const void * mem,size_t size,int flags)1802*7c568831SAndroid Build Coastguard Worker xmlNewInputFromMemory(const char *url, const void *mem, size_t size,
1803*7c568831SAndroid Build Coastguard Worker                       int flags) {
1804*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr buf;
1805*7c568831SAndroid Build Coastguard Worker 
1806*7c568831SAndroid Build Coastguard Worker     if (mem == NULL)
1807*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1808*7c568831SAndroid Build Coastguard Worker 
1809*7c568831SAndroid Build Coastguard Worker     buf = xmlNewInputBufferMemory(mem, size, flags, XML_CHAR_ENCODING_NONE);
1810*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
1811*7c568831SAndroid Build Coastguard Worker         return(NULL);
1812*7c568831SAndroid Build Coastguard Worker 
1813*7c568831SAndroid Build Coastguard Worker     return(xmlNewInputInternal(buf, url));
1814*7c568831SAndroid Build Coastguard Worker }
1815*7c568831SAndroid Build Coastguard Worker 
1816*7c568831SAndroid Build Coastguard Worker /**
1817*7c568831SAndroid Build Coastguard Worker  * xmlCtxtNewInputFromMemory:
1818*7c568831SAndroid Build Coastguard Worker  * @ctxt:  parser context
1819*7c568831SAndroid Build Coastguard Worker  * @url:  base URL (optional)
1820*7c568831SAndroid Build Coastguard Worker  * @mem:  pointer to char array
1821*7c568831SAndroid Build Coastguard Worker  * @size:  size of array
1822*7c568831SAndroid Build Coastguard Worker  * @encoding:  character encoding (optional)
1823*7c568831SAndroid Build Coastguard Worker  * @flags:  optimization hints
1824*7c568831SAndroid Build Coastguard Worker  *
1825*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input or NULL in case of error.
1826*7c568831SAndroid Build Coastguard Worker  */
1827*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlCtxtNewInputFromMemory(xmlParserCtxtPtr ctxt,const char * url,const void * mem,size_t size,const char * encoding,int flags)1828*7c568831SAndroid Build Coastguard Worker xmlCtxtNewInputFromMemory(xmlParserCtxtPtr ctxt, const char *url,
1829*7c568831SAndroid Build Coastguard Worker                           const void *mem, size_t size,
1830*7c568831SAndroid Build Coastguard Worker                           const char *encoding, int flags) {
1831*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
1832*7c568831SAndroid Build Coastguard Worker 
1833*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (mem == NULL))
1834*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1835*7c568831SAndroid Build Coastguard Worker 
1836*7c568831SAndroid Build Coastguard Worker     input = xmlNewInputFromMemory(url, mem, size, flags);
1837*7c568831SAndroid Build Coastguard Worker     if (input == NULL) {
1838*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrMemory(ctxt);
1839*7c568831SAndroid Build Coastguard Worker         return(NULL);
1840*7c568831SAndroid Build Coastguard Worker     }
1841*7c568831SAndroid Build Coastguard Worker 
1842*7c568831SAndroid Build Coastguard Worker     if (encoding != NULL)
1843*7c568831SAndroid Build Coastguard Worker         xmlSwitchInputEncodingName(ctxt, input, encoding);
1844*7c568831SAndroid Build Coastguard Worker 
1845*7c568831SAndroid Build Coastguard Worker     return(input);
1846*7c568831SAndroid Build Coastguard Worker }
1847*7c568831SAndroid Build Coastguard Worker 
1848*7c568831SAndroid Build Coastguard Worker /**
1849*7c568831SAndroid Build Coastguard Worker  * xmlNewInputFromString:
1850*7c568831SAndroid Build Coastguard Worker  * @url:  base URL (optional)
1851*7c568831SAndroid Build Coastguard Worker  * @str:  zero-terminated string
1852*7c568831SAndroid Build Coastguard Worker  * @flags:  optimization hints
1853*7c568831SAndroid Build Coastguard Worker  *
1854*7c568831SAndroid Build Coastguard Worker  * Creates a new parser input to read from a zero-terminated string.
1855*7c568831SAndroid Build Coastguard Worker  *
1856*7c568831SAndroid Build Coastguard Worker  * @url is used as base to resolve external entities and for
1857*7c568831SAndroid Build Coastguard Worker  * error reporting.
1858*7c568831SAndroid Build Coastguard Worker  *
1859*7c568831SAndroid Build Coastguard Worker  * If the XML_INPUT_BUF_STATIC flag is set, the string must
1860*7c568831SAndroid Build Coastguard Worker  * stay unchanged until parsing has finished. This can avoid
1861*7c568831SAndroid Build Coastguard Worker  * temporary copies.
1862*7c568831SAndroid Build Coastguard Worker  *
1863*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
1864*7c568831SAndroid Build Coastguard Worker  *
1865*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input or NULL if a memory allocation failed.
1866*7c568831SAndroid Build Coastguard Worker  */
1867*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNewInputFromString(const char * url,const char * str,int flags)1868*7c568831SAndroid Build Coastguard Worker xmlNewInputFromString(const char *url, const char *str, int flags) {
1869*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr buf;
1870*7c568831SAndroid Build Coastguard Worker 
1871*7c568831SAndroid Build Coastguard Worker     if (str == NULL)
1872*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1873*7c568831SAndroid Build Coastguard Worker 
1874*7c568831SAndroid Build Coastguard Worker     buf = xmlNewInputBufferString(str, flags);
1875*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
1876*7c568831SAndroid Build Coastguard Worker         return(NULL);
1877*7c568831SAndroid Build Coastguard Worker 
1878*7c568831SAndroid Build Coastguard Worker     return(xmlNewInputInternal(buf, url));
1879*7c568831SAndroid Build Coastguard Worker }
1880*7c568831SAndroid Build Coastguard Worker 
1881*7c568831SAndroid Build Coastguard Worker /**
1882*7c568831SAndroid Build Coastguard Worker  * xmlCtxtNewInputFromString:
1883*7c568831SAndroid Build Coastguard Worker  * @ctxt:  parser context
1884*7c568831SAndroid Build Coastguard Worker  * @url:  base URL (optional)
1885*7c568831SAndroid Build Coastguard Worker  * @str:  zero-terminated string
1886*7c568831SAndroid Build Coastguard Worker  * @encoding:  character encoding (optional)
1887*7c568831SAndroid Build Coastguard Worker  * @flags:  optimization hints
1888*7c568831SAndroid Build Coastguard Worker  *
1889*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input.
1890*7c568831SAndroid Build Coastguard Worker  */
1891*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlCtxtNewInputFromString(xmlParserCtxtPtr ctxt,const char * url,const char * str,const char * encoding,int flags)1892*7c568831SAndroid Build Coastguard Worker xmlCtxtNewInputFromString(xmlParserCtxtPtr ctxt, const char *url,
1893*7c568831SAndroid Build Coastguard Worker                           const char *str, const char *encoding, int flags) {
1894*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
1895*7c568831SAndroid Build Coastguard Worker 
1896*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (str == NULL))
1897*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1898*7c568831SAndroid Build Coastguard Worker 
1899*7c568831SAndroid Build Coastguard Worker     input = xmlNewInputFromString(url, str, flags);
1900*7c568831SAndroid Build Coastguard Worker     if (input == NULL) {
1901*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrMemory(ctxt);
1902*7c568831SAndroid Build Coastguard Worker         return(NULL);
1903*7c568831SAndroid Build Coastguard Worker     }
1904*7c568831SAndroid Build Coastguard Worker 
1905*7c568831SAndroid Build Coastguard Worker     if (encoding != NULL)
1906*7c568831SAndroid Build Coastguard Worker         xmlSwitchInputEncodingName(ctxt, input, encoding);
1907*7c568831SAndroid Build Coastguard Worker 
1908*7c568831SAndroid Build Coastguard Worker     return(input);
1909*7c568831SAndroid Build Coastguard Worker }
1910*7c568831SAndroid Build Coastguard Worker 
1911*7c568831SAndroid Build Coastguard Worker /**
1912*7c568831SAndroid Build Coastguard Worker  * xmlNewInputFromFd:
1913*7c568831SAndroid Build Coastguard Worker  * @url:  base URL (optional)
1914*7c568831SAndroid Build Coastguard Worker  * @fd:  file descriptor
1915*7c568831SAndroid Build Coastguard Worker  * @flags:  unused, pass 0
1916*7c568831SAndroid Build Coastguard Worker  *
1917*7c568831SAndroid Build Coastguard Worker  * Creates a new parser input to read from a zero-terminated string.
1918*7c568831SAndroid Build Coastguard Worker  *
1919*7c568831SAndroid Build Coastguard Worker  * @url is used as base to resolve external entities and for
1920*7c568831SAndroid Build Coastguard Worker  * error reporting.
1921*7c568831SAndroid Build Coastguard Worker  *
1922*7c568831SAndroid Build Coastguard Worker  * @fd is closed after parsing has finished.
1923*7c568831SAndroid Build Coastguard Worker  *
1924*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
1925*7c568831SAndroid Build Coastguard Worker  *
1926*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input or NULL if a memory allocation failed.
1927*7c568831SAndroid Build Coastguard Worker  */
1928*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNewInputFromFd(const char * url,int fd,int flags ATTRIBUTE_UNUSED)1929*7c568831SAndroid Build Coastguard Worker xmlNewInputFromFd(const char *url, int fd, int flags ATTRIBUTE_UNUSED) {
1930*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr buf;
1931*7c568831SAndroid Build Coastguard Worker 
1932*7c568831SAndroid Build Coastguard Worker     if (fd < 0)
1933*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1934*7c568831SAndroid Build Coastguard Worker 
1935*7c568831SAndroid Build Coastguard Worker     buf = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
1936*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
1937*7c568831SAndroid Build Coastguard Worker         return(NULL);
1938*7c568831SAndroid Build Coastguard Worker 
1939*7c568831SAndroid Build Coastguard Worker     return(xmlNewInputInternal(buf, url));
1940*7c568831SAndroid Build Coastguard Worker }
1941*7c568831SAndroid Build Coastguard Worker 
1942*7c568831SAndroid Build Coastguard Worker /**
1943*7c568831SAndroid Build Coastguard Worker  * xmlCtxtNewInputFromFd:
1944*7c568831SAndroid Build Coastguard Worker  * @ctxt:  parser context
1945*7c568831SAndroid Build Coastguard Worker  * @url:  base URL (optional)
1946*7c568831SAndroid Build Coastguard Worker  * @fd:  file descriptor
1947*7c568831SAndroid Build Coastguard Worker  * @encoding:  character encoding (optional)
1948*7c568831SAndroid Build Coastguard Worker  * @flags:  unused, pass 0
1949*7c568831SAndroid Build Coastguard Worker  *
1950*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input.
1951*7c568831SAndroid Build Coastguard Worker  */
1952*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlCtxtNewInputFromFd(xmlParserCtxtPtr ctxt,const char * url,int fd,const char * encoding,int flags)1953*7c568831SAndroid Build Coastguard Worker xmlCtxtNewInputFromFd(xmlParserCtxtPtr ctxt, const char *url,
1954*7c568831SAndroid Build Coastguard Worker                       int fd, const char *encoding, int flags) {
1955*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
1956*7c568831SAndroid Build Coastguard Worker 
1957*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (fd < 0))
1958*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1959*7c568831SAndroid Build Coastguard Worker 
1960*7c568831SAndroid Build Coastguard Worker     input = xmlNewInputFromFd(url, fd, flags);
1961*7c568831SAndroid Build Coastguard Worker     if (input == NULL) {
1962*7c568831SAndroid Build Coastguard Worker 	xmlCtxtErrMemory(ctxt);
1963*7c568831SAndroid Build Coastguard Worker         return(NULL);
1964*7c568831SAndroid Build Coastguard Worker     }
1965*7c568831SAndroid Build Coastguard Worker 
1966*7c568831SAndroid Build Coastguard Worker     if (encoding != NULL)
1967*7c568831SAndroid Build Coastguard Worker         xmlSwitchInputEncodingName(ctxt, input, encoding);
1968*7c568831SAndroid Build Coastguard Worker 
1969*7c568831SAndroid Build Coastguard Worker     return(input);
1970*7c568831SAndroid Build Coastguard Worker }
1971*7c568831SAndroid Build Coastguard Worker 
1972*7c568831SAndroid Build Coastguard Worker /**
1973*7c568831SAndroid Build Coastguard Worker  * xmlNewInputFromIO:
1974*7c568831SAndroid Build Coastguard Worker  * @url:  base URL (optional)
1975*7c568831SAndroid Build Coastguard Worker  * @ioRead:  read callback
1976*7c568831SAndroid Build Coastguard Worker  * @ioClose:  close callback (optional)
1977*7c568831SAndroid Build Coastguard Worker  * @ioCtxt:  IO context
1978*7c568831SAndroid Build Coastguard Worker  * @flags:  unused, pass 0
1979*7c568831SAndroid Build Coastguard Worker  *
1980*7c568831SAndroid Build Coastguard Worker  * Creates a new parser input to read from input callbacks and
1981*7c568831SAndroid Build Coastguard Worker  * cintext.
1982*7c568831SAndroid Build Coastguard Worker  *
1983*7c568831SAndroid Build Coastguard Worker  * @url is used as base to resolve external entities and for
1984*7c568831SAndroid Build Coastguard Worker  * error reporting.
1985*7c568831SAndroid Build Coastguard Worker  *
1986*7c568831SAndroid Build Coastguard Worker  * @ioRead is called to read new data into a provided buffer.
1987*7c568831SAndroid Build Coastguard Worker  * It must return the number of bytes written into the buffer
1988*7c568831SAndroid Build Coastguard Worker  * ot a negative xmlParserErrors code on failure.
1989*7c568831SAndroid Build Coastguard Worker  *
1990*7c568831SAndroid Build Coastguard Worker  * @ioClose is called after parsing has finished.
1991*7c568831SAndroid Build Coastguard Worker  *
1992*7c568831SAndroid Build Coastguard Worker  * @ioCtxt is an opaque pointer passed to the callbacks.
1993*7c568831SAndroid Build Coastguard Worker  *
1994*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
1995*7c568831SAndroid Build Coastguard Worker  *
1996*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input or NULL if a memory allocation failed.
1997*7c568831SAndroid Build Coastguard Worker  */
1998*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNewInputFromIO(const char * url,xmlInputReadCallback ioRead,xmlInputCloseCallback ioClose,void * ioCtxt,int flags ATTRIBUTE_UNUSED)1999*7c568831SAndroid Build Coastguard Worker xmlNewInputFromIO(const char *url, xmlInputReadCallback ioRead,
2000*7c568831SAndroid Build Coastguard Worker                   xmlInputCloseCallback ioClose, void *ioCtxt,
2001*7c568831SAndroid Build Coastguard Worker                   int flags ATTRIBUTE_UNUSED) {
2002*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr buf;
2003*7c568831SAndroid Build Coastguard Worker 
2004*7c568831SAndroid Build Coastguard Worker     if (ioRead == NULL)
2005*7c568831SAndroid Build Coastguard Worker 	return(NULL);
2006*7c568831SAndroid Build Coastguard Worker 
2007*7c568831SAndroid Build Coastguard Worker     buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
2008*7c568831SAndroid Build Coastguard Worker     if (buf == NULL) {
2009*7c568831SAndroid Build Coastguard Worker         if (ioClose != NULL)
2010*7c568831SAndroid Build Coastguard Worker             ioClose(ioCtxt);
2011*7c568831SAndroid Build Coastguard Worker         return(NULL);
2012*7c568831SAndroid Build Coastguard Worker     }
2013*7c568831SAndroid Build Coastguard Worker 
2014*7c568831SAndroid Build Coastguard Worker     buf->context = ioCtxt;
2015*7c568831SAndroid Build Coastguard Worker     buf->readcallback = ioRead;
2016*7c568831SAndroid Build Coastguard Worker     buf->closecallback = ioClose;
2017*7c568831SAndroid Build Coastguard Worker 
2018*7c568831SAndroid Build Coastguard Worker     return(xmlNewInputInternal(buf, url));
2019*7c568831SAndroid Build Coastguard Worker }
2020*7c568831SAndroid Build Coastguard Worker 
2021*7c568831SAndroid Build Coastguard Worker /**
2022*7c568831SAndroid Build Coastguard Worker  * xmlCtxtNewInputFromIO:
2023*7c568831SAndroid Build Coastguard Worker  * @ctxt:  parser context
2024*7c568831SAndroid Build Coastguard Worker  * @url:  base URL (optional)
2025*7c568831SAndroid Build Coastguard Worker  * @ioRead:  read callback
2026*7c568831SAndroid Build Coastguard Worker  * @ioClose:  close callback (optional)
2027*7c568831SAndroid Build Coastguard Worker  * @ioCtxt:  IO context
2028*7c568831SAndroid Build Coastguard Worker  * @encoding:  character encoding (optional)
2029*7c568831SAndroid Build Coastguard Worker  * @flags:  unused, pass 0
2030*7c568831SAndroid Build Coastguard Worker  *
2031*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input.
2032*7c568831SAndroid Build Coastguard Worker  */
2033*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlCtxtNewInputFromIO(xmlParserCtxtPtr ctxt,const char * url,xmlInputReadCallback ioRead,xmlInputCloseCallback ioClose,void * ioCtxt,const char * encoding,int flags)2034*7c568831SAndroid Build Coastguard Worker xmlCtxtNewInputFromIO(xmlParserCtxtPtr ctxt, const char *url,
2035*7c568831SAndroid Build Coastguard Worker                       xmlInputReadCallback ioRead,
2036*7c568831SAndroid Build Coastguard Worker                       xmlInputCloseCallback ioClose,
2037*7c568831SAndroid Build Coastguard Worker                       void *ioCtxt, const char *encoding, int flags) {
2038*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
2039*7c568831SAndroid Build Coastguard Worker 
2040*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ioRead == NULL))
2041*7c568831SAndroid Build Coastguard Worker 	return(NULL);
2042*7c568831SAndroid Build Coastguard Worker 
2043*7c568831SAndroid Build Coastguard Worker     input = xmlNewInputFromIO(url, ioRead, ioClose, ioCtxt, flags);
2044*7c568831SAndroid Build Coastguard Worker     if (input == NULL) {
2045*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrMemory(ctxt);
2046*7c568831SAndroid Build Coastguard Worker         return(NULL);
2047*7c568831SAndroid Build Coastguard Worker     }
2048*7c568831SAndroid Build Coastguard Worker 
2049*7c568831SAndroid Build Coastguard Worker     if (encoding != NULL)
2050*7c568831SAndroid Build Coastguard Worker         xmlSwitchInputEncodingName(ctxt, input, encoding);
2051*7c568831SAndroid Build Coastguard Worker 
2052*7c568831SAndroid Build Coastguard Worker     return(input);
2053*7c568831SAndroid Build Coastguard Worker }
2054*7c568831SAndroid Build Coastguard Worker 
2055*7c568831SAndroid Build Coastguard Worker /**
2056*7c568831SAndroid Build Coastguard Worker  * xmlNewPushInput:
2057*7c568831SAndroid Build Coastguard Worker  * @url:  base URL (optional)
2058*7c568831SAndroid Build Coastguard Worker  * @chunk:  pointer to char array
2059*7c568831SAndroid Build Coastguard Worker  * @size:  size of array
2060*7c568831SAndroid Build Coastguard Worker  *
2061*7c568831SAndroid Build Coastguard Worker  * Creates a new parser input for a push parser.
2062*7c568831SAndroid Build Coastguard Worker  *
2063*7c568831SAndroid Build Coastguard Worker  * Returns a new parser input or NULL if a memory allocation failed.
2064*7c568831SAndroid Build Coastguard Worker  */
2065*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNewPushInput(const char * url,const char * chunk,int size)2066*7c568831SAndroid Build Coastguard Worker xmlNewPushInput(const char *url, const char *chunk, int size) {
2067*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr buf;
2068*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
2069*7c568831SAndroid Build Coastguard Worker 
2070*7c568831SAndroid Build Coastguard Worker     buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
2071*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
2072*7c568831SAndroid Build Coastguard Worker         return(NULL);
2073*7c568831SAndroid Build Coastguard Worker 
2074*7c568831SAndroid Build Coastguard Worker     input = xmlNewInputInternal(buf, url);
2075*7c568831SAndroid Build Coastguard Worker     if (input == NULL)
2076*7c568831SAndroid Build Coastguard Worker 	return(NULL);
2077*7c568831SAndroid Build Coastguard Worker 
2078*7c568831SAndroid Build Coastguard Worker     input->flags |= XML_INPUT_PROGRESSIVE;
2079*7c568831SAndroid Build Coastguard Worker 
2080*7c568831SAndroid Build Coastguard Worker     if ((size > 0) && (chunk != NULL)) {
2081*7c568831SAndroid Build Coastguard Worker         int res;
2082*7c568831SAndroid Build Coastguard Worker 
2083*7c568831SAndroid Build Coastguard Worker 	res = xmlParserInputBufferPush(input->buf, size, chunk);
2084*7c568831SAndroid Build Coastguard Worker         xmlBufResetInput(input->buf->buffer, input);
2085*7c568831SAndroid Build Coastguard Worker         if (res < 0) {
2086*7c568831SAndroid Build Coastguard Worker             xmlFreeInputStream(input);
2087*7c568831SAndroid Build Coastguard Worker             return(NULL);
2088*7c568831SAndroid Build Coastguard Worker         }
2089*7c568831SAndroid Build Coastguard Worker     }
2090*7c568831SAndroid Build Coastguard Worker 
2091*7c568831SAndroid Build Coastguard Worker     return(input);
2092*7c568831SAndroid Build Coastguard Worker }
2093*7c568831SAndroid Build Coastguard Worker 
2094*7c568831SAndroid Build Coastguard Worker /**
2095*7c568831SAndroid Build Coastguard Worker  * xmlNewIOInputStream:
2096*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
2097*7c568831SAndroid Build Coastguard Worker  * @buf:  an input buffer
2098*7c568831SAndroid Build Coastguard Worker  * @enc:  the charset encoding if known
2099*7c568831SAndroid Build Coastguard Worker  *
2100*7c568831SAndroid Build Coastguard Worker  * Create a new input stream structure encapsulating the @input into
2101*7c568831SAndroid Build Coastguard Worker  * a stream suitable for the parser.
2102*7c568831SAndroid Build Coastguard Worker  *
2103*7c568831SAndroid Build Coastguard Worker  * Returns the new input stream or NULL
2104*7c568831SAndroid Build Coastguard Worker  */
2105*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNewIOInputStream(xmlParserCtxtPtr ctxt,xmlParserInputBufferPtr buf,xmlCharEncoding enc)2106*7c568831SAndroid Build Coastguard Worker xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr buf,
2107*7c568831SAndroid Build Coastguard Worker 	            xmlCharEncoding enc) {
2108*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
2109*7c568831SAndroid Build Coastguard Worker     const char *encoding;
2110*7c568831SAndroid Build Coastguard Worker 
2111*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (buf == NULL))
2112*7c568831SAndroid Build Coastguard Worker         return(NULL);
2113*7c568831SAndroid Build Coastguard Worker 
2114*7c568831SAndroid Build Coastguard Worker     input = xmlNewInputInternal(buf, NULL);
2115*7c568831SAndroid Build Coastguard Worker     if (input == NULL) {
2116*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrMemory(ctxt);
2117*7c568831SAndroid Build Coastguard Worker 	return(NULL);
2118*7c568831SAndroid Build Coastguard Worker     }
2119*7c568831SAndroid Build Coastguard Worker 
2120*7c568831SAndroid Build Coastguard Worker     encoding = xmlGetCharEncodingName(enc);
2121*7c568831SAndroid Build Coastguard Worker     if (encoding != NULL)
2122*7c568831SAndroid Build Coastguard Worker         xmlSwitchInputEncodingName(ctxt, input, encoding);
2123*7c568831SAndroid Build Coastguard Worker 
2124*7c568831SAndroid Build Coastguard Worker     return(input);
2125*7c568831SAndroid Build Coastguard Worker }
2126*7c568831SAndroid Build Coastguard Worker 
2127*7c568831SAndroid Build Coastguard Worker /**
2128*7c568831SAndroid Build Coastguard Worker  * xmlNewEntityInputStream:
2129*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
2130*7c568831SAndroid Build Coastguard Worker  * @ent:  an Entity pointer
2131*7c568831SAndroid Build Coastguard Worker  *
2132*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Internal function, do not use.
2133*7c568831SAndroid Build Coastguard Worker  *
2134*7c568831SAndroid Build Coastguard Worker  * Create a new input stream based on an xmlEntityPtr
2135*7c568831SAndroid Build Coastguard Worker  *
2136*7c568831SAndroid Build Coastguard Worker  * Returns the new input stream or NULL
2137*7c568831SAndroid Build Coastguard Worker  */
2138*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNewEntityInputStream(xmlParserCtxtPtr ctxt,xmlEntityPtr ent)2139*7c568831SAndroid Build Coastguard Worker xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
2140*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
2141*7c568831SAndroid Build Coastguard Worker 
2142*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ent == NULL))
2143*7c568831SAndroid Build Coastguard Worker 	return(NULL);
2144*7c568831SAndroid Build Coastguard Worker 
2145*7c568831SAndroid Build Coastguard Worker     if (ent->content != NULL) {
2146*7c568831SAndroid Build Coastguard Worker         input = xmlCtxtNewInputFromString(ctxt, NULL,
2147*7c568831SAndroid Build Coastguard Worker                 (const char *) ent->content, NULL, XML_INPUT_BUF_STATIC);
2148*7c568831SAndroid Build Coastguard Worker     } else if (ent->URI != NULL) {
2149*7c568831SAndroid Build Coastguard Worker         xmlResourceType rtype;
2150*7c568831SAndroid Build Coastguard Worker 
2151*7c568831SAndroid Build Coastguard Worker         if (ent->etype == XML_EXTERNAL_PARAMETER_ENTITY)
2152*7c568831SAndroid Build Coastguard Worker             rtype = XML_RESOURCE_PARAMETER_ENTITY;
2153*7c568831SAndroid Build Coastguard Worker         else
2154*7c568831SAndroid Build Coastguard Worker             rtype = XML_RESOURCE_GENERAL_ENTITY;
2155*7c568831SAndroid Build Coastguard Worker 
2156*7c568831SAndroid Build Coastguard Worker         input = xmlLoadResource(ctxt, (char *) ent->URI,
2157*7c568831SAndroid Build Coastguard Worker                                 (char *) ent->ExternalID, rtype);
2158*7c568831SAndroid Build Coastguard Worker     } else {
2159*7c568831SAndroid Build Coastguard Worker         return(NULL);
2160*7c568831SAndroid Build Coastguard Worker     }
2161*7c568831SAndroid Build Coastguard Worker 
2162*7c568831SAndroid Build Coastguard Worker     if (input == NULL)
2163*7c568831SAndroid Build Coastguard Worker         return(NULL);
2164*7c568831SAndroid Build Coastguard Worker 
2165*7c568831SAndroid Build Coastguard Worker     input->entity = ent;
2166*7c568831SAndroid Build Coastguard Worker 
2167*7c568831SAndroid Build Coastguard Worker     return(input);
2168*7c568831SAndroid Build Coastguard Worker }
2169*7c568831SAndroid Build Coastguard Worker 
2170*7c568831SAndroid Build Coastguard Worker /**
2171*7c568831SAndroid Build Coastguard Worker  * xmlNewStringInputStream:
2172*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
2173*7c568831SAndroid Build Coastguard Worker  * @buffer:  an memory buffer
2174*7c568831SAndroid Build Coastguard Worker  *
2175*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Use xmlNewInputFromString.
2176*7c568831SAndroid Build Coastguard Worker  *
2177*7c568831SAndroid Build Coastguard Worker  * Create a new input stream based on a memory buffer.
2178*7c568831SAndroid Build Coastguard Worker  *
2179*7c568831SAndroid Build Coastguard Worker  * Returns the new input stream
2180*7c568831SAndroid Build Coastguard Worker  */
2181*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNewStringInputStream(xmlParserCtxtPtr ctxt,const xmlChar * buffer)2182*7c568831SAndroid Build Coastguard Worker xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
2183*7c568831SAndroid Build Coastguard Worker     return(xmlCtxtNewInputFromString(ctxt, NULL, (const char *) buffer,
2184*7c568831SAndroid Build Coastguard Worker                                      NULL, 0));
2185*7c568831SAndroid Build Coastguard Worker }
2186*7c568831SAndroid Build Coastguard Worker 
2187*7c568831SAndroid Build Coastguard Worker 
2188*7c568831SAndroid Build Coastguard Worker /****************************************************************
2189*7c568831SAndroid Build Coastguard Worker  *								*
2190*7c568831SAndroid Build Coastguard Worker  *		External entities loading			*
2191*7c568831SAndroid Build Coastguard Worker  *								*
2192*7c568831SAndroid Build Coastguard Worker  ****************************************************************/
2193*7c568831SAndroid Build Coastguard Worker 
2194*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
2195*7c568831SAndroid Build Coastguard Worker 
2196*7c568831SAndroid Build Coastguard Worker /**
2197*7c568831SAndroid Build Coastguard Worker  * xmlResolveResourceFromCatalog:
2198*7c568831SAndroid Build Coastguard Worker  * @URL:  the URL for the entity to load
2199*7c568831SAndroid Build Coastguard Worker  * @ID:  the System ID for the entity to load
2200*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the context in which the entity is called or NULL
2201*7c568831SAndroid Build Coastguard Worker  *
2202*7c568831SAndroid Build Coastguard Worker  * Resolves the URL and ID against the appropriate catalog.
2203*7c568831SAndroid Build Coastguard Worker  * This function is used by xmlDefaultExternalEntityLoader and
2204*7c568831SAndroid Build Coastguard Worker  * xmlNoNetExternalEntityLoader.
2205*7c568831SAndroid Build Coastguard Worker  *
2206*7c568831SAndroid Build Coastguard Worker  * Returns a new allocated URL, or NULL.
2207*7c568831SAndroid Build Coastguard Worker  */
2208*7c568831SAndroid Build Coastguard Worker static xmlChar *
xmlResolveResourceFromCatalog(const char * URL,const char * ID,xmlParserCtxtPtr ctxt)2209*7c568831SAndroid Build Coastguard Worker xmlResolveResourceFromCatalog(const char *URL, const char *ID,
2210*7c568831SAndroid Build Coastguard Worker                               xmlParserCtxtPtr ctxt) {
2211*7c568831SAndroid Build Coastguard Worker     xmlChar *resource = NULL;
2212*7c568831SAndroid Build Coastguard Worker     xmlCatalogAllow pref;
2213*7c568831SAndroid Build Coastguard Worker     int allowLocal = 0;
2214*7c568831SAndroid Build Coastguard Worker     int allowGlobal = 0;
2215*7c568831SAndroid Build Coastguard Worker 
2216*7c568831SAndroid Build Coastguard Worker     /*
2217*7c568831SAndroid Build Coastguard Worker      * If the resource doesn't exists as a file,
2218*7c568831SAndroid Build Coastguard Worker      * try to load it from the resource pointed in the catalogs
2219*7c568831SAndroid Build Coastguard Worker      */
2220*7c568831SAndroid Build Coastguard Worker     pref = xmlCatalogGetDefaults();
2221*7c568831SAndroid Build Coastguard Worker 
2222*7c568831SAndroid Build Coastguard Worker     if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
2223*7c568831SAndroid Build Coastguard Worker         ((pref == XML_CATA_ALLOW_ALL) ||
2224*7c568831SAndroid Build Coastguard Worker          (pref == XML_CATA_ALLOW_DOCUMENT)))
2225*7c568831SAndroid Build Coastguard Worker         allowLocal = 1;
2226*7c568831SAndroid Build Coastguard Worker 
2227*7c568831SAndroid Build Coastguard Worker     if (((ctxt == NULL) ||
2228*7c568831SAndroid Build Coastguard Worker          ((ctxt->options & XML_PARSE_NO_SYS_CATALOG) == 0)) &&
2229*7c568831SAndroid Build Coastguard Worker         ((pref == XML_CATA_ALLOW_ALL) ||
2230*7c568831SAndroid Build Coastguard Worker          (pref == XML_CATA_ALLOW_GLOBAL)))
2231*7c568831SAndroid Build Coastguard Worker         allowGlobal = 1;
2232*7c568831SAndroid Build Coastguard Worker 
2233*7c568831SAndroid Build Coastguard Worker     if ((pref != XML_CATA_ALLOW_NONE) && (!xmlNoNetExists(URL))) {
2234*7c568831SAndroid Build Coastguard Worker 	/*
2235*7c568831SAndroid Build Coastguard Worker 	 * Do a local lookup
2236*7c568831SAndroid Build Coastguard Worker 	 */
2237*7c568831SAndroid Build Coastguard Worker         if (allowLocal) {
2238*7c568831SAndroid Build Coastguard Worker 	    resource = xmlCatalogLocalResolve(ctxt->catalogs,
2239*7c568831SAndroid Build Coastguard Worker 					      (const xmlChar *)ID,
2240*7c568831SAndroid Build Coastguard Worker 					      (const xmlChar *)URL);
2241*7c568831SAndroid Build Coastguard Worker         }
2242*7c568831SAndroid Build Coastguard Worker 	/*
2243*7c568831SAndroid Build Coastguard Worker 	 * Try a global lookup
2244*7c568831SAndroid Build Coastguard Worker 	 */
2245*7c568831SAndroid Build Coastguard Worker 	if ((resource == NULL) && (allowGlobal)) {
2246*7c568831SAndroid Build Coastguard Worker 	    resource = xmlCatalogResolve((const xmlChar *)ID,
2247*7c568831SAndroid Build Coastguard Worker 					 (const xmlChar *)URL);
2248*7c568831SAndroid Build Coastguard Worker 	}
2249*7c568831SAndroid Build Coastguard Worker 	if ((resource == NULL) && (URL != NULL))
2250*7c568831SAndroid Build Coastguard Worker 	    resource = xmlStrdup((const xmlChar *) URL);
2251*7c568831SAndroid Build Coastguard Worker 
2252*7c568831SAndroid Build Coastguard Worker 	/*
2253*7c568831SAndroid Build Coastguard Worker 	 * TODO: do an URI lookup on the reference
2254*7c568831SAndroid Build Coastguard Worker 	 */
2255*7c568831SAndroid Build Coastguard Worker 	if ((resource != NULL) && (!xmlNoNetExists((const char *)resource))) {
2256*7c568831SAndroid Build Coastguard Worker 	    xmlChar *tmp = NULL;
2257*7c568831SAndroid Build Coastguard Worker 
2258*7c568831SAndroid Build Coastguard Worker 	    if (allowLocal) {
2259*7c568831SAndroid Build Coastguard Worker 		tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource);
2260*7c568831SAndroid Build Coastguard Worker 	    }
2261*7c568831SAndroid Build Coastguard Worker 	    if ((tmp == NULL) && (allowGlobal)) {
2262*7c568831SAndroid Build Coastguard Worker 		tmp = xmlCatalogResolveURI(resource);
2263*7c568831SAndroid Build Coastguard Worker 	    }
2264*7c568831SAndroid Build Coastguard Worker 
2265*7c568831SAndroid Build Coastguard Worker 	    if (tmp != NULL) {
2266*7c568831SAndroid Build Coastguard Worker 		xmlFree(resource);
2267*7c568831SAndroid Build Coastguard Worker 		resource = tmp;
2268*7c568831SAndroid Build Coastguard Worker 	    }
2269*7c568831SAndroid Build Coastguard Worker 	}
2270*7c568831SAndroid Build Coastguard Worker     }
2271*7c568831SAndroid Build Coastguard Worker 
2272*7c568831SAndroid Build Coastguard Worker     return resource;
2273*7c568831SAndroid Build Coastguard Worker }
2274*7c568831SAndroid Build Coastguard Worker 
2275*7c568831SAndroid Build Coastguard Worker #endif
2276*7c568831SAndroid Build Coastguard Worker 
2277*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTTP_ENABLED
2278*7c568831SAndroid Build Coastguard Worker static int
xmlCheckHTTPInputInternal(xmlParserInputPtr input)2279*7c568831SAndroid Build Coastguard Worker xmlCheckHTTPInputInternal(xmlParserInputPtr input) {
2280*7c568831SAndroid Build Coastguard Worker     const char *encoding;
2281*7c568831SAndroid Build Coastguard Worker     const char *redir;
2282*7c568831SAndroid Build Coastguard Worker     const char *mime;
2283*7c568831SAndroid Build Coastguard Worker     int code;
2284*7c568831SAndroid Build Coastguard Worker 
2285*7c568831SAndroid Build Coastguard Worker     if ((input == NULL) || (input->buf == NULL) ||
2286*7c568831SAndroid Build Coastguard Worker         (input->buf->readcallback != xmlIOHTTPRead) ||
2287*7c568831SAndroid Build Coastguard Worker         (input->buf->context == NULL))
2288*7c568831SAndroid Build Coastguard Worker         return(XML_ERR_OK);
2289*7c568831SAndroid Build Coastguard Worker 
2290*7c568831SAndroid Build Coastguard Worker     code = xmlNanoHTTPReturnCode(input->buf->context);
2291*7c568831SAndroid Build Coastguard Worker     if (code >= 400) {
2292*7c568831SAndroid Build Coastguard Worker         /* fatal error */
2293*7c568831SAndroid Build Coastguard Worker         return(XML_IO_LOAD_ERROR);
2294*7c568831SAndroid Build Coastguard Worker     }
2295*7c568831SAndroid Build Coastguard Worker 
2296*7c568831SAndroid Build Coastguard Worker     mime = xmlNanoHTTPMimeType(input->buf->context);
2297*7c568831SAndroid Build Coastguard Worker     if ((xmlStrstr(BAD_CAST mime, BAD_CAST "/xml")) ||
2298*7c568831SAndroid Build Coastguard Worker         (xmlStrstr(BAD_CAST mime, BAD_CAST "+xml"))) {
2299*7c568831SAndroid Build Coastguard Worker         encoding = xmlNanoHTTPEncoding(input->buf->context);
2300*7c568831SAndroid Build Coastguard Worker         if (encoding != NULL) {
2301*7c568831SAndroid Build Coastguard Worker             xmlCharEncodingHandlerPtr handler;
2302*7c568831SAndroid Build Coastguard Worker             int res;
2303*7c568831SAndroid Build Coastguard Worker 
2304*7c568831SAndroid Build Coastguard Worker             res = xmlOpenCharEncodingHandler(encoding, /* output */ 0,
2305*7c568831SAndroid Build Coastguard Worker                                              &handler);
2306*7c568831SAndroid Build Coastguard Worker             if (res == 0)
2307*7c568831SAndroid Build Coastguard Worker                 xmlInputSetEncodingHandler(input, handler);
2308*7c568831SAndroid Build Coastguard Worker         }
2309*7c568831SAndroid Build Coastguard Worker     }
2310*7c568831SAndroid Build Coastguard Worker 
2311*7c568831SAndroid Build Coastguard Worker     redir = xmlNanoHTTPRedir(input->buf->context);
2312*7c568831SAndroid Build Coastguard Worker     if (redir != NULL) {
2313*7c568831SAndroid Build Coastguard Worker         if (input->filename != NULL)
2314*7c568831SAndroid Build Coastguard Worker             xmlFree((xmlChar *) input->filename);
2315*7c568831SAndroid Build Coastguard Worker         input->filename = xmlMemStrdup(redir);
2316*7c568831SAndroid Build Coastguard Worker         if (input->filename == NULL)
2317*7c568831SAndroid Build Coastguard Worker             return(XML_ERR_NO_MEMORY);
2318*7c568831SAndroid Build Coastguard Worker     }
2319*7c568831SAndroid Build Coastguard Worker 
2320*7c568831SAndroid Build Coastguard Worker     return(XML_ERR_OK);
2321*7c568831SAndroid Build Coastguard Worker }
2322*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_HTTP_ENABLED */
2323*7c568831SAndroid Build Coastguard Worker 
2324*7c568831SAndroid Build Coastguard Worker /**
2325*7c568831SAndroid Build Coastguard Worker  * xmlCheckHTTPInput:
2326*7c568831SAndroid Build Coastguard Worker  * @ctxt: an XML parser context
2327*7c568831SAndroid Build Coastguard Worker  * @ret: an XML parser input
2328*7c568831SAndroid Build Coastguard Worker  *
2329*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Internal function, don't use.
2330*7c568831SAndroid Build Coastguard Worker  *
2331*7c568831SAndroid Build Coastguard Worker  * Check an input in case it was created from an HTTP stream, in that
2332*7c568831SAndroid Build Coastguard Worker  * case it will handle encoding and update of the base URL in case of
2333*7c568831SAndroid Build Coastguard Worker  * redirection. It also checks for HTTP errors in which case the input
2334*7c568831SAndroid Build Coastguard Worker  * is cleanly freed up and an appropriate error is raised in context
2335*7c568831SAndroid Build Coastguard Worker  *
2336*7c568831SAndroid Build Coastguard Worker  * Returns the input or NULL in case of HTTP error.
2337*7c568831SAndroid Build Coastguard Worker  */
2338*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlCheckHTTPInput(xmlParserCtxtPtr ctxt,xmlParserInputPtr ret)2339*7c568831SAndroid Build Coastguard Worker xmlCheckHTTPInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr ret) {
2340*7c568831SAndroid Build Coastguard Worker     /* Avoid unused variable warning if features are disabled. */
2341*7c568831SAndroid Build Coastguard Worker     (void) ctxt;
2342*7c568831SAndroid Build Coastguard Worker 
2343*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTTP_ENABLED
2344*7c568831SAndroid Build Coastguard Worker     {
2345*7c568831SAndroid Build Coastguard Worker         int code = xmlCheckHTTPInputInternal(ret);
2346*7c568831SAndroid Build Coastguard Worker 
2347*7c568831SAndroid Build Coastguard Worker         if (code != XML_ERR_OK) {
2348*7c568831SAndroid Build Coastguard Worker             if (ret->filename != NULL)
2349*7c568831SAndroid Build Coastguard Worker                 xmlCtxtErrIO(ctxt, XML_IO_LOAD_ERROR, ret->filename);
2350*7c568831SAndroid Build Coastguard Worker             else
2351*7c568831SAndroid Build Coastguard Worker                 xmlCtxtErrIO(ctxt, XML_IO_LOAD_ERROR, "<null>");
2352*7c568831SAndroid Build Coastguard Worker             xmlFreeInputStream(ret);
2353*7c568831SAndroid Build Coastguard Worker             return(NULL);
2354*7c568831SAndroid Build Coastguard Worker         }
2355*7c568831SAndroid Build Coastguard Worker     }
2356*7c568831SAndroid Build Coastguard Worker #endif
2357*7c568831SAndroid Build Coastguard Worker 
2358*7c568831SAndroid Build Coastguard Worker     return(ret);
2359*7c568831SAndroid Build Coastguard Worker }
2360*7c568831SAndroid Build Coastguard Worker 
2361*7c568831SAndroid Build Coastguard Worker /**
2362*7c568831SAndroid Build Coastguard Worker  * xmlNewInputFromUrl:
2363*7c568831SAndroid Build Coastguard Worker  * @filename:  the filename to use as entity
2364*7c568831SAndroid Build Coastguard Worker  * @flags:  XML_INPUT flags
2365*7c568831SAndroid Build Coastguard Worker  * @out:  pointer to new parser input
2366*7c568831SAndroid Build Coastguard Worker  *
2367*7c568831SAndroid Build Coastguard Worker  * Create a new input stream based on a file or a URL.
2368*7c568831SAndroid Build Coastguard Worker  *
2369*7c568831SAndroid Build Coastguard Worker  * The flag XML_INPUT_UNZIP allows decompression.
2370*7c568831SAndroid Build Coastguard Worker  *
2371*7c568831SAndroid Build Coastguard Worker  * The flag XML_INPUT_NETWORK allows network access.
2372*7c568831SAndroid Build Coastguard Worker  *
2373*7c568831SAndroid Build Coastguard Worker  * The following resource loaders will be called if they were
2374*7c568831SAndroid Build Coastguard Worker  * registered (in order of precedence):
2375*7c568831SAndroid Build Coastguard Worker  *
2376*7c568831SAndroid Build Coastguard Worker  * - the per-thread xmlParserInputBufferCreateFilenameFunc set with
2377*7c568831SAndroid Build Coastguard Worker  *   xmlParserInputBufferCreateFilenameDefault (deprecated)
2378*7c568831SAndroid Build Coastguard Worker  * - the default loader which will return
2379*7c568831SAndroid Build Coastguard Worker  *   - the result from a matching global input callback set with
2380*7c568831SAndroid Build Coastguard Worker  *     xmlRegisterInputCallbacks (deprecated)
2381*7c568831SAndroid Build Coastguard Worker  *   - a HTTP resource if support is compiled in.
2382*7c568831SAndroid Build Coastguard Worker  *   - a file opened from the filesystem, with automatic detection
2383*7c568831SAndroid Build Coastguard Worker  *     of compressed files if support is compiled in.
2384*7c568831SAndroid Build Coastguard Worker  *
2385*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
2386*7c568831SAndroid Build Coastguard Worker  *
2387*7c568831SAndroid Build Coastguard Worker  * Returns an xmlParserErrors code.
2388*7c568831SAndroid Build Coastguard Worker  */
2389*7c568831SAndroid Build Coastguard Worker int
xmlNewInputFromUrl(const char * filename,int flags,xmlParserInputPtr * out)2390*7c568831SAndroid Build Coastguard Worker xmlNewInputFromUrl(const char *filename, int flags, xmlParserInputPtr *out) {
2391*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr buf;
2392*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
2393*7c568831SAndroid Build Coastguard Worker     int code = XML_ERR_OK;
2394*7c568831SAndroid Build Coastguard Worker 
2395*7c568831SAndroid Build Coastguard Worker     if (out == NULL)
2396*7c568831SAndroid Build Coastguard Worker         return(XML_ERR_ARGUMENT);
2397*7c568831SAndroid Build Coastguard Worker     *out = NULL;
2398*7c568831SAndroid Build Coastguard Worker     if (filename == NULL)
2399*7c568831SAndroid Build Coastguard Worker         return(XML_ERR_ARGUMENT);
2400*7c568831SAndroid Build Coastguard Worker 
2401*7c568831SAndroid Build Coastguard Worker     if (xmlParserInputBufferCreateFilenameValue != NULL) {
2402*7c568831SAndroid Build Coastguard Worker         buf = xmlParserInputBufferCreateFilenameValue(filename,
2403*7c568831SAndroid Build Coastguard Worker                 XML_CHAR_ENCODING_NONE);
2404*7c568831SAndroid Build Coastguard Worker         if (buf == NULL)
2405*7c568831SAndroid Build Coastguard Worker             code = XML_IO_ENOENT;
2406*7c568831SAndroid Build Coastguard Worker     } else {
2407*7c568831SAndroid Build Coastguard Worker         code = xmlParserInputBufferCreateUrl(filename, XML_CHAR_ENCODING_NONE,
2408*7c568831SAndroid Build Coastguard Worker                                              flags, &buf);
2409*7c568831SAndroid Build Coastguard Worker     }
2410*7c568831SAndroid Build Coastguard Worker     if (code != XML_ERR_OK)
2411*7c568831SAndroid Build Coastguard Worker 	return(code);
2412*7c568831SAndroid Build Coastguard Worker 
2413*7c568831SAndroid Build Coastguard Worker     input = xmlNewInputInternal(buf, filename);
2414*7c568831SAndroid Build Coastguard Worker     if (input == NULL)
2415*7c568831SAndroid Build Coastguard Worker 	return(XML_ERR_NO_MEMORY);
2416*7c568831SAndroid Build Coastguard Worker 
2417*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTTP_ENABLED
2418*7c568831SAndroid Build Coastguard Worker     code = xmlCheckHTTPInputInternal(input);
2419*7c568831SAndroid Build Coastguard Worker     if (code != XML_ERR_OK) {
2420*7c568831SAndroid Build Coastguard Worker         xmlFreeInputStream(input);
2421*7c568831SAndroid Build Coastguard Worker         return(code);
2422*7c568831SAndroid Build Coastguard Worker     }
2423*7c568831SAndroid Build Coastguard Worker #endif
2424*7c568831SAndroid Build Coastguard Worker 
2425*7c568831SAndroid Build Coastguard Worker     *out = input;
2426*7c568831SAndroid Build Coastguard Worker     return(XML_ERR_OK);
2427*7c568831SAndroid Build Coastguard Worker }
2428*7c568831SAndroid Build Coastguard Worker 
2429*7c568831SAndroid Build Coastguard Worker /**
2430*7c568831SAndroid Build Coastguard Worker  * xmlNewInputFromFile:
2431*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
2432*7c568831SAndroid Build Coastguard Worker  * @filename:  the filename to use as entity
2433*7c568831SAndroid Build Coastguard Worker  *
2434*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Use xmlNewInputFromUrl.
2435*7c568831SAndroid Build Coastguard Worker  *
2436*7c568831SAndroid Build Coastguard Worker  * Create a new input stream based on a file or an URL.
2437*7c568831SAndroid Build Coastguard Worker  *
2438*7c568831SAndroid Build Coastguard Worker  * Returns the new input stream or NULL in case of error
2439*7c568831SAndroid Build Coastguard Worker  */
2440*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNewInputFromFile(xmlParserCtxtPtr ctxt,const char * filename)2441*7c568831SAndroid Build Coastguard Worker xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
2442*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
2443*7c568831SAndroid Build Coastguard Worker     int flags = 0;
2444*7c568831SAndroid Build Coastguard Worker     int code;
2445*7c568831SAndroid Build Coastguard Worker 
2446*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (filename == NULL))
2447*7c568831SAndroid Build Coastguard Worker         return(NULL);
2448*7c568831SAndroid Build Coastguard Worker 
2449*7c568831SAndroid Build Coastguard Worker     if ((ctxt->options & XML_PARSE_NO_UNZIP) == 0)
2450*7c568831SAndroid Build Coastguard Worker         flags |= XML_INPUT_UNZIP;
2451*7c568831SAndroid Build Coastguard Worker     if ((ctxt->options & XML_PARSE_NONET) == 0)
2452*7c568831SAndroid Build Coastguard Worker         flags |= XML_INPUT_NETWORK;
2453*7c568831SAndroid Build Coastguard Worker 
2454*7c568831SAndroid Build Coastguard Worker     code = xmlNewInputFromUrl(filename, flags, &input);
2455*7c568831SAndroid Build Coastguard Worker     if (code != XML_ERR_OK) {
2456*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrIO(ctxt, code, filename);
2457*7c568831SAndroid Build Coastguard Worker         return(NULL);
2458*7c568831SAndroid Build Coastguard Worker     }
2459*7c568831SAndroid Build Coastguard Worker 
2460*7c568831SAndroid Build Coastguard Worker     return(input);
2461*7c568831SAndroid Build Coastguard Worker }
2462*7c568831SAndroid Build Coastguard Worker 
2463*7c568831SAndroid Build Coastguard Worker /**
2464*7c568831SAndroid Build Coastguard Worker  * xmlDefaultExternalEntityLoader:
2465*7c568831SAndroid Build Coastguard Worker  * @URL:  the URL for the entity to load
2466*7c568831SAndroid Build Coastguard Worker  * @ID:  the System ID for the entity to load
2467*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the context in which the entity is called or NULL
2468*7c568831SAndroid Build Coastguard Worker  *
2469*7c568831SAndroid Build Coastguard Worker  * By default we don't load external entities, yet.
2470*7c568831SAndroid Build Coastguard Worker  *
2471*7c568831SAndroid Build Coastguard Worker  * Returns a new allocated xmlParserInputPtr, or NULL.
2472*7c568831SAndroid Build Coastguard Worker  */
2473*7c568831SAndroid Build Coastguard Worker static xmlParserInputPtr
xmlDefaultExternalEntityLoader(const char * url,const char * ID,xmlParserCtxtPtr ctxt)2474*7c568831SAndroid Build Coastguard Worker xmlDefaultExternalEntityLoader(const char *url, const char *ID,
2475*7c568831SAndroid Build Coastguard Worker                                xmlParserCtxtPtr ctxt)
2476*7c568831SAndroid Build Coastguard Worker {
2477*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input = NULL;
2478*7c568831SAndroid Build Coastguard Worker     char *resource = NULL;
2479*7c568831SAndroid Build Coastguard Worker 
2480*7c568831SAndroid Build Coastguard Worker     (void) ID;
2481*7c568831SAndroid Build Coastguard Worker 
2482*7c568831SAndroid Build Coastguard Worker     if (url == NULL)
2483*7c568831SAndroid Build Coastguard Worker         return(NULL);
2484*7c568831SAndroid Build Coastguard Worker 
2485*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
2486*7c568831SAndroid Build Coastguard Worker     resource = (char *) xmlResolveResourceFromCatalog(url, ID, ctxt);
2487*7c568831SAndroid Build Coastguard Worker     if (resource != NULL)
2488*7c568831SAndroid Build Coastguard Worker 	url = resource;
2489*7c568831SAndroid Build Coastguard Worker #endif
2490*7c568831SAndroid Build Coastguard Worker 
2491*7c568831SAndroid Build Coastguard Worker     if ((ctxt != NULL) &&
2492*7c568831SAndroid Build Coastguard Worker         (ctxt->options & XML_PARSE_NONET) &&
2493*7c568831SAndroid Build Coastguard Worker         (xmlStrncasecmp(BAD_CAST url, BAD_CAST "http://", 7) == 0)) {
2494*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrIO(ctxt, XML_IO_NETWORK_ATTEMPT, url);
2495*7c568831SAndroid Build Coastguard Worker     } else {
2496*7c568831SAndroid Build Coastguard Worker         input = xmlNewInputFromFile(ctxt, url);
2497*7c568831SAndroid Build Coastguard Worker     }
2498*7c568831SAndroid Build Coastguard Worker 
2499*7c568831SAndroid Build Coastguard Worker     if (resource != NULL)
2500*7c568831SAndroid Build Coastguard Worker 	xmlFree(resource);
2501*7c568831SAndroid Build Coastguard Worker     return(input);
2502*7c568831SAndroid Build Coastguard Worker }
2503*7c568831SAndroid Build Coastguard Worker 
2504*7c568831SAndroid Build Coastguard Worker /**
2505*7c568831SAndroid Build Coastguard Worker  * xmlNoNetExternalEntityLoader:
2506*7c568831SAndroid Build Coastguard Worker  * @URL:  the URL for the entity to load
2507*7c568831SAndroid Build Coastguard Worker  * @ID:  the System ID for the entity to load
2508*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the context in which the entity is called or NULL
2509*7c568831SAndroid Build Coastguard Worker  *
2510*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Use XML_PARSE_NONET.
2511*7c568831SAndroid Build Coastguard Worker  *
2512*7c568831SAndroid Build Coastguard Worker  * A specific entity loader disabling network accesses, though still
2513*7c568831SAndroid Build Coastguard Worker  * allowing local catalog accesses for resolution.
2514*7c568831SAndroid Build Coastguard Worker  *
2515*7c568831SAndroid Build Coastguard Worker  * Returns a new allocated xmlParserInputPtr, or NULL.
2516*7c568831SAndroid Build Coastguard Worker  */
2517*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlNoNetExternalEntityLoader(const char * URL,const char * ID,xmlParserCtxtPtr ctxt)2518*7c568831SAndroid Build Coastguard Worker xmlNoNetExternalEntityLoader(const char *URL, const char *ID,
2519*7c568831SAndroid Build Coastguard Worker                              xmlParserCtxtPtr ctxt) {
2520*7c568831SAndroid Build Coastguard Worker     int oldOptions = 0;
2521*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
2522*7c568831SAndroid Build Coastguard Worker 
2523*7c568831SAndroid Build Coastguard Worker     if (ctxt != NULL) {
2524*7c568831SAndroid Build Coastguard Worker         oldOptions = ctxt->options;
2525*7c568831SAndroid Build Coastguard Worker         ctxt->options |= XML_PARSE_NONET;
2526*7c568831SAndroid Build Coastguard Worker     }
2527*7c568831SAndroid Build Coastguard Worker 
2528*7c568831SAndroid Build Coastguard Worker     input = xmlDefaultExternalEntityLoader(URL, ID, ctxt);
2529*7c568831SAndroid Build Coastguard Worker 
2530*7c568831SAndroid Build Coastguard Worker     if (ctxt != NULL)
2531*7c568831SAndroid Build Coastguard Worker         ctxt->options = oldOptions;
2532*7c568831SAndroid Build Coastguard Worker 
2533*7c568831SAndroid Build Coastguard Worker     return(input);
2534*7c568831SAndroid Build Coastguard Worker }
2535*7c568831SAndroid Build Coastguard Worker 
2536*7c568831SAndroid Build Coastguard Worker /*
2537*7c568831SAndroid Build Coastguard Worker  * This global has to die eventually
2538*7c568831SAndroid Build Coastguard Worker  */
2539*7c568831SAndroid Build Coastguard Worker static xmlExternalEntityLoader
2540*7c568831SAndroid Build Coastguard Worker xmlCurrentExternalEntityLoader = xmlDefaultExternalEntityLoader;
2541*7c568831SAndroid Build Coastguard Worker 
2542*7c568831SAndroid Build Coastguard Worker /**
2543*7c568831SAndroid Build Coastguard Worker  * xmlSetExternalEntityLoader:
2544*7c568831SAndroid Build Coastguard Worker  * @f:  the new entity resolver function
2545*7c568831SAndroid Build Coastguard Worker  *
2546*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: This is a global setting and not thread-safe. Use
2547*7c568831SAndroid Build Coastguard Worker  * xmlCtxtSetResourceLoader or similar functions.
2548*7c568831SAndroid Build Coastguard Worker  *
2549*7c568831SAndroid Build Coastguard Worker  * Changes the default external entity resolver function for the
2550*7c568831SAndroid Build Coastguard Worker  * application.
2551*7c568831SAndroid Build Coastguard Worker  */
2552*7c568831SAndroid Build Coastguard Worker void
xmlSetExternalEntityLoader(xmlExternalEntityLoader f)2553*7c568831SAndroid Build Coastguard Worker xmlSetExternalEntityLoader(xmlExternalEntityLoader f) {
2554*7c568831SAndroid Build Coastguard Worker     xmlCurrentExternalEntityLoader = f;
2555*7c568831SAndroid Build Coastguard Worker }
2556*7c568831SAndroid Build Coastguard Worker 
2557*7c568831SAndroid Build Coastguard Worker /**
2558*7c568831SAndroid Build Coastguard Worker  * xmlGetExternalEntityLoader:
2559*7c568831SAndroid Build Coastguard Worker  *
2560*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: See xmlSetExternalEntityLoader.
2561*7c568831SAndroid Build Coastguard Worker  *
2562*7c568831SAndroid Build Coastguard Worker  * Get the default external entity resolver function for the application
2563*7c568831SAndroid Build Coastguard Worker  *
2564*7c568831SAndroid Build Coastguard Worker  * Returns the xmlExternalEntityLoader function pointer
2565*7c568831SAndroid Build Coastguard Worker  */
2566*7c568831SAndroid Build Coastguard Worker xmlExternalEntityLoader
xmlGetExternalEntityLoader(void)2567*7c568831SAndroid Build Coastguard Worker xmlGetExternalEntityLoader(void) {
2568*7c568831SAndroid Build Coastguard Worker     return(xmlCurrentExternalEntityLoader);
2569*7c568831SAndroid Build Coastguard Worker }
2570*7c568831SAndroid Build Coastguard Worker 
2571*7c568831SAndroid Build Coastguard Worker /**
2572*7c568831SAndroid Build Coastguard Worker  * xmlCtxtSetResourceLoader:
2573*7c568831SAndroid Build Coastguard Worker  * @ctxt:  parser context
2574*7c568831SAndroid Build Coastguard Worker  * @loader:  callback
2575*7c568831SAndroid Build Coastguard Worker  * @vctxt:  user data
2576*7c568831SAndroid Build Coastguard Worker  *
2577*7c568831SAndroid Build Coastguard Worker  * Installs a custom callback to load documents, DTDs or external
2578*7c568831SAndroid Build Coastguard Worker  * entities.
2579*7c568831SAndroid Build Coastguard Worker  *
2580*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
2581*7c568831SAndroid Build Coastguard Worker  */
2582*7c568831SAndroid Build Coastguard Worker void
xmlCtxtSetResourceLoader(xmlParserCtxtPtr ctxt,xmlResourceLoader loader,void * vctxt)2583*7c568831SAndroid Build Coastguard Worker xmlCtxtSetResourceLoader(xmlParserCtxtPtr ctxt, xmlResourceLoader loader,
2584*7c568831SAndroid Build Coastguard Worker                          void *vctxt) {
2585*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
2586*7c568831SAndroid Build Coastguard Worker         return;
2587*7c568831SAndroid Build Coastguard Worker 
2588*7c568831SAndroid Build Coastguard Worker     ctxt->resourceLoader = loader;
2589*7c568831SAndroid Build Coastguard Worker     ctxt->resourceCtxt = vctxt;
2590*7c568831SAndroid Build Coastguard Worker }
2591*7c568831SAndroid Build Coastguard Worker 
2592*7c568831SAndroid Build Coastguard Worker /**
2593*7c568831SAndroid Build Coastguard Worker  * xmlLoadResource:
2594*7c568831SAndroid Build Coastguard Worker  * @ctxt:  parser context
2595*7c568831SAndroid Build Coastguard Worker  * @url:  the URL for the entity to load
2596*7c568831SAndroid Build Coastguard Worker  * @publicId:  the Public ID for the entity to load
2597*7c568831SAndroid Build Coastguard Worker  * @type:  resource type
2598*7c568831SAndroid Build Coastguard Worker  *
2599*7c568831SAndroid Build Coastguard Worker  * Returns the xmlParserInputPtr or NULL in case of error.
2600*7c568831SAndroid Build Coastguard Worker  */
2601*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlLoadResource(xmlParserCtxtPtr ctxt,const char * url,const char * publicId,xmlResourceType type)2602*7c568831SAndroid Build Coastguard Worker xmlLoadResource(xmlParserCtxtPtr ctxt, const char *url, const char *publicId,
2603*7c568831SAndroid Build Coastguard Worker                 xmlResourceType type) {
2604*7c568831SAndroid Build Coastguard Worker     char *canonicFilename;
2605*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr ret;
2606*7c568831SAndroid Build Coastguard Worker 
2607*7c568831SAndroid Build Coastguard Worker     if (url == NULL)
2608*7c568831SAndroid Build Coastguard Worker         return(NULL);
2609*7c568831SAndroid Build Coastguard Worker 
2610*7c568831SAndroid Build Coastguard Worker     if ((ctxt != NULL) && (ctxt->resourceLoader != NULL)) {
2611*7c568831SAndroid Build Coastguard Worker         char *resource = NULL;
2612*7c568831SAndroid Build Coastguard Worker         int flags = 0;
2613*7c568831SAndroid Build Coastguard Worker         int code;
2614*7c568831SAndroid Build Coastguard Worker 
2615*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
2616*7c568831SAndroid Build Coastguard Worker         resource = (char *) xmlResolveResourceFromCatalog(url, publicId, ctxt);
2617*7c568831SAndroid Build Coastguard Worker         if (resource != NULL)
2618*7c568831SAndroid Build Coastguard Worker             url = resource;
2619*7c568831SAndroid Build Coastguard Worker #endif
2620*7c568831SAndroid Build Coastguard Worker 
2621*7c568831SAndroid Build Coastguard Worker         if ((ctxt->options & XML_PARSE_NO_UNZIP) == 0)
2622*7c568831SAndroid Build Coastguard Worker             flags |= XML_INPUT_UNZIP;
2623*7c568831SAndroid Build Coastguard Worker         if ((ctxt->options & XML_PARSE_NONET) == 0)
2624*7c568831SAndroid Build Coastguard Worker             flags |= XML_INPUT_NETWORK;
2625*7c568831SAndroid Build Coastguard Worker 
2626*7c568831SAndroid Build Coastguard Worker         code = ctxt->resourceLoader(ctxt->resourceCtxt, url, publicId, type,
2627*7c568831SAndroid Build Coastguard Worker                                     flags, &ret);
2628*7c568831SAndroid Build Coastguard Worker         if (code != XML_ERR_OK) {
2629*7c568831SAndroid Build Coastguard Worker             xmlCtxtErrIO(ctxt, code, url);
2630*7c568831SAndroid Build Coastguard Worker             ret = NULL;
2631*7c568831SAndroid Build Coastguard Worker         }
2632*7c568831SAndroid Build Coastguard Worker         if (resource != NULL)
2633*7c568831SAndroid Build Coastguard Worker             xmlFree(resource);
2634*7c568831SAndroid Build Coastguard Worker         return(ret);
2635*7c568831SAndroid Build Coastguard Worker     }
2636*7c568831SAndroid Build Coastguard Worker 
2637*7c568831SAndroid Build Coastguard Worker     canonicFilename = (char *) xmlCanonicPath((const xmlChar *) url);
2638*7c568831SAndroid Build Coastguard Worker     if (canonicFilename == NULL) {
2639*7c568831SAndroid Build Coastguard Worker         xmlCtxtErrMemory(ctxt);
2640*7c568831SAndroid Build Coastguard Worker         return(NULL);
2641*7c568831SAndroid Build Coastguard Worker     }
2642*7c568831SAndroid Build Coastguard Worker 
2643*7c568831SAndroid Build Coastguard Worker     ret = xmlCurrentExternalEntityLoader(canonicFilename, publicId, ctxt);
2644*7c568831SAndroid Build Coastguard Worker     xmlFree(canonicFilename);
2645*7c568831SAndroid Build Coastguard Worker     return(ret);
2646*7c568831SAndroid Build Coastguard Worker }
2647*7c568831SAndroid Build Coastguard Worker 
2648*7c568831SAndroid Build Coastguard Worker /**
2649*7c568831SAndroid Build Coastguard Worker  * xmlLoadExternalEntity:
2650*7c568831SAndroid Build Coastguard Worker  * @URL:  the URL for the entity to load
2651*7c568831SAndroid Build Coastguard Worker  * @ID:  the Public ID for the entity to load
2652*7c568831SAndroid Build Coastguard Worker  * @ctxt:  the context in which the entity is called or NULL
2653*7c568831SAndroid Build Coastguard Worker  *
2654*7c568831SAndroid Build Coastguard Worker  * @URL is a filename or URL. If if contains the substring "://",
2655*7c568831SAndroid Build Coastguard Worker  * it is assumed to be a Legacy Extended IRI. Otherwise, it is
2656*7c568831SAndroid Build Coastguard Worker  * treated as a filesystem path.
2657*7c568831SAndroid Build Coastguard Worker  *
2658*7c568831SAndroid Build Coastguard Worker  * @ID is an optional XML public ID, typically from a doctype
2659*7c568831SAndroid Build Coastguard Worker  * declaration. It is used for catalog lookups.
2660*7c568831SAndroid Build Coastguard Worker  *
2661*7c568831SAndroid Build Coastguard Worker  * If catalog lookup is enabled (default is yes) and URL or ID are
2662*7c568831SAndroid Build Coastguard Worker  * found in system or local XML catalogs, URL is replaced with the
2663*7c568831SAndroid Build Coastguard Worker  * result. Then the following resource loaders will be called if
2664*7c568831SAndroid Build Coastguard Worker  * they were registered (in order of precedence):
2665*7c568831SAndroid Build Coastguard Worker  *
2666*7c568831SAndroid Build Coastguard Worker  * - the resource loader set with xmlCtxtSetResourceLoader
2667*7c568831SAndroid Build Coastguard Worker  * - the global external entity loader set with
2668*7c568831SAndroid Build Coastguard Worker  *   xmlSetExternalEntityLoader (without catalog resolution,
2669*7c568831SAndroid Build Coastguard Worker  *   deprecated)
2670*7c568831SAndroid Build Coastguard Worker  * - the per-thread xmlParserInputBufferCreateFilenameFunc set with
2671*7c568831SAndroid Build Coastguard Worker  *   xmlParserInputBufferCreateFilenameDefault (deprecated)
2672*7c568831SAndroid Build Coastguard Worker  * - the default loader which will return
2673*7c568831SAndroid Build Coastguard Worker  *   - the result from a matching global input callback set with
2674*7c568831SAndroid Build Coastguard Worker  *     xmlRegisterInputCallbacks (deprecated)
2675*7c568831SAndroid Build Coastguard Worker  *   - a HTTP resource if support is compiled in.
2676*7c568831SAndroid Build Coastguard Worker  *   - a file opened from the filesystem, with automatic detection
2677*7c568831SAndroid Build Coastguard Worker  *     of compressed files if support is compiled in.
2678*7c568831SAndroid Build Coastguard Worker  *
2679*7c568831SAndroid Build Coastguard Worker  * Returns the xmlParserInputPtr or NULL
2680*7c568831SAndroid Build Coastguard Worker  */
2681*7c568831SAndroid Build Coastguard Worker xmlParserInputPtr
xmlLoadExternalEntity(const char * URL,const char * ID,xmlParserCtxtPtr ctxt)2682*7c568831SAndroid Build Coastguard Worker xmlLoadExternalEntity(const char *URL, const char *ID,
2683*7c568831SAndroid Build Coastguard Worker                       xmlParserCtxtPtr ctxt) {
2684*7c568831SAndroid Build Coastguard Worker     return(xmlLoadResource(ctxt, URL, ID, XML_RESOURCE_UNKNOWN));
2685*7c568831SAndroid Build Coastguard Worker }
2686*7c568831SAndroid Build Coastguard Worker 
2687*7c568831SAndroid Build Coastguard Worker /************************************************************************
2688*7c568831SAndroid Build Coastguard Worker  *									*
2689*7c568831SAndroid Build Coastguard Worker  *		Commodity functions to handle parser contexts		*
2690*7c568831SAndroid Build Coastguard Worker  *									*
2691*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
2692*7c568831SAndroid Build Coastguard Worker 
2693*7c568831SAndroid Build Coastguard Worker /**
2694*7c568831SAndroid Build Coastguard Worker  * xmlInitSAXParserCtxt:
2695*7c568831SAndroid Build Coastguard Worker  * @ctxt:  XML parser context
2696*7c568831SAndroid Build Coastguard Worker  * @sax:  SAX handlert
2697*7c568831SAndroid Build Coastguard Worker  * @userData:  user data
2698*7c568831SAndroid Build Coastguard Worker  *
2699*7c568831SAndroid Build Coastguard Worker  * Initialize a SAX parser context
2700*7c568831SAndroid Build Coastguard Worker  *
2701*7c568831SAndroid Build Coastguard Worker  * Returns 0 in case of success and -1 in case of error
2702*7c568831SAndroid Build Coastguard Worker  */
2703*7c568831SAndroid Build Coastguard Worker 
2704*7c568831SAndroid Build Coastguard Worker static int
xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt,const xmlSAXHandler * sax,void * userData)2705*7c568831SAndroid Build Coastguard Worker xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
2706*7c568831SAndroid Build Coastguard Worker                      void *userData)
2707*7c568831SAndroid Build Coastguard Worker {
2708*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
2709*7c568831SAndroid Build Coastguard Worker #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
2710*7c568831SAndroid Build Coastguard Worker     size_t initialNodeTabSize = 1;
2711*7c568831SAndroid Build Coastguard Worker #else
2712*7c568831SAndroid Build Coastguard Worker     size_t initialNodeTabSize = 10;
2713*7c568831SAndroid Build Coastguard Worker #endif
2714*7c568831SAndroid Build Coastguard Worker 
2715*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
2716*7c568831SAndroid Build Coastguard Worker         return(-1);
2717*7c568831SAndroid Build Coastguard Worker 
2718*7c568831SAndroid Build Coastguard Worker     if (ctxt->dict == NULL)
2719*7c568831SAndroid Build Coastguard Worker 	ctxt->dict = xmlDictCreate();
2720*7c568831SAndroid Build Coastguard Worker     if (ctxt->dict == NULL)
2721*7c568831SAndroid Build Coastguard Worker 	return(-1);
2722*7c568831SAndroid Build Coastguard Worker 
2723*7c568831SAndroid Build Coastguard Worker     if (ctxt->sax == NULL)
2724*7c568831SAndroid Build Coastguard Worker 	ctxt->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
2725*7c568831SAndroid Build Coastguard Worker     if (ctxt->sax == NULL)
2726*7c568831SAndroid Build Coastguard Worker 	return(-1);
2727*7c568831SAndroid Build Coastguard Worker     if (sax == NULL) {
2728*7c568831SAndroid Build Coastguard Worker 	memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
2729*7c568831SAndroid Build Coastguard Worker         xmlSAXVersion(ctxt->sax, 2);
2730*7c568831SAndroid Build Coastguard Worker         ctxt->userData = ctxt;
2731*7c568831SAndroid Build Coastguard Worker     } else {
2732*7c568831SAndroid Build Coastguard Worker 	if (sax->initialized == XML_SAX2_MAGIC) {
2733*7c568831SAndroid Build Coastguard Worker 	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
2734*7c568831SAndroid Build Coastguard Worker         } else {
2735*7c568831SAndroid Build Coastguard Worker 	    memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
2736*7c568831SAndroid Build Coastguard Worker 	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
2737*7c568831SAndroid Build Coastguard Worker         }
2738*7c568831SAndroid Build Coastguard Worker         ctxt->userData = userData ? userData : ctxt;
2739*7c568831SAndroid Build Coastguard Worker     }
2740*7c568831SAndroid Build Coastguard Worker 
2741*7c568831SAndroid Build Coastguard Worker     ctxt->maxatts = 0;
2742*7c568831SAndroid Build Coastguard Worker     ctxt->atts = NULL;
2743*7c568831SAndroid Build Coastguard Worker     /* Allocate the Input stack */
2744*7c568831SAndroid Build Coastguard Worker     if (ctxt->inputTab == NULL) {
2745*7c568831SAndroid Build Coastguard Worker #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
2746*7c568831SAndroid Build Coastguard Worker         size_t initialSize = 1;
2747*7c568831SAndroid Build Coastguard Worker #else
2748*7c568831SAndroid Build Coastguard Worker         size_t initialSize = 5;
2749*7c568831SAndroid Build Coastguard Worker #endif
2750*7c568831SAndroid Build Coastguard Worker 
2751*7c568831SAndroid Build Coastguard Worker 	ctxt->inputTab = xmlMalloc(initialSize * sizeof(xmlParserInputPtr));
2752*7c568831SAndroid Build Coastguard Worker 	ctxt->inputMax = initialSize;
2753*7c568831SAndroid Build Coastguard Worker     }
2754*7c568831SAndroid Build Coastguard Worker     if (ctxt->inputTab == NULL)
2755*7c568831SAndroid Build Coastguard Worker 	return(-1);
2756*7c568831SAndroid Build Coastguard Worker     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
2757*7c568831SAndroid Build Coastguard Worker         xmlFreeInputStream(input);
2758*7c568831SAndroid Build Coastguard Worker     }
2759*7c568831SAndroid Build Coastguard Worker     ctxt->inputNr = 0;
2760*7c568831SAndroid Build Coastguard Worker     ctxt->input = NULL;
2761*7c568831SAndroid Build Coastguard Worker 
2762*7c568831SAndroid Build Coastguard Worker     ctxt->version = NULL;
2763*7c568831SAndroid Build Coastguard Worker     ctxt->encoding = NULL;
2764*7c568831SAndroid Build Coastguard Worker     ctxt->standalone = -1;
2765*7c568831SAndroid Build Coastguard Worker     ctxt->hasExternalSubset = 0;
2766*7c568831SAndroid Build Coastguard Worker     ctxt->hasPErefs = 0;
2767*7c568831SAndroid Build Coastguard Worker     ctxt->html = 0;
2768*7c568831SAndroid Build Coastguard Worker     ctxt->instate = XML_PARSER_START;
2769*7c568831SAndroid Build Coastguard Worker 
2770*7c568831SAndroid Build Coastguard Worker     /* Allocate the Node stack */
2771*7c568831SAndroid Build Coastguard Worker     if (ctxt->nodeTab == NULL) {
2772*7c568831SAndroid Build Coastguard Worker 	ctxt->nodeTab = xmlMalloc(initialNodeTabSize * sizeof(xmlNodePtr));
2773*7c568831SAndroid Build Coastguard Worker 	ctxt->nodeMax = initialNodeTabSize;
2774*7c568831SAndroid Build Coastguard Worker     }
2775*7c568831SAndroid Build Coastguard Worker     if (ctxt->nodeTab == NULL)
2776*7c568831SAndroid Build Coastguard Worker 	return(-1);
2777*7c568831SAndroid Build Coastguard Worker     ctxt->nodeNr = 0;
2778*7c568831SAndroid Build Coastguard Worker     ctxt->node = NULL;
2779*7c568831SAndroid Build Coastguard Worker 
2780*7c568831SAndroid Build Coastguard Worker     /* Allocate the Name stack */
2781*7c568831SAndroid Build Coastguard Worker     if (ctxt->nameTab == NULL) {
2782*7c568831SAndroid Build Coastguard Worker 	ctxt->nameTab = xmlMalloc(initialNodeTabSize * sizeof(xmlChar *));
2783*7c568831SAndroid Build Coastguard Worker 	ctxt->nameMax = initialNodeTabSize;
2784*7c568831SAndroid Build Coastguard Worker     }
2785*7c568831SAndroid Build Coastguard Worker     if (ctxt->nameTab == NULL)
2786*7c568831SAndroid Build Coastguard Worker 	return(-1);
2787*7c568831SAndroid Build Coastguard Worker     ctxt->nameNr = 0;
2788*7c568831SAndroid Build Coastguard Worker     ctxt->name = NULL;
2789*7c568831SAndroid Build Coastguard Worker 
2790*7c568831SAndroid Build Coastguard Worker     /* Allocate the space stack */
2791*7c568831SAndroid Build Coastguard Worker     if (ctxt->spaceTab == NULL) {
2792*7c568831SAndroid Build Coastguard Worker 	ctxt->spaceTab = xmlMalloc(initialNodeTabSize * sizeof(int));
2793*7c568831SAndroid Build Coastguard Worker 	ctxt->spaceMax = initialNodeTabSize;
2794*7c568831SAndroid Build Coastguard Worker     }
2795*7c568831SAndroid Build Coastguard Worker     if (ctxt->spaceTab == NULL)
2796*7c568831SAndroid Build Coastguard Worker 	return(-1);
2797*7c568831SAndroid Build Coastguard Worker     ctxt->spaceNr = 1;
2798*7c568831SAndroid Build Coastguard Worker     ctxt->spaceTab[0] = -1;
2799*7c568831SAndroid Build Coastguard Worker     ctxt->space = &ctxt->spaceTab[0];
2800*7c568831SAndroid Build Coastguard Worker     ctxt->myDoc = NULL;
2801*7c568831SAndroid Build Coastguard Worker     ctxt->wellFormed = 1;
2802*7c568831SAndroid Build Coastguard Worker     ctxt->nsWellFormed = 1;
2803*7c568831SAndroid Build Coastguard Worker     ctxt->valid = 1;
2804*7c568831SAndroid Build Coastguard Worker 
2805*7c568831SAndroid Build Coastguard Worker     ctxt->options = XML_PARSE_NODICT;
2806*7c568831SAndroid Build Coastguard Worker 
2807*7c568831SAndroid Build Coastguard Worker     /*
2808*7c568831SAndroid Build Coastguard Worker      * Initialize some parser options from deprecated global variables.
2809*7c568831SAndroid Build Coastguard Worker      * Note that the "modern" API taking options arguments or
2810*7c568831SAndroid Build Coastguard Worker      * xmlCtxtSetOptions will ignore these defaults. They're only
2811*7c568831SAndroid Build Coastguard Worker      * relevant if old API functions like xmlParseFile are used.
2812*7c568831SAndroid Build Coastguard Worker      */
2813*7c568831SAndroid Build Coastguard Worker     ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
2814*7c568831SAndroid Build Coastguard Worker     if (ctxt->loadsubset) {
2815*7c568831SAndroid Build Coastguard Worker         ctxt->options |= XML_PARSE_DTDLOAD;
2816*7c568831SAndroid Build Coastguard Worker     }
2817*7c568831SAndroid Build Coastguard Worker     ctxt->validate = xmlDoValidityCheckingDefaultValue;
2818*7c568831SAndroid Build Coastguard Worker     if (ctxt->validate) {
2819*7c568831SAndroid Build Coastguard Worker         ctxt->options |= XML_PARSE_DTDVALID;
2820*7c568831SAndroid Build Coastguard Worker     }
2821*7c568831SAndroid Build Coastguard Worker     ctxt->pedantic = xmlPedanticParserDefaultValue;
2822*7c568831SAndroid Build Coastguard Worker     if (ctxt->pedantic) {
2823*7c568831SAndroid Build Coastguard Worker         ctxt->options |= XML_PARSE_PEDANTIC;
2824*7c568831SAndroid Build Coastguard Worker     }
2825*7c568831SAndroid Build Coastguard Worker     ctxt->linenumbers = xmlLineNumbersDefaultValue;
2826*7c568831SAndroid Build Coastguard Worker     ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
2827*7c568831SAndroid Build Coastguard Worker     if (ctxt->keepBlanks == 0) {
2828*7c568831SAndroid Build Coastguard Worker 	ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
2829*7c568831SAndroid Build Coastguard Worker 	ctxt->options |= XML_PARSE_NOBLANKS;
2830*7c568831SAndroid Build Coastguard Worker     }
2831*7c568831SAndroid Build Coastguard Worker     ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
2832*7c568831SAndroid Build Coastguard Worker     if (ctxt->replaceEntities) {
2833*7c568831SAndroid Build Coastguard Worker         ctxt->options |= XML_PARSE_NOENT;
2834*7c568831SAndroid Build Coastguard Worker     }
2835*7c568831SAndroid Build Coastguard Worker     if (xmlGetWarningsDefaultValue == 0)
2836*7c568831SAndroid Build Coastguard Worker         ctxt->options |= XML_PARSE_NOWARNING;
2837*7c568831SAndroid Build Coastguard Worker 
2838*7c568831SAndroid Build Coastguard Worker     ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT;
2839*7c568831SAndroid Build Coastguard Worker     ctxt->vctxt.userData = ctxt;
2840*7c568831SAndroid Build Coastguard Worker     ctxt->vctxt.error = xmlParserValidityError;
2841*7c568831SAndroid Build Coastguard Worker     ctxt->vctxt.warning = xmlParserValidityWarning;
2842*7c568831SAndroid Build Coastguard Worker 
2843*7c568831SAndroid Build Coastguard Worker     ctxt->record_info = 0;
2844*7c568831SAndroid Build Coastguard Worker     ctxt->checkIndex = 0;
2845*7c568831SAndroid Build Coastguard Worker     ctxt->inSubset = 0;
2846*7c568831SAndroid Build Coastguard Worker     ctxt->errNo = XML_ERR_OK;
2847*7c568831SAndroid Build Coastguard Worker     ctxt->depth = 0;
2848*7c568831SAndroid Build Coastguard Worker     ctxt->catalogs = NULL;
2849*7c568831SAndroid Build Coastguard Worker     ctxt->sizeentities = 0;
2850*7c568831SAndroid Build Coastguard Worker     ctxt->sizeentcopy = 0;
2851*7c568831SAndroid Build Coastguard Worker     ctxt->input_id = 1;
2852*7c568831SAndroid Build Coastguard Worker     ctxt->maxAmpl = XML_MAX_AMPLIFICATION_DEFAULT;
2853*7c568831SAndroid Build Coastguard Worker     xmlInitNodeInfoSeq(&ctxt->node_seq);
2854*7c568831SAndroid Build Coastguard Worker 
2855*7c568831SAndroid Build Coastguard Worker     if (ctxt->nsdb == NULL) {
2856*7c568831SAndroid Build Coastguard Worker         ctxt->nsdb = xmlParserNsCreate();
2857*7c568831SAndroid Build Coastguard Worker         if (ctxt->nsdb == NULL)
2858*7c568831SAndroid Build Coastguard Worker             return(-1);
2859*7c568831SAndroid Build Coastguard Worker     }
2860*7c568831SAndroid Build Coastguard Worker 
2861*7c568831SAndroid Build Coastguard Worker     return(0);
2862*7c568831SAndroid Build Coastguard Worker }
2863*7c568831SAndroid Build Coastguard Worker 
2864*7c568831SAndroid Build Coastguard Worker /**
2865*7c568831SAndroid Build Coastguard Worker  * xmlInitParserCtxt:
2866*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
2867*7c568831SAndroid Build Coastguard Worker  *
2868*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Internal function which will be made private in a future
2869*7c568831SAndroid Build Coastguard Worker  * version.
2870*7c568831SAndroid Build Coastguard Worker  *
2871*7c568831SAndroid Build Coastguard Worker  * Initialize a parser context
2872*7c568831SAndroid Build Coastguard Worker  *
2873*7c568831SAndroid Build Coastguard Worker  * Returns 0 in case of success and -1 in case of error
2874*7c568831SAndroid Build Coastguard Worker  */
2875*7c568831SAndroid Build Coastguard Worker 
2876*7c568831SAndroid Build Coastguard Worker int
xmlInitParserCtxt(xmlParserCtxtPtr ctxt)2877*7c568831SAndroid Build Coastguard Worker xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
2878*7c568831SAndroid Build Coastguard Worker {
2879*7c568831SAndroid Build Coastguard Worker     return(xmlInitSAXParserCtxt(ctxt, NULL, NULL));
2880*7c568831SAndroid Build Coastguard Worker }
2881*7c568831SAndroid Build Coastguard Worker 
2882*7c568831SAndroid Build Coastguard Worker /**
2883*7c568831SAndroid Build Coastguard Worker  * xmlFreeParserCtxt:
2884*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
2885*7c568831SAndroid Build Coastguard Worker  *
2886*7c568831SAndroid Build Coastguard Worker  * Free all the memory used by a parser context. However the parsed
2887*7c568831SAndroid Build Coastguard Worker  * document in ctxt->myDoc is not freed.
2888*7c568831SAndroid Build Coastguard Worker  */
2889*7c568831SAndroid Build Coastguard Worker 
2890*7c568831SAndroid Build Coastguard Worker void
xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)2891*7c568831SAndroid Build Coastguard Worker xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
2892*7c568831SAndroid Build Coastguard Worker {
2893*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr input;
2894*7c568831SAndroid Build Coastguard Worker 
2895*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL) return;
2896*7c568831SAndroid Build Coastguard Worker 
2897*7c568831SAndroid Build Coastguard Worker     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
2898*7c568831SAndroid Build Coastguard Worker         xmlFreeInputStream(input);
2899*7c568831SAndroid Build Coastguard Worker     }
2900*7c568831SAndroid Build Coastguard Worker     if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
2901*7c568831SAndroid Build Coastguard Worker     if (ctxt->nameTab != NULL) xmlFree((xmlChar * *)ctxt->nameTab);
2902*7c568831SAndroid Build Coastguard Worker     if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
2903*7c568831SAndroid Build Coastguard Worker     if (ctxt->nodeInfoTab != NULL) xmlFree(ctxt->nodeInfoTab);
2904*7c568831SAndroid Build Coastguard Worker     if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
2905*7c568831SAndroid Build Coastguard Worker     if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
2906*7c568831SAndroid Build Coastguard Worker     if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
2907*7c568831SAndroid Build Coastguard Worker     if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
2908*7c568831SAndroid Build Coastguard Worker     if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
2909*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
2910*7c568831SAndroid Build Coastguard Worker     if ((ctxt->sax != NULL) &&
2911*7c568831SAndroid Build Coastguard Worker         (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler))
2912*7c568831SAndroid Build Coastguard Worker #else
2913*7c568831SAndroid Build Coastguard Worker     if (ctxt->sax != NULL)
2914*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
2915*7c568831SAndroid Build Coastguard Worker         xmlFree(ctxt->sax);
2916*7c568831SAndroid Build Coastguard Worker     if (ctxt->directory != NULL) xmlFree(ctxt->directory);
2917*7c568831SAndroid Build Coastguard Worker     if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
2918*7c568831SAndroid Build Coastguard Worker     if (ctxt->atts != NULL) xmlFree((xmlChar * *)ctxt->atts);
2919*7c568831SAndroid Build Coastguard Worker     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
2920*7c568831SAndroid Build Coastguard Worker     if (ctxt->nsTab != NULL) xmlFree(ctxt->nsTab);
2921*7c568831SAndroid Build Coastguard Worker     if (ctxt->nsdb != NULL) xmlParserNsFree(ctxt->nsdb);
2922*7c568831SAndroid Build Coastguard Worker     if (ctxt->attrHash != NULL) xmlFree(ctxt->attrHash);
2923*7c568831SAndroid Build Coastguard Worker     if (ctxt->pushTab != NULL) xmlFree(ctxt->pushTab);
2924*7c568831SAndroid Build Coastguard Worker     if (ctxt->attallocs != NULL) xmlFree(ctxt->attallocs);
2925*7c568831SAndroid Build Coastguard Worker     if (ctxt->attsDefault != NULL)
2926*7c568831SAndroid Build Coastguard Worker         xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator);
2927*7c568831SAndroid Build Coastguard Worker     if (ctxt->attsSpecial != NULL)
2928*7c568831SAndroid Build Coastguard Worker         xmlHashFree(ctxt->attsSpecial, NULL);
2929*7c568831SAndroid Build Coastguard Worker     if (ctxt->freeElems != NULL) {
2930*7c568831SAndroid Build Coastguard Worker         xmlNodePtr cur, next;
2931*7c568831SAndroid Build Coastguard Worker 
2932*7c568831SAndroid Build Coastguard Worker 	cur = ctxt->freeElems;
2933*7c568831SAndroid Build Coastguard Worker 	while (cur != NULL) {
2934*7c568831SAndroid Build Coastguard Worker 	    next = cur->next;
2935*7c568831SAndroid Build Coastguard Worker 	    xmlFree(cur);
2936*7c568831SAndroid Build Coastguard Worker 	    cur = next;
2937*7c568831SAndroid Build Coastguard Worker 	}
2938*7c568831SAndroid Build Coastguard Worker     }
2939*7c568831SAndroid Build Coastguard Worker     if (ctxt->freeAttrs != NULL) {
2940*7c568831SAndroid Build Coastguard Worker         xmlAttrPtr cur, next;
2941*7c568831SAndroid Build Coastguard Worker 
2942*7c568831SAndroid Build Coastguard Worker 	cur = ctxt->freeAttrs;
2943*7c568831SAndroid Build Coastguard Worker 	while (cur != NULL) {
2944*7c568831SAndroid Build Coastguard Worker 	    next = cur->next;
2945*7c568831SAndroid Build Coastguard Worker 	    xmlFree(cur);
2946*7c568831SAndroid Build Coastguard Worker 	    cur = next;
2947*7c568831SAndroid Build Coastguard Worker 	}
2948*7c568831SAndroid Build Coastguard Worker     }
2949*7c568831SAndroid Build Coastguard Worker     /*
2950*7c568831SAndroid Build Coastguard Worker      * cleanup the error strings
2951*7c568831SAndroid Build Coastguard Worker      */
2952*7c568831SAndroid Build Coastguard Worker     if (ctxt->lastError.message != NULL)
2953*7c568831SAndroid Build Coastguard Worker         xmlFree(ctxt->lastError.message);
2954*7c568831SAndroid Build Coastguard Worker     if (ctxt->lastError.file != NULL)
2955*7c568831SAndroid Build Coastguard Worker         xmlFree(ctxt->lastError.file);
2956*7c568831SAndroid Build Coastguard Worker     if (ctxt->lastError.str1 != NULL)
2957*7c568831SAndroid Build Coastguard Worker         xmlFree(ctxt->lastError.str1);
2958*7c568831SAndroid Build Coastguard Worker     if (ctxt->lastError.str2 != NULL)
2959*7c568831SAndroid Build Coastguard Worker         xmlFree(ctxt->lastError.str2);
2960*7c568831SAndroid Build Coastguard Worker     if (ctxt->lastError.str3 != NULL)
2961*7c568831SAndroid Build Coastguard Worker         xmlFree(ctxt->lastError.str3);
2962*7c568831SAndroid Build Coastguard Worker 
2963*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
2964*7c568831SAndroid Build Coastguard Worker     if (ctxt->catalogs != NULL)
2965*7c568831SAndroid Build Coastguard Worker 	xmlCatalogFreeLocal(ctxt->catalogs);
2966*7c568831SAndroid Build Coastguard Worker #endif
2967*7c568831SAndroid Build Coastguard Worker     xmlFree(ctxt);
2968*7c568831SAndroid Build Coastguard Worker }
2969*7c568831SAndroid Build Coastguard Worker 
2970*7c568831SAndroid Build Coastguard Worker /**
2971*7c568831SAndroid Build Coastguard Worker  * xmlNewParserCtxt:
2972*7c568831SAndroid Build Coastguard Worker  *
2973*7c568831SAndroid Build Coastguard Worker  * Allocate and initialize a new parser context.
2974*7c568831SAndroid Build Coastguard Worker  *
2975*7c568831SAndroid Build Coastguard Worker  * Returns the xmlParserCtxtPtr or NULL
2976*7c568831SAndroid Build Coastguard Worker  */
2977*7c568831SAndroid Build Coastguard Worker 
2978*7c568831SAndroid Build Coastguard Worker xmlParserCtxtPtr
xmlNewParserCtxt(void)2979*7c568831SAndroid Build Coastguard Worker xmlNewParserCtxt(void)
2980*7c568831SAndroid Build Coastguard Worker {
2981*7c568831SAndroid Build Coastguard Worker     return(xmlNewSAXParserCtxt(NULL, NULL));
2982*7c568831SAndroid Build Coastguard Worker }
2983*7c568831SAndroid Build Coastguard Worker 
2984*7c568831SAndroid Build Coastguard Worker /**
2985*7c568831SAndroid Build Coastguard Worker  * xmlNewSAXParserCtxt:
2986*7c568831SAndroid Build Coastguard Worker  * @sax:  SAX handler
2987*7c568831SAndroid Build Coastguard Worker  * @userData:  user data
2988*7c568831SAndroid Build Coastguard Worker  *
2989*7c568831SAndroid Build Coastguard Worker  * Allocate and initialize a new SAX parser context. If userData is NULL,
2990*7c568831SAndroid Build Coastguard Worker  * the parser context will be passed as user data.
2991*7c568831SAndroid Build Coastguard Worker  *
2992*7c568831SAndroid Build Coastguard Worker  * Available since 2.11.0. If you want support older versions,
2993*7c568831SAndroid Build Coastguard Worker  * it's best to invoke xmlNewParserCtxt and set ctxt->sax with
2994*7c568831SAndroid Build Coastguard Worker  * struct assignment.
2995*7c568831SAndroid Build Coastguard Worker  *
2996*7c568831SAndroid Build Coastguard Worker  * Returns the xmlParserCtxtPtr or NULL if memory allocation failed.
2997*7c568831SAndroid Build Coastguard Worker  */
2998*7c568831SAndroid Build Coastguard Worker 
2999*7c568831SAndroid Build Coastguard Worker xmlParserCtxtPtr
xmlNewSAXParserCtxt(const xmlSAXHandler * sax,void * userData)3000*7c568831SAndroid Build Coastguard Worker xmlNewSAXParserCtxt(const xmlSAXHandler *sax, void *userData)
3001*7c568831SAndroid Build Coastguard Worker {
3002*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
3003*7c568831SAndroid Build Coastguard Worker 
3004*7c568831SAndroid Build Coastguard Worker     xmlInitParser();
3005*7c568831SAndroid Build Coastguard Worker 
3006*7c568831SAndroid Build Coastguard Worker     ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
3007*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
3008*7c568831SAndroid Build Coastguard Worker 	return(NULL);
3009*7c568831SAndroid Build Coastguard Worker     memset(ctxt, 0, sizeof(xmlParserCtxt));
3010*7c568831SAndroid Build Coastguard Worker     if (xmlInitSAXParserCtxt(ctxt, sax, userData) < 0) {
3011*7c568831SAndroid Build Coastguard Worker         xmlFreeParserCtxt(ctxt);
3012*7c568831SAndroid Build Coastguard Worker 	return(NULL);
3013*7c568831SAndroid Build Coastguard Worker     }
3014*7c568831SAndroid Build Coastguard Worker     return(ctxt);
3015*7c568831SAndroid Build Coastguard Worker }
3016*7c568831SAndroid Build Coastguard Worker 
3017*7c568831SAndroid Build Coastguard Worker /**
3018*7c568831SAndroid Build Coastguard Worker  * xmlCtxtGetPrivate:
3019*7c568831SAndroid Build Coastguard Worker  * ctxt:  parser context
3020*7c568831SAndroid Build Coastguard Worker  *
3021*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
3022*7c568831SAndroid Build Coastguard Worker  *
3023*7c568831SAndroid Build Coastguard Worker  * Returns the private application data.
3024*7c568831SAndroid Build Coastguard Worker  */
3025*7c568831SAndroid Build Coastguard Worker void *
xmlCtxtGetPrivate(xmlParserCtxtPtr ctxt)3026*7c568831SAndroid Build Coastguard Worker xmlCtxtGetPrivate(xmlParserCtxtPtr ctxt) {
3027*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
3028*7c568831SAndroid Build Coastguard Worker         return(NULL);
3029*7c568831SAndroid Build Coastguard Worker 
3030*7c568831SAndroid Build Coastguard Worker     return(ctxt->_private);
3031*7c568831SAndroid Build Coastguard Worker }
3032*7c568831SAndroid Build Coastguard Worker 
3033*7c568831SAndroid Build Coastguard Worker /**
3034*7c568831SAndroid Build Coastguard Worker  * xmlCtxtSetPrivate:
3035*7c568831SAndroid Build Coastguard Worker  * ctxt:  parser context
3036*7c568831SAndroid Build Coastguard Worker  * priv:  private application data
3037*7c568831SAndroid Build Coastguard Worker  *
3038*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
3039*7c568831SAndroid Build Coastguard Worker  *
3040*7c568831SAndroid Build Coastguard Worker  * Set the private application data.
3041*7c568831SAndroid Build Coastguard Worker  */
3042*7c568831SAndroid Build Coastguard Worker void
xmlCtxtSetPrivate(xmlParserCtxtPtr ctxt,void * priv)3043*7c568831SAndroid Build Coastguard Worker xmlCtxtSetPrivate(xmlParserCtxtPtr ctxt, void *priv) {
3044*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
3045*7c568831SAndroid Build Coastguard Worker         return;
3046*7c568831SAndroid Build Coastguard Worker 
3047*7c568831SAndroid Build Coastguard Worker     ctxt->_private = priv;
3048*7c568831SAndroid Build Coastguard Worker }
3049*7c568831SAndroid Build Coastguard Worker 
3050*7c568831SAndroid Build Coastguard Worker /**
3051*7c568831SAndroid Build Coastguard Worker  * xmlCtxtGetCatalogs:
3052*7c568831SAndroid Build Coastguard Worker  * ctxt:  parser context
3053*7c568831SAndroid Build Coastguard Worker  *
3054*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
3055*7c568831SAndroid Build Coastguard Worker  *
3056*7c568831SAndroid Build Coastguard Worker  * Returns the local catalogs.
3057*7c568831SAndroid Build Coastguard Worker  */
3058*7c568831SAndroid Build Coastguard Worker void *
xmlCtxtGetCatalogs(xmlParserCtxtPtr ctxt)3059*7c568831SAndroid Build Coastguard Worker xmlCtxtGetCatalogs(xmlParserCtxtPtr ctxt) {
3060*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
3061*7c568831SAndroid Build Coastguard Worker         return(NULL);
3062*7c568831SAndroid Build Coastguard Worker 
3063*7c568831SAndroid Build Coastguard Worker     return(ctxt->catalogs);
3064*7c568831SAndroid Build Coastguard Worker }
3065*7c568831SAndroid Build Coastguard Worker 
3066*7c568831SAndroid Build Coastguard Worker /**
3067*7c568831SAndroid Build Coastguard Worker  * xmlCtxtSetCatalogs:
3068*7c568831SAndroid Build Coastguard Worker  * ctxt:  parser context
3069*7c568831SAndroid Build Coastguard Worker  * catalogs:  catalogs pointer
3070*7c568831SAndroid Build Coastguard Worker  *
3071*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
3072*7c568831SAndroid Build Coastguard Worker  *
3073*7c568831SAndroid Build Coastguard Worker  * Set the local catalogs.
3074*7c568831SAndroid Build Coastguard Worker  */
3075*7c568831SAndroid Build Coastguard Worker void
xmlCtxtSetCatalogs(xmlParserCtxtPtr ctxt,void * catalogs)3076*7c568831SAndroid Build Coastguard Worker xmlCtxtSetCatalogs(xmlParserCtxtPtr ctxt, void *catalogs) {
3077*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
3078*7c568831SAndroid Build Coastguard Worker         return;
3079*7c568831SAndroid Build Coastguard Worker 
3080*7c568831SAndroid Build Coastguard Worker     ctxt->catalogs = catalogs;
3081*7c568831SAndroid Build Coastguard Worker }
3082*7c568831SAndroid Build Coastguard Worker 
3083*7c568831SAndroid Build Coastguard Worker /**
3084*7c568831SAndroid Build Coastguard Worker  * xmlCtxtGetDict:
3085*7c568831SAndroid Build Coastguard Worker  * ctxt:  parser context
3086*7c568831SAndroid Build Coastguard Worker  *
3087*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
3088*7c568831SAndroid Build Coastguard Worker  *
3089*7c568831SAndroid Build Coastguard Worker  * Returns the dictionary.
3090*7c568831SAndroid Build Coastguard Worker  */
3091*7c568831SAndroid Build Coastguard Worker xmlDictPtr
xmlCtxtGetDict(xmlParserCtxtPtr ctxt)3092*7c568831SAndroid Build Coastguard Worker xmlCtxtGetDict(xmlParserCtxtPtr ctxt) {
3093*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
3094*7c568831SAndroid Build Coastguard Worker         return(NULL);
3095*7c568831SAndroid Build Coastguard Worker 
3096*7c568831SAndroid Build Coastguard Worker     return(ctxt->dict);
3097*7c568831SAndroid Build Coastguard Worker }
3098*7c568831SAndroid Build Coastguard Worker 
3099*7c568831SAndroid Build Coastguard Worker /**
3100*7c568831SAndroid Build Coastguard Worker  * xmlCtxtSetDict:
3101*7c568831SAndroid Build Coastguard Worker  * ctxt:  parser context
3102*7c568831SAndroid Build Coastguard Worker  * dict:  dictionary
3103*7c568831SAndroid Build Coastguard Worker  *
3104*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
3105*7c568831SAndroid Build Coastguard Worker  *
3106*7c568831SAndroid Build Coastguard Worker  * Set the dictionary. This should only be done immediately after
3107*7c568831SAndroid Build Coastguard Worker  * creating a parser context.
3108*7c568831SAndroid Build Coastguard Worker  */
3109*7c568831SAndroid Build Coastguard Worker void
xmlCtxtSetDict(xmlParserCtxtPtr ctxt,xmlDictPtr dict)3110*7c568831SAndroid Build Coastguard Worker xmlCtxtSetDict(xmlParserCtxtPtr ctxt, xmlDictPtr dict) {
3111*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
3112*7c568831SAndroid Build Coastguard Worker         return;
3113*7c568831SAndroid Build Coastguard Worker 
3114*7c568831SAndroid Build Coastguard Worker     if (ctxt->dict != NULL)
3115*7c568831SAndroid Build Coastguard Worker         xmlDictFree(ctxt->dict);
3116*7c568831SAndroid Build Coastguard Worker 
3117*7c568831SAndroid Build Coastguard Worker     xmlDictReference(dict);
3118*7c568831SAndroid Build Coastguard Worker     ctxt->dict = dict;
3119*7c568831SAndroid Build Coastguard Worker }
3120*7c568831SAndroid Build Coastguard Worker 
3121*7c568831SAndroid Build Coastguard Worker /************************************************************************
3122*7c568831SAndroid Build Coastguard Worker  *									*
3123*7c568831SAndroid Build Coastguard Worker  *		Handling of node information				*
3124*7c568831SAndroid Build Coastguard Worker  *									*
3125*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
3126*7c568831SAndroid Build Coastguard Worker 
3127*7c568831SAndroid Build Coastguard Worker /**
3128*7c568831SAndroid Build Coastguard Worker  * xmlClearParserCtxt:
3129*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
3130*7c568831SAndroid Build Coastguard Worker  *
3131*7c568831SAndroid Build Coastguard Worker  * Clear (release owned resources) and reinitialize a parser context
3132*7c568831SAndroid Build Coastguard Worker  */
3133*7c568831SAndroid Build Coastguard Worker 
3134*7c568831SAndroid Build Coastguard Worker void
xmlClearParserCtxt(xmlParserCtxtPtr ctxt)3135*7c568831SAndroid Build Coastguard Worker xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
3136*7c568831SAndroid Build Coastguard Worker {
3137*7c568831SAndroid Build Coastguard Worker   if (ctxt==NULL)
3138*7c568831SAndroid Build Coastguard Worker     return;
3139*7c568831SAndroid Build Coastguard Worker   xmlClearNodeInfoSeq(&ctxt->node_seq);
3140*7c568831SAndroid Build Coastguard Worker   xmlCtxtReset(ctxt);
3141*7c568831SAndroid Build Coastguard Worker }
3142*7c568831SAndroid Build Coastguard Worker 
3143*7c568831SAndroid Build Coastguard Worker 
3144*7c568831SAndroid Build Coastguard Worker /**
3145*7c568831SAndroid Build Coastguard Worker  * xmlParserFindNodeInfo:
3146*7c568831SAndroid Build Coastguard Worker  * @ctx:  an XML parser context
3147*7c568831SAndroid Build Coastguard Worker  * @node:  an XML node within the tree
3148*7c568831SAndroid Build Coastguard Worker  *
3149*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
3150*7c568831SAndroid Build Coastguard Worker  *
3151*7c568831SAndroid Build Coastguard Worker  * Find the parser node info struct for a given node
3152*7c568831SAndroid Build Coastguard Worker  *
3153*7c568831SAndroid Build Coastguard Worker  * Returns an xmlParserNodeInfo block pointer or NULL
3154*7c568831SAndroid Build Coastguard Worker  */
3155*7c568831SAndroid Build Coastguard Worker const xmlParserNodeInfo *
xmlParserFindNodeInfo(xmlParserCtxtPtr ctx,xmlNodePtr node)3156*7c568831SAndroid Build Coastguard Worker xmlParserFindNodeInfo(xmlParserCtxtPtr ctx, xmlNodePtr node)
3157*7c568831SAndroid Build Coastguard Worker {
3158*7c568831SAndroid Build Coastguard Worker     unsigned long pos;
3159*7c568831SAndroid Build Coastguard Worker 
3160*7c568831SAndroid Build Coastguard Worker     if ((ctx == NULL) || (node == NULL))
3161*7c568831SAndroid Build Coastguard Worker         return (NULL);
3162*7c568831SAndroid Build Coastguard Worker     /* Find position where node should be at */
3163*7c568831SAndroid Build Coastguard Worker     pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
3164*7c568831SAndroid Build Coastguard Worker     if (pos < ctx->node_seq.length
3165*7c568831SAndroid Build Coastguard Worker         && ctx->node_seq.buffer[pos].node == node)
3166*7c568831SAndroid Build Coastguard Worker         return &ctx->node_seq.buffer[pos];
3167*7c568831SAndroid Build Coastguard Worker     else
3168*7c568831SAndroid Build Coastguard Worker         return NULL;
3169*7c568831SAndroid Build Coastguard Worker }
3170*7c568831SAndroid Build Coastguard Worker 
3171*7c568831SAndroid Build Coastguard Worker 
3172*7c568831SAndroid Build Coastguard Worker /**
3173*7c568831SAndroid Build Coastguard Worker  * xmlInitNodeInfoSeq:
3174*7c568831SAndroid Build Coastguard Worker  * @seq:  a node info sequence pointer
3175*7c568831SAndroid Build Coastguard Worker  *
3176*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
3177*7c568831SAndroid Build Coastguard Worker  *
3178*7c568831SAndroid Build Coastguard Worker  * -- Initialize (set to initial state) node info sequence
3179*7c568831SAndroid Build Coastguard Worker  */
3180*7c568831SAndroid Build Coastguard Worker void
xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)3181*7c568831SAndroid Build Coastguard Worker xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
3182*7c568831SAndroid Build Coastguard Worker {
3183*7c568831SAndroid Build Coastguard Worker     if (seq == NULL)
3184*7c568831SAndroid Build Coastguard Worker         return;
3185*7c568831SAndroid Build Coastguard Worker     seq->length = 0;
3186*7c568831SAndroid Build Coastguard Worker     seq->maximum = 0;
3187*7c568831SAndroid Build Coastguard Worker     seq->buffer = NULL;
3188*7c568831SAndroid Build Coastguard Worker }
3189*7c568831SAndroid Build Coastguard Worker 
3190*7c568831SAndroid Build Coastguard Worker /**
3191*7c568831SAndroid Build Coastguard Worker  * xmlClearNodeInfoSeq:
3192*7c568831SAndroid Build Coastguard Worker  * @seq:  a node info sequence pointer
3193*7c568831SAndroid Build Coastguard Worker  *
3194*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
3195*7c568831SAndroid Build Coastguard Worker  *
3196*7c568831SAndroid Build Coastguard Worker  * -- Clear (release memory and reinitialize) node
3197*7c568831SAndroid Build Coastguard Worker  *   info sequence
3198*7c568831SAndroid Build Coastguard Worker  */
3199*7c568831SAndroid Build Coastguard Worker void
xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)3200*7c568831SAndroid Build Coastguard Worker xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
3201*7c568831SAndroid Build Coastguard Worker {
3202*7c568831SAndroid Build Coastguard Worker     if (seq == NULL)
3203*7c568831SAndroid Build Coastguard Worker         return;
3204*7c568831SAndroid Build Coastguard Worker     if (seq->buffer != NULL)
3205*7c568831SAndroid Build Coastguard Worker         xmlFree(seq->buffer);
3206*7c568831SAndroid Build Coastguard Worker     xmlInitNodeInfoSeq(seq);
3207*7c568831SAndroid Build Coastguard Worker }
3208*7c568831SAndroid Build Coastguard Worker 
3209*7c568831SAndroid Build Coastguard Worker /**
3210*7c568831SAndroid Build Coastguard Worker  * xmlParserFindNodeInfoIndex:
3211*7c568831SAndroid Build Coastguard Worker  * @seq:  a node info sequence pointer
3212*7c568831SAndroid Build Coastguard Worker  * @node:  an XML node pointer
3213*7c568831SAndroid Build Coastguard Worker  *
3214*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
3215*7c568831SAndroid Build Coastguard Worker  *
3216*7c568831SAndroid Build Coastguard Worker  * xmlParserFindNodeInfoIndex : Find the index that the info record for
3217*7c568831SAndroid Build Coastguard Worker  *   the given node is or should be at in a sorted sequence
3218*7c568831SAndroid Build Coastguard Worker  *
3219*7c568831SAndroid Build Coastguard Worker  * Returns a long indicating the position of the record
3220*7c568831SAndroid Build Coastguard Worker  */
3221*7c568831SAndroid Build Coastguard Worker unsigned long
xmlParserFindNodeInfoIndex(xmlParserNodeInfoSeqPtr seq,xmlNodePtr node)3222*7c568831SAndroid Build Coastguard Worker xmlParserFindNodeInfoIndex(xmlParserNodeInfoSeqPtr seq,
3223*7c568831SAndroid Build Coastguard Worker                            xmlNodePtr node)
3224*7c568831SAndroid Build Coastguard Worker {
3225*7c568831SAndroid Build Coastguard Worker     unsigned long upper, lower, middle;
3226*7c568831SAndroid Build Coastguard Worker     int found = 0;
3227*7c568831SAndroid Build Coastguard Worker 
3228*7c568831SAndroid Build Coastguard Worker     if ((seq == NULL) || (node == NULL))
3229*7c568831SAndroid Build Coastguard Worker         return ((unsigned long) -1);
3230*7c568831SAndroid Build Coastguard Worker 
3231*7c568831SAndroid Build Coastguard Worker     /* Do a binary search for the key */
3232*7c568831SAndroid Build Coastguard Worker     lower = 1;
3233*7c568831SAndroid Build Coastguard Worker     upper = seq->length;
3234*7c568831SAndroid Build Coastguard Worker     middle = 0;
3235*7c568831SAndroid Build Coastguard Worker     while (lower <= upper && !found) {
3236*7c568831SAndroid Build Coastguard Worker         middle = lower + (upper - lower) / 2;
3237*7c568831SAndroid Build Coastguard Worker         if (node == seq->buffer[middle - 1].node)
3238*7c568831SAndroid Build Coastguard Worker             found = 1;
3239*7c568831SAndroid Build Coastguard Worker         else if (node < seq->buffer[middle - 1].node)
3240*7c568831SAndroid Build Coastguard Worker             upper = middle - 1;
3241*7c568831SAndroid Build Coastguard Worker         else
3242*7c568831SAndroid Build Coastguard Worker             lower = middle + 1;
3243*7c568831SAndroid Build Coastguard Worker     }
3244*7c568831SAndroid Build Coastguard Worker 
3245*7c568831SAndroid Build Coastguard Worker     /* Return position */
3246*7c568831SAndroid Build Coastguard Worker     if (middle == 0 || seq->buffer[middle - 1].node < node)
3247*7c568831SAndroid Build Coastguard Worker         return middle;
3248*7c568831SAndroid Build Coastguard Worker     else
3249*7c568831SAndroid Build Coastguard Worker         return middle - 1;
3250*7c568831SAndroid Build Coastguard Worker }
3251*7c568831SAndroid Build Coastguard Worker 
3252*7c568831SAndroid Build Coastguard Worker 
3253*7c568831SAndroid Build Coastguard Worker /**
3254*7c568831SAndroid Build Coastguard Worker  * xmlParserAddNodeInfo:
3255*7c568831SAndroid Build Coastguard Worker  * @ctxt:  an XML parser context
3256*7c568831SAndroid Build Coastguard Worker  * @info:  a node info sequence pointer
3257*7c568831SAndroid Build Coastguard Worker  *
3258*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
3259*7c568831SAndroid Build Coastguard Worker  *
3260*7c568831SAndroid Build Coastguard Worker  * Insert node info record into the sorted sequence
3261*7c568831SAndroid Build Coastguard Worker  */
3262*7c568831SAndroid Build Coastguard Worker void
xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,xmlParserNodeInfoPtr info)3263*7c568831SAndroid Build Coastguard Worker xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
3264*7c568831SAndroid Build Coastguard Worker                      xmlParserNodeInfoPtr info)
3265*7c568831SAndroid Build Coastguard Worker {
3266*7c568831SAndroid Build Coastguard Worker     unsigned long pos;
3267*7c568831SAndroid Build Coastguard Worker 
3268*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (info == NULL)) return;
3269*7c568831SAndroid Build Coastguard Worker 
3270*7c568831SAndroid Build Coastguard Worker     /* Find pos and check to see if node is already in the sequence */
3271*7c568831SAndroid Build Coastguard Worker     pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, (xmlNodePtr)
3272*7c568831SAndroid Build Coastguard Worker                                      info->node);
3273*7c568831SAndroid Build Coastguard Worker 
3274*7c568831SAndroid Build Coastguard Worker     if ((pos < ctxt->node_seq.length) &&
3275*7c568831SAndroid Build Coastguard Worker         (ctxt->node_seq.buffer != NULL) &&
3276*7c568831SAndroid Build Coastguard Worker         (ctxt->node_seq.buffer[pos].node == info->node)) {
3277*7c568831SAndroid Build Coastguard Worker         ctxt->node_seq.buffer[pos] = *info;
3278*7c568831SAndroid Build Coastguard Worker     }
3279*7c568831SAndroid Build Coastguard Worker 
3280*7c568831SAndroid Build Coastguard Worker     /* Otherwise, we need to add new node to buffer */
3281*7c568831SAndroid Build Coastguard Worker     else {
3282*7c568831SAndroid Build Coastguard Worker         if ((ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) ||
3283*7c568831SAndroid Build Coastguard Worker 	    (ctxt->node_seq.buffer == NULL)) {
3284*7c568831SAndroid Build Coastguard Worker             xmlParserNodeInfo *tmp_buffer;
3285*7c568831SAndroid Build Coastguard Worker             unsigned int byte_size;
3286*7c568831SAndroid Build Coastguard Worker 
3287*7c568831SAndroid Build Coastguard Worker             if (ctxt->node_seq.maximum == 0)
3288*7c568831SAndroid Build Coastguard Worker                 ctxt->node_seq.maximum = 2;
3289*7c568831SAndroid Build Coastguard Worker             byte_size = (sizeof(*ctxt->node_seq.buffer) *
3290*7c568831SAndroid Build Coastguard Worker 			(2 * ctxt->node_seq.maximum));
3291*7c568831SAndroid Build Coastguard Worker 
3292*7c568831SAndroid Build Coastguard Worker             if (ctxt->node_seq.buffer == NULL)
3293*7c568831SAndroid Build Coastguard Worker                 tmp_buffer = (xmlParserNodeInfo *) xmlMalloc(byte_size);
3294*7c568831SAndroid Build Coastguard Worker             else
3295*7c568831SAndroid Build Coastguard Worker                 tmp_buffer =
3296*7c568831SAndroid Build Coastguard Worker                     (xmlParserNodeInfo *) xmlRealloc(ctxt->node_seq.buffer,
3297*7c568831SAndroid Build Coastguard Worker                                                      byte_size);
3298*7c568831SAndroid Build Coastguard Worker 
3299*7c568831SAndroid Build Coastguard Worker             if (tmp_buffer == NULL) {
3300*7c568831SAndroid Build Coastguard Worker 		xmlCtxtErrMemory(ctxt);
3301*7c568831SAndroid Build Coastguard Worker                 return;
3302*7c568831SAndroid Build Coastguard Worker             }
3303*7c568831SAndroid Build Coastguard Worker             ctxt->node_seq.buffer = tmp_buffer;
3304*7c568831SAndroid Build Coastguard Worker             ctxt->node_seq.maximum *= 2;
3305*7c568831SAndroid Build Coastguard Worker         }
3306*7c568831SAndroid Build Coastguard Worker 
3307*7c568831SAndroid Build Coastguard Worker         /* If position is not at end, move elements out of the way */
3308*7c568831SAndroid Build Coastguard Worker         if (pos != ctxt->node_seq.length) {
3309*7c568831SAndroid Build Coastguard Worker             unsigned long i;
3310*7c568831SAndroid Build Coastguard Worker 
3311*7c568831SAndroid Build Coastguard Worker             for (i = ctxt->node_seq.length; i > pos; i--)
3312*7c568831SAndroid Build Coastguard Worker                 ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
3313*7c568831SAndroid Build Coastguard Worker         }
3314*7c568831SAndroid Build Coastguard Worker 
3315*7c568831SAndroid Build Coastguard Worker         /* Copy element and increase length */
3316*7c568831SAndroid Build Coastguard Worker         ctxt->node_seq.buffer[pos] = *info;
3317*7c568831SAndroid Build Coastguard Worker         ctxt->node_seq.length++;
3318*7c568831SAndroid Build Coastguard Worker     }
3319*7c568831SAndroid Build Coastguard Worker }
3320*7c568831SAndroid Build Coastguard Worker 
3321*7c568831SAndroid Build Coastguard Worker /************************************************************************
3322*7c568831SAndroid Build Coastguard Worker  *									*
3323*7c568831SAndroid Build Coastguard Worker  *		Defaults settings					*
3324*7c568831SAndroid Build Coastguard Worker  *									*
3325*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
3326*7c568831SAndroid Build Coastguard Worker /**
3327*7c568831SAndroid Build Coastguard Worker  * xmlPedanticParserDefault:
3328*7c568831SAndroid Build Coastguard Worker  * @val:  int 0 or 1
3329*7c568831SAndroid Build Coastguard Worker  *
3330*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Use the modern options API with XML_PARSE_PEDANTIC.
3331*7c568831SAndroid Build Coastguard Worker  *
3332*7c568831SAndroid Build Coastguard Worker  * Set and return the previous value for enabling pedantic warnings.
3333*7c568831SAndroid Build Coastguard Worker  *
3334*7c568831SAndroid Build Coastguard Worker  * Returns the last value for 0 for no substitution, 1 for substitution.
3335*7c568831SAndroid Build Coastguard Worker  */
3336*7c568831SAndroid Build Coastguard Worker 
3337*7c568831SAndroid Build Coastguard Worker int
xmlPedanticParserDefault(int val)3338*7c568831SAndroid Build Coastguard Worker xmlPedanticParserDefault(int val) {
3339*7c568831SAndroid Build Coastguard Worker     int old = xmlPedanticParserDefaultValue;
3340*7c568831SAndroid Build Coastguard Worker 
3341*7c568831SAndroid Build Coastguard Worker     xmlPedanticParserDefaultValue = val;
3342*7c568831SAndroid Build Coastguard Worker     return(old);
3343*7c568831SAndroid Build Coastguard Worker }
3344*7c568831SAndroid Build Coastguard Worker 
3345*7c568831SAndroid Build Coastguard Worker /**
3346*7c568831SAndroid Build Coastguard Worker  * xmlLineNumbersDefault:
3347*7c568831SAndroid Build Coastguard Worker  * @val:  int 0 or 1
3348*7c568831SAndroid Build Coastguard Worker  *
3349*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: The modern options API always enables line numbers.
3350*7c568831SAndroid Build Coastguard Worker  *
3351*7c568831SAndroid Build Coastguard Worker  * Set and return the previous value for enabling line numbers in elements
3352*7c568831SAndroid Build Coastguard Worker  * contents. This may break on old application and is turned off by default.
3353*7c568831SAndroid Build Coastguard Worker  *
3354*7c568831SAndroid Build Coastguard Worker  * Returns the last value for 0 for no substitution, 1 for substitution.
3355*7c568831SAndroid Build Coastguard Worker  */
3356*7c568831SAndroid Build Coastguard Worker 
3357*7c568831SAndroid Build Coastguard Worker int
xmlLineNumbersDefault(int val)3358*7c568831SAndroid Build Coastguard Worker xmlLineNumbersDefault(int val) {
3359*7c568831SAndroid Build Coastguard Worker     int old = xmlLineNumbersDefaultValue;
3360*7c568831SAndroid Build Coastguard Worker 
3361*7c568831SAndroid Build Coastguard Worker     xmlLineNumbersDefaultValue = val;
3362*7c568831SAndroid Build Coastguard Worker     return(old);
3363*7c568831SAndroid Build Coastguard Worker }
3364*7c568831SAndroid Build Coastguard Worker 
3365*7c568831SAndroid Build Coastguard Worker /**
3366*7c568831SAndroid Build Coastguard Worker  * xmlSubstituteEntitiesDefault:
3367*7c568831SAndroid Build Coastguard Worker  * @val:  int 0 or 1
3368*7c568831SAndroid Build Coastguard Worker  *
3369*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Use the modern options API with XML_PARSE_NOENT.
3370*7c568831SAndroid Build Coastguard Worker  *
3371*7c568831SAndroid Build Coastguard Worker  * Set and return the previous value for default entity support.
3372*7c568831SAndroid Build Coastguard Worker  * Initially the parser always keep entity references instead of substituting
3373*7c568831SAndroid Build Coastguard Worker  * entity values in the output. This function has to be used to change the
3374*7c568831SAndroid Build Coastguard Worker  * default parser behavior
3375*7c568831SAndroid Build Coastguard Worker  * SAX::substituteEntities() has to be used for changing that on a file by
3376*7c568831SAndroid Build Coastguard Worker  * file basis.
3377*7c568831SAndroid Build Coastguard Worker  *
3378*7c568831SAndroid Build Coastguard Worker  * Returns the last value for 0 for no substitution, 1 for substitution.
3379*7c568831SAndroid Build Coastguard Worker  */
3380*7c568831SAndroid Build Coastguard Worker 
3381*7c568831SAndroid Build Coastguard Worker int
xmlSubstituteEntitiesDefault(int val)3382*7c568831SAndroid Build Coastguard Worker xmlSubstituteEntitiesDefault(int val) {
3383*7c568831SAndroid Build Coastguard Worker     int old = xmlSubstituteEntitiesDefaultValue;
3384*7c568831SAndroid Build Coastguard Worker 
3385*7c568831SAndroid Build Coastguard Worker     xmlSubstituteEntitiesDefaultValue = val;
3386*7c568831SAndroid Build Coastguard Worker     return(old);
3387*7c568831SAndroid Build Coastguard Worker }
3388*7c568831SAndroid Build Coastguard Worker 
3389*7c568831SAndroid Build Coastguard Worker /**
3390*7c568831SAndroid Build Coastguard Worker  * xmlKeepBlanksDefault:
3391*7c568831SAndroid Build Coastguard Worker  * @val:  int 0 or 1
3392*7c568831SAndroid Build Coastguard Worker  *
3393*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Use the modern options API with XML_PARSE_NOBLANKS.
3394*7c568831SAndroid Build Coastguard Worker  *
3395*7c568831SAndroid Build Coastguard Worker  * Set and return the previous value for default blanks text nodes support.
3396*7c568831SAndroid Build Coastguard Worker  * The 1.x version of the parser used an heuristic to try to detect
3397*7c568831SAndroid Build Coastguard Worker  * ignorable white spaces. As a result the SAX callback was generating
3398*7c568831SAndroid Build Coastguard Worker  * xmlSAX2IgnorableWhitespace() callbacks instead of characters() one, and when
3399*7c568831SAndroid Build Coastguard Worker  * using the DOM output text nodes containing those blanks were not generated.
3400*7c568831SAndroid Build Coastguard Worker  * The 2.x and later version will switch to the XML standard way and
3401*7c568831SAndroid Build Coastguard Worker  * ignorableWhitespace() are only generated when running the parser in
3402*7c568831SAndroid Build Coastguard Worker  * validating mode and when the current element doesn't allow CDATA or
3403*7c568831SAndroid Build Coastguard Worker  * mixed content.
3404*7c568831SAndroid Build Coastguard Worker  * This function is provided as a way to force the standard behavior
3405*7c568831SAndroid Build Coastguard Worker  * on 1.X libs and to switch back to the old mode for compatibility when
3406*7c568831SAndroid Build Coastguard Worker  * running 1.X client code on 2.X . Upgrade of 1.X code should be done
3407*7c568831SAndroid Build Coastguard Worker  * by using xmlIsBlankNode() commodity function to detect the "empty"
3408*7c568831SAndroid Build Coastguard Worker  * nodes generated.
3409*7c568831SAndroid Build Coastguard Worker  * This value also affect autogeneration of indentation when saving code
3410*7c568831SAndroid Build Coastguard Worker  * if blanks sections are kept, indentation is not generated.
3411*7c568831SAndroid Build Coastguard Worker  *
3412*7c568831SAndroid Build Coastguard Worker  * Returns the last value for 0 for no substitution, 1 for substitution.
3413*7c568831SAndroid Build Coastguard Worker  */
3414*7c568831SAndroid Build Coastguard Worker 
3415*7c568831SAndroid Build Coastguard Worker int
xmlKeepBlanksDefault(int val)3416*7c568831SAndroid Build Coastguard Worker xmlKeepBlanksDefault(int val) {
3417*7c568831SAndroid Build Coastguard Worker     int old = xmlKeepBlanksDefaultValue;
3418*7c568831SAndroid Build Coastguard Worker 
3419*7c568831SAndroid Build Coastguard Worker     xmlKeepBlanksDefaultValue = val;
3420*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
3421*7c568831SAndroid Build Coastguard Worker     if (!val)
3422*7c568831SAndroid Build Coastguard Worker         xmlIndentTreeOutput = 1;
3423*7c568831SAndroid Build Coastguard Worker #endif
3424*7c568831SAndroid Build Coastguard Worker     return(old);
3425*7c568831SAndroid Build Coastguard Worker }
3426*7c568831SAndroid Build Coastguard Worker 
3427