Bump to libxml2 2.9.7
[platform/upstream/libxml2.git] / parser.c
1 /*
2  * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
3  *            implemented on top of the SAX interfaces
4  *
5  * References:
6  *   The XML specification:
7  *     http://www.w3.org/TR/REC-xml
8  *   Original 1.0 version:
9  *     http://www.w3.org/TR/1998/REC-xml-19980210
10  *   XML second edition working draft
11  *     http://www.w3.org/TR/2000/WD-xml-2e-20000814
12  *
13  * Okay this is a big file, the parser core is around 7000 lines, then it
14  * is followed by the progressive parser top routines, then the various
15  * high level APIs to call the parser and a few miscellaneous functions.
16  * A number of helper functions and deprecated ones have been moved to
17  * parserInternals.c to reduce this file size.
18  * As much as possible the functions are associated with their relative
19  * production in the XML specification. A few productions defining the
20  * different ranges of character are actually implanted either in
21  * parserInternals.h or parserInternals.c
22  * The DOM tree build is realized from the default SAX callbacks in
23  * the module SAX.c.
24  * The routines doing the validation checks are in valid.c and called either
25  * from the SAX callbacks or as standalone functions using a preparsed
26  * document.
27  *
28  * See Copyright for the status of this software.
29  *
30  * daniel@veillard.com
31  */
32
33 /* To avoid EBCDIC trouble when parsing on zOS */
34 #if defined(__MVS__)
35 #pragma convert("ISO8859-1")
36 #endif
37
38 #define IN_LIBXML
39 #include "libxml.h"
40
41 #if defined(_WIN32) && !defined (__CYGWIN__)
42 #define XML_DIR_SEP '\\'
43 #else
44 #define XML_DIR_SEP '/'
45 #endif
46
47 #include <stdlib.h>
48 #include <limits.h>
49 #include <string.h>
50 #include <stdarg.h>
51 #include <stddef.h>
52 #include <libxml/xmlmemory.h>
53 #include <libxml/threads.h>
54 #include <libxml/globals.h>
55 #include <libxml/tree.h>
56 #include <libxml/parser.h>
57 #include <libxml/parserInternals.h>
58 #include <libxml/valid.h>
59 #include <libxml/entities.h>
60 #include <libxml/xmlerror.h>
61 #include <libxml/encoding.h>
62 #include <libxml/xmlIO.h>
63 #include <libxml/uri.h>
64 #ifdef LIBXML_CATALOG_ENABLED
65 #include <libxml/catalog.h>
66 #endif
67 #ifdef LIBXML_SCHEMAS_ENABLED
68 #include <libxml/xmlschemastypes.h>
69 #include <libxml/relaxng.h>
70 #endif
71 #ifdef HAVE_CTYPE_H
72 #include <ctype.h>
73 #endif
74 #ifdef HAVE_STDLIB_H
75 #include <stdlib.h>
76 #endif
77 #ifdef HAVE_SYS_STAT_H
78 #include <sys/stat.h>
79 #endif
80 #ifdef HAVE_FCNTL_H
81 #include <fcntl.h>
82 #endif
83 #ifdef HAVE_UNISTD_H
84 #include <unistd.h>
85 #endif
86 #ifdef HAVE_ZLIB_H
87 #include <zlib.h>
88 #endif
89 #ifdef HAVE_LZMA_H
90 #include <lzma.h>
91 #endif
92
93 #include "buf.h"
94 #include "enc.h"
95
96 static void
97 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
98
99 static xmlParserCtxtPtr
100 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
101                           const xmlChar *base, xmlParserCtxtPtr pctx);
102
103 static void xmlHaltParser(xmlParserCtxtPtr ctxt);
104
105 /************************************************************************
106  *                                                                      *
107  *      Arbitrary limits set in the parser. See XML_PARSE_HUGE          *
108  *                                                                      *
109  ************************************************************************/
110
111 #define XML_PARSER_BIG_ENTITY 1000
112 #define XML_PARSER_LOT_ENTITY 5000
113
114 /*
115  * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
116  *    replacement over the size in byte of the input indicates that you have
117  *    and eponential behaviour. A value of 10 correspond to at least 3 entity
118  *    replacement per byte of input.
119  */
120 #define XML_PARSER_NON_LINEAR 10
121
122 /*
123  * xmlParserEntityCheck
124  *
125  * Function to check non-linear entity expansion behaviour
126  * This is here to detect and stop exponential linear entity expansion
127  * This is not a limitation of the parser but a safety
128  * boundary feature. It can be disabled with the XML_PARSE_HUGE
129  * parser option.
130  */
131 static int
132 xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
133                      xmlEntityPtr ent, size_t replacement)
134 {
135     size_t consumed = 0;
136
137     if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
138         return (0);
139     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
140         return (1);
141
142     /*
143      * This may look absurd but is needed to detect
144      * entities problems
145      */
146     if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
147         (ent->content != NULL) && (ent->checked == 0) &&
148         (ctxt->errNo != XML_ERR_ENTITY_LOOP)) {
149         unsigned long oldnbent = ctxt->nbentities;
150         xmlChar *rep;
151
152         ent->checked = 1;
153
154         ++ctxt->depth;
155         rep = xmlStringDecodeEntities(ctxt, ent->content,
156                                   XML_SUBSTITUTE_REF, 0, 0, 0);
157         --ctxt->depth;
158         if (ctxt->errNo == XML_ERR_ENTITY_LOOP) {
159             ent->content[0] = 0;
160         }
161
162         ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
163         if (rep != NULL) {
164             if (xmlStrchr(rep, '<'))
165                 ent->checked |= 1;
166             xmlFree(rep);
167             rep = NULL;
168         }
169     }
170     if (replacement != 0) {
171         if (replacement < XML_MAX_TEXT_LENGTH)
172             return(0);
173
174         /*
175          * If the volume of entity copy reaches 10 times the
176          * amount of parsed data and over the large text threshold
177          * then that's very likely to be an abuse.
178          */
179         if (ctxt->input != NULL) {
180             consumed = ctxt->input->consumed +
181                        (ctxt->input->cur - ctxt->input->base);
182         }
183         consumed += ctxt->sizeentities;
184
185         if (replacement < XML_PARSER_NON_LINEAR * consumed)
186             return(0);
187     } else if (size != 0) {
188         /*
189          * Do the check based on the replacement size of the entity
190          */
191         if (size < XML_PARSER_BIG_ENTITY)
192             return(0);
193
194         /*
195          * A limit on the amount of text data reasonably used
196          */
197         if (ctxt->input != NULL) {
198             consumed = ctxt->input->consumed +
199                 (ctxt->input->cur - ctxt->input->base);
200         }
201         consumed += ctxt->sizeentities;
202
203         if ((size < XML_PARSER_NON_LINEAR * consumed) &&
204             (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
205             return (0);
206     } else if (ent != NULL) {
207         /*
208          * use the number of parsed entities in the replacement
209          */
210         size = ent->checked / 2;
211
212         /*
213          * The amount of data parsed counting entities size only once
214          */
215         if (ctxt->input != NULL) {
216             consumed = ctxt->input->consumed +
217                 (ctxt->input->cur - ctxt->input->base);
218         }
219         consumed += ctxt->sizeentities;
220
221         /*
222          * Check the density of entities for the amount of data
223          * knowing an entity reference will take at least 3 bytes
224          */
225         if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
226             return (0);
227     } else {
228         /*
229          * strange we got no data for checking
230          */
231         if (((ctxt->lastError.code != XML_ERR_UNDECLARED_ENTITY) &&
232              (ctxt->lastError.code != XML_WAR_UNDECLARED_ENTITY)) ||
233             (ctxt->nbentities <= 10000))
234             return (0);
235     }
236     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
237     return (1);
238 }
239
240 /**
241  * xmlParserMaxDepth:
242  *
243  * arbitrary depth limit for the XML documents that we allow to
244  * process. This is not a limitation of the parser but a safety
245  * boundary feature. It can be disabled with the XML_PARSE_HUGE
246  * parser option.
247  */
248 unsigned int xmlParserMaxDepth = 256;
249
250
251
252 #define SAX2 1
253 #define XML_PARSER_BIG_BUFFER_SIZE 300
254 #define XML_PARSER_BUFFER_SIZE 100
255 #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
256
257 /**
258  * XML_PARSER_CHUNK_SIZE
259  *
260  * When calling GROW that's the minimal amount of data
261  * the parser expected to have received. It is not a hard
262  * limit but an optimization when reading strings like Names
263  * It is not strictly needed as long as inputs available characters
264  * are followed by 0, which should be provided by the I/O level
265  */
266 #define XML_PARSER_CHUNK_SIZE 100
267
268 /*
269  * List of XML prefixed PI allowed by W3C specs
270  */
271
272 static const char *xmlW3CPIs[] = {
273     "xml-stylesheet",
274     "xml-model",
275     NULL
276 };
277
278
279 /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
280 static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
281                                               const xmlChar **str);
282
283 static xmlParserErrors
284 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
285                       xmlSAXHandlerPtr sax,
286                       void *user_data, int depth, const xmlChar *URL,
287                       const xmlChar *ID, xmlNodePtr *list);
288
289 static int
290 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
291                           const char *encoding);
292 #ifdef LIBXML_LEGACY_ENABLED
293 static void
294 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
295                       xmlNodePtr lastNode);
296 #endif /* LIBXML_LEGACY_ENABLED */
297
298 static xmlParserErrors
299 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
300                       const xmlChar *string, void *user_data, xmlNodePtr *lst);
301
302 static int
303 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
304
305 /************************************************************************
306  *                                                                      *
307  *              Some factorized error routines                          *
308  *                                                                      *
309  ************************************************************************/
310
311 /**
312  * xmlErrAttributeDup:
313  * @ctxt:  an XML parser context
314  * @prefix:  the attribute prefix
315  * @localname:  the attribute localname
316  *
317  * Handle a redefinition of attribute error
318  */
319 static void
320 xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
321                    const xmlChar * localname)
322 {
323     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
324         (ctxt->instate == XML_PARSER_EOF))
325         return;
326     if (ctxt != NULL)
327         ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
328
329     if (prefix == NULL)
330         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
331                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
332                         (const char *) localname, NULL, NULL, 0, 0,
333                         "Attribute %s redefined\n", localname);
334     else
335         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
336                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
337                         (const char *) prefix, (const char *) localname,
338                         NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
339                         localname);
340     if (ctxt != NULL) {
341         ctxt->wellFormed = 0;
342         if (ctxt->recovery == 0)
343             ctxt->disableSAX = 1;
344     }
345 }
346
347 /**
348  * xmlFatalErr:
349  * @ctxt:  an XML parser context
350  * @error:  the error number
351  * @extra:  extra information string
352  *
353  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
354  */
355 static void
356 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
357 {
358     const char *errmsg;
359
360     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
361         (ctxt->instate == XML_PARSER_EOF))
362         return;
363     switch (error) {
364         case XML_ERR_INVALID_HEX_CHARREF:
365             errmsg = "CharRef: invalid hexadecimal value";
366             break;
367         case XML_ERR_INVALID_DEC_CHARREF:
368             errmsg = "CharRef: invalid decimal value";
369             break;
370         case XML_ERR_INVALID_CHARREF:
371             errmsg = "CharRef: invalid value";
372             break;
373         case XML_ERR_INTERNAL_ERROR:
374             errmsg = "internal error";
375             break;
376         case XML_ERR_PEREF_AT_EOF:
377             errmsg = "PEReference at end of document";
378             break;
379         case XML_ERR_PEREF_IN_PROLOG:
380             errmsg = "PEReference in prolog";
381             break;
382         case XML_ERR_PEREF_IN_EPILOG:
383             errmsg = "PEReference in epilog";
384             break;
385         case XML_ERR_PEREF_NO_NAME:
386             errmsg = "PEReference: no name";
387             break;
388         case XML_ERR_PEREF_SEMICOL_MISSING:
389             errmsg = "PEReference: expecting ';'";
390             break;
391         case XML_ERR_ENTITY_LOOP:
392             errmsg = "Detected an entity reference loop";
393             break;
394         case XML_ERR_ENTITY_NOT_STARTED:
395             errmsg = "EntityValue: \" or ' expected";
396             break;
397         case XML_ERR_ENTITY_PE_INTERNAL:
398             errmsg = "PEReferences forbidden in internal subset";
399             break;
400         case XML_ERR_ENTITY_NOT_FINISHED:
401             errmsg = "EntityValue: \" or ' expected";
402             break;
403         case XML_ERR_ATTRIBUTE_NOT_STARTED:
404             errmsg = "AttValue: \" or ' expected";
405             break;
406         case XML_ERR_LT_IN_ATTRIBUTE:
407             errmsg = "Unescaped '<' not allowed in attributes values";
408             break;
409         case XML_ERR_LITERAL_NOT_STARTED:
410             errmsg = "SystemLiteral \" or ' expected";
411             break;
412         case XML_ERR_LITERAL_NOT_FINISHED:
413             errmsg = "Unfinished System or Public ID \" or ' expected";
414             break;
415         case XML_ERR_MISPLACED_CDATA_END:
416             errmsg = "Sequence ']]>' not allowed in content";
417             break;
418         case XML_ERR_URI_REQUIRED:
419             errmsg = "SYSTEM or PUBLIC, the URI is missing";
420             break;
421         case XML_ERR_PUBID_REQUIRED:
422             errmsg = "PUBLIC, the Public Identifier is missing";
423             break;
424         case XML_ERR_HYPHEN_IN_COMMENT:
425             errmsg = "Comment must not contain '--' (double-hyphen)";
426             break;
427         case XML_ERR_PI_NOT_STARTED:
428             errmsg = "xmlParsePI : no target name";
429             break;
430         case XML_ERR_RESERVED_XML_NAME:
431             errmsg = "Invalid PI name";
432             break;
433         case XML_ERR_NOTATION_NOT_STARTED:
434             errmsg = "NOTATION: Name expected here";
435             break;
436         case XML_ERR_NOTATION_NOT_FINISHED:
437             errmsg = "'>' required to close NOTATION declaration";
438             break;
439         case XML_ERR_VALUE_REQUIRED:
440             errmsg = "Entity value required";
441             break;
442         case XML_ERR_URI_FRAGMENT:
443             errmsg = "Fragment not allowed";
444             break;
445         case XML_ERR_ATTLIST_NOT_STARTED:
446             errmsg = "'(' required to start ATTLIST enumeration";
447             break;
448         case XML_ERR_NMTOKEN_REQUIRED:
449             errmsg = "NmToken expected in ATTLIST enumeration";
450             break;
451         case XML_ERR_ATTLIST_NOT_FINISHED:
452             errmsg = "')' required to finish ATTLIST enumeration";
453             break;
454         case XML_ERR_MIXED_NOT_STARTED:
455             errmsg = "MixedContentDecl : '|' or ')*' expected";
456             break;
457         case XML_ERR_PCDATA_REQUIRED:
458             errmsg = "MixedContentDecl : '#PCDATA' expected";
459             break;
460         case XML_ERR_ELEMCONTENT_NOT_STARTED:
461             errmsg = "ContentDecl : Name or '(' expected";
462             break;
463         case XML_ERR_ELEMCONTENT_NOT_FINISHED:
464             errmsg = "ContentDecl : ',' '|' or ')' expected";
465             break;
466         case XML_ERR_PEREF_IN_INT_SUBSET:
467             errmsg =
468                 "PEReference: forbidden within markup decl in internal subset";
469             break;
470         case XML_ERR_GT_REQUIRED:
471             errmsg = "expected '>'";
472             break;
473         case XML_ERR_CONDSEC_INVALID:
474             errmsg = "XML conditional section '[' expected";
475             break;
476         case XML_ERR_EXT_SUBSET_NOT_FINISHED:
477             errmsg = "Content error in the external subset";
478             break;
479         case XML_ERR_CONDSEC_INVALID_KEYWORD:
480             errmsg =
481                 "conditional section INCLUDE or IGNORE keyword expected";
482             break;
483         case XML_ERR_CONDSEC_NOT_FINISHED:
484             errmsg = "XML conditional section not closed";
485             break;
486         case XML_ERR_XMLDECL_NOT_STARTED:
487             errmsg = "Text declaration '<?xml' required";
488             break;
489         case XML_ERR_XMLDECL_NOT_FINISHED:
490             errmsg = "parsing XML declaration: '?>' expected";
491             break;
492         case XML_ERR_EXT_ENTITY_STANDALONE:
493             errmsg = "external parsed entities cannot be standalone";
494             break;
495         case XML_ERR_ENTITYREF_SEMICOL_MISSING:
496             errmsg = "EntityRef: expecting ';'";
497             break;
498         case XML_ERR_DOCTYPE_NOT_FINISHED:
499             errmsg = "DOCTYPE improperly terminated";
500             break;
501         case XML_ERR_LTSLASH_REQUIRED:
502             errmsg = "EndTag: '</' not found";
503             break;
504         case XML_ERR_EQUAL_REQUIRED:
505             errmsg = "expected '='";
506             break;
507         case XML_ERR_STRING_NOT_CLOSED:
508             errmsg = "String not closed expecting \" or '";
509             break;
510         case XML_ERR_STRING_NOT_STARTED:
511             errmsg = "String not started expecting ' or \"";
512             break;
513         case XML_ERR_ENCODING_NAME:
514             errmsg = "Invalid XML encoding name";
515             break;
516         case XML_ERR_STANDALONE_VALUE:
517             errmsg = "standalone accepts only 'yes' or 'no'";
518             break;
519         case XML_ERR_DOCUMENT_EMPTY:
520             errmsg = "Document is empty";
521             break;
522         case XML_ERR_DOCUMENT_END:
523             errmsg = "Extra content at the end of the document";
524             break;
525         case XML_ERR_NOT_WELL_BALANCED:
526             errmsg = "chunk is not well balanced";
527             break;
528         case XML_ERR_EXTRA_CONTENT:
529             errmsg = "extra content at the end of well balanced chunk";
530             break;
531         case XML_ERR_VERSION_MISSING:
532             errmsg = "Malformed declaration expecting version";
533             break;
534         case XML_ERR_NAME_TOO_LONG:
535             errmsg = "Name too long use XML_PARSE_HUGE option";
536             break;
537 #if 0
538         case:
539             errmsg = "";
540             break;
541 #endif
542         default:
543             errmsg = "Unregistered error message";
544     }
545     if (ctxt != NULL)
546         ctxt->errNo = error;
547     if (info == NULL) {
548         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
549                         XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
550                         errmsg);
551     } else {
552         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
553                         XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
554                         errmsg, info);
555     }
556     if (ctxt != NULL) {
557         ctxt->wellFormed = 0;
558         if (ctxt->recovery == 0)
559             ctxt->disableSAX = 1;
560     }
561 }
562
563 /**
564  * xmlFatalErrMsg:
565  * @ctxt:  an XML parser context
566  * @error:  the error number
567  * @msg:  the error message
568  *
569  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
570  */
571 static void LIBXML_ATTR_FORMAT(3,0)
572 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
573                const char *msg)
574 {
575     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
576         (ctxt->instate == XML_PARSER_EOF))
577         return;
578     if (ctxt != NULL)
579         ctxt->errNo = error;
580     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
581                     XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
582     if (ctxt != NULL) {
583         ctxt->wellFormed = 0;
584         if (ctxt->recovery == 0)
585             ctxt->disableSAX = 1;
586     }
587 }
588
589 /**
590  * xmlWarningMsg:
591  * @ctxt:  an XML parser context
592  * @error:  the error number
593  * @msg:  the error message
594  * @str1:  extra data
595  * @str2:  extra data
596  *
597  * Handle a warning.
598  */
599 static void LIBXML_ATTR_FORMAT(3,0)
600 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
601               const char *msg, const xmlChar *str1, const xmlChar *str2)
602 {
603     xmlStructuredErrorFunc schannel = NULL;
604
605     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
606         (ctxt->instate == XML_PARSER_EOF))
607         return;
608     if ((ctxt != NULL) && (ctxt->sax != NULL) &&
609         (ctxt->sax->initialized == XML_SAX2_MAGIC))
610         schannel = ctxt->sax->serror;
611     if (ctxt != NULL) {
612         __xmlRaiseError(schannel,
613                     (ctxt->sax) ? ctxt->sax->warning : NULL,
614                     ctxt->userData,
615                     ctxt, NULL, XML_FROM_PARSER, error,
616                     XML_ERR_WARNING, NULL, 0,
617                     (const char *) str1, (const char *) str2, NULL, 0, 0,
618                     msg, (const char *) str1, (const char *) str2);
619     } else {
620         __xmlRaiseError(schannel, NULL, NULL,
621                     ctxt, NULL, XML_FROM_PARSER, error,
622                     XML_ERR_WARNING, NULL, 0,
623                     (const char *) str1, (const char *) str2, NULL, 0, 0,
624                     msg, (const char *) str1, (const char *) str2);
625     }
626 }
627
628 /**
629  * xmlValidityError:
630  * @ctxt:  an XML parser context
631  * @error:  the error number
632  * @msg:  the error message
633  * @str1:  extra data
634  *
635  * Handle a validity error.
636  */
637 static void LIBXML_ATTR_FORMAT(3,0)
638 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
639               const char *msg, const xmlChar *str1, const xmlChar *str2)
640 {
641     xmlStructuredErrorFunc schannel = NULL;
642
643     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
644         (ctxt->instate == XML_PARSER_EOF))
645         return;
646     if (ctxt != NULL) {
647         ctxt->errNo = error;
648         if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
649             schannel = ctxt->sax->serror;
650     }
651     if (ctxt != NULL) {
652         __xmlRaiseError(schannel,
653                     ctxt->vctxt.error, ctxt->vctxt.userData,
654                     ctxt, NULL, XML_FROM_DTD, error,
655                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
656                     (const char *) str2, NULL, 0, 0,
657                     msg, (const char *) str1, (const char *) str2);
658         ctxt->valid = 0;
659     } else {
660         __xmlRaiseError(schannel, NULL, NULL,
661                     ctxt, NULL, XML_FROM_DTD, error,
662                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
663                     (const char *) str2, NULL, 0, 0,
664                     msg, (const char *) str1, (const char *) str2);
665     }
666 }
667
668 /**
669  * xmlFatalErrMsgInt:
670  * @ctxt:  an XML parser context
671  * @error:  the error number
672  * @msg:  the error message
673  * @val:  an integer value
674  *
675  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
676  */
677 static void LIBXML_ATTR_FORMAT(3,0)
678 xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
679                   const char *msg, int val)
680 {
681     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
682         (ctxt->instate == XML_PARSER_EOF))
683         return;
684     if (ctxt != NULL)
685         ctxt->errNo = error;
686     __xmlRaiseError(NULL, NULL, NULL,
687                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
688                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
689     if (ctxt != NULL) {
690         ctxt->wellFormed = 0;
691         if (ctxt->recovery == 0)
692             ctxt->disableSAX = 1;
693     }
694 }
695
696 /**
697  * xmlFatalErrMsgStrIntStr:
698  * @ctxt:  an XML parser context
699  * @error:  the error number
700  * @msg:  the error message
701  * @str1:  an string info
702  * @val:  an integer value
703  * @str2:  an string info
704  *
705  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
706  */
707 static void LIBXML_ATTR_FORMAT(3,0)
708 xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
709                   const char *msg, const xmlChar *str1, int val,
710                   const xmlChar *str2)
711 {
712     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
713         (ctxt->instate == XML_PARSER_EOF))
714         return;
715     if (ctxt != NULL)
716         ctxt->errNo = error;
717     __xmlRaiseError(NULL, NULL, NULL,
718                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
719                     NULL, 0, (const char *) str1, (const char *) str2,
720                     NULL, val, 0, msg, str1, val, str2);
721     if (ctxt != NULL) {
722         ctxt->wellFormed = 0;
723         if (ctxt->recovery == 0)
724             ctxt->disableSAX = 1;
725     }
726 }
727
728 /**
729  * xmlFatalErrMsgStr:
730  * @ctxt:  an XML parser context
731  * @error:  the error number
732  * @msg:  the error message
733  * @val:  a string value
734  *
735  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
736  */
737 static void LIBXML_ATTR_FORMAT(3,0)
738 xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
739                   const char *msg, const xmlChar * val)
740 {
741     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
742         (ctxt->instate == XML_PARSER_EOF))
743         return;
744     if (ctxt != NULL)
745         ctxt->errNo = error;
746     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
747                     XML_FROM_PARSER, error, XML_ERR_FATAL,
748                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
749                     val);
750     if (ctxt != NULL) {
751         ctxt->wellFormed = 0;
752         if (ctxt->recovery == 0)
753             ctxt->disableSAX = 1;
754     }
755 }
756
757 /**
758  * xmlErrMsgStr:
759  * @ctxt:  an XML parser context
760  * @error:  the error number
761  * @msg:  the error message
762  * @val:  a string value
763  *
764  * Handle a non fatal parser error
765  */
766 static void LIBXML_ATTR_FORMAT(3,0)
767 xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
768                   const char *msg, const xmlChar * val)
769 {
770     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
771         (ctxt->instate == XML_PARSER_EOF))
772         return;
773     if (ctxt != NULL)
774         ctxt->errNo = error;
775     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
776                     XML_FROM_PARSER, error, XML_ERR_ERROR,
777                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
778                     val);
779 }
780
781 /**
782  * xmlNsErr:
783  * @ctxt:  an XML parser context
784  * @error:  the error number
785  * @msg:  the message
786  * @info1:  extra information string
787  * @info2:  extra information string
788  *
789  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
790  */
791 static void LIBXML_ATTR_FORMAT(3,0)
792 xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
793          const char *msg,
794          const xmlChar * info1, const xmlChar * info2,
795          const xmlChar * info3)
796 {
797     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
798         (ctxt->instate == XML_PARSER_EOF))
799         return;
800     if (ctxt != NULL)
801         ctxt->errNo = error;
802     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
803                     XML_ERR_ERROR, NULL, 0, (const char *) info1,
804                     (const char *) info2, (const char *) info3, 0, 0, msg,
805                     info1, info2, info3);
806     if (ctxt != NULL)
807         ctxt->nsWellFormed = 0;
808 }
809
810 /**
811  * xmlNsWarn
812  * @ctxt:  an XML parser context
813  * @error:  the error number
814  * @msg:  the message
815  * @info1:  extra information string
816  * @info2:  extra information string
817  *
818  * Handle a namespace warning error
819  */
820 static void LIBXML_ATTR_FORMAT(3,0)
821 xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
822          const char *msg,
823          const xmlChar * info1, const xmlChar * info2,
824          const xmlChar * info3)
825 {
826     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
827         (ctxt->instate == XML_PARSER_EOF))
828         return;
829     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
830                     XML_ERR_WARNING, NULL, 0, (const char *) info1,
831                     (const char *) info2, (const char *) info3, 0, 0, msg,
832                     info1, info2, info3);
833 }
834
835 /************************************************************************
836  *                                                                      *
837  *              Library wide options                                    *
838  *                                                                      *
839  ************************************************************************/
840
841 /**
842   * xmlHasFeature:
843   * @feature: the feature to be examined
844   *
845   * Examines if the library has been compiled with a given feature.
846   *
847   * Returns a non-zero value if the feature exist, otherwise zero.
848   * Returns zero (0) if the feature does not exist or an unknown
849   * unknown feature is requested, non-zero otherwise.
850   */
851 int
852 xmlHasFeature(xmlFeature feature)
853 {
854     switch (feature) {
855         case XML_WITH_THREAD:
856 #ifdef LIBXML_THREAD_ENABLED
857             return(1);
858 #else
859             return(0);
860 #endif
861         case XML_WITH_TREE:
862 #ifdef LIBXML_TREE_ENABLED
863             return(1);
864 #else
865             return(0);
866 #endif
867         case XML_WITH_OUTPUT:
868 #ifdef LIBXML_OUTPUT_ENABLED
869             return(1);
870 #else
871             return(0);
872 #endif
873         case XML_WITH_PUSH:
874 #ifdef LIBXML_PUSH_ENABLED
875             return(1);
876 #else
877             return(0);
878 #endif
879         case XML_WITH_READER:
880 #ifdef LIBXML_READER_ENABLED
881             return(1);
882 #else
883             return(0);
884 #endif
885         case XML_WITH_PATTERN:
886 #ifdef LIBXML_PATTERN_ENABLED
887             return(1);
888 #else
889             return(0);
890 #endif
891         case XML_WITH_WRITER:
892 #ifdef LIBXML_WRITER_ENABLED
893             return(1);
894 #else
895             return(0);
896 #endif
897         case XML_WITH_SAX1:
898 #ifdef LIBXML_SAX1_ENABLED
899             return(1);
900 #else
901             return(0);
902 #endif
903         case XML_WITH_FTP:
904 #ifdef LIBXML_FTP_ENABLED
905             return(1);
906 #else
907             return(0);
908 #endif
909         case XML_WITH_HTTP:
910 #ifdef LIBXML_HTTP_ENABLED
911             return(1);
912 #else
913             return(0);
914 #endif
915         case XML_WITH_VALID:
916 #ifdef LIBXML_VALID_ENABLED
917             return(1);
918 #else
919             return(0);
920 #endif
921         case XML_WITH_HTML:
922 #ifdef LIBXML_HTML_ENABLED
923             return(1);
924 #else
925             return(0);
926 #endif
927         case XML_WITH_LEGACY:
928 #ifdef LIBXML_LEGACY_ENABLED
929             return(1);
930 #else
931             return(0);
932 #endif
933         case XML_WITH_C14N:
934 #ifdef LIBXML_C14N_ENABLED
935             return(1);
936 #else
937             return(0);
938 #endif
939         case XML_WITH_CATALOG:
940 #ifdef LIBXML_CATALOG_ENABLED
941             return(1);
942 #else
943             return(0);
944 #endif
945         case XML_WITH_XPATH:
946 #ifdef LIBXML_XPATH_ENABLED
947             return(1);
948 #else
949             return(0);
950 #endif
951         case XML_WITH_XPTR:
952 #ifdef LIBXML_XPTR_ENABLED
953             return(1);
954 #else
955             return(0);
956 #endif
957         case XML_WITH_XINCLUDE:
958 #ifdef LIBXML_XINCLUDE_ENABLED
959             return(1);
960 #else
961             return(0);
962 #endif
963         case XML_WITH_ICONV:
964 #ifdef LIBXML_ICONV_ENABLED
965             return(1);
966 #else
967             return(0);
968 #endif
969         case XML_WITH_ISO8859X:
970 #ifdef LIBXML_ISO8859X_ENABLED
971             return(1);
972 #else
973             return(0);
974 #endif
975         case XML_WITH_UNICODE:
976 #ifdef LIBXML_UNICODE_ENABLED
977             return(1);
978 #else
979             return(0);
980 #endif
981         case XML_WITH_REGEXP:
982 #ifdef LIBXML_REGEXP_ENABLED
983             return(1);
984 #else
985             return(0);
986 #endif
987         case XML_WITH_AUTOMATA:
988 #ifdef LIBXML_AUTOMATA_ENABLED
989             return(1);
990 #else
991             return(0);
992 #endif
993         case XML_WITH_EXPR:
994 #ifdef LIBXML_EXPR_ENABLED
995             return(1);
996 #else
997             return(0);
998 #endif
999         case XML_WITH_SCHEMAS:
1000 #ifdef LIBXML_SCHEMAS_ENABLED
1001             return(1);
1002 #else
1003             return(0);
1004 #endif
1005         case XML_WITH_SCHEMATRON:
1006 #ifdef LIBXML_SCHEMATRON_ENABLED
1007             return(1);
1008 #else
1009             return(0);
1010 #endif
1011         case XML_WITH_MODULES:
1012 #ifdef LIBXML_MODULES_ENABLED
1013             return(1);
1014 #else
1015             return(0);
1016 #endif
1017         case XML_WITH_DEBUG:
1018 #ifdef LIBXML_DEBUG_ENABLED
1019             return(1);
1020 #else
1021             return(0);
1022 #endif
1023         case XML_WITH_DEBUG_MEM:
1024 #ifdef DEBUG_MEMORY_LOCATION
1025             return(1);
1026 #else
1027             return(0);
1028 #endif
1029         case XML_WITH_DEBUG_RUN:
1030 #ifdef LIBXML_DEBUG_RUNTIME
1031             return(1);
1032 #else
1033             return(0);
1034 #endif
1035         case XML_WITH_ZLIB:
1036 #ifdef LIBXML_ZLIB_ENABLED
1037             return(1);
1038 #else
1039             return(0);
1040 #endif
1041         case XML_WITH_LZMA:
1042 #ifdef LIBXML_LZMA_ENABLED
1043             return(1);
1044 #else
1045             return(0);
1046 #endif
1047         case XML_WITH_ICU:
1048 #ifdef LIBXML_ICU_ENABLED
1049             return(1);
1050 #else
1051             return(0);
1052 #endif
1053         default:
1054             break;
1055      }
1056      return(0);
1057 }
1058
1059 /************************************************************************
1060  *                                                                      *
1061  *              SAX2 defaulted attributes handling                      *
1062  *                                                                      *
1063  ************************************************************************/
1064
1065 /**
1066  * xmlDetectSAX2:
1067  * @ctxt:  an XML parser context
1068  *
1069  * Do the SAX2 detection and specific intialization
1070  */
1071 static void
1072 xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
1073     if (ctxt == NULL) return;
1074 #ifdef LIBXML_SAX1_ENABLED
1075     if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
1076         ((ctxt->sax->startElementNs != NULL) ||
1077          (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
1078 #else
1079     ctxt->sax2 = 1;
1080 #endif /* LIBXML_SAX1_ENABLED */
1081
1082     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
1083     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
1084     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
1085     if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
1086                 (ctxt->str_xml_ns == NULL)) {
1087         xmlErrMemory(ctxt, NULL);
1088     }
1089 }
1090
1091 typedef struct _xmlDefAttrs xmlDefAttrs;
1092 typedef xmlDefAttrs *xmlDefAttrsPtr;
1093 struct _xmlDefAttrs {
1094     int nbAttrs;        /* number of defaulted attributes on that element */
1095     int maxAttrs;       /* the size of the array */
1096 #if __STDC_VERSION__ >= 199901L
1097     /* Using a C99 flexible array member avoids UBSan errors. */
1098     const xmlChar *values[]; /* array of localname/prefix/values/external */
1099 #else
1100     const xmlChar *values[5];
1101 #endif
1102 };
1103
1104 /**
1105  * xmlAttrNormalizeSpace:
1106  * @src: the source string
1107  * @dst: the target string
1108  *
1109  * Normalize the space in non CDATA attribute values:
1110  * If the attribute type is not CDATA, then the XML processor MUST further
1111  * process the normalized attribute value by discarding any leading and
1112  * trailing space (#x20) characters, and by replacing sequences of space
1113  * (#x20) characters by a single space (#x20) character.
1114  * Note that the size of dst need to be at least src, and if one doesn't need
1115  * to preserve dst (and it doesn't come from a dictionary or read-only) then
1116  * passing src as dst is just fine.
1117  *
1118  * Returns a pointer to the normalized value (dst) or NULL if no conversion
1119  *         is needed.
1120  */
1121 static xmlChar *
1122 xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
1123 {
1124     if ((src == NULL) || (dst == NULL))
1125         return(NULL);
1126
1127     while (*src == 0x20) src++;
1128     while (*src != 0) {
1129         if (*src == 0x20) {
1130             while (*src == 0x20) src++;
1131             if (*src != 0)
1132                 *dst++ = 0x20;
1133         } else {
1134             *dst++ = *src++;
1135         }
1136     }
1137     *dst = 0;
1138     if (dst == src)
1139        return(NULL);
1140     return(dst);
1141 }
1142
1143 /**
1144  * xmlAttrNormalizeSpace2:
1145  * @src: the source string
1146  *
1147  * Normalize the space in non CDATA attribute values, a slightly more complex
1148  * front end to avoid allocation problems when running on attribute values
1149  * coming from the input.
1150  *
1151  * Returns a pointer to the normalized value (dst) or NULL if no conversion
1152  *         is needed.
1153  */
1154 static const xmlChar *
1155 xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
1156 {
1157     int i;
1158     int remove_head = 0;
1159     int need_realloc = 0;
1160     const xmlChar *cur;
1161
1162     if ((ctxt == NULL) || (src == NULL) || (len == NULL))
1163         return(NULL);
1164     i = *len;
1165     if (i <= 0)
1166         return(NULL);
1167
1168     cur = src;
1169     while (*cur == 0x20) {
1170         cur++;
1171         remove_head++;
1172     }
1173     while (*cur != 0) {
1174         if (*cur == 0x20) {
1175             cur++;
1176             if ((*cur == 0x20) || (*cur == 0)) {
1177                 need_realloc = 1;
1178                 break;
1179             }
1180         } else
1181             cur++;
1182     }
1183     if (need_realloc) {
1184         xmlChar *ret;
1185
1186         ret = xmlStrndup(src + remove_head, i - remove_head + 1);
1187         if (ret == NULL) {
1188             xmlErrMemory(ctxt, NULL);
1189             return(NULL);
1190         }
1191         xmlAttrNormalizeSpace(ret, ret);
1192         *len = (int) strlen((const char *)ret);
1193         return(ret);
1194     } else if (remove_head) {
1195         *len -= remove_head;
1196         memmove(src, src + remove_head, 1 + *len);
1197         return(src);
1198     }
1199     return(NULL);
1200 }
1201
1202 /**
1203  * xmlAddDefAttrs:
1204  * @ctxt:  an XML parser context
1205  * @fullname:  the element fullname
1206  * @fullattr:  the attribute fullname
1207  * @value:  the attribute value
1208  *
1209  * Add a defaulted attribute for an element
1210  */
1211 static void
1212 xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
1213                const xmlChar *fullname,
1214                const xmlChar *fullattr,
1215                const xmlChar *value) {
1216     xmlDefAttrsPtr defaults;
1217     int len;
1218     const xmlChar *name;
1219     const xmlChar *prefix;
1220
1221     /*
1222      * Allows to detect attribute redefinitions
1223      */
1224     if (ctxt->attsSpecial != NULL) {
1225         if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1226             return;
1227     }
1228
1229     if (ctxt->attsDefault == NULL) {
1230         ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
1231         if (ctxt->attsDefault == NULL)
1232             goto mem_error;
1233     }
1234
1235     /*
1236      * split the element name into prefix:localname , the string found
1237      * are within the DTD and then not associated to namespace names.
1238      */
1239     name = xmlSplitQName3(fullname, &len);
1240     if (name == NULL) {
1241         name = xmlDictLookup(ctxt->dict, fullname, -1);
1242         prefix = NULL;
1243     } else {
1244         name = xmlDictLookup(ctxt->dict, name, -1);
1245         prefix = xmlDictLookup(ctxt->dict, fullname, len);
1246     }
1247
1248     /*
1249      * make sure there is some storage
1250      */
1251     defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
1252     if (defaults == NULL) {
1253         defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
1254                            (4 * 5) * sizeof(const xmlChar *));
1255         if (defaults == NULL)
1256             goto mem_error;
1257         defaults->nbAttrs = 0;
1258         defaults->maxAttrs = 4;
1259         if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1260                                 defaults, NULL) < 0) {
1261             xmlFree(defaults);
1262             goto mem_error;
1263         }
1264     } else if (defaults->nbAttrs >= defaults->maxAttrs) {
1265         xmlDefAttrsPtr temp;
1266
1267         temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
1268                        (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
1269         if (temp == NULL)
1270             goto mem_error;
1271         defaults = temp;
1272         defaults->maxAttrs *= 2;
1273         if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1274                                 defaults, NULL) < 0) {
1275             xmlFree(defaults);
1276             goto mem_error;
1277         }
1278     }
1279
1280     /*
1281      * Split the element name into prefix:localname , the string found
1282      * are within the DTD and hen not associated to namespace names.
1283      */
1284     name = xmlSplitQName3(fullattr, &len);
1285     if (name == NULL) {
1286         name = xmlDictLookup(ctxt->dict, fullattr, -1);
1287         prefix = NULL;
1288     } else {
1289         name = xmlDictLookup(ctxt->dict, name, -1);
1290         prefix = xmlDictLookup(ctxt->dict, fullattr, len);
1291     }
1292
1293     defaults->values[5 * defaults->nbAttrs] = name;
1294     defaults->values[5 * defaults->nbAttrs + 1] = prefix;
1295     /* intern the string and precompute the end */
1296     len = xmlStrlen(value);
1297     value = xmlDictLookup(ctxt->dict, value, len);
1298     defaults->values[5 * defaults->nbAttrs + 2] = value;
1299     defaults->values[5 * defaults->nbAttrs + 3] = value + len;
1300     if (ctxt->external)
1301         defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
1302     else
1303         defaults->values[5 * defaults->nbAttrs + 4] = NULL;
1304     defaults->nbAttrs++;
1305
1306     return;
1307
1308 mem_error:
1309     xmlErrMemory(ctxt, NULL);
1310     return;
1311 }
1312
1313 /**
1314  * xmlAddSpecialAttr:
1315  * @ctxt:  an XML parser context
1316  * @fullname:  the element fullname
1317  * @fullattr:  the attribute fullname
1318  * @type:  the attribute type
1319  *
1320  * Register this attribute type
1321  */
1322 static void
1323 xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
1324                   const xmlChar *fullname,
1325                   const xmlChar *fullattr,
1326                   int type)
1327 {
1328     if (ctxt->attsSpecial == NULL) {
1329         ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
1330         if (ctxt->attsSpecial == NULL)
1331             goto mem_error;
1332     }
1333
1334     if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1335         return;
1336
1337     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
1338                      (void *) (ptrdiff_t) type);
1339     return;
1340
1341 mem_error:
1342     xmlErrMemory(ctxt, NULL);
1343     return;
1344 }
1345
1346 /**
1347  * xmlCleanSpecialAttrCallback:
1348  *
1349  * Removes CDATA attributes from the special attribute table
1350  */
1351 static void
1352 xmlCleanSpecialAttrCallback(void *payload, void *data,
1353                             const xmlChar *fullname, const xmlChar *fullattr,
1354                             const xmlChar *unused ATTRIBUTE_UNUSED) {
1355     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
1356
1357     if (((ptrdiff_t) payload) == XML_ATTRIBUTE_CDATA) {
1358         xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
1359     }
1360 }
1361
1362 /**
1363  * xmlCleanSpecialAttr:
1364  * @ctxt:  an XML parser context
1365  *
1366  * Trim the list of attributes defined to remove all those of type
1367  * CDATA as they are not special. This call should be done when finishing
1368  * to parse the DTD and before starting to parse the document root.
1369  */
1370 static void
1371 xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
1372 {
1373     if (ctxt->attsSpecial == NULL)
1374         return;
1375
1376     xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
1377
1378     if (xmlHashSize(ctxt->attsSpecial) == 0) {
1379         xmlHashFree(ctxt->attsSpecial, NULL);
1380         ctxt->attsSpecial = NULL;
1381     }
1382     return;
1383 }
1384
1385 /**
1386  * xmlCheckLanguageID:
1387  * @lang:  pointer to the string value
1388  *
1389  * Checks that the value conforms to the LanguageID production:
1390  *
1391  * NOTE: this is somewhat deprecated, those productions were removed from
1392  *       the XML Second edition.
1393  *
1394  * [33] LanguageID ::= Langcode ('-' Subcode)*
1395  * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
1396  * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
1397  * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
1398  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
1399  * [38] Subcode ::= ([a-z] | [A-Z])+
1400  *
1401  * The current REC reference the sucessors of RFC 1766, currently 5646
1402  *
1403  * http://www.rfc-editor.org/rfc/rfc5646.txt
1404  * langtag       = language
1405  *                 ["-" script]
1406  *                 ["-" region]
1407  *                 *("-" variant)
1408  *                 *("-" extension)
1409  *                 ["-" privateuse]
1410  * language      = 2*3ALPHA            ; shortest ISO 639 code
1411  *                 ["-" extlang]       ; sometimes followed by
1412  *                                     ; extended language subtags
1413  *               / 4ALPHA              ; or reserved for future use
1414  *               / 5*8ALPHA            ; or registered language subtag
1415  *
1416  * extlang       = 3ALPHA              ; selected ISO 639 codes
1417  *                 *2("-" 3ALPHA)      ; permanently reserved
1418  *
1419  * script        = 4ALPHA              ; ISO 15924 code
1420  *
1421  * region        = 2ALPHA              ; ISO 3166-1 code
1422  *               / 3DIGIT              ; UN M.49 code
1423  *
1424  * variant       = 5*8alphanum         ; registered variants
1425  *               / (DIGIT 3alphanum)
1426  *
1427  * extension     = singleton 1*("-" (2*8alphanum))
1428  *
1429  *                                     ; Single alphanumerics
1430  *                                     ; "x" reserved for private use
1431  * singleton     = DIGIT               ; 0 - 9
1432  *               / %x41-57             ; A - W
1433  *               / %x59-5A             ; Y - Z
1434  *               / %x61-77             ; a - w
1435  *               / %x79-7A             ; y - z
1436  *
1437  * it sounds right to still allow Irregular i-xxx IANA and user codes too
1438  * The parser below doesn't try to cope with extension or privateuse
1439  * that could be added but that's not interoperable anyway
1440  *
1441  * Returns 1 if correct 0 otherwise
1442  **/
1443 int
1444 xmlCheckLanguageID(const xmlChar * lang)
1445 {
1446     const xmlChar *cur = lang, *nxt;
1447
1448     if (cur == NULL)
1449         return (0);
1450     if (((cur[0] == 'i') && (cur[1] == '-')) ||
1451         ((cur[0] == 'I') && (cur[1] == '-')) ||
1452         ((cur[0] == 'x') && (cur[1] == '-')) ||
1453         ((cur[0] == 'X') && (cur[1] == '-'))) {
1454         /*
1455          * Still allow IANA code and user code which were coming
1456          * from the previous version of the XML-1.0 specification
1457          * it's deprecated but we should not fail
1458          */
1459         cur += 2;
1460         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1461                ((cur[0] >= 'a') && (cur[0] <= 'z')))
1462             cur++;
1463         return(cur[0] == 0);
1464     }
1465     nxt = cur;
1466     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1467            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1468            nxt++;
1469     if (nxt - cur >= 4) {
1470         /*
1471          * Reserved
1472          */
1473         if ((nxt - cur > 8) || (nxt[0] != 0))
1474             return(0);
1475         return(1);
1476     }
1477     if (nxt - cur < 2)
1478         return(0);
1479     /* we got an ISO 639 code */
1480     if (nxt[0] == 0)
1481         return(1);
1482     if (nxt[0] != '-')
1483         return(0);
1484
1485     nxt++;
1486     cur = nxt;
1487     /* now we can have extlang or script or region or variant */
1488     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1489         goto region_m49;
1490
1491     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1492            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1493            nxt++;
1494     if (nxt - cur == 4)
1495         goto script;
1496     if (nxt - cur == 2)
1497         goto region;
1498     if ((nxt - cur >= 5) && (nxt - cur <= 8))
1499         goto variant;
1500     if (nxt - cur != 3)
1501         return(0);
1502     /* we parsed an extlang */
1503     if (nxt[0] == 0)
1504         return(1);
1505     if (nxt[0] != '-')
1506         return(0);
1507
1508     nxt++;
1509     cur = nxt;
1510     /* now we can have script or region or variant */
1511     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1512         goto region_m49;
1513
1514     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1515            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1516            nxt++;
1517     if (nxt - cur == 2)
1518         goto region;
1519     if ((nxt - cur >= 5) && (nxt - cur <= 8))
1520         goto variant;
1521     if (nxt - cur != 4)
1522         return(0);
1523     /* we parsed a script */
1524 script:
1525     if (nxt[0] == 0)
1526         return(1);
1527     if (nxt[0] != '-')
1528         return(0);
1529
1530     nxt++;
1531     cur = nxt;
1532     /* now we can have region or variant */
1533     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1534         goto region_m49;
1535
1536     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1537            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1538            nxt++;
1539
1540     if ((nxt - cur >= 5) && (nxt - cur <= 8))
1541         goto variant;
1542     if (nxt - cur != 2)
1543         return(0);
1544     /* we parsed a region */
1545 region:
1546     if (nxt[0] == 0)
1547         return(1);
1548     if (nxt[0] != '-')
1549         return(0);
1550
1551     nxt++;
1552     cur = nxt;
1553     /* now we can just have a variant */
1554     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1555            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1556            nxt++;
1557
1558     if ((nxt - cur < 5) || (nxt - cur > 8))
1559         return(0);
1560
1561     /* we parsed a variant */
1562 variant:
1563     if (nxt[0] == 0)
1564         return(1);
1565     if (nxt[0] != '-')
1566         return(0);
1567     /* extensions and private use subtags not checked */
1568     return (1);
1569
1570 region_m49:
1571     if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
1572         ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
1573         nxt += 3;
1574         goto region;
1575     }
1576     return(0);
1577 }
1578
1579 /************************************************************************
1580  *                                                                      *
1581  *              Parser stacks related functions and macros              *
1582  *                                                                      *
1583  ************************************************************************/
1584
1585 static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
1586                                             const xmlChar ** str);
1587
1588 #ifdef SAX2
1589 /**
1590  * nsPush:
1591  * @ctxt:  an XML parser context
1592  * @prefix:  the namespace prefix or NULL
1593  * @URL:  the namespace name
1594  *
1595  * Pushes a new parser namespace on top of the ns stack
1596  *
1597  * Returns -1 in case of error, -2 if the namespace should be discarded
1598  *         and the index in the stack otherwise.
1599  */
1600 static int
1601 nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
1602 {
1603     if (ctxt->options & XML_PARSE_NSCLEAN) {
1604         int i;
1605         for (i = ctxt->nsNr - 2;i >= 0;i -= 2) {
1606             if (ctxt->nsTab[i] == prefix) {
1607                 /* in scope */
1608                 if (ctxt->nsTab[i + 1] == URL)
1609                     return(-2);
1610                 /* out of scope keep it */
1611                 break;
1612             }
1613         }
1614     }
1615     if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
1616         ctxt->nsMax = 10;
1617         ctxt->nsNr = 0;
1618         ctxt->nsTab = (const xmlChar **)
1619                       xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
1620         if (ctxt->nsTab == NULL) {
1621             xmlErrMemory(ctxt, NULL);
1622             ctxt->nsMax = 0;
1623             return (-1);
1624         }
1625     } else if (ctxt->nsNr >= ctxt->nsMax) {
1626         const xmlChar ** tmp;
1627         ctxt->nsMax *= 2;
1628         tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
1629                                     ctxt->nsMax * sizeof(ctxt->nsTab[0]));
1630         if (tmp == NULL) {
1631             xmlErrMemory(ctxt, NULL);
1632             ctxt->nsMax /= 2;
1633             return (-1);
1634         }
1635         ctxt->nsTab = tmp;
1636     }
1637     ctxt->nsTab[ctxt->nsNr++] = prefix;
1638     ctxt->nsTab[ctxt->nsNr++] = URL;
1639     return (ctxt->nsNr);
1640 }
1641 /**
1642  * nsPop:
1643  * @ctxt: an XML parser context
1644  * @nr:  the number to pop
1645  *
1646  * Pops the top @nr parser prefix/namespace from the ns stack
1647  *
1648  * Returns the number of namespaces removed
1649  */
1650 static int
1651 nsPop(xmlParserCtxtPtr ctxt, int nr)
1652 {
1653     int i;
1654
1655     if (ctxt->nsTab == NULL) return(0);
1656     if (ctxt->nsNr < nr) {
1657         xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
1658         nr = ctxt->nsNr;
1659     }
1660     if (ctxt->nsNr <= 0)
1661         return (0);
1662
1663     for (i = 0;i < nr;i++) {
1664          ctxt->nsNr--;
1665          ctxt->nsTab[ctxt->nsNr] = NULL;
1666     }
1667     return(nr);
1668 }
1669 #endif
1670
1671 static int
1672 xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
1673     const xmlChar **atts;
1674     int *attallocs;
1675     int maxatts;
1676
1677     if (ctxt->atts == NULL) {
1678         maxatts = 55; /* allow for 10 attrs by default */
1679         atts = (const xmlChar **)
1680                xmlMalloc(maxatts * sizeof(xmlChar *));
1681         if (atts == NULL) goto mem_error;
1682         ctxt->atts = atts;
1683         attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
1684         if (attallocs == NULL) goto mem_error;
1685         ctxt->attallocs = attallocs;
1686         ctxt->maxatts = maxatts;
1687     } else if (nr + 5 > ctxt->maxatts) {
1688         maxatts = (nr + 5) * 2;
1689         atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
1690                                      maxatts * sizeof(const xmlChar *));
1691         if (atts == NULL) goto mem_error;
1692         ctxt->atts = atts;
1693         attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
1694                                      (maxatts / 5) * sizeof(int));
1695         if (attallocs == NULL) goto mem_error;
1696         ctxt->attallocs = attallocs;
1697         ctxt->maxatts = maxatts;
1698     }
1699     return(ctxt->maxatts);
1700 mem_error:
1701     xmlErrMemory(ctxt, NULL);
1702     return(-1);
1703 }
1704
1705 /**
1706  * inputPush:
1707  * @ctxt:  an XML parser context
1708  * @value:  the parser input
1709  *
1710  * Pushes a new parser input on top of the input stack
1711  *
1712  * Returns -1 in case of error, the index in the stack otherwise
1713  */
1714 int
1715 inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
1716 {
1717     if ((ctxt == NULL) || (value == NULL))
1718         return(-1);
1719     if (ctxt->inputNr >= ctxt->inputMax) {
1720         ctxt->inputMax *= 2;
1721         ctxt->inputTab =
1722             (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
1723                                              ctxt->inputMax *
1724                                              sizeof(ctxt->inputTab[0]));
1725         if (ctxt->inputTab == NULL) {
1726             xmlErrMemory(ctxt, NULL);
1727             xmlFreeInputStream(value);
1728             ctxt->inputMax /= 2;
1729             value = NULL;
1730             return (-1);
1731         }
1732     }
1733     ctxt->inputTab[ctxt->inputNr] = value;
1734     ctxt->input = value;
1735     return (ctxt->inputNr++);
1736 }
1737 /**
1738  * inputPop:
1739  * @ctxt: an XML parser context
1740  *
1741  * Pops the top parser input from the input stack
1742  *
1743  * Returns the input just removed
1744  */
1745 xmlParserInputPtr
1746 inputPop(xmlParserCtxtPtr ctxt)
1747 {
1748     xmlParserInputPtr ret;
1749
1750     if (ctxt == NULL)
1751         return(NULL);
1752     if (ctxt->inputNr <= 0)
1753         return (NULL);
1754     ctxt->inputNr--;
1755     if (ctxt->inputNr > 0)
1756         ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
1757     else
1758         ctxt->input = NULL;
1759     ret = ctxt->inputTab[ctxt->inputNr];
1760     ctxt->inputTab[ctxt->inputNr] = NULL;
1761     return (ret);
1762 }
1763 /**
1764  * nodePush:
1765  * @ctxt:  an XML parser context
1766  * @value:  the element node
1767  *
1768  * Pushes a new element node on top of the node stack
1769  *
1770  * Returns -1 in case of error, the index in the stack otherwise
1771  */
1772 int
1773 nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
1774 {
1775     if (ctxt == NULL) return(0);
1776     if (ctxt->nodeNr >= ctxt->nodeMax) {
1777         xmlNodePtr *tmp;
1778
1779         tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
1780                                       ctxt->nodeMax * 2 *
1781                                       sizeof(ctxt->nodeTab[0]));
1782         if (tmp == NULL) {
1783             xmlErrMemory(ctxt, NULL);
1784             return (-1);
1785         }
1786         ctxt->nodeTab = tmp;
1787         ctxt->nodeMax *= 2;
1788     }
1789     if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
1790         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
1791         xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
1792                  "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
1793                           xmlParserMaxDepth);
1794         xmlHaltParser(ctxt);
1795         return(-1);
1796     }
1797     ctxt->nodeTab[ctxt->nodeNr] = value;
1798     ctxt->node = value;
1799     return (ctxt->nodeNr++);
1800 }
1801
1802 /**
1803  * nodePop:
1804  * @ctxt: an XML parser context
1805  *
1806  * Pops the top element node from the node stack
1807  *
1808  * Returns the node just removed
1809  */
1810 xmlNodePtr
1811 nodePop(xmlParserCtxtPtr ctxt)
1812 {
1813     xmlNodePtr ret;
1814
1815     if (ctxt == NULL) return(NULL);
1816     if (ctxt->nodeNr <= 0)
1817         return (NULL);
1818     ctxt->nodeNr--;
1819     if (ctxt->nodeNr > 0)
1820         ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
1821     else
1822         ctxt->node = NULL;
1823     ret = ctxt->nodeTab[ctxt->nodeNr];
1824     ctxt->nodeTab[ctxt->nodeNr] = NULL;
1825     return (ret);
1826 }
1827
1828 #ifdef LIBXML_PUSH_ENABLED
1829 /**
1830  * nameNsPush:
1831  * @ctxt:  an XML parser context
1832  * @value:  the element name
1833  * @prefix:  the element prefix
1834  * @URI:  the element namespace name
1835  *
1836  * Pushes a new element name/prefix/URL on top of the name stack
1837  *
1838  * Returns -1 in case of error, the index in the stack otherwise
1839  */
1840 static int
1841 nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
1842            const xmlChar *prefix, const xmlChar *URI, int nsNr)
1843 {
1844     if (ctxt->nameNr >= ctxt->nameMax) {
1845         const xmlChar * *tmp;
1846         void **tmp2;
1847         ctxt->nameMax *= 2;
1848         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1849                                     ctxt->nameMax *
1850                                     sizeof(ctxt->nameTab[0]));
1851         if (tmp == NULL) {
1852             ctxt->nameMax /= 2;
1853             goto mem_error;
1854         }
1855         ctxt->nameTab = tmp;
1856         tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
1857                                     ctxt->nameMax * 3 *
1858                                     sizeof(ctxt->pushTab[0]));
1859         if (tmp2 == NULL) {
1860             ctxt->nameMax /= 2;
1861             goto mem_error;
1862         }
1863         ctxt->pushTab = tmp2;
1864     }
1865     ctxt->nameTab[ctxt->nameNr] = value;
1866     ctxt->name = value;
1867     ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
1868     ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
1869     ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (ptrdiff_t) nsNr;
1870     return (ctxt->nameNr++);
1871 mem_error:
1872     xmlErrMemory(ctxt, NULL);
1873     return (-1);
1874 }
1875 /**
1876  * nameNsPop:
1877  * @ctxt: an XML parser context
1878  *
1879  * Pops the top element/prefix/URI name from the name stack
1880  *
1881  * Returns the name just removed
1882  */
1883 static const xmlChar *
1884 nameNsPop(xmlParserCtxtPtr ctxt)
1885 {
1886     const xmlChar *ret;
1887
1888     if (ctxt->nameNr <= 0)
1889         return (NULL);
1890     ctxt->nameNr--;
1891     if (ctxt->nameNr > 0)
1892         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1893     else
1894         ctxt->name = NULL;
1895     ret = ctxt->nameTab[ctxt->nameNr];
1896     ctxt->nameTab[ctxt->nameNr] = NULL;
1897     return (ret);
1898 }
1899 #endif /* LIBXML_PUSH_ENABLED */
1900
1901 /**
1902  * namePush:
1903  * @ctxt:  an XML parser context
1904  * @value:  the element name
1905  *
1906  * Pushes a new element name on top of the name stack
1907  *
1908  * Returns -1 in case of error, the index in the stack otherwise
1909  */
1910 int
1911 namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
1912 {
1913     if (ctxt == NULL) return (-1);
1914
1915     if (ctxt->nameNr >= ctxt->nameMax) {
1916         const xmlChar * *tmp;
1917         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1918                                     ctxt->nameMax * 2 *
1919                                     sizeof(ctxt->nameTab[0]));
1920         if (tmp == NULL) {
1921             goto mem_error;
1922         }
1923         ctxt->nameTab = tmp;
1924         ctxt->nameMax *= 2;
1925     }
1926     ctxt->nameTab[ctxt->nameNr] = value;
1927     ctxt->name = value;
1928     return (ctxt->nameNr++);
1929 mem_error:
1930     xmlErrMemory(ctxt, NULL);
1931     return (-1);
1932 }
1933 /**
1934  * namePop:
1935  * @ctxt: an XML parser context
1936  *
1937  * Pops the top element name from the name stack
1938  *
1939  * Returns the name just removed
1940  */
1941 const xmlChar *
1942 namePop(xmlParserCtxtPtr ctxt)
1943 {
1944     const xmlChar *ret;
1945
1946     if ((ctxt == NULL) || (ctxt->nameNr <= 0))
1947         return (NULL);
1948     ctxt->nameNr--;
1949     if (ctxt->nameNr > 0)
1950         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1951     else
1952         ctxt->name = NULL;
1953     ret = ctxt->nameTab[ctxt->nameNr];
1954     ctxt->nameTab[ctxt->nameNr] = NULL;
1955     return (ret);
1956 }
1957
1958 static int spacePush(xmlParserCtxtPtr ctxt, int val) {
1959     if (ctxt->spaceNr >= ctxt->spaceMax) {
1960         int *tmp;
1961
1962         ctxt->spaceMax *= 2;
1963         tmp = (int *) xmlRealloc(ctxt->spaceTab,
1964                                  ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
1965         if (tmp == NULL) {
1966             xmlErrMemory(ctxt, NULL);
1967             ctxt->spaceMax /=2;
1968             return(-1);
1969         }
1970         ctxt->spaceTab = tmp;
1971     }
1972     ctxt->spaceTab[ctxt->spaceNr] = val;
1973     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
1974     return(ctxt->spaceNr++);
1975 }
1976
1977 static int spacePop(xmlParserCtxtPtr ctxt) {
1978     int ret;
1979     if (ctxt->spaceNr <= 0) return(0);
1980     ctxt->spaceNr--;
1981     if (ctxt->spaceNr > 0)
1982         ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
1983     else
1984         ctxt->space = &ctxt->spaceTab[0];
1985     ret = ctxt->spaceTab[ctxt->spaceNr];
1986     ctxt->spaceTab[ctxt->spaceNr] = -1;
1987     return(ret);
1988 }
1989
1990 /*
1991  * Macros for accessing the content. Those should be used only by the parser,
1992  * and not exported.
1993  *
1994  * Dirty macros, i.e. one often need to make assumption on the context to
1995  * use them
1996  *
1997  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
1998  *           To be used with extreme caution since operations consuming
1999  *           characters may move the input buffer to a different location !
2000  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
2001  *           This should be used internally by the parser
2002  *           only to compare to ASCII values otherwise it would break when
2003  *           running with UTF-8 encoding.
2004  *   RAW     same as CUR but in the input buffer, bypass any token
2005  *           extraction that may have been done
2006  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
2007  *           to compare on ASCII based substring.
2008  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
2009  *           strings without newlines within the parser.
2010  *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII
2011  *           defined char within the parser.
2012  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
2013  *
2014  *   NEXT    Skip to the next character, this does the proper decoding
2015  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
2016  *   NEXTL(l) Skip the current unicode character of l xmlChars long.
2017  *   CUR_CHAR(l) returns the current unicode character (int), set l
2018  *           to the number of xmlChars used for the encoding [0-5].
2019  *   CUR_SCHAR  same but operate on a string instead of the context
2020  *   COPY_BUF  copy the current unicode char to the target buffer, increment
2021  *            the index
2022  *   GROW, SHRINK  handling of input buffers
2023  */
2024
2025 #define RAW (*ctxt->input->cur)
2026 #define CUR (*ctxt->input->cur)
2027 #define NXT(val) ctxt->input->cur[(val)]
2028 #define CUR_PTR ctxt->input->cur
2029 #define BASE_PTR ctxt->input->base
2030
2031 #define CMP4( s, c1, c2, c3, c4 ) \
2032   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
2033     ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
2034 #define CMP5( s, c1, c2, c3, c4, c5 ) \
2035   ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
2036 #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
2037   ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
2038 #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
2039   ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
2040 #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
2041   ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
2042 #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
2043   ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
2044     ((unsigned char *) s)[ 8 ] == c9 )
2045 #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
2046   ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
2047     ((unsigned char *) s)[ 9 ] == c10 )
2048
2049 #define SKIP(val) do {                                                  \
2050     ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);                   \
2051     if (*ctxt->input->cur == 0)                                         \
2052         xmlParserInputGrow(ctxt->input, INPUT_CHUNK);                   \
2053   } while (0)
2054
2055 #define SKIPL(val) do {                                                 \
2056     int skipl;                                                          \
2057     for(skipl=0; skipl<val; skipl++) {                                  \
2058         if (*(ctxt->input->cur) == '\n') {                              \
2059         ctxt->input->line++; ctxt->input->col = 1;                      \
2060         } else ctxt->input->col++;                                      \
2061         ctxt->nbChars++;                                                \
2062         ctxt->input->cur++;                                             \
2063     }                                                                   \
2064     if (*ctxt->input->cur == 0)                                         \
2065         xmlParserInputGrow(ctxt->input, INPUT_CHUNK);                   \
2066   } while (0)
2067
2068 #define SHRINK if ((ctxt->progressive == 0) &&                          \
2069                    (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
2070                    (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
2071         xmlSHRINK (ctxt);
2072
2073 static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
2074     xmlParserInputShrink(ctxt->input);
2075     if (*ctxt->input->cur == 0)
2076         xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2077 }
2078
2079 #define GROW if ((ctxt->progressive == 0) &&                            \
2080                  (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))   \
2081         xmlGROW (ctxt);
2082
2083 static void xmlGROW (xmlParserCtxtPtr ctxt) {
2084     unsigned long curEnd = ctxt->input->end - ctxt->input->cur;
2085     unsigned long curBase = ctxt->input->cur - ctxt->input->base;
2086
2087     if (((curEnd > (unsigned long) XML_MAX_LOOKUP_LIMIT) ||
2088          (curBase > (unsigned long) XML_MAX_LOOKUP_LIMIT)) &&
2089          ((ctxt->input->buf) && (ctxt->input->buf->readcallback != (xmlInputReadCallback) xmlNop)) &&
2090         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
2091         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
2092         xmlHaltParser(ctxt);
2093         return;
2094     }
2095     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2096     if ((ctxt->input->cur > ctxt->input->end) ||
2097         (ctxt->input->cur < ctxt->input->base)) {
2098         xmlHaltParser(ctxt);
2099         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "cur index out of bound");
2100         return;
2101     }
2102     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0))
2103         xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2104 }
2105
2106 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
2107
2108 #define NEXT xmlNextChar(ctxt)
2109
2110 #define NEXT1 {                                                         \
2111         ctxt->input->col++;                                             \
2112         ctxt->input->cur++;                                             \
2113         ctxt->nbChars++;                                                \
2114         if (*ctxt->input->cur == 0)                                     \
2115             xmlParserInputGrow(ctxt->input, INPUT_CHUNK);               \
2116     }
2117
2118 #define NEXTL(l) do {                                                   \
2119     if (*(ctxt->input->cur) == '\n') {                                  \
2120         ctxt->input->line++; ctxt->input->col = 1;                      \
2121     } else ctxt->input->col++;                                          \
2122     ctxt->input->cur += l;                              \
2123   } while (0)
2124
2125 #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
2126 #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
2127
2128 #define COPY_BUF(l,b,i,v)                                               \
2129     if (l == 1) b[i++] = (xmlChar) v;                                   \
2130     else i += xmlCopyCharMultiByte(&b[i],v)
2131
2132 /**
2133  * xmlSkipBlankChars:
2134  * @ctxt:  the XML parser context
2135  *
2136  * skip all blanks character found at that point in the input streams.
2137  * It pops up finished entities in the process if allowable at that point.
2138  *
2139  * Returns the number of space chars skipped
2140  */
2141
2142 int
2143 xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
2144     int res = 0;
2145
2146     /*
2147      * It's Okay to use CUR/NEXT here since all the blanks are on
2148      * the ASCII range.
2149      */
2150     if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
2151         const xmlChar *cur;
2152         /*
2153          * if we are in the document content, go really fast
2154          */
2155         cur = ctxt->input->cur;
2156         while (IS_BLANK_CH(*cur)) {
2157             if (*cur == '\n') {
2158                 ctxt->input->line++; ctxt->input->col = 1;
2159             } else {
2160                 ctxt->input->col++;
2161             }
2162             cur++;
2163             res++;
2164             if (*cur == 0) {
2165                 ctxt->input->cur = cur;
2166                 xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2167                 cur = ctxt->input->cur;
2168             }
2169         }
2170         ctxt->input->cur = cur;
2171     } else {
2172         int expandPE = ((ctxt->external != 0) || (ctxt->inputNr != 1));
2173
2174         while (1) {
2175             if (IS_BLANK_CH(CUR)) { /* CHECKED tstblanks.xml */
2176                 NEXT;
2177             } else if (CUR == '%') {
2178                 /*
2179                  * Need to handle support of entities branching here
2180                  */
2181                 if ((expandPE == 0) || (IS_BLANK_CH(NXT(1))) || (NXT(1) == 0))
2182                     break;
2183                 xmlParsePEReference(ctxt);
2184             } else if (CUR == 0) {
2185                 if (ctxt->inputNr <= 1)
2186                     break;
2187                 xmlPopInput(ctxt);
2188             } else {
2189                 break;
2190             }
2191
2192             /*
2193              * Also increase the counter when entering or exiting a PERef.
2194              * The spec says: "When a parameter-entity reference is recognized
2195              * in the DTD and included, its replacement text MUST be enlarged
2196              * by the attachment of one leading and one following space (#x20)
2197              * character."
2198              */
2199             res++;
2200         }
2201     }
2202     return(res);
2203 }
2204
2205 /************************************************************************
2206  *                                                                      *
2207  *              Commodity functions to handle entities                  *
2208  *                                                                      *
2209  ************************************************************************/
2210
2211 /**
2212  * xmlPopInput:
2213  * @ctxt:  an XML parser context
2214  *
2215  * xmlPopInput: the current input pointed by ctxt->input came to an end
2216  *          pop it and return the next char.
2217  *
2218  * Returns the current xmlChar in the parser context
2219  */
2220 xmlChar
2221 xmlPopInput(xmlParserCtxtPtr ctxt) {
2222     if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
2223     if (xmlParserDebugEntities)
2224         xmlGenericError(xmlGenericErrorContext,
2225                 "Popping input %d\n", ctxt->inputNr);
2226     if ((ctxt->inputNr > 1) && (ctxt->inSubset == 0) &&
2227         (ctxt->instate != XML_PARSER_EOF))
2228         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
2229                     "Unfinished entity outside the DTD");
2230     xmlFreeInputStream(inputPop(ctxt));
2231     if (*ctxt->input->cur == 0)
2232         xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2233     return(CUR);
2234 }
2235
2236 /**
2237  * xmlPushInput:
2238  * @ctxt:  an XML parser context
2239  * @input:  an XML parser input fragment (entity, XML fragment ...).
2240  *
2241  * xmlPushInput: switch to a new input stream which is stacked on top
2242  *               of the previous one(s).
2243  * Returns -1 in case of error or the index in the input stack
2244  */
2245 int
2246 xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
2247     int ret;
2248     if (input == NULL) return(-1);
2249
2250     if (xmlParserDebugEntities) {
2251         if ((ctxt->input != NULL) && (ctxt->input->filename))
2252             xmlGenericError(xmlGenericErrorContext,
2253                     "%s(%d): ", ctxt->input->filename,
2254                     ctxt->input->line);
2255         xmlGenericError(xmlGenericErrorContext,
2256                 "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
2257     }
2258     if (((ctxt->inputNr > 40) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2259         (ctxt->inputNr > 1024)) {
2260         xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2261         while (ctxt->inputNr > 1)
2262             xmlFreeInputStream(inputPop(ctxt));
2263         return(-1);
2264     }
2265     ret = inputPush(ctxt, input);
2266     if (ctxt->instate == XML_PARSER_EOF)
2267         return(-1);
2268     GROW;
2269     return(ret);
2270 }
2271
2272 /**
2273  * xmlParseCharRef:
2274  * @ctxt:  an XML parser context
2275  *
2276  * parse Reference declarations
2277  *
2278  * [66] CharRef ::= '&#' [0-9]+ ';' |
2279  *                  '&#x' [0-9a-fA-F]+ ';'
2280  *
2281  * [ WFC: Legal Character ]
2282  * Characters referred to using character references must match the
2283  * production for Char.
2284  *
2285  * Returns the value parsed (as an int), 0 in case of error
2286  */
2287 int
2288 xmlParseCharRef(xmlParserCtxtPtr ctxt) {
2289     unsigned int val = 0;
2290     int count = 0;
2291     unsigned int outofrange = 0;
2292
2293     /*
2294      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
2295      */
2296     if ((RAW == '&') && (NXT(1) == '#') &&
2297         (NXT(2) == 'x')) {
2298         SKIP(3);
2299         GROW;
2300         while (RAW != ';') { /* loop blocked by count */
2301             if (count++ > 20) {
2302                 count = 0;
2303                 GROW;
2304                 if (ctxt->instate == XML_PARSER_EOF)
2305                     return(0);
2306             }
2307             if ((RAW >= '0') && (RAW <= '9'))
2308                 val = val * 16 + (CUR - '0');
2309             else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
2310                 val = val * 16 + (CUR - 'a') + 10;
2311             else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
2312                 val = val * 16 + (CUR - 'A') + 10;
2313             else {
2314                 xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2315                 val = 0;
2316                 break;
2317             }
2318             if (val > 0x10FFFF)
2319                 outofrange = val;
2320
2321             NEXT;
2322             count++;
2323         }
2324         if (RAW == ';') {
2325             /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2326             ctxt->input->col++;
2327             ctxt->nbChars ++;
2328             ctxt->input->cur++;
2329         }
2330     } else if  ((RAW == '&') && (NXT(1) == '#')) {
2331         SKIP(2);
2332         GROW;
2333         while (RAW != ';') { /* loop blocked by count */
2334             if (count++ > 20) {
2335                 count = 0;
2336                 GROW;
2337                 if (ctxt->instate == XML_PARSER_EOF)
2338                     return(0);
2339             }
2340             if ((RAW >= '0') && (RAW <= '9'))
2341                 val = val * 10 + (CUR - '0');
2342             else {
2343                 xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2344                 val = 0;
2345                 break;
2346             }
2347             if (val > 0x10FFFF)
2348                 outofrange = val;
2349
2350             NEXT;
2351             count++;
2352         }
2353         if (RAW == ';') {
2354             /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2355             ctxt->input->col++;
2356             ctxt->nbChars ++;
2357             ctxt->input->cur++;
2358         }
2359     } else {
2360         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2361     }
2362
2363     /*
2364      * [ WFC: Legal Character ]
2365      * Characters referred to using character references must match the
2366      * production for Char.
2367      */
2368     if ((IS_CHAR(val) && (outofrange == 0))) {
2369         return(val);
2370     } else {
2371         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2372                           "xmlParseCharRef: invalid xmlChar value %d\n",
2373                           val);
2374     }
2375     return(0);
2376 }
2377
2378 /**
2379  * xmlParseStringCharRef:
2380  * @ctxt:  an XML parser context
2381  * @str:  a pointer to an index in the string
2382  *
2383  * parse Reference declarations, variant parsing from a string rather
2384  * than an an input flow.
2385  *
2386  * [66] CharRef ::= '&#' [0-9]+ ';' |
2387  *                  '&#x' [0-9a-fA-F]+ ';'
2388  *
2389  * [ WFC: Legal Character ]
2390  * Characters referred to using character references must match the
2391  * production for Char.
2392  *
2393  * Returns the value parsed (as an int), 0 in case of error, str will be
2394  *         updated to the current value of the index
2395  */
2396 static int
2397 xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
2398     const xmlChar *ptr;
2399     xmlChar cur;
2400     unsigned int val = 0;
2401     unsigned int outofrange = 0;
2402
2403     if ((str == NULL) || (*str == NULL)) return(0);
2404     ptr = *str;
2405     cur = *ptr;
2406     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
2407         ptr += 3;
2408         cur = *ptr;
2409         while (cur != ';') { /* Non input consuming loop */
2410             if ((cur >= '0') && (cur <= '9'))
2411                 val = val * 16 + (cur - '0');
2412             else if ((cur >= 'a') && (cur <= 'f'))
2413                 val = val * 16 + (cur - 'a') + 10;
2414             else if ((cur >= 'A') && (cur <= 'F'))
2415                 val = val * 16 + (cur - 'A') + 10;
2416             else {
2417                 xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2418                 val = 0;
2419                 break;
2420             }
2421             if (val > 0x10FFFF)
2422                 outofrange = val;
2423
2424             ptr++;
2425             cur = *ptr;
2426         }
2427         if (cur == ';')
2428             ptr++;
2429     } else if  ((cur == '&') && (ptr[1] == '#')){
2430         ptr += 2;
2431         cur = *ptr;
2432         while (cur != ';') { /* Non input consuming loops */
2433             if ((cur >= '0') && (cur <= '9'))
2434                 val = val * 10 + (cur - '0');
2435             else {
2436                 xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2437                 val = 0;
2438                 break;
2439             }
2440             if (val > 0x10FFFF)
2441                 outofrange = val;
2442
2443             ptr++;
2444             cur = *ptr;
2445         }
2446         if (cur == ';')
2447             ptr++;
2448     } else {
2449         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2450         return(0);
2451     }
2452     *str = ptr;
2453
2454     /*
2455      * [ WFC: Legal Character ]
2456      * Characters referred to using character references must match the
2457      * production for Char.
2458      */
2459     if ((IS_CHAR(val) && (outofrange == 0))) {
2460         return(val);
2461     } else {
2462         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2463                           "xmlParseStringCharRef: invalid xmlChar value %d\n",
2464                           val);
2465     }
2466     return(0);
2467 }
2468
2469 /**
2470  * xmlParserHandlePEReference:
2471  * @ctxt:  the parser context
2472  *
2473  * [69] PEReference ::= '%' Name ';'
2474  *
2475  * [ WFC: No Recursion ]
2476  * A parsed entity must not contain a recursive
2477  * reference to itself, either directly or indirectly.
2478  *
2479  * [ WFC: Entity Declared ]
2480  * In a document without any DTD, a document with only an internal DTD
2481  * subset which contains no parameter entity references, or a document
2482  * with "standalone='yes'", ...  ... The declaration of a parameter
2483  * entity must precede any reference to it...
2484  *
2485  * [ VC: Entity Declared ]
2486  * In a document with an external subset or external parameter entities
2487  * with "standalone='no'", ...  ... The declaration of a parameter entity
2488  * must precede any reference to it...
2489  *
2490  * [ WFC: In DTD ]
2491  * Parameter-entity references may only appear in the DTD.
2492  * NOTE: misleading but this is handled.
2493  *
2494  * A PEReference may have been detected in the current input stream
2495  * the handling is done accordingly to
2496  *      http://www.w3.org/TR/REC-xml#entproc
2497  * i.e.
2498  *   - Included in literal in entity values
2499  *   - Included as Parameter Entity reference within DTDs
2500  */
2501 void
2502 xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
2503     switch(ctxt->instate) {
2504         case XML_PARSER_CDATA_SECTION:
2505             return;
2506         case XML_PARSER_COMMENT:
2507             return;
2508         case XML_PARSER_START_TAG:
2509             return;
2510         case XML_PARSER_END_TAG:
2511             return;
2512         case XML_PARSER_EOF:
2513             xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
2514             return;
2515         case XML_PARSER_PROLOG:
2516         case XML_PARSER_START:
2517         case XML_PARSER_MISC:
2518             xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
2519             return;
2520         case XML_PARSER_ENTITY_DECL:
2521         case XML_PARSER_CONTENT:
2522         case XML_PARSER_ATTRIBUTE_VALUE:
2523         case XML_PARSER_PI:
2524         case XML_PARSER_SYSTEM_LITERAL:
2525         case XML_PARSER_PUBLIC_LITERAL:
2526             /* we just ignore it there */
2527             return;
2528         case XML_PARSER_EPILOG:
2529             xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
2530             return;
2531         case XML_PARSER_ENTITY_VALUE:
2532             /*
2533              * NOTE: in the case of entity values, we don't do the
2534              *       substitution here since we need the literal
2535              *       entity value to be able to save the internal
2536              *       subset of the document.
2537              *       This will be handled by xmlStringDecodeEntities
2538              */
2539             return;
2540         case XML_PARSER_DTD:
2541             /*
2542              * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
2543              * In the internal DTD subset, parameter-entity references
2544              * can occur only where markup declarations can occur, not
2545              * within markup declarations.
2546              * In that case this is handled in xmlParseMarkupDecl
2547              */
2548             if ((ctxt->external == 0) && (ctxt->inputNr == 1))
2549                 return;
2550             if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
2551                 return;
2552             break;
2553         case XML_PARSER_IGNORE:
2554             return;
2555     }
2556
2557     xmlParsePEReference(ctxt);
2558 }
2559
2560 /*
2561  * Macro used to grow the current buffer.
2562  * buffer##_size is expected to be a size_t
2563  * mem_error: is expected to handle memory allocation failures
2564  */
2565 #define growBuffer(buffer, n) {                                         \
2566     xmlChar *tmp;                                                       \
2567     size_t new_size = buffer##_size * 2 + n;                            \
2568     if (new_size < buffer##_size) goto mem_error;                       \
2569     tmp = (xmlChar *) xmlRealloc(buffer, new_size);                     \
2570     if (tmp == NULL) goto mem_error;                                    \
2571     buffer = tmp;                                                       \
2572     buffer##_size = new_size;                                           \
2573 }
2574
2575 /**
2576  * xmlStringLenDecodeEntities:
2577  * @ctxt:  the parser context
2578  * @str:  the input string
2579  * @len: the string length
2580  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2581  * @end:  an end marker xmlChar, 0 if none
2582  * @end2:  an end marker xmlChar, 0 if none
2583  * @end3:  an end marker xmlChar, 0 if none
2584  *
2585  * Takes a entity string content and process to do the adequate substitutions.
2586  *
2587  * [67] Reference ::= EntityRef | CharRef
2588  *
2589  * [69] PEReference ::= '%' Name ';'
2590  *
2591  * Returns A newly allocated string with the substitution done. The caller
2592  *      must deallocate it !
2593  */
2594 xmlChar *
2595 xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2596                       int what, xmlChar end, xmlChar  end2, xmlChar end3) {
2597     xmlChar *buffer = NULL;
2598     size_t buffer_size = 0;
2599     size_t nbchars = 0;
2600
2601     xmlChar *current = NULL;
2602     xmlChar *rep = NULL;
2603     const xmlChar *last;
2604     xmlEntityPtr ent;
2605     int c,l;
2606
2607     if ((ctxt == NULL) || (str == NULL) || (len < 0))
2608         return(NULL);
2609     last = str + len;
2610
2611     if (((ctxt->depth > 40) &&
2612          ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2613         (ctxt->depth > 1024)) {
2614         xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2615         return(NULL);
2616     }
2617
2618     /*
2619      * allocate a translation buffer.
2620      */
2621     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
2622     buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
2623     if (buffer == NULL) goto mem_error;
2624
2625     /*
2626      * OK loop until we reach one of the ending char or a size limit.
2627      * we are operating on already parsed values.
2628      */
2629     if (str < last)
2630         c = CUR_SCHAR(str, l);
2631     else
2632         c = 0;
2633     while ((c != 0) && (c != end) && /* non input consuming loop */
2634            (c != end2) && (c != end3)) {
2635
2636         if (c == 0) break;
2637         if ((c == '&') && (str[1] == '#')) {
2638             int val = xmlParseStringCharRef(ctxt, &str);
2639             if (val == 0)
2640                 goto int_error;
2641             COPY_BUF(0,buffer,nbchars,val);
2642             if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2643                 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2644             }
2645         } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
2646             if (xmlParserDebugEntities)
2647                 xmlGenericError(xmlGenericErrorContext,
2648                         "String decoding Entity Reference: %.30s\n",
2649                         str);
2650             ent = xmlParseStringEntityRef(ctxt, &str);
2651             xmlParserEntityCheck(ctxt, 0, ent, 0);
2652             if (ent != NULL)
2653                 ctxt->nbentities += ent->checked / 2;
2654             if ((ent != NULL) &&
2655                 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
2656                 if (ent->content != NULL) {
2657                     COPY_BUF(0,buffer,nbchars,ent->content[0]);
2658                     if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2659                         growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2660                     }
2661                 } else {
2662                     xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
2663                             "predefined entity has no content\n");
2664                     goto int_error;
2665                 }
2666             } else if ((ent != NULL) && (ent->content != NULL)) {
2667                 ctxt->depth++;
2668                 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2669                                               0, 0, 0);
2670                 ctxt->depth--;
2671                 if (rep == NULL)
2672                     goto int_error;
2673
2674                 current = rep;
2675                 while (*current != 0) { /* non input consuming loop */
2676                     buffer[nbchars++] = *current++;
2677                     if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2678                         if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
2679                             goto int_error;
2680                         growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2681                     }
2682                 }
2683                 xmlFree(rep);
2684                 rep = NULL;
2685             } else if (ent != NULL) {
2686                 int i = xmlStrlen(ent->name);
2687                 const xmlChar *cur = ent->name;
2688
2689                 buffer[nbchars++] = '&';
2690                 if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
2691                     growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
2692                 }
2693                 for (;i > 0;i--)
2694                     buffer[nbchars++] = *cur++;
2695                 buffer[nbchars++] = ';';
2696             }
2697         } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
2698             if (xmlParserDebugEntities)
2699                 xmlGenericError(xmlGenericErrorContext,
2700                         "String decoding PE Reference: %.30s\n", str);
2701             ent = xmlParseStringPEReference(ctxt, &str);
2702             xmlParserEntityCheck(ctxt, 0, ent, 0);
2703             if (ent != NULL)
2704                 ctxt->nbentities += ent->checked / 2;
2705             if (ent != NULL) {
2706                 if (ent->content == NULL) {
2707                     /*
2708                      * Note: external parsed entities will not be loaded,
2709                      * it is not required for a non-validating parser to
2710                      * complete external PEreferences coming from the
2711                      * internal subset
2712                      */
2713                     if (((ctxt->options & XML_PARSE_NOENT) != 0) ||
2714                         ((ctxt->options & XML_PARSE_DTDVALID) != 0) ||
2715                         (ctxt->validate != 0)) {
2716                         xmlLoadEntityContent(ctxt, ent);
2717                     } else {
2718                         xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
2719                   "not validating will not read content for PE entity %s\n",
2720                                       ent->name, NULL);
2721                     }
2722                 }
2723                 ctxt->depth++;
2724                 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2725                                               0, 0, 0);
2726                 ctxt->depth--;
2727                 if (rep == NULL)
2728                     goto int_error;
2729                 current = rep;
2730                 while (*current != 0) { /* non input consuming loop */
2731                     buffer[nbchars++] = *current++;
2732                     if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2733                         if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
2734                             goto int_error;
2735                         growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2736                     }
2737                 }
2738                 xmlFree(rep);
2739                 rep = NULL;
2740             }
2741         } else {
2742             COPY_BUF(l,buffer,nbchars,c);
2743             str += l;
2744             if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2745                 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2746             }
2747         }
2748         if (str < last)
2749             c = CUR_SCHAR(str, l);
2750         else
2751             c = 0;
2752     }
2753     buffer[nbchars] = 0;
2754     return(buffer);
2755
2756 mem_error:
2757     xmlErrMemory(ctxt, NULL);
2758 int_error:
2759     if (rep != NULL)
2760         xmlFree(rep);
2761     if (buffer != NULL)
2762         xmlFree(buffer);
2763     return(NULL);
2764 }
2765
2766 /**
2767  * xmlStringDecodeEntities:
2768  * @ctxt:  the parser context
2769  * @str:  the input string
2770  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2771  * @end:  an end marker xmlChar, 0 if none
2772  * @end2:  an end marker xmlChar, 0 if none
2773  * @end3:  an end marker xmlChar, 0 if none
2774  *
2775  * Takes a entity string content and process to do the adequate substitutions.
2776  *
2777  * [67] Reference ::= EntityRef | CharRef
2778  *
2779  * [69] PEReference ::= '%' Name ';'
2780  *
2781  * Returns A newly allocated string with the substitution done. The caller
2782  *      must deallocate it !
2783  */
2784 xmlChar *
2785 xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
2786                         xmlChar end, xmlChar  end2, xmlChar end3) {
2787     if ((ctxt == NULL) || (str == NULL)) return(NULL);
2788     return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
2789            end, end2, end3));
2790 }
2791
2792 /************************************************************************
2793  *                                                                      *
2794  *              Commodity functions, cleanup needed ?                   *
2795  *                                                                      *
2796  ************************************************************************/
2797
2798 /**
2799  * areBlanks:
2800  * @ctxt:  an XML parser context
2801  * @str:  a xmlChar *
2802  * @len:  the size of @str
2803  * @blank_chars: we know the chars are blanks
2804  *
2805  * Is this a sequence of blank chars that one can ignore ?
2806  *
2807  * Returns 1 if ignorable 0 otherwise.
2808  */
2809
2810 static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2811                      int blank_chars) {
2812     int i, ret;
2813     xmlNodePtr lastChild;
2814
2815     /*
2816      * Don't spend time trying to differentiate them, the same callback is
2817      * used !
2818      */
2819     if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
2820         return(0);
2821
2822     /*
2823      * Check for xml:space value.
2824      */
2825     if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
2826         (*(ctxt->space) == -2))
2827         return(0);
2828
2829     /*
2830      * Check that the string is made of blanks
2831      */
2832     if (blank_chars == 0) {
2833         for (i = 0;i < len;i++)
2834             if (!(IS_BLANK_CH(str[i]))) return(0);
2835     }
2836
2837     /*
2838      * Look if the element is mixed content in the DTD if available
2839      */
2840     if (ctxt->node == NULL) return(0);
2841     if (ctxt->myDoc != NULL) {
2842         ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
2843         if (ret == 0) return(1);
2844         if (ret == 1) return(0);
2845     }
2846
2847     /*
2848      * Otherwise, heuristic :-\
2849      */
2850     if ((RAW != '<') && (RAW != 0xD)) return(0);
2851     if ((ctxt->node->children == NULL) &&
2852         (RAW == '<') && (NXT(1) == '/')) return(0);
2853
2854     lastChild = xmlGetLastChild(ctxt->node);
2855     if (lastChild == NULL) {
2856         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
2857             (ctxt->node->content != NULL)) return(0);
2858     } else if (xmlNodeIsText(lastChild))
2859         return(0);
2860     else if ((ctxt->node->children != NULL) &&
2861              (xmlNodeIsText(ctxt->node->children)))
2862         return(0);
2863     return(1);
2864 }
2865
2866 /************************************************************************
2867  *                                                                      *
2868  *              Extra stuff for namespace support                       *
2869  *      Relates to http://www.w3.org/TR/WD-xml-names                    *
2870  *                                                                      *
2871  ************************************************************************/
2872
2873 /**
2874  * xmlSplitQName:
2875  * @ctxt:  an XML parser context
2876  * @name:  an XML parser context
2877  * @prefix:  a xmlChar **
2878  *
2879  * parse an UTF8 encoded XML qualified name string
2880  *
2881  * [NS 5] QName ::= (Prefix ':')? LocalPart
2882  *
2883  * [NS 6] Prefix ::= NCName
2884  *
2885  * [NS 7] LocalPart ::= NCName
2886  *
2887  * Returns the local part, and prefix is updated
2888  *   to get the Prefix if any.
2889  */
2890
2891 xmlChar *
2892 xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
2893     xmlChar buf[XML_MAX_NAMELEN + 5];
2894     xmlChar *buffer = NULL;
2895     int len = 0;
2896     int max = XML_MAX_NAMELEN;
2897     xmlChar *ret = NULL;
2898     const xmlChar *cur = name;
2899     int c;
2900
2901     if (prefix == NULL) return(NULL);
2902     *prefix = NULL;
2903
2904     if (cur == NULL) return(NULL);
2905
2906 #ifndef XML_XML_NAMESPACE
2907     /* xml: prefix is not really a namespace */
2908     if ((cur[0] == 'x') && (cur[1] == 'm') &&
2909         (cur[2] == 'l') && (cur[3] == ':'))
2910         return(xmlStrdup(name));
2911 #endif
2912
2913     /* nasty but well=formed */
2914     if (cur[0] == ':')
2915         return(xmlStrdup(name));
2916
2917     c = *cur++;
2918     while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
2919         buf[len++] = c;
2920         c = *cur++;
2921     }
2922     if (len >= max) {
2923         /*
2924          * Okay someone managed to make a huge name, so he's ready to pay
2925          * for the processing speed.
2926          */
2927         max = len * 2;
2928
2929         buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
2930         if (buffer == NULL) {
2931             xmlErrMemory(ctxt, NULL);
2932             return(NULL);
2933         }
2934         memcpy(buffer, buf, len);
2935         while ((c != 0) && (c != ':')) { /* tested bigname.xml */
2936             if (len + 10 > max) {
2937                 xmlChar *tmp;
2938
2939                 max *= 2;
2940                 tmp = (xmlChar *) xmlRealloc(buffer,
2941                                                 max * sizeof(xmlChar));
2942                 if (tmp == NULL) {
2943                     xmlFree(buffer);
2944                     xmlErrMemory(ctxt, NULL);
2945                     return(NULL);
2946                 }
2947                 buffer = tmp;
2948             }
2949             buffer[len++] = c;
2950             c = *cur++;
2951         }
2952         buffer[len] = 0;
2953     }
2954
2955     if ((c == ':') && (*cur == 0)) {
2956         if (buffer != NULL)
2957             xmlFree(buffer);
2958         *prefix = NULL;
2959         return(xmlStrdup(name));
2960     }
2961
2962     if (buffer == NULL)
2963         ret = xmlStrndup(buf, len);
2964     else {
2965         ret = buffer;
2966         buffer = NULL;
2967         max = XML_MAX_NAMELEN;
2968     }
2969
2970
2971     if (c == ':') {
2972         c = *cur;
2973         *prefix = ret;
2974         if (c == 0) {
2975             return(xmlStrndup(BAD_CAST "", 0));
2976         }
2977         len = 0;
2978
2979         /*
2980          * Check that the first character is proper to start
2981          * a new name
2982          */
2983         if (!(((c >= 0x61) && (c <= 0x7A)) ||
2984               ((c >= 0x41) && (c <= 0x5A)) ||
2985               (c == '_') || (c == ':'))) {
2986             int l;
2987             int first = CUR_SCHAR(cur, l);
2988
2989             if (!IS_LETTER(first) && (first != '_')) {
2990                 xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
2991                             "Name %s is not XML Namespace compliant\n",
2992                                   name);
2993             }
2994         }
2995         cur++;
2996
2997         while ((c != 0) && (len < max)) { /* tested bigname2.xml */
2998             buf[len++] = c;
2999             c = *cur++;
3000         }
3001         if (len >= max) {
3002             /*
3003              * Okay someone managed to make a huge name, so he's ready to pay
3004              * for the processing speed.
3005              */
3006             max = len * 2;
3007
3008             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3009             if (buffer == NULL) {
3010                 xmlErrMemory(ctxt, NULL);
3011                 return(NULL);
3012             }
3013             memcpy(buffer, buf, len);
3014             while (c != 0) { /* tested bigname2.xml */
3015                 if (len + 10 > max) {
3016                     xmlChar *tmp;
3017
3018                     max *= 2;
3019                     tmp = (xmlChar *) xmlRealloc(buffer,
3020                                                     max * sizeof(xmlChar));
3021                     if (tmp == NULL) {
3022                         xmlErrMemory(ctxt, NULL);
3023                         xmlFree(buffer);
3024                         return(NULL);
3025                     }
3026                     buffer = tmp;
3027                 }
3028                 buffer[len++] = c;
3029                 c = *cur++;
3030             }
3031             buffer[len] = 0;
3032         }
3033
3034         if (buffer == NULL)
3035             ret = xmlStrndup(buf, len);
3036         else {
3037             ret = buffer;
3038         }
3039     }
3040
3041     return(ret);
3042 }
3043
3044 /************************************************************************
3045  *                                                                      *
3046  *                      The parser itself                               *
3047  *      Relates to http://www.w3.org/TR/REC-xml                         *
3048  *                                                                      *
3049  ************************************************************************/
3050
3051 /************************************************************************
3052  *                                                                      *
3053  *      Routines to parse Name, NCName and NmToken                      *
3054  *                                                                      *
3055  ************************************************************************/
3056 #ifdef DEBUG
3057 static unsigned long nbParseName = 0;
3058 static unsigned long nbParseNmToken = 0;
3059 static unsigned long nbParseNCName = 0;
3060 static unsigned long nbParseNCNameComplex = 0;
3061 static unsigned long nbParseNameComplex = 0;
3062 static unsigned long nbParseStringName = 0;
3063 #endif
3064
3065 /*
3066  * The two following functions are related to the change of accepted
3067  * characters for Name and NmToken in the Revision 5 of XML-1.0
3068  * They correspond to the modified production [4] and the new production [4a]
3069  * changes in that revision. Also note that the macros used for the
3070  * productions Letter, Digit, CombiningChar and Extender are not needed
3071  * anymore.
3072  * We still keep compatibility to pre-revision5 parsing semantic if the
3073  * new XML_PARSE_OLD10 option is given to the parser.
3074  */
3075 static int
3076 xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
3077     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3078         /*
3079          * Use the new checks of production [4] [4a] amd [5] of the
3080          * Update 5 of XML-1.0
3081          */
3082         if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3083             (((c >= 'a') && (c <= 'z')) ||
3084              ((c >= 'A') && (c <= 'Z')) ||
3085              (c == '_') || (c == ':') ||
3086              ((c >= 0xC0) && (c <= 0xD6)) ||
3087              ((c >= 0xD8) && (c <= 0xF6)) ||
3088              ((c >= 0xF8) && (c <= 0x2FF)) ||
3089              ((c >= 0x370) && (c <= 0x37D)) ||
3090              ((c >= 0x37F) && (c <= 0x1FFF)) ||
3091              ((c >= 0x200C) && (c <= 0x200D)) ||
3092              ((c >= 0x2070) && (c <= 0x218F)) ||
3093              ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3094              ((c >= 0x3001) && (c <= 0xD7FF)) ||
3095              ((c >= 0xF900) && (c <= 0xFDCF)) ||
3096              ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3097              ((c >= 0x10000) && (c <= 0xEFFFF))))
3098             return(1);
3099     } else {
3100         if (IS_LETTER(c) || (c == '_') || (c == ':'))
3101             return(1);
3102     }
3103     return(0);
3104 }
3105
3106 static int
3107 xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
3108     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3109         /*
3110          * Use the new checks of production [4] [4a] amd [5] of the
3111          * Update 5 of XML-1.0
3112          */
3113         if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3114             (((c >= 'a') && (c <= 'z')) ||
3115              ((c >= 'A') && (c <= 'Z')) ||
3116              ((c >= '0') && (c <= '9')) || /* !start */
3117              (c == '_') || (c == ':') ||
3118              (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3119              ((c >= 0xC0) && (c <= 0xD6)) ||
3120              ((c >= 0xD8) && (c <= 0xF6)) ||
3121              ((c >= 0xF8) && (c <= 0x2FF)) ||
3122              ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3123              ((c >= 0x370) && (c <= 0x37D)) ||
3124              ((c >= 0x37F) && (c <= 0x1FFF)) ||
3125              ((c >= 0x200C) && (c <= 0x200D)) ||
3126              ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3127              ((c >= 0x2070) && (c <= 0x218F)) ||
3128              ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3129              ((c >= 0x3001) && (c <= 0xD7FF)) ||
3130              ((c >= 0xF900) && (c <= 0xFDCF)) ||
3131              ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3132              ((c >= 0x10000) && (c <= 0xEFFFF))))
3133              return(1);
3134     } else {
3135         if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3136             (c == '.') || (c == '-') ||
3137             (c == '_') || (c == ':') ||
3138             (IS_COMBINING(c)) ||
3139             (IS_EXTENDER(c)))
3140             return(1);
3141     }
3142     return(0);
3143 }
3144
3145 static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
3146                                           int *len, int *alloc, int normalize);
3147
3148 static const xmlChar *
3149 xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
3150     int len = 0, l;
3151     int c;
3152     int count = 0;
3153
3154 #ifdef DEBUG
3155     nbParseNameComplex++;
3156 #endif
3157
3158     /*
3159      * Handler for more complex cases
3160      */
3161     GROW;
3162     if (ctxt->instate == XML_PARSER_EOF)
3163         return(NULL);
3164     c = CUR_CHAR(l);
3165     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3166         /*
3167          * Use the new checks of production [4] [4a] amd [5] of the
3168          * Update 5 of XML-1.0
3169          */
3170         if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3171             (!(((c >= 'a') && (c <= 'z')) ||
3172                ((c >= 'A') && (c <= 'Z')) ||
3173                (c == '_') || (c == ':') ||
3174                ((c >= 0xC0) && (c <= 0xD6)) ||
3175                ((c >= 0xD8) && (c <= 0xF6)) ||
3176                ((c >= 0xF8) && (c <= 0x2FF)) ||
3177                ((c >= 0x370) && (c <= 0x37D)) ||
3178                ((c >= 0x37F) && (c <= 0x1FFF)) ||
3179                ((c >= 0x200C) && (c <= 0x200D)) ||
3180                ((c >= 0x2070) && (c <= 0x218F)) ||
3181                ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3182                ((c >= 0x3001) && (c <= 0xD7FF)) ||
3183                ((c >= 0xF900) && (c <= 0xFDCF)) ||
3184                ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3185                ((c >= 0x10000) && (c <= 0xEFFFF))))) {
3186             return(NULL);
3187         }
3188         len += l;
3189         NEXTL(l);
3190         c = CUR_CHAR(l);
3191         while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3192                (((c >= 'a') && (c <= 'z')) ||
3193                 ((c >= 'A') && (c <= 'Z')) ||
3194                 ((c >= '0') && (c <= '9')) || /* !start */
3195                 (c == '_') || (c == ':') ||
3196                 (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3197                 ((c >= 0xC0) && (c <= 0xD6)) ||
3198                 ((c >= 0xD8) && (c <= 0xF6)) ||
3199                 ((c >= 0xF8) && (c <= 0x2FF)) ||
3200                 ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3201                 ((c >= 0x370) && (c <= 0x37D)) ||
3202                 ((c >= 0x37F) && (c <= 0x1FFF)) ||
3203                 ((c >= 0x200C) && (c <= 0x200D)) ||
3204                 ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3205                 ((c >= 0x2070) && (c <= 0x218F)) ||
3206                 ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3207                 ((c >= 0x3001) && (c <= 0xD7FF)) ||
3208                 ((c >= 0xF900) && (c <= 0xFDCF)) ||
3209                 ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3210                 ((c >= 0x10000) && (c <= 0xEFFFF))
3211                 )) {
3212             if (count++ > XML_PARSER_CHUNK_SIZE) {
3213                 count = 0;
3214                 GROW;
3215                 if (ctxt->instate == XML_PARSER_EOF)
3216                     return(NULL);
3217             }
3218             len += l;
3219             NEXTL(l);
3220             c = CUR_CHAR(l);
3221         }
3222     } else {
3223         if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3224             (!IS_LETTER(c) && (c != '_') &&
3225              (c != ':'))) {
3226             return(NULL);
3227         }
3228         len += l;
3229         NEXTL(l);
3230         c = CUR_CHAR(l);
3231
3232         while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3233                ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3234                 (c == '.') || (c == '-') ||
3235                 (c == '_') || (c == ':') ||
3236                 (IS_COMBINING(c)) ||
3237                 (IS_EXTENDER(c)))) {
3238             if (count++ > XML_PARSER_CHUNK_SIZE) {
3239                 count = 0;
3240                 GROW;
3241                 if (ctxt->instate == XML_PARSER_EOF)
3242                     return(NULL);
3243             }
3244             len += l;
3245             NEXTL(l);
3246             c = CUR_CHAR(l);
3247         }
3248     }
3249     if ((len > XML_MAX_NAME_LENGTH) &&
3250         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3251         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3252         return(NULL);
3253     }
3254     if (ctxt->input->cur - ctxt->input->base < len) {
3255         /*
3256          * There were a couple of bugs where PERefs lead to to a change
3257          * of the buffer. Check the buffer size to avoid passing an invalid
3258          * pointer to xmlDictLookup.
3259          */
3260         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
3261                     "unexpected change of input buffer");
3262         return (NULL);
3263     }
3264     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
3265         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
3266     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3267 }
3268
3269 /**
3270  * xmlParseName:
3271  * @ctxt:  an XML parser context
3272  *
3273  * parse an XML name.
3274  *
3275  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3276  *                  CombiningChar | Extender
3277  *
3278  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3279  *
3280  * [6] Names ::= Name (#x20 Name)*
3281  *
3282  * Returns the Name parsed or NULL
3283  */
3284
3285 const xmlChar *
3286 xmlParseName(xmlParserCtxtPtr ctxt) {
3287     const xmlChar *in;
3288     const xmlChar *ret;
3289     int count = 0;
3290
3291     GROW;
3292
3293 #ifdef DEBUG
3294     nbParseName++;
3295 #endif
3296
3297     /*
3298      * Accelerator for simple ASCII names
3299      */
3300     in = ctxt->input->cur;
3301     if (((*in >= 0x61) && (*in <= 0x7A)) ||
3302         ((*in >= 0x41) && (*in <= 0x5A)) ||
3303         (*in == '_') || (*in == ':')) {
3304         in++;
3305         while (((*in >= 0x61) && (*in <= 0x7A)) ||
3306                ((*in >= 0x41) && (*in <= 0x5A)) ||
3307                ((*in >= 0x30) && (*in <= 0x39)) ||
3308                (*in == '_') || (*in == '-') ||
3309                (*in == ':') || (*in == '.'))
3310             in++;
3311         if ((*in > 0) && (*in < 0x80)) {
3312             count = in - ctxt->input->cur;
3313             if ((count > XML_MAX_NAME_LENGTH) &&
3314                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3315                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3316                 return(NULL);
3317             }
3318             ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3319             ctxt->input->cur = in;
3320             ctxt->nbChars += count;
3321             ctxt->input->col += count;
3322             if (ret == NULL)
3323                 xmlErrMemory(ctxt, NULL);
3324             return(ret);
3325         }
3326     }
3327     /* accelerator for special cases */
3328     return(xmlParseNameComplex(ctxt));
3329 }
3330
3331 static const xmlChar *
3332 xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
3333     int len = 0, l;
3334     int c;
3335     int count = 0;
3336     size_t startPosition = 0;
3337
3338 #ifdef DEBUG
3339     nbParseNCNameComplex++;
3340 #endif
3341
3342     /*
3343      * Handler for more complex cases
3344      */
3345     GROW;
3346     startPosition = CUR_PTR - BASE_PTR;
3347     c = CUR_CHAR(l);
3348     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3349         (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
3350         return(NULL);
3351     }
3352
3353     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3354            (xmlIsNameChar(ctxt, c) && (c != ':'))) {
3355         if (count++ > XML_PARSER_CHUNK_SIZE) {
3356             if ((len > XML_MAX_NAME_LENGTH) &&
3357                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3358                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3359                 return(NULL);
3360             }
3361             count = 0;
3362             GROW;
3363             if (ctxt->instate == XML_PARSER_EOF)
3364                 return(NULL);
3365         }
3366         len += l;
3367         NEXTL(l);
3368         c = CUR_CHAR(l);
3369         if (c == 0) {
3370             count = 0;
3371             /*
3372              * when shrinking to extend the buffer we really need to preserve
3373              * the part of the name we already parsed. Hence rolling back
3374              * by current lenght.
3375              */
3376             ctxt->input->cur -= l;
3377             GROW;
3378             ctxt->input->cur += l;
3379             if (ctxt->instate == XML_PARSER_EOF)
3380                 return(NULL);
3381             c = CUR_CHAR(l);
3382         }
3383     }
3384     if ((len > XML_MAX_NAME_LENGTH) &&
3385         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3386         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3387         return(NULL);
3388     }
3389     return(xmlDictLookup(ctxt->dict, (BASE_PTR + startPosition), len));
3390 }
3391
3392 /**
3393  * xmlParseNCName:
3394  * @ctxt:  an XML parser context
3395  * @len:  length of the string parsed
3396  *
3397  * parse an XML name.
3398  *
3399  * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
3400  *                      CombiningChar | Extender
3401  *
3402  * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
3403  *
3404  * Returns the Name parsed or NULL
3405  */
3406
3407 static const xmlChar *
3408 xmlParseNCName(xmlParserCtxtPtr ctxt) {
3409     const xmlChar *in, *e;
3410     const xmlChar *ret;
3411     int count = 0;
3412
3413 #ifdef DEBUG
3414     nbParseNCName++;
3415 #endif
3416
3417     /*
3418      * Accelerator for simple ASCII names
3419      */
3420     in = ctxt->input->cur;
3421     e = ctxt->input->end;
3422     if ((((*in >= 0x61) && (*in <= 0x7A)) ||
3423          ((*in >= 0x41) && (*in <= 0x5A)) ||
3424          (*in == '_')) && (in < e)) {
3425         in++;
3426         while ((((*in >= 0x61) && (*in <= 0x7A)) ||
3427                 ((*in >= 0x41) && (*in <= 0x5A)) ||
3428                 ((*in >= 0x30) && (*in <= 0x39)) ||
3429                 (*in == '_') || (*in == '-') ||
3430                 (*in == '.')) && (in < e))
3431             in++;
3432         if (in >= e)
3433             goto complex;
3434         if ((*in > 0) && (*in < 0x80)) {
3435             count = in - ctxt->input->cur;
3436             if ((count > XML_MAX_NAME_LENGTH) &&
3437                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3438                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3439                 return(NULL);
3440             }
3441             ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3442             ctxt->input->cur = in;
3443             ctxt->nbChars += count;
3444             ctxt->input->col += count;
3445             if (ret == NULL) {
3446                 xmlErrMemory(ctxt, NULL);
3447             }
3448             return(ret);
3449         }
3450     }
3451 complex:
3452     return(xmlParseNCNameComplex(ctxt));
3453 }
3454
3455 /**
3456  * xmlParseNameAndCompare:
3457  * @ctxt:  an XML parser context
3458  *
3459  * parse an XML name and compares for match
3460  * (specialized for endtag parsing)
3461  *
3462  * Returns NULL for an illegal name, (xmlChar*) 1 for success
3463  * and the name for mismatch
3464  */
3465
3466 static const xmlChar *
3467 xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
3468     register const xmlChar *cmp = other;
3469     register const xmlChar *in;
3470     const xmlChar *ret;
3471
3472     GROW;
3473     if (ctxt->instate == XML_PARSER_EOF)
3474         return(NULL);
3475
3476     in = ctxt->input->cur;
3477     while (*in != 0 && *in == *cmp) {
3478         ++in;
3479         ++cmp;
3480         ctxt->input->col++;
3481     }
3482     if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
3483         /* success */
3484         ctxt->input->cur = in;
3485         return (const xmlChar*) 1;
3486     }
3487     /* failure (or end of input buffer), check with full function */
3488     ret = xmlParseName (ctxt);
3489     /* strings coming from the dictionary direct compare possible */
3490     if (ret == other) {
3491         return (const xmlChar*) 1;
3492     }
3493     return ret;
3494 }
3495
3496 /**
3497  * xmlParseStringName:
3498  * @ctxt:  an XML parser context
3499  * @str:  a pointer to the string pointer (IN/OUT)
3500  *
3501  * parse an XML name.
3502  *
3503  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3504  *                  CombiningChar | Extender
3505  *
3506  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3507  *
3508  * [6] Names ::= Name (#x20 Name)*
3509  *
3510  * Returns the Name parsed or NULL. The @str pointer
3511  * is updated to the current location in the string.
3512  */
3513
3514 static xmlChar *
3515 xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
3516     xmlChar buf[XML_MAX_NAMELEN + 5];
3517     const xmlChar *cur = *str;
3518     int len = 0, l;
3519     int c;
3520
3521 #ifdef DEBUG
3522     nbParseStringName++;
3523 #endif
3524
3525     c = CUR_SCHAR(cur, l);
3526     if (!xmlIsNameStartChar(ctxt, c)) {
3527         return(NULL);
3528     }
3529
3530     COPY_BUF(l,buf,len,c);
3531     cur += l;
3532     c = CUR_SCHAR(cur, l);
3533     while (xmlIsNameChar(ctxt, c)) {
3534         COPY_BUF(l,buf,len,c);
3535         cur += l;
3536         c = CUR_SCHAR(cur, l);
3537         if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
3538             /*
3539              * Okay someone managed to make a huge name, so he's ready to pay
3540              * for the processing speed.
3541              */
3542             xmlChar *buffer;
3543             int max = len * 2;
3544
3545             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3546             if (buffer == NULL) {
3547                 xmlErrMemory(ctxt, NULL);
3548                 return(NULL);
3549             }
3550             memcpy(buffer, buf, len);
3551             while (xmlIsNameChar(ctxt, c)) {
3552                 if (len + 10 > max) {
3553                     xmlChar *tmp;
3554
3555                     if ((len > XML_MAX_NAME_LENGTH) &&
3556                         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3557                         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3558                         xmlFree(buffer);
3559                         return(NULL);
3560                     }
3561                     max *= 2;
3562                     tmp = (xmlChar *) xmlRealloc(buffer,
3563                                                     max * sizeof(xmlChar));
3564                     if (tmp == NULL) {
3565                         xmlErrMemory(ctxt, NULL);
3566                         xmlFree(buffer);
3567                         return(NULL);
3568                     }
3569                     buffer = tmp;
3570                 }
3571                 COPY_BUF(l,buffer,len,c);
3572                 cur += l;
3573                 c = CUR_SCHAR(cur, l);
3574             }
3575             buffer[len] = 0;
3576             *str = cur;
3577             return(buffer);
3578         }
3579     }
3580     if ((len > XML_MAX_NAME_LENGTH) &&
3581         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3582         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3583         return(NULL);
3584     }
3585     *str = cur;
3586     return(xmlStrndup(buf, len));
3587 }
3588
3589 /**
3590  * xmlParseNmtoken:
3591  * @ctxt:  an XML parser context
3592  *
3593  * parse an XML Nmtoken.
3594  *
3595  * [7] Nmtoken ::= (NameChar)+
3596  *
3597  * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
3598  *
3599  * Returns the Nmtoken parsed or NULL
3600  */
3601
3602 xmlChar *
3603 xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
3604     xmlChar buf[XML_MAX_NAMELEN + 5];
3605     int len = 0, l;
3606     int c;
3607     int count = 0;
3608
3609 #ifdef DEBUG
3610     nbParseNmToken++;
3611 #endif
3612
3613     GROW;
3614     if (ctxt->instate == XML_PARSER_EOF)
3615         return(NULL);
3616     c = CUR_CHAR(l);
3617
3618     while (xmlIsNameChar(ctxt, c)) {
3619         if (count++ > XML_PARSER_CHUNK_SIZE) {
3620             count = 0;
3621             GROW;
3622         }
3623         COPY_BUF(l,buf,len,c);
3624         NEXTL(l);
3625         c = CUR_CHAR(l);
3626         if (c == 0) {
3627             count = 0;
3628             GROW;
3629             if (ctxt->instate == XML_PARSER_EOF)
3630                 return(NULL);
3631             c = CUR_CHAR(l);
3632         }
3633         if (len >= XML_MAX_NAMELEN) {
3634             /*
3635              * Okay someone managed to make a huge token, so he's ready to pay
3636              * for the processing speed.
3637              */
3638             xmlChar *buffer;
3639             int max = len * 2;
3640
3641             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3642             if (buffer == NULL) {
3643                 xmlErrMemory(ctxt, NULL);
3644                 return(NULL);
3645             }
3646             memcpy(buffer, buf, len);
3647             while (xmlIsNameChar(ctxt, c)) {
3648                 if (count++ > XML_PARSER_CHUNK_SIZE) {
3649                     count = 0;
3650                     GROW;
3651                     if (ctxt->instate == XML_PARSER_EOF) {
3652                         xmlFree(buffer);
3653                         return(NULL);
3654                     }
3655                 }
3656                 if (len + 10 > max) {
3657                     xmlChar *tmp;
3658
3659                     if ((max > XML_MAX_NAME_LENGTH) &&
3660                         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3661                         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3662                         xmlFree(buffer);
3663                         return(NULL);
3664                     }
3665                     max *= 2;
3666                     tmp = (xmlChar *) xmlRealloc(buffer,
3667                                                     max * sizeof(xmlChar));
3668                     if (tmp == NULL) {
3669                         xmlErrMemory(ctxt, NULL);
3670                         xmlFree(buffer);
3671                         return(NULL);
3672                     }
3673                     buffer = tmp;
3674                 }
3675                 COPY_BUF(l,buffer,len,c);
3676                 NEXTL(l);
3677                 c = CUR_CHAR(l);
3678             }
3679             buffer[len] = 0;
3680             return(buffer);
3681         }
3682     }
3683     if (len == 0)
3684         return(NULL);
3685     if ((len > XML_MAX_NAME_LENGTH) &&
3686         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3687         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3688         return(NULL);
3689     }
3690     return(xmlStrndup(buf, len));
3691 }
3692
3693 /**
3694  * xmlParseEntityValue:
3695  * @ctxt:  an XML parser context
3696  * @orig:  if non-NULL store a copy of the original entity value
3697  *
3698  * parse a value for ENTITY declarations
3699  *
3700  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
3701  *                     "'" ([^%&'] | PEReference | Reference)* "'"
3702  *
3703  * Returns the EntityValue parsed with reference substituted or NULL
3704  */
3705
3706 xmlChar *
3707 xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
3708     xmlChar *buf = NULL;
3709     int len = 0;
3710     int size = XML_PARSER_BUFFER_SIZE;
3711     int c, l;
3712     xmlChar stop;
3713     xmlChar *ret = NULL;
3714     const xmlChar *cur = NULL;
3715     xmlParserInputPtr input;
3716
3717     if (RAW == '"') stop = '"';
3718     else if (RAW == '\'') stop = '\'';
3719     else {
3720         xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
3721         return(NULL);
3722     }
3723     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3724     if (buf == NULL) {
3725         xmlErrMemory(ctxt, NULL);
3726         return(NULL);
3727     }
3728
3729     /*
3730      * The content of the entity definition is copied in a buffer.
3731      */
3732
3733     ctxt->instate = XML_PARSER_ENTITY_VALUE;
3734     input = ctxt->input;
3735     GROW;
3736     if (ctxt->instate == XML_PARSER_EOF)
3737         goto error;
3738     NEXT;
3739     c = CUR_CHAR(l);
3740     /*
3741      * NOTE: 4.4.5 Included in Literal
3742      * When a parameter entity reference appears in a literal entity
3743      * value, ... a single or double quote character in the replacement
3744      * text is always treated as a normal data character and will not
3745      * terminate the literal.
3746      * In practice it means we stop the loop only when back at parsing
3747      * the initial entity and the quote is found
3748      */
3749     while (((IS_CHAR(c)) && ((c != stop) || /* checked */
3750             (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
3751         if (len + 5 >= size) {
3752             xmlChar *tmp;
3753
3754             size *= 2;
3755             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
3756             if (tmp == NULL) {
3757                 xmlErrMemory(ctxt, NULL);
3758                 goto error;
3759             }
3760             buf = tmp;
3761         }
3762         COPY_BUF(l,buf,len,c);
3763         NEXTL(l);
3764
3765         GROW;
3766         c = CUR_CHAR(l);
3767         if (c == 0) {
3768             GROW;
3769             c = CUR_CHAR(l);
3770         }
3771     }
3772     buf[len] = 0;
3773     if (ctxt->instate == XML_PARSER_EOF)
3774         goto error;
3775     if (c != stop) {
3776         xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
3777         goto error;
3778     }
3779     NEXT;
3780
3781     /*
3782      * Raise problem w.r.t. '&' and '%' being used in non-entities
3783      * reference constructs. Note Charref will be handled in
3784      * xmlStringDecodeEntities()
3785      */
3786     cur = buf;
3787     while (*cur != 0) { /* non input consuming */
3788         if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
3789             xmlChar *name;
3790             xmlChar tmp = *cur;
3791             int nameOk = 0;
3792
3793             cur++;
3794             name = xmlParseStringName(ctxt, &cur);
3795             if (name != NULL) {
3796                 nameOk = 1;
3797                 xmlFree(name);
3798             }
3799             if ((nameOk == 0) || (*cur != ';')) {
3800                 xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
3801             "EntityValue: '%c' forbidden except for entities references\n",
3802                                   tmp);
3803                 goto error;
3804             }
3805             if ((tmp == '%') && (ctxt->inSubset == 1) &&
3806                 (ctxt->inputNr == 1)) {
3807                 xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
3808                 goto error;
3809             }
3810             if (*cur == 0)
3811                 break;
3812         }
3813         cur++;
3814     }
3815
3816     /*
3817      * Then PEReference entities are substituted.
3818      *
3819      * NOTE: 4.4.7 Bypassed
3820      * When a general entity reference appears in the EntityValue in
3821      * an entity declaration, it is bypassed and left as is.
3822      * so XML_SUBSTITUTE_REF is not set here.
3823      */
3824     ++ctxt->depth;
3825     ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
3826                                   0, 0, 0);
3827     --ctxt->depth;
3828     if (orig != NULL) {
3829         *orig = buf;
3830         buf = NULL;
3831     }
3832
3833 error:
3834     if (buf != NULL)
3835         xmlFree(buf);
3836     return(ret);
3837 }
3838
3839 /**
3840  * xmlParseAttValueComplex:
3841  * @ctxt:  an XML parser context
3842  * @len:   the resulting attribute len
3843  * @normalize:  wether to apply the inner normalization
3844  *
3845  * parse a value for an attribute, this is the fallback function
3846  * of xmlParseAttValue() when the attribute parsing requires handling
3847  * of non-ASCII characters, or normalization compaction.
3848  *
3849  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
3850  */
3851 static xmlChar *
3852 xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
3853     xmlChar limit = 0;
3854     xmlChar *buf = NULL;
3855     xmlChar *rep = NULL;
3856     size_t len = 0;
3857     size_t buf_size = 0;
3858     int c, l, in_space = 0;
3859     xmlChar *current = NULL;
3860     xmlEntityPtr ent;
3861
3862     if (NXT(0) == '"') {
3863         ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3864         limit = '"';
3865         NEXT;
3866     } else if (NXT(0) == '\'') {
3867         limit = '\'';
3868         ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3869         NEXT;
3870     } else {
3871         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
3872         return(NULL);
3873     }
3874
3875     /*
3876      * allocate a translation buffer.
3877      */
3878     buf_size = XML_PARSER_BUFFER_SIZE;
3879     buf = (xmlChar *) xmlMallocAtomic(buf_size);
3880     if (buf == NULL) goto mem_error;
3881
3882     /*
3883      * OK loop until we reach one of the ending char or a size limit.
3884      */
3885     c = CUR_CHAR(l);
3886     while (((NXT(0) != limit) && /* checked */
3887             (IS_CHAR(c)) && (c != '<')) &&
3888             (ctxt->instate != XML_PARSER_EOF)) {
3889         /*
3890          * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
3891          * special option is given
3892          */
3893         if ((len > XML_MAX_TEXT_LENGTH) &&
3894             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3895             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
3896                            "AttValue length too long\n");
3897             goto mem_error;
3898         }
3899         if (c == 0) break;
3900         if (c == '&') {
3901             in_space = 0;
3902             if (NXT(1) == '#') {
3903                 int val = xmlParseCharRef(ctxt);
3904
3905                 if (val == '&') {
3906                     if (ctxt->replaceEntities) {
3907                         if (len + 10 > buf_size) {
3908                             growBuffer(buf, 10);
3909                         }
3910                         buf[len++] = '&';
3911                     } else {
3912                         /*
3913                          * The reparsing will be done in xmlStringGetNodeList()
3914                          * called by the attribute() function in SAX.c
3915                          */
3916                         if (len + 10 > buf_size) {
3917                             growBuffer(buf, 10);
3918                         }
3919                         buf[len++] = '&';
3920                         buf[len++] = '#';
3921                         buf[len++] = '3';
3922                         buf[len++] = '8';
3923                         buf[len++] = ';';
3924                     }
3925                 } else if (val != 0) {
3926                     if (len + 10 > buf_size) {
3927                         growBuffer(buf, 10);
3928                     }
3929                     len += xmlCopyChar(0, &buf[len], val);
3930                 }
3931             } else {
3932                 ent = xmlParseEntityRef(ctxt);
3933                 ctxt->nbentities++;
3934                 if (ent != NULL)
3935                     ctxt->nbentities += ent->owner;
3936                 if ((ent != NULL) &&
3937                     (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
3938                     if (len + 10 > buf_size) {
3939                         growBuffer(buf, 10);
3940                     }
3941                     if ((ctxt->replaceEntities == 0) &&
3942                         (ent->content[0] == '&')) {
3943                         buf[len++] = '&';
3944                         buf[len++] = '#';
3945                         buf[len++] = '3';
3946                         buf[len++] = '8';
3947                         buf[len++] = ';';
3948                     } else {
3949                         buf[len++] = ent->content[0];
3950                     }
3951                 } else if ((ent != NULL) &&
3952                            (ctxt->replaceEntities != 0)) {
3953                     if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
3954                         ++ctxt->depth;
3955                         rep = xmlStringDecodeEntities(ctxt, ent->content,
3956                                                       XML_SUBSTITUTE_REF,
3957                                                       0, 0, 0);
3958                         --ctxt->depth;
3959                         if (rep != NULL) {
3960                             current = rep;
3961                             while (*current != 0) { /* non input consuming */
3962                                 if ((*current == 0xD) || (*current == 0xA) ||
3963                                     (*current == 0x9)) {
3964                                     buf[len++] = 0x20;
3965                                     current++;
3966                                 } else
3967                                     buf[len++] = *current++;
3968                                 if (len + 10 > buf_size) {
3969                                     growBuffer(buf, 10);
3970                                 }
3971                             }
3972                             xmlFree(rep);
3973                             rep = NULL;
3974                         }
3975                     } else {
3976                         if (len + 10 > buf_size) {
3977                             growBuffer(buf, 10);
3978                         }
3979                         if (ent->content != NULL)
3980                             buf[len++] = ent->content[0];
3981                     }
3982                 } else if (ent != NULL) {
3983                     int i = xmlStrlen(ent->name);
3984                     const xmlChar *cur = ent->name;
3985
3986                     /*
3987                      * This may look absurd but is needed to detect
3988                      * entities problems
3989                      */
3990                     if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
3991                         (ent->content != NULL) && (ent->checked == 0)) {
3992                         unsigned long oldnbent = ctxt->nbentities;
3993
3994                         ++ctxt->depth;
3995                         rep = xmlStringDecodeEntities(ctxt, ent->content,
3996                                                   XML_SUBSTITUTE_REF, 0, 0, 0);
3997                         --ctxt->depth;
3998
3999                         ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
4000                         if (rep != NULL) {
4001                             if (xmlStrchr(rep, '<'))
4002                                 ent->checked |= 1;
4003                             xmlFree(rep);
4004                             rep = NULL;
4005                         } else {
4006                             ent->content[0] = 0;
4007                         }
4008                     }
4009
4010                     /*
4011                      * Just output the reference
4012                      */
4013                     buf[len++] = '&';
4014                     while (len + i + 10 > buf_size) {
4015                         growBuffer(buf, i + 10);
4016                     }
4017                     for (;i > 0;i--)
4018                         buf[len++] = *cur++;
4019                     buf[len++] = ';';
4020                 }
4021             }
4022         } else {
4023             if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
4024                 if ((len != 0) || (!normalize)) {
4025                     if ((!normalize) || (!in_space)) {
4026                         COPY_BUF(l,buf,len,0x20);
4027                         while (len + 10 > buf_size) {
4028                             growBuffer(buf, 10);
4029                         }
4030                     }
4031                     in_space = 1;
4032                 }
4033             } else {
4034                 in_space = 0;
4035                 COPY_BUF(l,buf,len,c);
4036                 if (len + 10 > buf_size) {
4037                     growBuffer(buf, 10);
4038                 }
4039             }
4040             NEXTL(l);
4041         }
4042         GROW;
4043         c = CUR_CHAR(l);
4044     }
4045     if (ctxt->instate == XML_PARSER_EOF)
4046         goto error;
4047
4048     if ((in_space) && (normalize)) {
4049         while ((len > 0) && (buf[len - 1] == 0x20)) len--;
4050     }
4051     buf[len] = 0;
4052     if (RAW == '<') {
4053         xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
4054     } else if (RAW != limit) {
4055         if ((c != 0) && (!IS_CHAR(c))) {
4056             xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
4057                            "invalid character in attribute value\n");
4058         } else {
4059             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4060                            "AttValue: ' expected\n");
4061         }
4062     } else
4063         NEXT;
4064
4065     /*
4066      * There we potentially risk an overflow, don't allow attribute value of
4067      * length more than INT_MAX it is a very reasonnable assumption !
4068      */
4069     if (len >= INT_MAX) {
4070         xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4071                        "AttValue length too long\n");
4072         goto mem_error;
4073     }
4074
4075     if (attlen != NULL) *attlen = (int) len;
4076     return(buf);
4077
4078 mem_error:
4079     xmlErrMemory(ctxt, NULL);
4080 error:
4081     if (buf != NULL)
4082         xmlFree(buf);
4083     if (rep != NULL)
4084         xmlFree(rep);
4085     return(NULL);
4086 }
4087
4088 /**
4089  * xmlParseAttValue:
4090  * @ctxt:  an XML parser context
4091  *
4092  * parse a value for an attribute
4093  * Note: the parser won't do substitution of entities here, this
4094  * will be handled later in xmlStringGetNodeList
4095  *
4096  * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
4097  *                   "'" ([^<&'] | Reference)* "'"
4098  *
4099  * 3.3.3 Attribute-Value Normalization:
4100  * Before the value of an attribute is passed to the application or
4101  * checked for validity, the XML processor must normalize it as follows:
4102  * - a character reference is processed by appending the referenced
4103  *   character to the attribute value
4104  * - an entity reference is processed by recursively processing the
4105  *   replacement text of the entity
4106  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
4107  *   appending #x20 to the normalized value, except that only a single
4108  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
4109  *   parsed entity or the literal entity value of an internal parsed entity
4110  * - other characters are processed by appending them to the normalized value
4111  * If the declared value is not CDATA, then the XML processor must further
4112  * process the normalized attribute value by discarding any leading and
4113  * trailing space (#x20) characters, and by replacing sequences of space
4114  * (#x20) characters by a single space (#x20) character.
4115  * All attributes for which no declaration has been read should be treated
4116  * by a non-validating parser as if declared CDATA.
4117  *
4118  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
4119  */
4120
4121
4122 xmlChar *
4123 xmlParseAttValue(xmlParserCtxtPtr ctxt) {
4124     if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
4125     return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
4126 }
4127
4128 /**
4129  * xmlParseSystemLiteral:
4130  * @ctxt:  an XML parser context
4131  *
4132  * parse an XML Literal
4133  *
4134  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
4135  *
4136  * Returns the SystemLiteral parsed or NULL
4137  */
4138
4139 xmlChar *
4140 xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
4141     xmlChar *buf = NULL;
4142     int len = 0;
4143     int size = XML_PARSER_BUFFER_SIZE;
4144     int cur, l;
4145     xmlChar stop;
4146     int state = ctxt->instate;
4147     int count = 0;
4148
4149     SHRINK;
4150     if (RAW == '"') {
4151         NEXT;
4152         stop = '"';
4153     } else if (RAW == '\'') {
4154         NEXT;
4155         stop = '\'';
4156     } else {
4157         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4158         return(NULL);
4159     }
4160
4161     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4162     if (buf == NULL) {
4163         xmlErrMemory(ctxt, NULL);
4164         return(NULL);
4165     }
4166     ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
4167     cur = CUR_CHAR(l);
4168     while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
4169         if (len + 5 >= size) {
4170             xmlChar *tmp;
4171
4172             if ((size > XML_MAX_NAME_LENGTH) &&
4173                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4174                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
4175                 xmlFree(buf);
4176                 ctxt->instate = (xmlParserInputState) state;
4177                 return(NULL);
4178             }
4179             size *= 2;
4180             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4181             if (tmp == NULL) {
4182                 xmlFree(buf);
4183                 xmlErrMemory(ctxt, NULL);
4184                 ctxt->instate = (xmlParserInputState) state;
4185                 return(NULL);
4186             }
4187             buf = tmp;
4188         }
4189         count++;
4190         if (count > 50) {
4191             GROW;
4192             count = 0;
4193             if (ctxt->instate == XML_PARSER_EOF) {
4194                 xmlFree(buf);
4195                 return(NULL);
4196             }
4197         }
4198         COPY_BUF(l,buf,len,cur);
4199         NEXTL(l);
4200         cur = CUR_CHAR(l);
4201         if (cur == 0) {
4202             GROW;
4203             SHRINK;
4204             cur = CUR_CHAR(l);
4205         }
4206     }
4207     buf[len] = 0;
4208     ctxt->instate = (xmlParserInputState) state;
4209     if (!IS_CHAR(cur)) {
4210         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4211     } else {
4212         NEXT;
4213     }
4214     return(buf);
4215 }
4216
4217 /**
4218  * xmlParsePubidLiteral:
4219  * @ctxt:  an XML parser context
4220  *
4221  * parse an XML public literal
4222  *
4223  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
4224  *
4225  * Returns the PubidLiteral parsed or NULL.
4226  */
4227
4228 xmlChar *
4229 xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
4230     xmlChar *buf = NULL;
4231     int len = 0;
4232     int size = XML_PARSER_BUFFER_SIZE;
4233     xmlChar cur;
4234     xmlChar stop;
4235     int count = 0;
4236     xmlParserInputState oldstate = ctxt->instate;
4237
4238     SHRINK;
4239     if (RAW == '"') {
4240         NEXT;
4241         stop = '"';
4242     } else if (RAW == '\'') {
4243         NEXT;
4244         stop = '\'';
4245     } else {
4246         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4247         return(NULL);
4248     }
4249     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4250     if (buf == NULL) {
4251         xmlErrMemory(ctxt, NULL);
4252         return(NULL);
4253     }
4254     ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
4255     cur = CUR;
4256     while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
4257         if (len + 1 >= size) {
4258             xmlChar *tmp;
4259
4260             if ((size > XML_MAX_NAME_LENGTH) &&
4261                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4262                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
4263                 xmlFree(buf);
4264                 return(NULL);
4265             }
4266             size *= 2;
4267             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4268             if (tmp == NULL) {
4269                 xmlErrMemory(ctxt, NULL);
4270                 xmlFree(buf);
4271                 return(NULL);
4272             }
4273             buf = tmp;
4274         }
4275         buf[len++] = cur;
4276         count++;
4277         if (count > 50) {
4278             GROW;
4279             count = 0;
4280             if (ctxt->instate == XML_PARSER_EOF) {
4281                 xmlFree(buf);
4282                 return(NULL);
4283             }
4284         }
4285         NEXT;
4286         cur = CUR;
4287         if (cur == 0) {
4288             GROW;
4289             SHRINK;
4290             cur = CUR;
4291         }
4292     }
4293     buf[len] = 0;
4294     if (cur != stop) {
4295         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4296     } else {
4297         NEXT;
4298     }
4299     ctxt->instate = oldstate;
4300     return(buf);
4301 }
4302
4303 static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
4304
4305 /*
4306  * used for the test in the inner loop of the char data testing
4307  */
4308 static const unsigned char test_char_data[256] = {
4309     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4310     0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
4311     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4312     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4313     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
4314     0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
4315     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
4316     0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
4317     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
4318     0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
4319     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
4320     0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
4321     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
4322     0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
4323     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
4324     0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
4325     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
4326     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4327     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4328     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4329     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4330     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4331     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4332     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4333     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4334     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4335     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4336     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4337     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4338     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4339     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4340     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4341 };
4342
4343 /**
4344  * xmlParseCharData:
4345  * @ctxt:  an XML parser context
4346  * @cdata:  int indicating whether we are within a CDATA section
4347  *
4348  * parse a CharData section.
4349  * if we are within a CDATA section ']]>' marks an end of section.
4350  *
4351  * The right angle bracket (>) may be represented using the string "&gt;",
4352  * and must, for compatibility, be escaped using "&gt;" or a character
4353  * reference when it appears in the string "]]>" in content, when that
4354  * string is not marking the end of a CDATA section.
4355  *
4356  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
4357  */
4358
4359 void
4360 xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
4361     const xmlChar *in;
4362     int nbchar = 0;
4363     int line = ctxt->input->line;
4364     int col = ctxt->input->col;
4365     int ccol;
4366
4367     SHRINK;
4368     GROW;
4369     /*
4370      * Accelerated common case where input don't need to be
4371      * modified before passing it to the handler.
4372      */
4373     if (!cdata) {
4374         in = ctxt->input->cur;
4375         do {
4376 get_more_space:
4377             while (*in == 0x20) { in++; ctxt->input->col++; }
4378             if (*in == 0xA) {
4379                 do {
4380                     ctxt->input->line++; ctxt->input->col = 1;
4381                     in++;
4382                 } while (*in == 0xA);
4383                 goto get_more_space;
4384             }
4385             if (*in == '<') {
4386                 nbchar = in - ctxt->input->cur;
4387                 if (nbchar > 0) {
4388                     const xmlChar *tmp = ctxt->input->cur;
4389                     ctxt->input->cur = in;
4390
4391                     if ((ctxt->sax != NULL) &&
4392                         (ctxt->sax->ignorableWhitespace !=
4393                          ctxt->sax->characters)) {
4394                         if (areBlanks(ctxt, tmp, nbchar, 1)) {
4395                             if (ctxt->sax->ignorableWhitespace != NULL)
4396                                 ctxt->sax->ignorableWhitespace(ctxt->userData,
4397                                                        tmp, nbchar);
4398                         } else {
4399                             if (ctxt->sax->characters != NULL)
4400                                 ctxt->sax->characters(ctxt->userData,
4401                                                       tmp, nbchar);
4402                             if (*ctxt->space == -1)
4403                                 *ctxt->space = -2;
4404                         }
4405                     } else if ((ctxt->sax != NULL) &&
4406                                (ctxt->sax->characters != NULL)) {
4407                         ctxt->sax->characters(ctxt->userData,
4408                                               tmp, nbchar);
4409                     }
4410                 }
4411                 return;
4412             }
4413
4414 get_more:
4415             ccol = ctxt->input->col;
4416             while (test_char_data[*in]) {
4417                 in++;
4418                 ccol++;
4419             }
4420             ctxt->input->col = ccol;
4421             if (*in == 0xA) {
4422                 do {
4423                     ctxt->input->line++; ctxt->input->col = 1;
4424                     in++;
4425                 } while (*in == 0xA);
4426                 goto get_more;
4427             }
4428             if (*in == ']') {
4429                 if ((in[1] == ']') && (in[2] == '>')) {
4430                     xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4431                     ctxt->input->cur = in + 1;
4432                     return;
4433                 }
4434                 in++;
4435                 ctxt->input->col++;
4436                 goto get_more;
4437             }
4438             nbchar = in - ctxt->input->cur;
4439             if (nbchar > 0) {
4440                 if ((ctxt->sax != NULL) &&
4441                     (ctxt->sax->ignorableWhitespace !=
4442                      ctxt->sax->characters) &&
4443                     (IS_BLANK_CH(*ctxt->input->cur))) {
4444                     const xmlChar *tmp = ctxt->input->cur;
4445                     ctxt->input->cur = in;
4446
4447                     if (areBlanks(ctxt, tmp, nbchar, 0)) {
4448                         if (ctxt->sax->ignorableWhitespace != NULL)
4449                             ctxt->sax->ignorableWhitespace(ctxt->userData,
4450                                                            tmp, nbchar);
4451                     } else {
4452                         if (ctxt->sax->characters != NULL)
4453                             ctxt->sax->characters(ctxt->userData,
4454                                                   tmp, nbchar);
4455                         if (*ctxt->space == -1)
4456                             *ctxt->space = -2;
4457                     }
4458                     line = ctxt->input->line;
4459                     col = ctxt->input->col;
4460                 } else if (ctxt->sax != NULL) {
4461                     if (ctxt->sax->characters != NULL)
4462                         ctxt->sax->characters(ctxt->userData,
4463                                               ctxt->input->cur, nbchar);
4464                     line = ctxt->input->line;
4465                     col = ctxt->input->col;
4466                 }
4467                 /* something really bad happened in the SAX callback */
4468                 if (ctxt->instate != XML_PARSER_CONTENT)
4469                     return;
4470             }
4471             ctxt->input->cur = in;
4472             if (*in == 0xD) {
4473                 in++;
4474                 if (*in == 0xA) {
4475                     ctxt->input->cur = in;
4476                     in++;
4477                     ctxt->input->line++; ctxt->input->col = 1;
4478                     continue; /* while */
4479                 }
4480                 in--;
4481             }
4482             if (*in == '<') {
4483                 return;
4484             }
4485             if (*in == '&') {
4486                 return;
4487             }
4488             SHRINK;
4489             GROW;
4490             if (ctxt->instate == XML_PARSER_EOF)
4491                 return;
4492             in = ctxt->input->cur;
4493         } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
4494         nbchar = 0;
4495     }
4496     ctxt->input->line = line;
4497     ctxt->input->col = col;
4498     xmlParseCharDataComplex(ctxt, cdata);
4499 }
4500
4501 /**
4502  * xmlParseCharDataComplex:
4503  * @ctxt:  an XML parser context
4504  * @cdata:  int indicating whether we are within a CDATA section
4505  *
4506  * parse a CharData section.this is the fallback function
4507  * of xmlParseCharData() when the parsing requires handling
4508  * of non-ASCII characters.
4509  */
4510 static void
4511 xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
4512     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
4513     int nbchar = 0;
4514     int cur, l;
4515     int count = 0;
4516
4517     SHRINK;
4518     GROW;
4519     cur = CUR_CHAR(l);
4520     while ((cur != '<') && /* checked */
4521            (cur != '&') &&
4522            (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
4523         if ((cur == ']') && (NXT(1) == ']') &&
4524             (NXT(2) == '>')) {
4525             if (cdata) break;
4526             else {
4527                 xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4528             }
4529         }
4530         COPY_BUF(l,buf,nbchar,cur);
4531         if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
4532             buf[nbchar] = 0;
4533
4534             /*
4535              * OK the segment is to be consumed as chars.
4536              */
4537             if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4538                 if (areBlanks(ctxt, buf, nbchar, 0)) {
4539                     if (ctxt->sax->ignorableWhitespace != NULL)
4540                         ctxt->sax->ignorableWhitespace(ctxt->userData,
4541                                                        buf, nbchar);
4542                 } else {
4543                     if (ctxt->sax->characters != NULL)
4544                         ctxt->sax->characters(ctxt->userData, buf, nbchar);
4545                     if ((ctxt->sax->characters !=
4546                          ctxt->sax->ignorableWhitespace) &&
4547                         (*ctxt->space == -1))
4548                         *ctxt->space = -2;
4549                 }
4550             }
4551             nbchar = 0;
4552             /* something really bad happened in the SAX callback */
4553             if (ctxt->instate != XML_PARSER_CONTENT)
4554                 return;
4555         }
4556         count++;
4557         if (count > 50) {
4558             GROW;
4559             count = 0;
4560             if (ctxt->instate == XML_PARSER_EOF)
4561                 return;
4562         }
4563         NEXTL(l);
4564         cur = CUR_CHAR(l);
4565     }
4566     if (nbchar != 0) {
4567         buf[nbchar] = 0;
4568         /*
4569          * OK the segment is to be consumed as chars.
4570          */
4571         if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4572             if (areBlanks(ctxt, buf, nbchar, 0)) {
4573                 if (ctxt->sax->ignorableWhitespace != NULL)
4574                     ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
4575             } else {
4576                 if (ctxt->sax->characters != NULL)
4577                     ctxt->sax->characters(ctxt->userData, buf, nbchar);
4578                 if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
4579                     (*ctxt->space == -1))
4580                     *ctxt->space = -2;
4581             }
4582         }
4583     }
4584     if ((cur != 0) && (!IS_CHAR(cur))) {
4585         /* Generate the error and skip the offending character */
4586         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4587                           "PCDATA invalid Char value %d\n",
4588                           cur);
4589         NEXTL(l);
4590     }
4591 }
4592
4593 /**
4594  * xmlParseExternalID:
4595  * @ctxt:  an XML parser context
4596  * @publicID:  a xmlChar** receiving PubidLiteral
4597  * @strict: indicate whether we should restrict parsing to only
4598  *          production [75], see NOTE below
4599  *
4600  * Parse an External ID or a Public ID
4601  *
4602  * NOTE: Productions [75] and [83] interact badly since [75] can generate
4603  *       'PUBLIC' S PubidLiteral S SystemLiteral
4604  *
4605  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
4606  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
4607  *
4608  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
4609  *
4610  * Returns the function returns SystemLiteral and in the second
4611  *                case publicID receives PubidLiteral, is strict is off
4612  *                it is possible to return NULL and have publicID set.
4613  */
4614
4615 xmlChar *
4616 xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
4617     xmlChar *URI = NULL;
4618
4619     SHRINK;
4620
4621     *publicID = NULL;
4622     if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
4623         SKIP(6);
4624         if (SKIP_BLANKS == 0) {
4625             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4626                            "Space required after 'SYSTEM'\n");
4627         }
4628         URI = xmlParseSystemLiteral(ctxt);
4629         if (URI == NULL) {
4630             xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4631         }
4632     } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
4633         SKIP(6);
4634         if (SKIP_BLANKS == 0) {
4635             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4636                     "Space required after 'PUBLIC'\n");
4637         }
4638         *publicID = xmlParsePubidLiteral(ctxt);
4639         if (*publicID == NULL) {
4640             xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
4641         }
4642         if (strict) {
4643             /*
4644              * We don't handle [83] so "S SystemLiteral" is required.
4645              */
4646             if (SKIP_BLANKS == 0) {
4647                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4648                         "Space required after the Public Identifier\n");
4649             }
4650         } else {
4651             /*
4652              * We handle [83] so we return immediately, if
4653              * "S SystemLiteral" is not detected. We skip blanks if no
4654              * system literal was found, but this is harmless since we must
4655              * be at the end of a NotationDecl.
4656              */
4657             if (SKIP_BLANKS == 0) return(NULL);
4658             if ((CUR != '\'') && (CUR != '"')) return(NULL);
4659         }
4660         URI = xmlParseSystemLiteral(ctxt);
4661         if (URI == NULL) {
4662             xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4663         }
4664     }
4665     return(URI);
4666 }
4667
4668 /**
4669  * xmlParseCommentComplex:
4670  * @ctxt:  an XML parser context
4671  * @buf:  the already parsed part of the buffer
4672  * @len:  number of bytes filles in the buffer
4673  * @size:  allocated size of the buffer
4674  *
4675  * Skip an XML (SGML) comment <!-- .... -->
4676  *  The spec says that "For compatibility, the string "--" (double-hyphen)
4677  *  must not occur within comments. "
4678  * This is the slow routine in case the accelerator for ascii didn't work
4679  *
4680  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4681  */
4682 static void
4683 xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
4684                        size_t len, size_t size) {
4685     int q, ql;
4686     int r, rl;
4687     int cur, l;
4688     size_t count = 0;
4689     int inputid;
4690
4691     inputid = ctxt->input->id;
4692
4693     if (buf == NULL) {
4694         len = 0;
4695         size = XML_PARSER_BUFFER_SIZE;
4696         buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4697         if (buf == NULL) {
4698             xmlErrMemory(ctxt, NULL);
4699             return;
4700         }
4701     }
4702     GROW;       /* Assure there's enough input data */
4703     q = CUR_CHAR(ql);
4704     if (q == 0)
4705         goto not_terminated;
4706     if (!IS_CHAR(q)) {
4707         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4708                           "xmlParseComment: invalid xmlChar value %d\n",
4709                           q);
4710         xmlFree (buf);
4711         return;
4712     }
4713     NEXTL(ql);
4714     r = CUR_CHAR(rl);
4715     if (r == 0)
4716         goto not_terminated;
4717     if (!IS_CHAR(r)) {
4718         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4719                           "xmlParseComment: invalid xmlChar value %d\n",
4720                           q);
4721         xmlFree (buf);
4722         return;
4723     }
4724     NEXTL(rl);
4725     cur = CUR_CHAR(l);
4726     if (cur == 0)
4727         goto not_terminated;
4728     while (IS_CHAR(cur) && /* checked */
4729            ((cur != '>') ||
4730             (r != '-') || (q != '-'))) {
4731         if ((r == '-') && (q == '-')) {
4732             xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
4733         }
4734         if ((len > XML_MAX_TEXT_LENGTH) &&
4735             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4736             xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4737                          "Comment too big found", NULL);
4738             xmlFree (buf);
4739             return;
4740         }
4741         if (len + 5 >= size) {
4742             xmlChar *new_buf;
4743             size_t new_size;
4744
4745             new_size = size * 2;
4746             new_buf = (xmlChar *) xmlRealloc(buf, new_size);
4747             if (new_buf == NULL) {
4748                 xmlFree (buf);
4749                 xmlErrMemory(ctxt, NULL);
4750                 return;
4751             }
4752             buf = new_buf;
4753             size = new_size;
4754         }
4755         COPY_BUF(ql,buf,len,q);
4756         q = r;
4757         ql = rl;
4758         r = cur;
4759         rl = l;
4760
4761         count++;
4762         if (count > 50) {
4763             GROW;
4764             count = 0;
4765             if (ctxt->instate == XML_PARSER_EOF) {
4766                 xmlFree(buf);
4767                 return;
4768             }
4769         }
4770         NEXTL(l);
4771         cur = CUR_CHAR(l);
4772         if (cur == 0) {
4773             SHRINK;
4774             GROW;
4775             cur = CUR_CHAR(l);
4776         }
4777     }
4778     buf[len] = 0;
4779     if (cur == 0) {
4780         xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4781                              "Comment not terminated \n<!--%.50s\n", buf);
4782     } else if (!IS_CHAR(cur)) {
4783         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4784                           "xmlParseComment: invalid xmlChar value %d\n",
4785                           cur);
4786     } else {
4787         if (inputid != ctxt->input->id) {
4788             xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4789                            "Comment doesn't start and stop in the same"
4790                            " entity\n");
4791         }
4792         NEXT;
4793         if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4794             (!ctxt->disableSAX))
4795             ctxt->sax->comment(ctxt->userData, buf);
4796     }
4797     xmlFree(buf);
4798     return;
4799 not_terminated:
4800     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4801                          "Comment not terminated\n", NULL);
4802     xmlFree(buf);
4803     return;
4804 }
4805
4806 /**
4807  * xmlParseComment:
4808  * @ctxt:  an XML parser context
4809  *
4810  * Skip an XML (SGML) comment <!-- .... -->
4811  *  The spec says that "For compatibility, the string "--" (double-hyphen)
4812  *  must not occur within comments. "
4813  *
4814  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4815  */
4816 void
4817 xmlParseComment(xmlParserCtxtPtr ctxt) {
4818     xmlChar *buf = NULL;
4819     size_t size = XML_PARSER_BUFFER_SIZE;
4820     size_t len = 0;
4821     xmlParserInputState state;
4822     const xmlChar *in;
4823     size_t nbchar = 0;
4824     int ccol;
4825     int inputid;
4826
4827     /*
4828      * Check that there is a comment right here.
4829      */
4830     if ((RAW != '<') || (NXT(1) != '!') ||
4831         (NXT(2) != '-') || (NXT(3) != '-')) return;
4832     state = ctxt->instate;
4833     ctxt->instate = XML_PARSER_COMMENT;
4834     inputid = ctxt->input->id;
4835     SKIP(4);
4836     SHRINK;
4837     GROW;
4838
4839     /*
4840      * Accelerated common case where input don't need to be
4841      * modified before passing it to the handler.
4842      */
4843     in = ctxt->input->cur;
4844     do {
4845         if (*in == 0xA) {
4846             do {
4847                 ctxt->input->line++; ctxt->input->col = 1;
4848                 in++;
4849             } while (*in == 0xA);
4850         }
4851 get_more:
4852         ccol = ctxt->input->col;
4853         while (((*in > '-') && (*in <= 0x7F)) ||
4854                ((*in >= 0x20) && (*in < '-')) ||
4855                (*in == 0x09)) {
4856                     in++;
4857                     ccol++;
4858         }
4859         ctxt->input->col = ccol;
4860         if (*in == 0xA) {
4861             do {
4862                 ctxt->input->line++; ctxt->input->col = 1;
4863                 in++;
4864             } while (*in == 0xA);
4865             goto get_more;
4866         }
4867         nbchar = in - ctxt->input->cur;
4868         /*
4869          * save current set of data
4870          */
4871         if (nbchar > 0) {
4872             if ((ctxt->sax != NULL) &&
4873                 (ctxt->sax->comment != NULL)) {
4874                 if (buf == NULL) {
4875                     if ((*in == '-') && (in[1] == '-'))
4876                         size = nbchar + 1;
4877                     else
4878                         size = XML_PARSER_BUFFER_SIZE + nbchar;
4879                     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4880                     if (buf == NULL) {
4881                         xmlErrMemory(ctxt, NULL);
4882                         ctxt->instate = state;
4883                         return;
4884                     }
4885                     len = 0;
4886                 } else if (len + nbchar + 1 >= size) {
4887                     xmlChar *new_buf;
4888                     size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
4889                     new_buf = (xmlChar *) xmlRealloc(buf,
4890                                                      size * sizeof(xmlChar));
4891                     if (new_buf == NULL) {
4892                         xmlFree (buf);
4893                         xmlErrMemory(ctxt, NULL);
4894                         ctxt->instate = state;
4895                         return;
4896                     }
4897                     buf = new_buf;
4898                 }
4899                 memcpy(&buf[len], ctxt->input->cur, nbchar);
4900                 len += nbchar;
4901                 buf[len] = 0;
4902             }
4903         }
4904         if ((len > XML_MAX_TEXT_LENGTH) &&
4905             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4906             xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4907                          "Comment too big found", NULL);
4908             xmlFree (buf);
4909             return;
4910         }
4911         ctxt->input->cur = in;
4912         if (*in == 0xA) {
4913             in++;
4914             ctxt->input->line++; ctxt->input->col = 1;
4915         }
4916         if (*in == 0xD) {
4917             in++;
4918             if (*in == 0xA) {
4919                 ctxt->input->cur = in;
4920                 in++;
4921                 ctxt->input->line++; ctxt->input->col = 1;
4922                 continue; /* while */
4923             }
4924             in--;
4925         }
4926         SHRINK;
4927         GROW;
4928         if (ctxt->instate == XML_PARSER_EOF) {
4929             xmlFree(buf);
4930             return;
4931         }
4932         in = ctxt->input->cur;
4933         if (*in == '-') {
4934             if (in[1] == '-') {
4935                 if (in[2] == '>') {
4936                     if (ctxt->input->id != inputid) {
4937                         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4938                                        "comment doesn't start and stop in the"
4939                                        " same entity\n");
4940                     }
4941                     SKIP(3);
4942                     if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4943                         (!ctxt->disableSAX)) {
4944                         if (buf != NULL)
4945                             ctxt->sax->comment(ctxt->userData, buf);
4946                         else
4947                             ctxt->sax->comment(ctxt->userData, BAD_CAST "");
4948                     }
4949                     if (buf != NULL)
4950                         xmlFree(buf);
4951                     if (ctxt->instate != XML_PARSER_EOF)
4952                         ctxt->instate = state;
4953                     return;
4954                 }
4955                 if (buf != NULL) {
4956                     xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
4957                                       "Double hyphen within comment: "
4958                                       "<!--%.50s\n",
4959                                       buf);
4960                 } else
4961                     xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
4962                                       "Double hyphen within comment\n", NULL);
4963                 in++;
4964                 ctxt->input->col++;
4965             }
4966             in++;
4967             ctxt->input->col++;
4968             goto get_more;
4969         }
4970     } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
4971     xmlParseCommentComplex(ctxt, buf, len, size);
4972     ctxt->instate = state;
4973     return;
4974 }
4975
4976
4977 /**
4978  * xmlParsePITarget:
4979  * @ctxt:  an XML parser context
4980  *
4981  * parse the name of a PI
4982  *
4983  * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
4984  *
4985  * Returns the PITarget name or NULL
4986  */
4987
4988 const xmlChar *
4989 xmlParsePITarget(xmlParserCtxtPtr ctxt) {
4990     const xmlChar *name;
4991
4992     name = xmlParseName(ctxt);
4993     if ((name != NULL) &&
4994         ((name[0] == 'x') || (name[0] == 'X')) &&
4995         ((name[1] == 'm') || (name[1] == 'M')) &&
4996         ((name[2] == 'l') || (name[2] == 'L'))) {
4997         int i;
4998         if ((name[0] == 'x') && (name[1] == 'm') &&
4999             (name[2] == 'l') && (name[3] == 0)) {
5000             xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5001                  "XML declaration allowed only at the start of the document\n");
5002             return(name);
5003         } else if (name[3] == 0) {
5004             xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
5005             return(name);
5006         }
5007         for (i = 0;;i++) {
5008             if (xmlW3CPIs[i] == NULL) break;
5009             if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
5010                 return(name);
5011         }
5012         xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5013                       "xmlParsePITarget: invalid name prefix 'xml'\n",
5014                       NULL, NULL);
5015     }
5016     if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
5017         xmlNsErr(ctxt, XML_NS_ERR_COLON,
5018                  "colons are forbidden from PI names '%s'\n", name, NULL, NULL);
5019     }
5020     return(name);
5021 }
5022
5023 #ifdef LIBXML_CATALOG_ENABLED
5024 /**
5025  * xmlParseCatalogPI:
5026  * @ctxt:  an XML parser context
5027  * @catalog:  the PI value string
5028  *
5029  * parse an XML Catalog Processing Instruction.
5030  *
5031  * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
5032  *
5033  * Occurs only if allowed by the user and if happening in the Misc
5034  * part of the document before any doctype informations
5035  * This will add the given catalog to the parsing context in order
5036  * to be used if there is a resolution need further down in the document
5037  */
5038
5039 static void
5040 xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
5041     xmlChar *URL = NULL;
5042     const xmlChar *tmp, *base;
5043     xmlChar marker;
5044
5045     tmp = catalog;
5046     while (IS_BLANK_CH(*tmp)) tmp++;
5047     if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
5048         goto error;
5049     tmp += 7;
5050     while (IS_BLANK_CH(*tmp)) tmp++;
5051     if (*tmp != '=') {
5052         return;
5053     }
5054     tmp++;
5055     while (IS_BLANK_CH(*tmp)) tmp++;
5056     marker = *tmp;
5057     if ((marker != '\'') && (marker != '"'))
5058         goto error;
5059     tmp++;
5060     base = tmp;
5061     while ((*tmp != 0) && (*tmp != marker)) tmp++;
5062     if (*tmp == 0)
5063         goto error;
5064     URL = xmlStrndup(base, tmp - base);
5065     tmp++;
5066     while (IS_BLANK_CH(*tmp)) tmp++;
5067     if (*tmp != 0)
5068         goto error;
5069
5070     if (URL != NULL) {
5071         ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
5072         xmlFree(URL);
5073     }
5074     return;
5075
5076 error:
5077     xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
5078                   "Catalog PI syntax error: %s\n",
5079                   catalog, NULL);
5080     if (URL != NULL)
5081         xmlFree(URL);
5082 }
5083 #endif
5084
5085 /**
5086  * xmlParsePI:
5087  * @ctxt:  an XML parser context
5088  *
5089  * parse an XML Processing Instruction.
5090  *
5091  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
5092  *
5093  * The processing is transfered to SAX once parsed.
5094  */
5095
5096 void
5097 xmlParsePI(xmlParserCtxtPtr ctxt) {
5098     xmlChar *buf = NULL;
5099     size_t len = 0;
5100     size_t size = XML_PARSER_BUFFER_SIZE;
5101     int cur, l;
5102     const xmlChar *target;
5103     xmlParserInputState state;
5104     int count = 0;
5105
5106     if ((RAW == '<') && (NXT(1) == '?')) {
5107         int inputid = ctxt->input->id;
5108         state = ctxt->instate;
5109         ctxt->instate = XML_PARSER_PI;
5110         /*
5111          * this is a Processing Instruction.
5112          */
5113         SKIP(2);
5114         SHRINK;
5115
5116         /*
5117          * Parse the target name and check for special support like
5118          * namespace.
5119          */
5120         target = xmlParsePITarget(ctxt);
5121         if (target != NULL) {
5122             if ((RAW == '?') && (NXT(1) == '>')) {
5123                 if (inputid != ctxt->input->id) {
5124                     xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5125                                    "PI declaration doesn't start and stop in"
5126                                    " the same entity\n");
5127                 }
5128                 SKIP(2);
5129
5130                 /*
5131                  * SAX: PI detected.
5132                  */
5133                 if ((ctxt->sax) && (!ctxt->disableSAX) &&
5134                     (ctxt->sax->processingInstruction != NULL))
5135                     ctxt->sax->processingInstruction(ctxt->userData,
5136                                                      target, NULL);
5137                 if (ctxt->instate != XML_PARSER_EOF)
5138                     ctxt->instate = state;
5139                 return;
5140             }
5141             buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
5142             if (buf == NULL) {
5143                 xmlErrMemory(ctxt, NULL);
5144                 ctxt->instate = state;
5145                 return;
5146             }
5147             if (SKIP_BLANKS == 0) {
5148                 xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
5149                           "ParsePI: PI %s space expected\n", target);
5150             }
5151             cur = CUR_CHAR(l);
5152             while (IS_CHAR(cur) && /* checked */
5153                    ((cur != '?') || (NXT(1) != '>'))) {
5154                 if (len + 5 >= size) {
5155                     xmlChar *tmp;
5156                     size_t new_size = size * 2;
5157                     tmp = (xmlChar *) xmlRealloc(buf, new_size);
5158                     if (tmp == NULL) {
5159                         xmlErrMemory(ctxt, NULL);
5160                         xmlFree(buf);
5161                         ctxt->instate = state;
5162                         return;
5163                     }
5164                     buf = tmp;
5165                     size = new_size;
5166                 }
5167                 count++;
5168                 if (count > 50) {
5169                     GROW;
5170                     if (ctxt->instate == XML_PARSER_EOF) {
5171                         xmlFree(buf);
5172                         return;
5173                     }
5174                     count = 0;
5175                     if ((len > XML_MAX_TEXT_LENGTH) &&
5176                         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
5177                         xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5178                                           "PI %s too big found", target);
5179                         xmlFree(buf);
5180                         ctxt->instate = state;
5181                         return;
5182                     }
5183                 }
5184                 COPY_BUF(l,buf,len,cur);
5185                 NEXTL(l);
5186                 cur = CUR_CHAR(l);
5187                 if (cur == 0) {
5188                     SHRINK;
5189                     GROW;
5190                     cur = CUR_CHAR(l);
5191                 }
5192             }
5193             if ((len > XML_MAX_TEXT_LENGTH) &&
5194                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
5195                 xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5196                                   "PI %s too big found", target);
5197                 xmlFree(buf);
5198                 ctxt->instate = state;
5199                 return;
5200             }
5201             buf[len] = 0;
5202             if (cur != '?') {
5203                 xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5204                       "ParsePI: PI %s never end ...\n", target);
5205             } else {
5206                 if (inputid != ctxt->input->id) {
5207                     xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5208                                    "PI declaration doesn't start and stop in"
5209                                    " the same entity\n");
5210                 }
5211                 SKIP(2);
5212
5213 #ifdef LIBXML_CATALOG_ENABLED
5214                 if (((state == XML_PARSER_MISC) ||
5215                      (state == XML_PARSER_START)) &&
5216                     (xmlStrEqual(target, XML_CATALOG_PI))) {
5217                     xmlCatalogAllow allow = xmlCatalogGetDefaults();
5218                     if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
5219                         (allow == XML_CATA_ALLOW_ALL))
5220                         xmlParseCatalogPI(ctxt, buf);
5221                 }
5222 #endif
5223
5224
5225                 /*
5226                  * SAX: PI detected.
5227                  */
5228                 if ((ctxt->sax) && (!ctxt->disableSAX) &&
5229                     (ctxt->sax->processingInstruction != NULL))
5230                     ctxt->sax->processingInstruction(ctxt->userData,
5231                                                      target, buf);
5232             }
5233             xmlFree(buf);
5234         } else {
5235             xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
5236         }
5237         if (ctxt->instate != XML_PARSER_EOF)
5238             ctxt->instate = state;
5239     }
5240 }
5241
5242 /**
5243  * xmlParseNotationDecl:
5244  * @ctxt:  an XML parser context
5245  *
5246  * parse a notation declaration
5247  *
5248  * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
5249  *
5250  * Hence there is actually 3 choices:
5251  *     'PUBLIC' S PubidLiteral
5252  *     'PUBLIC' S PubidLiteral S SystemLiteral
5253  * and 'SYSTEM' S SystemLiteral
5254  *
5255  * See the NOTE on xmlParseExternalID().
5256  */
5257
5258 void
5259 xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
5260     const xmlChar *name;
5261     xmlChar *Pubid;
5262     xmlChar *Systemid;
5263
5264     if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5265         int inputid = ctxt->input->id;
5266         SHRINK;
5267         SKIP(10);
5268         if (SKIP_BLANKS == 0) {
5269             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5270                            "Space required after '<!NOTATION'\n");
5271             return;
5272         }
5273
5274         name = xmlParseName(ctxt);
5275         if (name == NULL) {
5276             xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5277             return;
5278         }
5279         if (xmlStrchr(name, ':') != NULL) {
5280             xmlNsErr(ctxt, XML_NS_ERR_COLON,
5281                      "colons are forbidden from notation names '%s'\n",
5282                      name, NULL, NULL);
5283         }
5284         if (SKIP_BLANKS == 0) {
5285             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5286                      "Space required after the NOTATION name'\n");
5287             return;
5288         }
5289
5290         /*
5291          * Parse the IDs.
5292          */
5293         Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
5294         SKIP_BLANKS;
5295
5296         if (RAW == '>') {
5297             if (inputid != ctxt->input->id) {
5298                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5299                                "Notation declaration doesn't start and stop"
5300                                " in the same entity\n");
5301             }
5302             NEXT;
5303             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5304                 (ctxt->sax->notationDecl != NULL))
5305                 ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
5306         } else {
5307             xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5308         }
5309         if (Systemid != NULL) xmlFree(Systemid);
5310         if (Pubid != NULL) xmlFree(Pubid);
5311     }
5312 }
5313
5314 /**
5315  * xmlParseEntityDecl:
5316  * @ctxt:  an XML parser context
5317  *
5318  * parse <!ENTITY declarations
5319  *
5320  * [70] EntityDecl ::= GEDecl | PEDecl
5321  *
5322  * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
5323  *
5324  * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
5325  *
5326  * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
5327  *
5328  * [74] PEDef ::= EntityValue | ExternalID
5329  *
5330  * [76] NDataDecl ::= S 'NDATA' S Name
5331  *
5332  * [ VC: Notation Declared ]
5333  * The Name must match the declared name of a notation.
5334  */
5335
5336 void
5337 xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
5338     const xmlChar *name = NULL;
5339     xmlChar *value = NULL;
5340     xmlChar *URI = NULL, *literal = NULL;
5341     const xmlChar *ndata = NULL;
5342     int isParameter = 0;
5343     xmlChar *orig = NULL;
5344
5345     /* GROW; done in the caller */
5346     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
5347         int inputid = ctxt->input->id;
5348         SHRINK;
5349         SKIP(8);
5350         if (SKIP_BLANKS == 0) {
5351             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5352                            "Space required after '<!ENTITY'\n");
5353         }
5354
5355         if (RAW == '%') {
5356             NEXT;
5357             if (SKIP_BLANKS == 0) {
5358                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5359                                "Space required after '%%'\n");
5360             }
5361             isParameter = 1;
5362         }
5363
5364         name = xmlParseName(ctxt);
5365         if (name == NULL) {
5366             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5367                            "xmlParseEntityDecl: no name\n");
5368             return;
5369         }
5370         if (xmlStrchr(name, ':') != NULL) {
5371             xmlNsErr(ctxt, XML_NS_ERR_COLON,
5372                      "colons are forbidden from entities names '%s'\n",
5373                      name, NULL, NULL);
5374         }
5375         if (SKIP_BLANKS == 0) {
5376             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5377                            "Space required after the entity name\n");
5378         }
5379
5380         ctxt->instate = XML_PARSER_ENTITY_DECL;
5381         /*
5382          * handle the various case of definitions...
5383          */
5384         if (isParameter) {
5385             if ((RAW == '"') || (RAW == '\'')) {
5386                 value = xmlParseEntityValue(ctxt, &orig);
5387                 if (value) {
5388                     if ((ctxt->sax != NULL) &&
5389                         (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5390                         ctxt->sax->entityDecl(ctxt->userData, name,
5391                                     XML_INTERNAL_PARAMETER_ENTITY,
5392                                     NULL, NULL, value);
5393                 }
5394             } else {
5395                 URI = xmlParseExternalID(ctxt, &literal, 1);
5396                 if ((URI == NULL) && (literal == NULL)) {
5397                     xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5398                 }
5399                 if (URI) {
5400                     xmlURIPtr uri;
5401
5402                     uri = xmlParseURI((const char *) URI);
5403                     if (uri == NULL) {
5404                         xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5405                                      "Invalid URI: %s\n", URI);
5406                         /*
5407                          * This really ought to be a well formedness error
5408                          * but the XML Core WG decided otherwise c.f. issue
5409                          * E26 of the XML erratas.
5410                          */
5411                     } else {
5412                         if (uri->fragment != NULL) {
5413                             /*
5414                              * Okay this is foolish to block those but not
5415                              * invalid URIs.
5416                              */
5417                             xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5418                         } else {
5419                             if ((ctxt->sax != NULL) &&
5420                                 (!ctxt->disableSAX) &&
5421                                 (ctxt->sax->entityDecl != NULL))
5422                                 ctxt->sax->entityDecl(ctxt->userData, name,
5423                                             XML_EXTERNAL_PARAMETER_ENTITY,
5424                                             literal, URI, NULL);
5425                         }
5426                         xmlFreeURI(uri);
5427                     }
5428                 }
5429             }
5430         } else {
5431             if ((RAW == '"') || (RAW == '\'')) {
5432                 value = xmlParseEntityValue(ctxt, &orig);
5433                 if ((ctxt->sax != NULL) &&
5434                     (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5435                     ctxt->sax->entityDecl(ctxt->userData, name,
5436                                 XML_INTERNAL_GENERAL_ENTITY,
5437                                 NULL, NULL, value);
5438                 /*
5439                  * For expat compatibility in SAX mode.
5440                  */
5441                 if ((ctxt->myDoc == NULL) ||
5442                     (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
5443                     if (ctxt->myDoc == NULL) {
5444                         ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5445                         if (ctxt->myDoc == NULL) {
5446                             xmlErrMemory(ctxt, "New Doc failed");
5447                             return;
5448                         }
5449                         ctxt->myDoc->properties = XML_DOC_INTERNAL;
5450                     }
5451                     if (ctxt->myDoc->intSubset == NULL)
5452                         ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5453                                             BAD_CAST "fake", NULL, NULL);
5454
5455                     xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
5456                                       NULL, NULL, value);
5457                 }
5458             } else {
5459                 URI = xmlParseExternalID(ctxt, &literal, 1);
5460                 if ((URI == NULL) && (literal == NULL)) {
5461                     xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5462                 }
5463                 if (URI) {
5464                     xmlURIPtr uri;
5465
5466                     uri = xmlParseURI((const char *)URI);
5467                     if (uri == NULL) {
5468                         xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5469                                      "Invalid URI: %s\n", URI);
5470                         /*
5471                          * This really ought to be a well formedness error
5472                          * but the XML Core WG decided otherwise c.f. issue
5473                          * E26 of the XML erratas.
5474                          */
5475                     } else {
5476                         if (uri->fragment != NULL) {
5477                             /*
5478                              * Okay this is foolish to block those but not
5479                              * invalid URIs.
5480                              */
5481                             xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5482                         }
5483                         xmlFreeURI(uri);
5484                     }
5485                 }
5486                 if ((RAW != '>') && (SKIP_BLANKS == 0)) {
5487                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5488                                    "Space required before 'NDATA'\n");
5489                 }
5490                 if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
5491                     SKIP(5);
5492                     if (SKIP_BLANKS == 0) {
5493                         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5494                                        "Space required after 'NDATA'\n");
5495                     }
5496                     ndata = xmlParseName(ctxt);
5497                     if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5498                         (ctxt->sax->unparsedEntityDecl != NULL))
5499                         ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
5500                                     literal, URI, ndata);
5501                 } else {
5502                     if ((ctxt->sax != NULL) &&
5503                         (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5504                         ctxt->sax->entityDecl(ctxt->userData, name,
5505                                     XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5506                                     literal, URI, NULL);
5507                     /*
5508                      * For expat compatibility in SAX mode.
5509                      * assuming the entity repalcement was asked for
5510                      */
5511                     if ((ctxt->replaceEntities != 0) &&
5512                         ((ctxt->myDoc == NULL) ||
5513                         (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
5514                         if (ctxt->myDoc == NULL) {
5515                             ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5516                             if (ctxt->myDoc == NULL) {
5517                                 xmlErrMemory(ctxt, "New Doc failed");
5518                                 return;
5519                             }
5520                             ctxt->myDoc->properties = XML_DOC_INTERNAL;
5521                         }
5522
5523                         if (ctxt->myDoc->intSubset == NULL)
5524                             ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5525                                                 BAD_CAST "fake", NULL, NULL);
5526                         xmlSAX2EntityDecl(ctxt, name,
5527                                           XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5528                                           literal, URI, NULL);
5529                     }
5530                 }
5531             }
5532         }
5533         if (ctxt->instate == XML_PARSER_EOF)
5534             goto done;
5535         SKIP_BLANKS;
5536         if (RAW != '>') {
5537             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
5538                     "xmlParseEntityDecl: entity %s not terminated\n", name);
5539             xmlHaltParser(ctxt);
5540         } else {
5541             if (inputid != ctxt->input->id) {
5542                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5543                                "Entity declaration doesn't start and stop in"
5544                                " the same entity\n");
5545             }
5546             NEXT;
5547         }
5548         if (orig != NULL) {
5549             /*
5550              * Ugly mechanism to save the raw entity value.
5551              */
5552             xmlEntityPtr cur = NULL;
5553
5554             if (isParameter) {
5555                 if ((ctxt->sax != NULL) &&
5556                     (ctxt->sax->getParameterEntity != NULL))
5557                     cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
5558             } else {
5559                 if ((ctxt->sax != NULL) &&
5560                     (ctxt->sax->getEntity != NULL))
5561                     cur = ctxt->sax->getEntity(ctxt->userData, name);
5562                 if ((cur == NULL) && (ctxt->userData==ctxt)) {
5563                     cur = xmlSAX2GetEntity(ctxt, name);
5564                 }
5565             }
5566             if ((cur != NULL) && (cur->orig == NULL)) {
5567                 cur->orig = orig;
5568                 orig = NULL;
5569             }
5570         }
5571
5572 done:
5573         if (value != NULL) xmlFree(value);
5574         if (URI != NULL) xmlFree(URI);
5575         if (literal != NULL) xmlFree(literal);
5576         if (orig != NULL) xmlFree(orig);
5577     }
5578 }
5579
5580 /**
5581  * xmlParseDefaultDecl:
5582  * @ctxt:  an XML parser context
5583  * @value:  Receive a possible fixed default value for the attribute
5584  *
5585  * Parse an attribute default declaration
5586  *
5587  * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
5588  *
5589  * [ VC: Required Attribute ]
5590  * if the default declaration is the keyword #REQUIRED, then the
5591  * attribute must be specified for all elements of the type in the
5592  * attribute-list declaration.
5593  *
5594  * [ VC: Attribute Default Legal ]
5595  * The declared default value must meet the lexical constraints of
5596  * the declared attribute type c.f. xmlValidateAttributeDecl()
5597  *
5598  * [ VC: Fixed Attribute Default ]
5599  * if an attribute has a default value declared with the #FIXED
5600  * keyword, instances of that attribute must match the default value.
5601  *
5602  * [ WFC: No < in Attribute Values ]
5603  * handled in xmlParseAttValue()
5604  *
5605  * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
5606  *          or XML_ATTRIBUTE_FIXED.
5607  */
5608
5609 int
5610 xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
5611     int val;
5612     xmlChar *ret;
5613
5614     *value = NULL;
5615     if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
5616         SKIP(9);
5617         return(XML_ATTRIBUTE_REQUIRED);
5618     }
5619     if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
5620         SKIP(8);
5621         return(XML_ATTRIBUTE_IMPLIED);
5622     }
5623     val = XML_ATTRIBUTE_NONE;
5624     if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
5625         SKIP(6);
5626         val = XML_ATTRIBUTE_FIXED;
5627         if (SKIP_BLANKS == 0) {
5628             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5629                            "Space required after '#FIXED'\n");
5630         }
5631     }
5632     ret = xmlParseAttValue(ctxt);
5633     ctxt->instate = XML_PARSER_DTD;
5634     if (ret == NULL) {
5635         xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
5636                        "Attribute default value declaration error\n");
5637     } else
5638         *value = ret;
5639     return(val);
5640 }
5641
5642 /**
5643  * xmlParseNotationType:
5644  * @ctxt:  an XML parser context
5645  *
5646  * parse an Notation attribute type.
5647  *
5648  * Note: the leading 'NOTATION' S part has already being parsed...
5649  *
5650  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5651  *
5652  * [ VC: Notation Attributes ]
5653  * Values of this type must match one of the notation names included
5654  * in the declaration; all notation names in the declaration must be declared.
5655  *
5656  * Returns: the notation attribute tree built while parsing
5657  */
5658
5659 xmlEnumerationPtr
5660 xmlParseNotationType(xmlParserCtxtPtr ctxt) {
5661     const xmlChar *name;
5662     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5663
5664     if (RAW != '(') {
5665         xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5666         return(NULL);
5667     }
5668     SHRINK;
5669     do {
5670         NEXT;
5671         SKIP_BLANKS;
5672         name = xmlParseName(ctxt);
5673         if (name == NULL) {
5674             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5675                            "Name expected in NOTATION declaration\n");
5676             xmlFreeEnumeration(ret);
5677             return(NULL);
5678         }
5679         tmp = ret;
5680         while (tmp != NULL) {
5681             if (xmlStrEqual(name, tmp->name)) {
5682                 xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5683           "standalone: attribute notation value token %s duplicated\n",
5684                                  name, NULL);
5685                 if (!xmlDictOwns(ctxt->dict, name))
5686                     xmlFree((xmlChar *) name);
5687                 break;
5688             }
5689             tmp = tmp->next;
5690         }
5691         if (tmp == NULL) {
5692             cur = xmlCreateEnumeration(name);
5693             if (cur == NULL) {
5694                 xmlFreeEnumeration(ret);
5695                 return(NULL);
5696             }
5697             if (last == NULL) ret = last = cur;
5698             else {
5699                 last->next = cur;
5700                 last = cur;
5701             }
5702         }
5703         SKIP_BLANKS;
5704     } while (RAW == '|');
5705     if (RAW != ')') {
5706         xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5707         xmlFreeEnumeration(ret);
5708         return(NULL);
5709     }
5710     NEXT;
5711     return(ret);
5712 }
5713
5714 /**
5715  * xmlParseEnumerationType:
5716  * @ctxt:  an XML parser context
5717  *
5718  * parse an Enumeration attribute type.
5719  *
5720  * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
5721  *
5722  * [ VC: Enumeration ]
5723  * Values of this type must match one of the Nmtoken tokens in
5724  * the declaration
5725  *
5726  * Returns: the enumeration attribute tree built while parsing
5727  */
5728
5729 xmlEnumerationPtr
5730 xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
5731     xmlChar *name;
5732     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5733
5734     if (RAW != '(') {
5735         xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
5736         return(NULL);
5737     }
5738     SHRINK;
5739     do {
5740         NEXT;
5741         SKIP_BLANKS;
5742         name = xmlParseNmtoken(ctxt);
5743         if (name == NULL) {
5744             xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
5745             return(ret);
5746         }
5747         tmp = ret;
5748         while (tmp != NULL) {
5749             if (xmlStrEqual(name, tmp->name)) {
5750                 xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5751           "standalone: attribute enumeration value token %s duplicated\n",
5752                                  name, NULL);
5753                 if (!xmlDictOwns(ctxt->dict, name))
5754                     xmlFree(name);
5755                 break;
5756             }
5757             tmp = tmp->next;
5758         }
5759         if (tmp == NULL) {
5760             cur = xmlCreateEnumeration(name);
5761             if (!xmlDictOwns(ctxt->dict, name))
5762                 xmlFree(name);
5763             if (cur == NULL) {
5764                 xmlFreeEnumeration(ret);
5765                 return(NULL);
5766             }
5767             if (last == NULL) ret = last = cur;
5768             else {
5769                 last->next = cur;
5770                 last = cur;
5771             }
5772         }
5773         SKIP_BLANKS;
5774     } while (RAW == '|');
5775     if (RAW != ')') {
5776         xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
5777         return(ret);
5778     }
5779     NEXT;
5780     return(ret);
5781 }
5782
5783 /**
5784  * xmlParseEnumeratedType:
5785  * @ctxt:  an XML parser context
5786  * @tree:  the enumeration tree built while parsing
5787  *
5788  * parse an Enumerated attribute type.
5789  *
5790  * [57] EnumeratedType ::= NotationType | Enumeration
5791  *
5792  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5793  *
5794  *
5795  * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
5796  */
5797
5798 int
5799 xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5800     if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5801         SKIP(8);
5802         if (SKIP_BLANKS == 0) {
5803             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5804                            "Space required after 'NOTATION'\n");
5805             return(0);
5806         }
5807         *tree = xmlParseNotationType(ctxt);
5808         if (*tree == NULL) return(0);
5809         return(XML_ATTRIBUTE_NOTATION);
5810     }
5811     *tree = xmlParseEnumerationType(ctxt);
5812     if (*tree == NULL) return(0);
5813     return(XML_ATTRIBUTE_ENUMERATION);
5814 }
5815
5816 /**
5817  * xmlParseAttributeType:
5818  * @ctxt:  an XML parser context
5819  * @tree:  the enumeration tree built while parsing
5820  *
5821  * parse the Attribute list def for an element
5822  *
5823  * [54] AttType ::= StringType | TokenizedType | EnumeratedType
5824  *
5825  * [55] StringType ::= 'CDATA'
5826  *
5827  * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
5828  *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
5829  *
5830  * Validity constraints for attribute values syntax are checked in
5831  * xmlValidateAttributeValue()
5832  *
5833  * [ VC: ID ]
5834  * Values of type ID must match the Name production. A name must not
5835  * appear more than once in an XML document as a value of this type;
5836  * i.e., ID values must uniquely identify the elements which bear them.
5837  *
5838  * [ VC: One ID per Element Type ]
5839  * No element type may have more than one ID attribute specified.
5840  *
5841  * [ VC: ID Attribute Default ]
5842  * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
5843  *
5844  * [ VC: IDREF ]
5845  * Values of type IDREF must match the Name production, and values
5846  * of type IDREFS must match Names; each IDREF Name must match the value
5847  * of an ID attribute on some element in the XML document; i.e. IDREF
5848  * values must match the value of some ID attribute.
5849  *
5850  * [ VC: Entity Name ]
5851  * Values of type ENTITY must match the Name production, values
5852  * of type ENTITIES must match Names; each Entity Name must match the
5853  * name of an unparsed entity declared in the DTD.
5854  *
5855  * [ VC: Name Token ]
5856  * Values of type NMTOKEN must match the Nmtoken production; values
5857  * of type NMTOKENS must match Nmtokens.
5858  *
5859  * Returns the attribute type
5860  */
5861 int
5862 xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5863     SHRINK;
5864     if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
5865         SKIP(5);
5866         return(XML_ATTRIBUTE_CDATA);
5867      } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
5868         SKIP(6);
5869         return(XML_ATTRIBUTE_IDREFS);
5870      } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
5871         SKIP(5);
5872         return(XML_ATTRIBUTE_IDREF);
5873      } else if ((RAW == 'I') && (NXT(1) == 'D')) {
5874         SKIP(2);
5875         return(XML_ATTRIBUTE_ID);
5876      } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
5877         SKIP(6);
5878         return(XML_ATTRIBUTE_ENTITY);
5879      } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
5880         SKIP(8);
5881         return(XML_ATTRIBUTE_ENTITIES);
5882      } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
5883         SKIP(8);
5884         return(XML_ATTRIBUTE_NMTOKENS);
5885      } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
5886         SKIP(7);
5887         return(XML_ATTRIBUTE_NMTOKEN);
5888      }
5889      return(xmlParseEnumeratedType(ctxt, tree));
5890 }
5891
5892 /**
5893  * xmlParseAttributeListDecl:
5894  * @ctxt:  an XML parser context
5895  *
5896  * : parse the Attribute list def for an element
5897  *
5898  * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
5899  *
5900  * [53] AttDef ::= S Name S AttType S DefaultDecl
5901  *
5902  */
5903 void
5904 xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
5905     const xmlChar *elemName;
5906     const xmlChar *attrName;
5907     xmlEnumerationPtr tree;
5908
5909     if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
5910         int inputid = ctxt->input->id;
5911
5912         SKIP(9);
5913         if (SKIP_BLANKS == 0) {
5914             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5915                                  "Space required after '<!ATTLIST'\n");
5916         }
5917         elemName = xmlParseName(ctxt);
5918         if (elemName == NULL) {
5919             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5920                            "ATTLIST: no name for Element\n");
5921             return;
5922         }
5923         SKIP_BLANKS;
5924         GROW;
5925         while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
5926             int type;
5927             int def;
5928             xmlChar *defaultValue = NULL;
5929
5930             GROW;
5931             tree = NULL;
5932             attrName = xmlParseName(ctxt);
5933             if (attrName == NULL) {
5934                 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5935                                "ATTLIST: no name for Attribute\n");
5936                 break;
5937             }
5938             GROW;
5939             if (SKIP_BLANKS == 0) {
5940                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5941                         "Space required after the attribute name\n");
5942                 break;
5943             }
5944
5945             type = xmlParseAttributeType(ctxt, &tree);
5946             if (type <= 0) {
5947                 break;
5948             }
5949
5950             GROW;
5951             if (SKIP_BLANKS == 0) {
5952                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5953                                "Space required after the attribute type\n");
5954                 if (tree != NULL)
5955                     xmlFreeEnumeration(tree);
5956                 break;
5957             }
5958
5959             def = xmlParseDefaultDecl(ctxt, &defaultValue);
5960             if (def <= 0) {
5961                 if (defaultValue != NULL)
5962                     xmlFree(defaultValue);
5963                 if (tree != NULL)
5964                     xmlFreeEnumeration(tree);
5965                 break;
5966             }
5967             if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
5968                 xmlAttrNormalizeSpace(defaultValue, defaultValue);
5969
5970             GROW;
5971             if (RAW != '>') {
5972                 if (SKIP_BLANKS == 0) {
5973                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5974                         "Space required after the attribute default value\n");
5975                     if (defaultValue != NULL)
5976                         xmlFree(defaultValue);
5977                     if (tree != NULL)
5978                         xmlFreeEnumeration(tree);
5979                     break;
5980                 }
5981             }
5982             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5983                 (ctxt->sax->attributeDecl != NULL))
5984                 ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
5985                                 type, def, defaultValue, tree);
5986             else if (tree != NULL)
5987                 xmlFreeEnumeration(tree);
5988
5989             if ((ctxt->sax2) && (defaultValue != NULL) &&
5990                 (def != XML_ATTRIBUTE_IMPLIED) &&
5991                 (def != XML_ATTRIBUTE_REQUIRED)) {
5992                 xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
5993             }
5994             if (ctxt->sax2) {
5995                 xmlAddSpecialAttr(ctxt, elemName, attrName, type);
5996             }
5997             if (defaultValue != NULL)
5998                 xmlFree(defaultValue);
5999             GROW;
6000         }
6001         if (RAW == '>') {
6002             if (inputid != ctxt->input->id) {
6003                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6004                                "Attribute list declaration doesn't start and"
6005                                " stop in the same entity\n");
6006             }
6007             NEXT;
6008         }
6009     }
6010 }
6011
6012 /**
6013  * xmlParseElementMixedContentDecl:
6014  * @ctxt:  an XML parser context
6015  * @inputchk:  the input used for the current entity, needed for boundary checks
6016  *
6017  * parse the declaration for a Mixed Element content
6018  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6019  *
6020  * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
6021  *                '(' S? '#PCDATA' S? ')'
6022  *
6023  * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
6024  *
6025  * [ VC: No Duplicate Types ]
6026  * The same name must not appear more than once in a single
6027  * mixed-content declaration.
6028  *
6029  * returns: the list of the xmlElementContentPtr describing the element choices
6030  */
6031 xmlElementContentPtr
6032 xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6033     xmlElementContentPtr ret = NULL, cur = NULL, n;
6034     const xmlChar *elem = NULL;
6035
6036     GROW;
6037     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6038         SKIP(7);
6039         SKIP_BLANKS;
6040         SHRINK;
6041         if (RAW == ')') {
6042             if (ctxt->input->id != inputchk) {
6043                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6044                                "Element content declaration doesn't start and"
6045                                " stop in the same entity\n");
6046             }
6047             NEXT;
6048             ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6049             if (ret == NULL)
6050                 return(NULL);
6051             if (RAW == '*') {
6052                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6053                 NEXT;
6054             }
6055             return(ret);
6056         }
6057         if ((RAW == '(') || (RAW == '|')) {
6058             ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6059             if (ret == NULL) return(NULL);
6060         }
6061         while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
6062             NEXT;
6063             if (elem == NULL) {
6064                 ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6065                 if (ret == NULL) return(NULL);
6066                 ret->c1 = cur;
6067                 if (cur != NULL)
6068                     cur->parent = ret;
6069                 cur = ret;
6070             } else {
6071                 n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6072                 if (n == NULL) return(NULL);
6073                 n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6074                 if (n->c1 != NULL)
6075                     n->c1->parent = n;
6076                 cur->c2 = n;
6077                 if (n != NULL)
6078                     n->parent = cur;
6079                 cur = n;
6080             }
6081             SKIP_BLANKS;
6082             elem = xmlParseName(ctxt);
6083             if (elem == NULL) {
6084                 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6085                         "xmlParseElementMixedContentDecl : Name expected\n");
6086                 xmlFreeDocElementContent(ctxt->myDoc, ret);
6087                 return(NULL);
6088             }
6089             SKIP_BLANKS;
6090             GROW;
6091         }
6092         if ((RAW == ')') && (NXT(1) == '*')) {
6093             if (elem != NULL) {
6094                 cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
6095                                                XML_ELEMENT_CONTENT_ELEMENT);
6096                 if (cur->c2 != NULL)
6097                     cur->c2->parent = cur;
6098             }
6099             if (ret != NULL)
6100                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6101             if (ctxt->input->id != inputchk) {
6102                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6103                                "Element content declaration doesn't start and"
6104                                " stop in the same entity\n");
6105             }
6106             SKIP(2);
6107         } else {
6108             xmlFreeDocElementContent(ctxt->myDoc, ret);
6109             xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
6110             return(NULL);
6111         }
6112
6113     } else {
6114         xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
6115     }
6116     return(ret);
6117 }
6118
6119 /**
6120  * xmlParseElementChildrenContentDeclPriv:
6121  * @ctxt:  an XML parser context
6122  * @inputchk:  the input used for the current entity, needed for boundary checks
6123  * @depth: the level of recursion
6124  *
6125  * parse the declaration for a Mixed Element content
6126  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6127  *
6128  *
6129  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6130  *
6131  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6132  *
6133  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6134  *
6135  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6136  *
6137  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6138  * TODO Parameter-entity replacement text must be properly nested
6139  *      with parenthesized groups. That is to say, if either of the
6140  *      opening or closing parentheses in a choice, seq, or Mixed
6141  *      construct is contained in the replacement text for a parameter
6142  *      entity, both must be contained in the same replacement text. For
6143  *      interoperability, if a parameter-entity reference appears in a
6144  *      choice, seq, or Mixed construct, its replacement text should not
6145  *      be empty, and neither the first nor last non-blank character of
6146  *      the replacement text should be a connector (| or ,).
6147  *
6148  * Returns the tree of xmlElementContentPtr describing the element
6149  *          hierarchy.
6150  */
6151 static xmlElementContentPtr
6152 xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
6153                                        int depth) {
6154     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
6155     const xmlChar *elem;
6156     xmlChar type = 0;
6157
6158     if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
6159         (depth >  2048)) {
6160         xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
6161 "xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
6162                           depth);
6163         return(NULL);
6164     }
6165     SKIP_BLANKS;
6166     GROW;
6167     if (RAW == '(') {
6168         int inputid = ctxt->input->id;
6169
6170         /* Recurse on first child */
6171         NEXT;
6172         SKIP_BLANKS;
6173         cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6174                                                            depth + 1);
6175         SKIP_BLANKS;
6176         GROW;
6177     } else {
6178         elem = xmlParseName(ctxt);
6179         if (elem == NULL) {
6180             xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6181             return(NULL);
6182         }
6183         cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6184         if (cur == NULL) {
6185             xmlErrMemory(ctxt, NULL);
6186             return(NULL);
6187         }
6188         GROW;
6189         if (RAW == '?') {
6190             cur->ocur = XML_ELEMENT_CONTENT_OPT;
6191             NEXT;
6192         } else if (RAW == '*') {
6193             cur->ocur = XML_ELEMENT_CONTENT_MULT;
6194             NEXT;
6195         } else if (RAW == '+') {
6196             cur->ocur = XML_ELEMENT_CONTENT_PLUS;
6197             NEXT;
6198         } else {
6199             cur->ocur = XML_ELEMENT_CONTENT_ONCE;
6200         }
6201         GROW;
6202     }
6203     SKIP_BLANKS;
6204     SHRINK;
6205     while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
6206         /*
6207          * Each loop we parse one separator and one element.
6208          */
6209         if (RAW == ',') {
6210             if (type == 0) type = CUR;
6211
6212             /*
6213              * Detect "Name | Name , Name" error
6214              */
6215             else if (type != CUR) {
6216                 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6217                     "xmlParseElementChildrenContentDecl : '%c' expected\n",
6218                                   type);
6219                 if ((last != NULL) && (last != ret))
6220                     xmlFreeDocElementContent(ctxt->myDoc, last);
6221                 if (ret != NULL)
6222                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6223                 return(NULL);
6224             }
6225             NEXT;
6226
6227             op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
6228             if (op == NULL) {
6229                 if ((last != NULL) && (last != ret))
6230                     xmlFreeDocElementContent(ctxt->myDoc, last);
6231                 xmlFreeDocElementContent(ctxt->myDoc, ret);
6232                 return(NULL);
6233             }
6234             if (last == NULL) {
6235                 op->c1 = ret;
6236                 if (ret != NULL)
6237                     ret->parent = op;
6238                 ret = cur = op;
6239             } else {
6240                 cur->c2 = op;
6241                 if (op != NULL)
6242                     op->parent = cur;
6243                 op->c1 = last;
6244                 if (last != NULL)
6245                     last->parent = op;
6246                 cur =op;
6247                 last = NULL;
6248             }
6249         } else if (RAW == '|') {
6250             if (type == 0) type = CUR;
6251
6252             /*
6253              * Detect "Name , Name | Name" error
6254              */
6255             else if (type != CUR) {
6256                 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6257                     "xmlParseElementChildrenContentDecl : '%c' expected\n",
6258                                   type);
6259                 if ((last != NULL) && (last != ret))
6260                     xmlFreeDocElementContent(ctxt->myDoc, last);
6261                 if (ret != NULL)
6262                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6263                 return(NULL);
6264             }
6265             NEXT;
6266
6267             op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6268             if (op == NULL) {
6269                 if ((last != NULL) && (last != ret))
6270                     xmlFreeDocElementContent(ctxt->myDoc, last);
6271                 if (ret != NULL)
6272                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6273                 return(NULL);
6274             }
6275             if (last == NULL) {
6276                 op->c1 = ret;
6277                 if (ret != NULL)
6278                     ret->parent = op;
6279                 ret = cur = op;
6280             } else {
6281                 cur->c2 = op;
6282                 if (op != NULL)
6283                     op->parent = cur;
6284                 op->c1 = last;
6285                 if (last != NULL)
6286                     last->parent = op;
6287                 cur =op;
6288                 last = NULL;
6289             }
6290         } else {
6291             xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
6292             if ((last != NULL) && (last != ret))
6293                 xmlFreeDocElementContent(ctxt->myDoc, last);
6294             if (ret != NULL)
6295                 xmlFreeDocElementContent(ctxt->myDoc, ret);
6296             return(NULL);
6297         }
6298         GROW;
6299         SKIP_BLANKS;
6300         GROW;
6301         if (RAW == '(') {
6302             int inputid = ctxt->input->id;
6303             /* Recurse on second child */
6304             NEXT;
6305             SKIP_BLANKS;
6306             last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6307                                                           depth + 1);
6308             SKIP_BLANKS;
6309         } else {
6310             elem = xmlParseName(ctxt);
6311             if (elem == NULL) {
6312                 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6313                 if (ret != NULL)
6314                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6315                 return(NULL);
6316             }
6317             last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6318             if (last == NULL) {
6319                 if (ret != NULL)
6320                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6321                 return(NULL);
6322             }
6323             if (RAW == '?') {
6324                 last->ocur = XML_ELEMENT_CONTENT_OPT;
6325                 NEXT;
6326             } else if (RAW == '*') {
6327                 last->ocur = XML_ELEMENT_CONTENT_MULT;
6328                 NEXT;
6329             } else if (RAW == '+') {
6330                 last->ocur = XML_ELEMENT_CONTENT_PLUS;
6331                 NEXT;
6332             } else {
6333                 last->ocur = XML_ELEMENT_CONTENT_ONCE;
6334             }
6335         }
6336         SKIP_BLANKS;
6337         GROW;
6338     }
6339     if ((cur != NULL) && (last != NULL)) {
6340         cur->c2 = last;
6341         if (last != NULL)
6342             last->parent = cur;
6343     }
6344     if (ctxt->input->id != inputchk) {
6345         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6346                        "Element content declaration doesn't start and stop in"
6347                        " the same entity\n");
6348     }
6349     NEXT;
6350     if (RAW == '?') {
6351         if (ret != NULL) {
6352             if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
6353                 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6354                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6355             else
6356                 ret->ocur = XML_ELEMENT_CONTENT_OPT;
6357         }
6358         NEXT;
6359     } else if (RAW == '*') {
6360         if (ret != NULL) {
6361             ret->ocur = XML_ELEMENT_CONTENT_MULT;
6362             cur = ret;
6363             /*
6364              * Some normalization:
6365              * (a | b* | c?)* == (a | b | c)*
6366              */
6367             while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6368                 if ((cur->c1 != NULL) &&
6369                     ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6370                      (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
6371                     cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6372                 if ((cur->c2 != NULL) &&
6373                     ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6374                      (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
6375                     cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6376                 cur = cur->c2;
6377             }
6378         }
6379         NEXT;
6380     } else if (RAW == '+') {
6381         if (ret != NULL) {
6382             int found = 0;
6383
6384             if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
6385                 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6386                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6387             else
6388                 ret->ocur = XML_ELEMENT_CONTENT_PLUS;
6389             /*
6390              * Some normalization:
6391              * (a | b*)+ == (a | b)*
6392              * (a | b?)+ == (a | b)*
6393              */
6394             while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6395                 if ((cur->c1 != NULL) &&
6396                     ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6397                      (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
6398                     cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6399                     found = 1;
6400                 }
6401                 if ((cur->c2 != NULL) &&
6402                     ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6403                      (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
6404                     cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6405                     found = 1;
6406                 }
6407                 cur = cur->c2;
6408             }
6409             if (found)
6410                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6411         }
6412         NEXT;
6413     }
6414     return(ret);
6415 }
6416
6417 /**
6418  * xmlParseElementChildrenContentDecl:
6419  * @ctxt:  an XML parser context
6420  * @inputchk:  the input used for the current entity, needed for boundary checks
6421  *
6422  * parse the declaration for a Mixed Element content
6423  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6424  *
6425  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6426  *
6427  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6428  *
6429  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6430  *
6431  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6432  *
6433  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6434  * TODO Parameter-entity replacement text must be properly nested
6435  *      with parenthesized groups. That is to say, if either of the
6436  *      opening or closing parentheses in a choice, seq, or Mixed
6437  *      construct is contained in the replacement text for a parameter
6438  *      entity, both must be contained in the same replacement text. For
6439  *      interoperability, if a parameter-entity reference appears in a
6440  *      choice, seq, or Mixed construct, its replacement text should not
6441  *      be empty, and neither the first nor last non-blank character of
6442  *      the replacement text should be a connector (| or ,).
6443  *
6444  * Returns the tree of xmlElementContentPtr describing the element
6445  *          hierarchy.
6446  */
6447 xmlElementContentPtr
6448 xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6449     /* stub left for API/ABI compat */
6450     return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
6451 }
6452
6453 /**
6454  * xmlParseElementContentDecl:
6455  * @ctxt:  an XML parser context
6456  * @name:  the name of the element being defined.
6457  * @result:  the Element Content pointer will be stored here if any
6458  *
6459  * parse the declaration for an Element content either Mixed or Children,
6460  * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
6461  *
6462  * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
6463  *
6464  * returns: the type of element content XML_ELEMENT_TYPE_xxx
6465  */
6466
6467 int
6468 xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
6469                            xmlElementContentPtr *result) {
6470
6471     xmlElementContentPtr tree = NULL;
6472     int inputid = ctxt->input->id;
6473     int res;
6474
6475     *result = NULL;
6476
6477     if (RAW != '(') {
6478         xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6479                 "xmlParseElementContentDecl : %s '(' expected\n", name);
6480         return(-1);
6481     }
6482     NEXT;
6483     GROW;
6484     if (ctxt->instate == XML_PARSER_EOF)
6485         return(-1);
6486     SKIP_BLANKS;
6487     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6488         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
6489         res = XML_ELEMENT_TYPE_MIXED;
6490     } else {
6491         tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
6492         res = XML_ELEMENT_TYPE_ELEMENT;
6493     }
6494     SKIP_BLANKS;
6495     *result = tree;
6496     return(res);
6497 }
6498
6499 /**
6500  * xmlParseElementDecl:
6501  * @ctxt:  an XML parser context
6502  *
6503  * parse an Element declaration.
6504  *
6505  * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
6506  *
6507  * [ VC: Unique Element Type Declaration ]
6508  * No element type may be declared more than once
6509  *
6510  * Returns the type of the element, or -1 in case of error
6511  */
6512 int
6513 xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
6514     const xmlChar *name;
6515     int ret = -1;
6516     xmlElementContentPtr content  = NULL;
6517
6518     /* GROW; done in the caller */
6519     if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
6520         int inputid = ctxt->input->id;
6521
6522         SKIP(9);
6523         if (SKIP_BLANKS == 0) {
6524             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6525                            "Space required after 'ELEMENT'\n");
6526             return(-1);
6527         }
6528         name = xmlParseName(ctxt);
6529         if (name == NULL) {
6530             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6531                            "xmlParseElementDecl: no name for Element\n");
6532             return(-1);
6533         }
6534         if (SKIP_BLANKS == 0) {
6535             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6536                            "Space required after the element name\n");
6537         }
6538         if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
6539             SKIP(5);
6540             /*
6541              * Element must always be empty.
6542              */
6543             ret = XML_ELEMENT_TYPE_EMPTY;
6544         } else if ((RAW == 'A') && (NXT(1) == 'N') &&
6545                    (NXT(2) == 'Y')) {
6546             SKIP(3);
6547             /*
6548              * Element is a generic container.
6549              */
6550             ret = XML_ELEMENT_TYPE_ANY;
6551         } else if (RAW == '(') {
6552             ret = xmlParseElementContentDecl(ctxt, name, &content);
6553         } else {
6554             /*
6555              * [ WFC: PEs in Internal Subset ] error handling.
6556              */
6557             if ((RAW == '%') && (ctxt->external == 0) &&
6558                 (ctxt->inputNr == 1)) {
6559                 xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
6560           "PEReference: forbidden within markup decl in internal subset\n");
6561             } else {
6562                 xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6563                       "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
6564             }
6565             return(-1);
6566         }
6567
6568         SKIP_BLANKS;
6569
6570         if (RAW != '>') {
6571             xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
6572             if (content != NULL) {
6573                 xmlFreeDocElementContent(ctxt->myDoc, content);
6574             }
6575         } else {
6576             if (inputid != ctxt->input->id) {
6577                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6578                                "Element declaration doesn't start and stop in"
6579                                " the same entity\n");
6580             }
6581
6582             NEXT;
6583             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6584                 (ctxt->sax->elementDecl != NULL)) {
6585                 if (content != NULL)
6586                     content->parent = NULL;
6587                 ctxt->sax->elementDecl(ctxt->userData, name, ret,
6588                                        content);
6589                 if ((content != NULL) && (content->parent == NULL)) {
6590                     /*
6591                      * this is a trick: if xmlAddElementDecl is called,
6592                      * instead of copying the full tree it is plugged directly
6593                      * if called from the parser. Avoid duplicating the
6594                      * interfaces or change the API/ABI
6595                      */
6596                     xmlFreeDocElementContent(ctxt->myDoc, content);
6597                 }
6598             } else if (content != NULL) {
6599                 xmlFreeDocElementContent(ctxt->myDoc, content);
6600             }
6601         }
6602     }
6603     return(ret);
6604 }
6605
6606 /**
6607  * xmlParseConditionalSections
6608  * @ctxt:  an XML parser context
6609  *
6610  * [61] conditionalSect ::= includeSect | ignoreSect
6611  * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
6612  * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
6613  * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
6614  * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
6615  */
6616
6617 static void
6618 xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
6619     int id = ctxt->input->id;
6620
6621     SKIP(3);
6622     SKIP_BLANKS;
6623     if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
6624         SKIP(7);
6625         SKIP_BLANKS;
6626         if (RAW != '[') {
6627             xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6628             xmlHaltParser(ctxt);
6629             return;
6630         } else {
6631             if (ctxt->input->id != id) {
6632                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6633                                "All markup of the conditional section is not"
6634                                " in the same entity\n");
6635             }
6636             NEXT;
6637         }
6638         if (xmlParserDebugEntities) {
6639             if ((ctxt->input != NULL) && (ctxt->input->filename))
6640                 xmlGenericError(xmlGenericErrorContext,
6641                         "%s(%d): ", ctxt->input->filename,
6642                         ctxt->input->line);
6643             xmlGenericError(xmlGenericErrorContext,
6644                     "Entering INCLUDE Conditional Section\n");
6645         }
6646
6647         SKIP_BLANKS;
6648         GROW;
6649         while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
6650                 (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
6651             const xmlChar *check = CUR_PTR;
6652             unsigned int cons = ctxt->input->consumed;
6653
6654             if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6655                 xmlParseConditionalSections(ctxt);
6656             } else
6657                 xmlParseMarkupDecl(ctxt);
6658
6659             SKIP_BLANKS;
6660             GROW;
6661
6662             if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
6663                 xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6664                 xmlHaltParser(ctxt);
6665                 break;
6666             }
6667         }
6668         if (xmlParserDebugEntities) {
6669             if ((ctxt->input != NULL) && (ctxt->input->filename))
6670                 xmlGenericError(xmlGenericErrorContext,
6671                         "%s(%d): ", ctxt->input->filename,
6672                         ctxt->input->line);
6673             xmlGenericError(xmlGenericErrorContext,
6674                     "Leaving INCLUDE Conditional Section\n");
6675         }
6676
6677     } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
6678         int state;
6679         xmlParserInputState instate;
6680         int depth = 0;
6681
6682         SKIP(6);
6683         SKIP_BLANKS;
6684         if (RAW != '[') {
6685             xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6686             xmlHaltParser(ctxt);
6687             return;
6688         } else {
6689             if (ctxt->input->id != id) {
6690                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6691                                "All markup of the conditional section is not"
6692                                " in the same entity\n");
6693             }
6694             NEXT;
6695         }
6696         if (xmlParserDebugEntities) {
6697             if ((ctxt->input != NULL) && (ctxt->input->filename))
6698                 xmlGenericError(xmlGenericErrorContext,
6699                         "%s(%d): ", ctxt->input->filename,
6700                         ctxt->input->line);
6701             xmlGenericError(xmlGenericErrorContext,
6702                     "Entering IGNORE Conditional Section\n");
6703         }
6704
6705         /*
6706          * Parse up to the end of the conditional section
6707          * But disable SAX event generating DTD building in the meantime
6708          */
6709         state = ctxt->disableSAX;
6710         instate = ctxt->instate;
6711         if (ctxt->recovery == 0) ctxt->disableSAX = 1;
6712         ctxt->instate = XML_PARSER_IGNORE;
6713
6714         while (((depth >= 0) && (RAW != 0)) &&
6715                (ctxt->instate != XML_PARSER_EOF)) {
6716           if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6717             depth++;
6718             SKIP(3);
6719             continue;
6720           }
6721           if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
6722             if (--depth >= 0) SKIP(3);
6723             continue;
6724           }
6725           NEXT;
6726           continue;
6727         }
6728
6729         ctxt->disableSAX = state;
6730         ctxt->instate = instate;
6731
6732         if (xmlParserDebugEntities) {
6733             if ((ctxt->input != NULL) && (ctxt->input->filename))
6734                 xmlGenericError(xmlGenericErrorContext,
6735                         "%s(%d): ", ctxt->input->filename,
6736                         ctxt->input->line);
6737             xmlGenericError(xmlGenericErrorContext,
6738                     "Leaving IGNORE Conditional Section\n");
6739         }
6740
6741     } else {
6742         xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
6743         xmlHaltParser(ctxt);
6744         return;
6745     }
6746
6747     if (RAW == 0)
6748         SHRINK;
6749
6750     if (RAW == 0) {
6751         xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
6752     } else {
6753         if (ctxt->input->id != id) {
6754             xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6755                            "All markup of the conditional section is not in"
6756                            " the same entity\n");
6757         }
6758         if ((ctxt-> instate != XML_PARSER_EOF) &&
6759             ((ctxt->input->cur + 3) <= ctxt->input->end))
6760             SKIP(3);
6761     }
6762 }
6763
6764 /**
6765  * xmlParseMarkupDecl:
6766  * @ctxt:  an XML parser context
6767  *
6768  * parse Markup declarations
6769  *
6770  * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
6771  *                     NotationDecl | PI | Comment
6772  *
6773  * [ VC: Proper Declaration/PE Nesting ]
6774  * Parameter-entity replacement text must be properly nested with
6775  * markup declarations. That is to say, if either the first character
6776  * or the last character of a markup declaration (markupdecl above) is
6777  * contained in the replacement text for a parameter-entity reference,
6778  * both must be contained in the same replacement text.
6779  *
6780  * [ WFC: PEs in Internal Subset ]
6781  * In the internal DTD subset, parameter-entity references can occur
6782  * only where markup declarations can occur, not within markup declarations.
6783  * (This does not apply to references that occur in external parameter
6784  * entities or to the external subset.)
6785  */
6786 void
6787 xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
6788     GROW;
6789     if (CUR == '<') {
6790         if (NXT(1) == '!') {
6791             switch (NXT(2)) {
6792                 case 'E':
6793                     if (NXT(3) == 'L')
6794                         xmlParseElementDecl(ctxt);
6795                     else if (NXT(3) == 'N')
6796                         xmlParseEntityDecl(ctxt);
6797                     break;
6798                 case 'A':
6799                     xmlParseAttributeListDecl(ctxt);
6800                     break;
6801                 case 'N':
6802                     xmlParseNotationDecl(ctxt);
6803                     break;
6804                 case '-':
6805                     xmlParseComment(ctxt);
6806                     break;
6807                 default:
6808                     /* there is an error but it will be detected later */
6809                     break;
6810             }
6811         } else if (NXT(1) == '?') {
6812             xmlParsePI(ctxt);
6813         }
6814     }
6815
6816     /*
6817      * detect requirement to exit there and act accordingly
6818      * and avoid having instate overriden later on
6819      */
6820     if (ctxt->instate == XML_PARSER_EOF)
6821         return;
6822
6823     /*
6824      * Conditional sections are allowed from entities included
6825      * by PE References in the internal subset.
6826      */
6827     if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
6828         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6829             xmlParseConditionalSections(ctxt);
6830         }
6831     }
6832
6833     ctxt->instate = XML_PARSER_DTD;
6834 }
6835
6836 /**
6837  * xmlParseTextDecl:
6838  * @ctxt:  an XML parser context
6839  *
6840  * parse an XML declaration header for external entities
6841  *
6842  * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
6843  */
6844
6845 void
6846 xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
6847     xmlChar *version;
6848     const xmlChar *encoding;
6849
6850     /*
6851      * We know that '<?xml' is here.
6852      */
6853     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
6854         SKIP(5);
6855     } else {
6856         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
6857         return;
6858     }
6859
6860     if (SKIP_BLANKS == 0) {
6861         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6862                        "Space needed after '<?xml'\n");
6863     }
6864
6865     /*
6866      * We may have the VersionInfo here.
6867      */
6868     version = xmlParseVersionInfo(ctxt);
6869     if (version == NULL)
6870         version = xmlCharStrdup(XML_DEFAULT_VERSION);
6871     else {
6872         if (SKIP_BLANKS == 0) {
6873             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6874                            "Space needed here\n");
6875         }
6876     }
6877     ctxt->input->version = version;
6878
6879     /*
6880      * We must have the encoding declaration
6881      */
6882     encoding = xmlParseEncodingDecl(ctxt);
6883     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
6884         /*
6885          * The XML REC instructs us to stop parsing right here
6886          */
6887         return;
6888     }
6889     if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
6890         xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
6891                        "Missing encoding in text declaration\n");
6892     }
6893
6894     SKIP_BLANKS;
6895     if ((RAW == '?') && (NXT(1) == '>')) {
6896         SKIP(2);
6897     } else if (RAW == '>') {
6898         /* Deprecated old WD ... */
6899         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
6900         NEXT;
6901     } else {
6902         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
6903         MOVETO_ENDTAG(CUR_PTR);
6904         NEXT;
6905     }
6906 }
6907
6908 /**
6909  * xmlParseExternalSubset:
6910  * @ctxt:  an XML parser context
6911  * @ExternalID: the external identifier
6912  * @SystemID: the system identifier (or URL)
6913  *
6914  * parse Markup declarations from an external subset
6915  *
6916  * [30] extSubset ::= textDecl? extSubsetDecl
6917  *
6918  * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
6919  */
6920 void
6921 xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
6922                        const xmlChar *SystemID) {
6923     xmlDetectSAX2(ctxt);
6924     GROW;
6925
6926     if ((ctxt->encoding == NULL) &&
6927         (ctxt->input->end - ctxt->input->cur >= 4)) {
6928         xmlChar start[4];
6929         xmlCharEncoding enc;
6930
6931         start[0] = RAW;
6932         start[1] = NXT(1);
6933         start[2] = NXT(2);
6934         start[3] = NXT(3);
6935         enc = xmlDetectCharEncoding(start, 4);
6936         if (enc != XML_CHAR_ENCODING_NONE)
6937             xmlSwitchEncoding(ctxt, enc);
6938     }
6939
6940     if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
6941         xmlParseTextDecl(ctxt);
6942         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
6943             /*
6944              * The XML REC instructs us to stop parsing right here
6945              */
6946             xmlHaltParser(ctxt);
6947             return;
6948         }
6949     }
6950     if (ctxt->myDoc == NULL) {
6951         ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
6952         if (ctxt->myDoc == NULL) {
6953             xmlErrMemory(ctxt, "New Doc failed");
6954             return;
6955         }
6956         ctxt->myDoc->properties = XML_DOC_INTERNAL;
6957     }
6958     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
6959         xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
6960
6961     ctxt->instate = XML_PARSER_DTD;
6962     ctxt->external = 1;
6963     SKIP_BLANKS;
6964     while (((RAW == '<') && (NXT(1) == '?')) ||
6965            ((RAW == '<') && (NXT(1) == '!')) ||
6966            (RAW == '%')) {
6967         const xmlChar *check = CUR_PTR;
6968         unsigned int cons = ctxt->input->consumed;
6969
6970         GROW;
6971         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6972             xmlParseConditionalSections(ctxt);
6973         } else
6974             xmlParseMarkupDecl(ctxt);
6975         SKIP_BLANKS;
6976
6977         if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
6978             xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6979             break;
6980         }
6981     }
6982
6983     if (RAW != 0) {
6984         xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6985     }
6986
6987 }
6988
6989 /**
6990  * xmlParseReference:
6991  * @ctxt:  an XML parser context
6992  *
6993  * parse and handle entity references in content, depending on the SAX
6994  * interface, this may end-up in a call to character() if this is a
6995  * CharRef, a predefined entity, if there is no reference() callback.
6996  * or if the parser was asked to switch to that mode.
6997  *
6998  * [67] Reference ::= EntityRef | CharRef
6999  */
7000 void
7001 xmlParseReference(xmlParserCtxtPtr ctxt) {
7002     xmlEntityPtr ent;
7003     xmlChar *val;
7004     int was_checked;
7005     xmlNodePtr list = NULL;
7006     xmlParserErrors ret = XML_ERR_OK;
7007
7008
7009     if (RAW != '&')
7010         return;
7011
7012     /*
7013      * Simple case of a CharRef
7014      */
7015     if (NXT(1) == '#') {
7016         int i = 0;
7017         xmlChar out[10];
7018         int hex = NXT(2);
7019         int value = xmlParseCharRef(ctxt);
7020
7021         if (value == 0)
7022             return;
7023         if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
7024             /*
7025              * So we are using non-UTF-8 buffers
7026              * Check that the char fit on 8bits, if not
7027              * generate a CharRef.
7028              */
7029             if (value <= 0xFF) {
7030                 out[0] = value;
7031                 out[1] = 0;
7032                 if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7033                     (!ctxt->disableSAX))
7034                     ctxt->sax->characters(ctxt->userData, out, 1);
7035             } else {
7036                 if ((hex == 'x') || (hex == 'X'))
7037                     snprintf((char *)out, sizeof(out), "#x%X", value);
7038                 else
7039                     snprintf((char *)out, sizeof(out), "#%d", value);
7040                 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7041                     (!ctxt->disableSAX))
7042                     ctxt->sax->reference(ctxt->userData, out);
7043             }
7044         } else {
7045             /*
7046              * Just encode the value in UTF-8
7047              */
7048             COPY_BUF(0 ,out, i, value);
7049             out[i] = 0;
7050             if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7051                 (!ctxt->disableSAX))
7052                 ctxt->sax->characters(ctxt->userData, out, i);
7053         }
7054         return;
7055     }
7056
7057     /*
7058      * We are seeing an entity reference
7059      */
7060     ent = xmlParseEntityRef(ctxt);
7061     if (ent == NULL) return;
7062     if (!ctxt->wellFormed)
7063         return;
7064     was_checked = ent->checked;
7065
7066     /* special case of predefined entities */
7067     if ((ent->name == NULL) ||
7068         (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
7069         val = ent->content;
7070         if (val == NULL) return;
7071         /*
7072          * inline the entity.
7073          */
7074         if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7075             (!ctxt->disableSAX))
7076             ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
7077         return;
7078     }
7079
7080     /*
7081      * The first reference to the entity trigger a parsing phase
7082      * where the ent->children is filled with the result from
7083      * the parsing.
7084      * Note: external parsed entities will not be loaded, it is not
7085      * required for a non-validating parser, unless the parsing option
7086      * of validating, or substituting entities were given. Doing so is
7087      * far more secure as the parser will only process data coming from
7088      * the document entity by default.
7089      */
7090     if (((ent->checked == 0) ||
7091          ((ent->children == NULL) && (ctxt->options & XML_PARSE_NOENT))) &&
7092         ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
7093          (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
7094         unsigned long oldnbent = ctxt->nbentities;
7095
7096         /*
7097          * This is a bit hackish but this seems the best
7098          * way to make sure both SAX and DOM entity support
7099          * behaves okay.
7100          */
7101         void *user_data;
7102         if (ctxt->userData == ctxt)
7103             user_data = NULL;
7104         else
7105             user_data = ctxt->userData;
7106
7107         /*
7108          * Check that this entity is well formed
7109          * 4.3.2: An internal general parsed entity is well-formed
7110          * if its replacement text matches the production labeled
7111          * content.
7112          */
7113         if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7114             ctxt->depth++;
7115             ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
7116                                                       user_data, &list);
7117             ctxt->depth--;
7118
7119         } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7120             ctxt->depth++;
7121             ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
7122                                            user_data, ctxt->depth, ent->URI,
7123                                            ent->ExternalID, &list);
7124             ctxt->depth--;
7125         } else {
7126             ret = XML_ERR_ENTITY_PE_INTERNAL;
7127             xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7128                          "invalid entity type found\n", NULL);
7129         }
7130
7131         /*
7132          * Store the number of entities needing parsing for this entity
7133          * content and do checkings
7134          */
7135         ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
7136         if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
7137             ent->checked |= 1;
7138         if (ret == XML_ERR_ENTITY_LOOP) {
7139             xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7140             xmlFreeNodeList(list);
7141             return;
7142         }
7143         if (xmlParserEntityCheck(ctxt, 0, ent, 0)) {
7144             xmlFreeNodeList(list);
7145             return;
7146         }
7147
7148         if ((ret == XML_ERR_OK) && (list != NULL)) {
7149             if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
7150              (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
7151                 (ent->children == NULL)) {
7152                 ent->children = list;
7153                 if (ctxt->replaceEntities) {
7154                     /*
7155                      * Prune it directly in the generated document
7156                      * except for single text nodes.
7157                      */
7158                     if (((list->type == XML_TEXT_NODE) &&
7159                          (list->next == NULL)) ||
7160                         (ctxt->parseMode == XML_PARSE_READER)) {
7161                         list->parent = (xmlNodePtr) ent;
7162                         list = NULL;
7163                         ent->owner = 1;
7164                     } else {
7165                         ent->owner = 0;
7166                         while (list != NULL) {
7167                             list->parent = (xmlNodePtr) ctxt->node;
7168                             list->doc = ctxt->myDoc;
7169                             if (list->next == NULL)
7170                                 ent->last = list;
7171                             list = list->next;
7172                         }
7173                         list = ent->children;
7174 #ifdef LIBXML_LEGACY_ENABLED
7175                         if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7176                           xmlAddEntityReference(ent, list, NULL);
7177 #endif /* LIBXML_LEGACY_ENABLED */
7178                     }
7179                 } else {
7180                     ent->owner = 1;
7181                     while (list != NULL) {
7182                         list->parent = (xmlNodePtr) ent;
7183                         xmlSetTreeDoc(list, ent->doc);
7184                         if (list->next == NULL)
7185                             ent->last = list;
7186                         list = list->next;
7187                     }
7188                 }
7189             } else {
7190                 xmlFreeNodeList(list);
7191                 list = NULL;
7192             }
7193         } else if ((ret != XML_ERR_OK) &&
7194                    (ret != XML_WAR_UNDECLARED_ENTITY)) {
7195             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7196                      "Entity '%s' failed to parse\n", ent->name);
7197             xmlParserEntityCheck(ctxt, 0, ent, 0);
7198         } else if (list != NULL) {
7199             xmlFreeNodeList(list);
7200             list = NULL;
7201         }
7202         if (ent->checked == 0)
7203             ent->checked = 2;
7204
7205         /* Prevent entity from being parsed and expanded twice (Bug 760367). */
7206         was_checked = 0;
7207     } else if (ent->checked != 1) {
7208         ctxt->nbentities += ent->checked / 2;
7209     }
7210
7211     /*
7212      * Now that the entity content has been gathered
7213      * provide it to the application, this can take different forms based
7214      * on the parsing modes.
7215      */
7216     if (ent->children == NULL) {
7217         /*
7218          * Probably running in SAX mode and the callbacks don't
7219          * build the entity content. So unless we already went
7220          * though parsing for first checking go though the entity
7221          * content to generate callbacks associated to the entity
7222          */
7223         if (was_checked != 0) {
7224             void *user_data;
7225             /*
7226              * This is a bit hackish but this seems the best
7227              * way to make sure both SAX and DOM entity support
7228              * behaves okay.
7229              */
7230             if (ctxt->userData == ctxt)
7231                 user_data = NULL;
7232             else
7233                 user_data = ctxt->userData;
7234
7235             if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7236                 ctxt->depth++;
7237                 ret = xmlParseBalancedChunkMemoryInternal(ctxt,
7238                                    ent->content, user_data, NULL);
7239                 ctxt->depth--;
7240             } else if (ent->etype ==
7241                        XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7242                 ctxt->depth++;
7243                 ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
7244                            ctxt->sax, user_data, ctxt->depth,
7245                            ent->URI, ent->ExternalID, NULL);
7246                 ctxt->depth--;
7247             } else {
7248                 ret = XML_ERR_ENTITY_PE_INTERNAL;
7249                 xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7250                              "invalid entity type found\n", NULL);
7251             }
7252             if (ret == XML_ERR_ENTITY_LOOP) {
7253                 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7254                 return;
7255             }
7256         }
7257         if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7258             (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7259             /*
7260              * Entity reference callback comes second, it's somewhat
7261              * superfluous but a compatibility to historical behaviour
7262              */
7263             ctxt->sax->reference(ctxt->userData, ent->name);
7264         }
7265         return;
7266     }
7267
7268     /*
7269      * If we didn't get any children for the entity being built
7270      */
7271     if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7272         (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7273         /*
7274          * Create a node.
7275          */
7276         ctxt->sax->reference(ctxt->userData, ent->name);
7277         return;
7278     }
7279
7280     if ((ctxt->replaceEntities) || (ent->children == NULL))  {
7281         /*
7282          * There is a problem on the handling of _private for entities
7283          * (bug 155816): Should we copy the content of the field from
7284          * the entity (possibly overwriting some value set by the user
7285          * when a copy is created), should we leave it alone, or should
7286          * we try to take care of different situations?  The problem
7287          * is exacerbated by the usage of this field by the xmlReader.
7288          * To fix this bug, we look at _private on the created node
7289          * and, if it's NULL, we copy in whatever was in the entity.
7290          * If it's not NULL we leave it alone.  This is somewhat of a
7291          * hack - maybe we should have further tests to determine
7292          * what to do.
7293          */
7294         if ((ctxt->node != NULL) && (ent->children != NULL)) {
7295             /*
7296              * Seems we are generating the DOM content, do
7297              * a simple tree copy for all references except the first
7298              * In the first occurrence list contains the replacement.
7299              */
7300             if (((list == NULL) && (ent->owner == 0)) ||
7301                 (ctxt->parseMode == XML_PARSE_READER)) {
7302                 xmlNodePtr nw = NULL, cur, firstChild = NULL;
7303
7304                 /*
7305                  * We are copying here, make sure there is no abuse
7306                  */
7307                 ctxt->sizeentcopy += ent->length + 5;
7308                 if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
7309                     return;
7310
7311                 /*
7312                  * when operating on a reader, the entities definitions
7313                  * are always owning the entities subtree.
7314                 if (ctxt->parseMode == XML_PARSE_READER)
7315                     ent->owner = 1;
7316                  */
7317
7318                 cur = ent->children;
7319                 while (cur != NULL) {
7320                     nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7321                     if (nw != NULL) {
7322                         if (nw->_private == NULL)
7323                             nw->_private = cur->_private;
7324                         if (firstChild == NULL){
7325                             firstChild = nw;
7326                         }
7327                         nw = xmlAddChild(ctxt->node, nw);
7328                     }
7329                     if (cur == ent->last) {
7330                         /*
7331                          * needed to detect some strange empty
7332                          * node cases in the reader tests
7333                          */
7334                         if ((ctxt->parseMode == XML_PARSE_READER) &&
7335                             (nw != NULL) &&
7336                             (nw->type == XML_ELEMENT_NODE) &&
7337                             (nw->children == NULL))
7338                             nw->extra = 1;
7339
7340                         break;
7341                     }
7342                     cur = cur->next;
7343                 }
7344 #ifdef LIBXML_LEGACY_ENABLED
7345                 if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7346                   xmlAddEntityReference(ent, firstChild, nw);
7347 #endif /* LIBXML_LEGACY_ENABLED */
7348             } else if ((list == NULL) || (ctxt->inputNr > 0)) {
7349                 xmlNodePtr nw = NULL, cur, next, last,
7350                            firstChild = NULL;
7351
7352                 /*
7353                  * We are copying here, make sure there is no abuse
7354                  */
7355                 ctxt->sizeentcopy += ent->length + 5;
7356                 if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
7357                     return;
7358
7359                 /*
7360                  * Copy the entity child list and make it the new
7361                  * entity child list. The goal is to make sure any
7362                  * ID or REF referenced will be the one from the
7363                  * document content and not the entity copy.
7364                  */
7365                 cur = ent->children;
7366                 ent->children = NULL;
7367                 last = ent->last;
7368                 ent->last = NULL;
7369                 while (cur != NULL) {
7370                     next = cur->next;
7371                     cur->next = NULL;
7372                     cur->parent = NULL;
7373                     nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7374                     if (nw != NULL) {
7375                         if (nw->_private == NULL)
7376                             nw->_private = cur->_private;
7377                         if (firstChild == NULL){
7378                             firstChild = cur;
7379                         }
7380                         xmlAddChild((xmlNodePtr) ent, nw);
7381                         xmlAddChild(ctxt->node, cur);
7382                     }
7383                     if (cur == last)
7384                         break;
7385                     cur = next;
7386                 }
7387                 if (ent->owner == 0)
7388                     ent->owner = 1;
7389 #ifdef LIBXML_LEGACY_ENABLED
7390                 if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7391                   xmlAddEntityReference(ent, firstChild, nw);
7392 #endif /* LIBXML_LEGACY_ENABLED */
7393             } else {
7394                 const xmlChar *nbktext;
7395
7396                 /*
7397                  * the name change is to avoid coalescing of the
7398                  * node with a possible previous text one which
7399                  * would make ent->children a dangling pointer
7400                  */
7401                 nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
7402                                         -1);
7403                 if (ent->children->type == XML_TEXT_NODE)
7404                     ent->children->name = nbktext;
7405                 if ((ent->last != ent->children) &&
7406                     (ent->last->type == XML_TEXT_NODE))
7407                     ent->last->name = nbktext;
7408                 xmlAddChildList(ctxt->node, ent->children);
7409             }
7410
7411             /*
7412              * This is to avoid a nasty side effect, see
7413              * characters() in SAX.c
7414              */
7415             ctxt->nodemem = 0;
7416             ctxt->nodelen = 0;
7417             return;
7418         }
7419     }
7420 }
7421
7422 /**
7423  * xmlParseEntityRef:
7424  * @ctxt:  an XML parser context
7425  *
7426  * parse ENTITY references declarations
7427  *
7428  * [68] EntityRef ::= '&' Name ';'
7429  *
7430  * [ WFC: Entity Declared ]
7431  * In a document without any DTD, a document with only an internal DTD
7432  * subset which contains no parameter entity references, or a document
7433  * with "standalone='yes'", the Name given in the entity reference
7434  * must match that in an entity declaration, except that well-formed
7435  * documents need not declare any of the following entities: amp, lt,
7436  * gt, apos, quot.  The declaration of a parameter entity must precede
7437  * any reference to it.  Similarly, the declaration of a general entity
7438  * must precede any reference to it which appears in a default value in an
7439  * attribute-list declaration. Note that if entities are declared in the
7440  * external subset or in external parameter entities, a non-validating
7441  * processor is not obligated to read and process their declarations;
7442  * for such documents, the rule that an entity must be declared is a
7443  * well-formedness constraint only if standalone='yes'.
7444  *
7445  * [ WFC: Parsed Entity ]
7446  * An entity reference must not contain the name of an unparsed entity
7447  *
7448  * Returns the xmlEntityPtr if found, or NULL otherwise.
7449  */
7450 xmlEntityPtr
7451 xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
7452     const xmlChar *name;
7453     xmlEntityPtr ent = NULL;
7454
7455     GROW;
7456     if (ctxt->instate == XML_PARSER_EOF)
7457         return(NULL);
7458
7459     if (RAW != '&')
7460         return(NULL);
7461     NEXT;
7462     name = xmlParseName(ctxt);
7463     if (name == NULL) {
7464         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7465                        "xmlParseEntityRef: no name\n");
7466         return(NULL);
7467     }
7468     if (RAW != ';') {
7469         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7470         return(NULL);
7471     }
7472     NEXT;
7473
7474     /*
7475      * Predefined entities override any extra definition
7476      */
7477     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7478         ent = xmlGetPredefinedEntity(name);
7479         if (ent != NULL)
7480             return(ent);
7481     }
7482
7483     /*
7484      * Increase the number of entity references parsed
7485      */
7486     ctxt->nbentities++;
7487
7488     /*
7489      * Ask first SAX for entity resolution, otherwise try the
7490      * entities which may have stored in the parser context.
7491      */
7492     if (ctxt->sax != NULL) {
7493         if (ctxt->sax->getEntity != NULL)
7494             ent = ctxt->sax->getEntity(ctxt->userData, name);
7495         if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7496             (ctxt->options & XML_PARSE_OLDSAX))
7497             ent = xmlGetPredefinedEntity(name);
7498         if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7499             (ctxt->userData==ctxt)) {
7500             ent = xmlSAX2GetEntity(ctxt, name);
7501         }
7502     }
7503     if (ctxt->instate == XML_PARSER_EOF)
7504         return(NULL);
7505     /*
7506      * [ WFC: Entity Declared ]
7507      * In a document without any DTD, a document with only an
7508      * internal DTD subset which contains no parameter entity
7509      * references, or a document with "standalone='yes'", the
7510      * Name given in the entity reference must match that in an
7511      * entity declaration, except that well-formed documents
7512      * need not declare any of the following entities: amp, lt,
7513      * gt, apos, quot.
7514      * The declaration of a parameter entity must precede any
7515      * reference to it.
7516      * Similarly, the declaration of a general entity must
7517      * precede any reference to it which appears in a default
7518      * value in an attribute-list declaration. Note that if
7519      * entities are declared in the external subset or in
7520      * external parameter entities, a non-validating processor
7521      * is not obligated to read and process their declarations;
7522      * for such documents, the rule that an entity must be
7523      * declared is a well-formedness constraint only if
7524      * standalone='yes'.
7525      */
7526     if (ent == NULL) {
7527         if ((ctxt->standalone == 1) ||
7528             ((ctxt->hasExternalSubset == 0) &&
7529              (ctxt->hasPErefs == 0))) {
7530             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7531                      "Entity '%s' not defined\n", name);
7532         } else {
7533             xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7534                      "Entity '%s' not defined\n", name);
7535             if ((ctxt->inSubset == 0) &&
7536                 (ctxt->sax != NULL) &&
7537                 (ctxt->sax->reference != NULL)) {
7538                 ctxt->sax->reference(ctxt->userData, name);
7539             }
7540         }
7541         xmlParserEntityCheck(ctxt, 0, ent, 0);
7542         ctxt->valid = 0;
7543     }
7544
7545     /*
7546      * [ WFC: Parsed Entity ]
7547      * An entity reference must not contain the name of an
7548      * unparsed entity
7549      */
7550     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7551         xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7552                  "Entity reference to unparsed entity %s\n", name);
7553     }
7554
7555     /*
7556      * [ WFC: No External Entity References ]
7557      * Attribute values cannot contain direct or indirect
7558      * entity references to external entities.
7559      */
7560     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7561              (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7562         xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7563              "Attribute references external entity '%s'\n", name);
7564     }
7565     /*
7566      * [ WFC: No < in Attribute Values ]
7567      * The replacement text of any entity referred to directly or
7568      * indirectly in an attribute value (other than "&lt;") must
7569      * not contain a <.
7570      */
7571     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7572              (ent != NULL) && 
7573              (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
7574         if (((ent->checked & 1) || (ent->checked == 0)) &&
7575              (ent->content != NULL) && (xmlStrchr(ent->content, '<'))) {
7576             xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7577         "'<' in entity '%s' is not allowed in attributes values\n", name);
7578         }
7579     }
7580
7581     /*
7582      * Internal check, no parameter entities here ...
7583      */
7584     else {
7585         switch (ent->etype) {
7586             case XML_INTERNAL_PARAMETER_ENTITY:
7587             case XML_EXTERNAL_PARAMETER_ENTITY:
7588             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7589              "Attempt to reference the parameter entity '%s'\n",
7590                               name);
7591             break;
7592             default:
7593             break;
7594         }
7595     }
7596
7597     /*
7598      * [ WFC: No Recursion ]
7599      * A parsed entity must not contain a recursive reference
7600      * to itself, either directly or indirectly.
7601      * Done somewhere else
7602      */
7603     return(ent);
7604 }
7605
7606 /**
7607  * xmlParseStringEntityRef:
7608  * @ctxt:  an XML parser context
7609  * @str:  a pointer to an index in the string
7610  *
7611  * parse ENTITY references declarations, but this version parses it from
7612  * a string value.
7613  *
7614  * [68] EntityRef ::= '&' Name ';'
7615  *
7616  * [ WFC: Entity Declared ]
7617  * In a document without any DTD, a document with only an internal DTD
7618  * subset which contains no parameter entity references, or a document
7619  * with "standalone='yes'", the Name given in the entity reference
7620  * must match that in an entity declaration, except that well-formed
7621  * documents need not declare any of the following entities: amp, lt,
7622  * gt, apos, quot.  The declaration of a parameter entity must precede
7623  * any reference to it.  Similarly, the declaration of a general entity
7624  * must precede any reference to it which appears in a default value in an
7625  * attribute-list declaration. Note that if entities are declared in the
7626  * external subset or in external parameter entities, a non-validating
7627  * processor is not obligated to read and process their declarations;
7628  * for such documents, the rule that an entity must be declared is a
7629  * well-formedness constraint only if standalone='yes'.
7630  *
7631  * [ WFC: Parsed Entity ]
7632  * An entity reference must not contain the name of an unparsed entity
7633  *
7634  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
7635  * is updated to the current location in the string.
7636  */
7637 static xmlEntityPtr
7638 xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
7639     xmlChar *name;
7640     const xmlChar *ptr;
7641     xmlChar cur;
7642     xmlEntityPtr ent = NULL;
7643
7644     if ((str == NULL) || (*str == NULL))
7645         return(NULL);
7646     ptr = *str;
7647     cur = *ptr;
7648     if (cur != '&')
7649         return(NULL);
7650
7651     ptr++;
7652     name = xmlParseStringName(ctxt, &ptr);
7653     if (name == NULL) {
7654         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7655                        "xmlParseStringEntityRef: no name\n");
7656         *str = ptr;
7657         return(NULL);
7658     }
7659     if (*ptr != ';') {
7660         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7661         xmlFree(name);
7662         *str = ptr;
7663         return(NULL);
7664     }
7665     ptr++;
7666
7667
7668     /*
7669      * Predefined entities override any extra definition
7670      */
7671     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7672         ent = xmlGetPredefinedEntity(name);
7673         if (ent != NULL) {
7674             xmlFree(name);
7675             *str = ptr;
7676             return(ent);
7677         }
7678     }
7679
7680     /*
7681      * Increate the number of entity references parsed
7682      */
7683     ctxt->nbentities++;
7684
7685     /*
7686      * Ask first SAX for entity resolution, otherwise try the
7687      * entities which may have stored in the parser context.
7688      */
7689     if (ctxt->sax != NULL) {
7690         if (ctxt->sax->getEntity != NULL)
7691             ent = ctxt->sax->getEntity(ctxt->userData, name);
7692         if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
7693             ent = xmlGetPredefinedEntity(name);
7694         if ((ent == NULL) && (ctxt->userData==ctxt)) {
7695             ent = xmlSAX2GetEntity(ctxt, name);
7696         }
7697     }
7698     if (ctxt->instate == XML_PARSER_EOF) {
7699         xmlFree(name);
7700         return(NULL);
7701     }
7702
7703     /*
7704      * [ WFC: Entity Declared ]
7705      * In a document without any DTD, a document with only an
7706      * internal DTD subset which contains no parameter entity
7707      * references, or a document with "standalone='yes'", the
7708      * Name given in the entity reference must match that in an
7709      * entity declaration, except that well-formed documents
7710      * need not declare any of the following entities: amp, lt,
7711      * gt, apos, quot.
7712      * The declaration of a parameter entity must precede any
7713      * reference to it.
7714      * Similarly, the declaration of a general entity must
7715      * precede any reference to it which appears in a default
7716      * value in an attribute-list declaration. Note that if
7717      * entities are declared in the external subset or in
7718      * external parameter entities, a non-validating processor
7719      * is not obligated to read and process their declarations;
7720      * for such documents, the rule that an entity must be
7721      * declared is a well-formedness constraint only if
7722      * standalone='yes'.
7723      */
7724     if (ent == NULL) {
7725         if ((ctxt->standalone == 1) ||
7726             ((ctxt->hasExternalSubset == 0) &&
7727              (ctxt->hasPErefs == 0))) {
7728             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7729                      "Entity '%s' not defined\n", name);
7730         } else {
7731             xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7732                           "Entity '%s' not defined\n",
7733                           name);
7734         }
7735         xmlParserEntityCheck(ctxt, 0, ent, 0);
7736         /* TODO ? check regressions ctxt->valid = 0; */
7737     }
7738
7739     /*
7740      * [ WFC: Parsed Entity ]
7741      * An entity reference must not contain the name of an
7742      * unparsed entity
7743      */
7744     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7745         xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7746                  "Entity reference to unparsed entity %s\n", name);
7747     }
7748
7749     /*
7750      * [ WFC: No External Entity References ]
7751      * Attribute values cannot contain direct or indirect
7752      * entity references to external entities.
7753      */
7754     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7755              (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7756         xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7757          "Attribute references external entity '%s'\n", name);
7758     }
7759     /*
7760      * [ WFC: No < in Attribute Values ]
7761      * The replacement text of any entity referred to directly or
7762      * indirectly in an attribute value (other than "&lt;") must
7763      * not contain a <.
7764      */
7765     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7766              (ent != NULL) && (ent->content != NULL) &&
7767              (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
7768              (xmlStrchr(ent->content, '<'))) {
7769         xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7770      "'<' in entity '%s' is not allowed in attributes values\n",
7771                           name);
7772     }
7773
7774     /*
7775      * Internal check, no parameter entities here ...
7776      */
7777     else {
7778         switch (ent->etype) {
7779             case XML_INTERNAL_PARAMETER_ENTITY:
7780             case XML_EXTERNAL_PARAMETER_ENTITY:
7781                 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7782              "Attempt to reference the parameter entity '%s'\n",
7783                                   name);
7784             break;
7785             default:
7786             break;
7787         }
7788     }
7789
7790     /*
7791      * [ WFC: No Recursion ]
7792      * A parsed entity must not contain a recursive reference
7793      * to itself, either directly or indirectly.
7794      * Done somewhere else
7795      */
7796
7797     xmlFree(name);
7798     *str = ptr;
7799     return(ent);
7800 }
7801
7802 /**
7803  * xmlParsePEReference:
7804  * @ctxt:  an XML parser context
7805  *
7806  * parse PEReference declarations
7807  * The entity content is handled directly by pushing it's content as
7808  * a new input stream.
7809  *
7810  * [69] PEReference ::= '%' Name ';'
7811  *
7812  * [ WFC: No Recursion ]
7813  * A parsed entity must not contain a recursive
7814  * reference to itself, either directly or indirectly.
7815  *
7816  * [ WFC: Entity Declared ]
7817  * In a document without any DTD, a document with only an internal DTD
7818  * subset which contains no parameter entity references, or a document
7819  * with "standalone='yes'", ...  ... The declaration of a parameter
7820  * entity must precede any reference to it...
7821  *
7822  * [ VC: Entity Declared ]
7823  * In a document with an external subset or external parameter entities
7824  * with "standalone='no'", ...  ... The declaration of a parameter entity
7825  * must precede any reference to it...
7826  *
7827  * [ WFC: In DTD ]
7828  * Parameter-entity references may only appear in the DTD.
7829  * NOTE: misleading but this is handled.
7830  */
7831 void
7832 xmlParsePEReference(xmlParserCtxtPtr ctxt)
7833 {
7834     const xmlChar *name;
7835     xmlEntityPtr entity = NULL;
7836     xmlParserInputPtr input;
7837
7838     if (RAW != '%')
7839         return;
7840     NEXT;
7841     name = xmlParseName(ctxt);
7842     if (name == NULL) {
7843         xmlFatalErrMsg(ctxt, XML_ERR_PEREF_NO_NAME, "PEReference: no name\n");
7844         return;
7845     }
7846     if (xmlParserDebugEntities)
7847         xmlGenericError(xmlGenericErrorContext,
7848                 "PEReference: %s\n", name);
7849     if (RAW != ';') {
7850         xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
7851         return;
7852     }
7853
7854     NEXT;
7855
7856     /*
7857      * Increate the number of entity references parsed
7858      */
7859     ctxt->nbentities++;
7860
7861     /*
7862      * Request the entity from SAX
7863      */
7864     if ((ctxt->sax != NULL) &&
7865         (ctxt->sax->getParameterEntity != NULL))
7866         entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
7867     if (ctxt->instate == XML_PARSER_EOF)
7868         return;
7869     if (entity == NULL) {
7870         /*
7871          * [ WFC: Entity Declared ]
7872          * In a document without any DTD, a document with only an
7873          * internal DTD subset which contains no parameter entity
7874          * references, or a document with "standalone='yes'", ...
7875          * ... The declaration of a parameter entity must precede
7876          * any reference to it...
7877          */
7878         if ((ctxt->standalone == 1) ||
7879             ((ctxt->hasExternalSubset == 0) &&
7880              (ctxt->hasPErefs == 0))) {
7881             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7882                               "PEReference: %%%s; not found\n",
7883                               name);
7884         } else {
7885             /*
7886              * [ VC: Entity Declared ]
7887              * In a document with an external subset or external
7888              * parameter entities with "standalone='no'", ...
7889              * ... The declaration of a parameter entity must
7890              * precede any reference to it...
7891              */
7892             if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
7893                 xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
7894                                  "PEReference: %%%s; not found\n",
7895                                  name, NULL);
7896             } else
7897                 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7898                               "PEReference: %%%s; not found\n",
7899                               name, NULL);
7900             ctxt->valid = 0;
7901         }
7902         xmlParserEntityCheck(ctxt, 0, NULL, 0);
7903     } else {
7904         /*
7905          * Internal checking in case the entity quest barfed
7906          */
7907         if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
7908             (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
7909             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7910                   "Internal: %%%s; is not a parameter entity\n",
7911                           name, NULL);
7912         } else {
7913             xmlChar start[4];
7914             xmlCharEncoding enc;
7915
7916             if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
7917                 ((ctxt->options & XML_PARSE_NOENT) == 0) &&
7918                 ((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
7919                 ((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
7920                 ((ctxt->options & XML_PARSE_DTDATTR) == 0) &&
7921                 (ctxt->replaceEntities == 0) &&
7922                 (ctxt->validate == 0))
7923                 return;
7924
7925             input = xmlNewEntityInputStream(ctxt, entity);
7926             if (xmlPushInput(ctxt, input) < 0) {
7927                 xmlFreeInputStream(input);
7928                 return;
7929             }
7930
7931             if (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) {
7932                 /*
7933                  * Get the 4 first bytes and decode the charset
7934                  * if enc != XML_CHAR_ENCODING_NONE
7935                  * plug some encoding conversion routines.
7936                  * Note that, since we may have some non-UTF8
7937                  * encoding (like UTF16, bug 135229), the 'length'
7938                  * is not known, but we can calculate based upon
7939                  * the amount of data in the buffer.
7940                  */
7941                 GROW
7942                 if (ctxt->instate == XML_PARSER_EOF)
7943                     return;
7944                 if ((ctxt->input->end - ctxt->input->cur)>=4) {
7945                     start[0] = RAW;
7946                     start[1] = NXT(1);
7947                     start[2] = NXT(2);
7948                     start[3] = NXT(3);
7949                     enc = xmlDetectCharEncoding(start, 4);
7950                     if (enc != XML_CHAR_ENCODING_NONE) {
7951                         xmlSwitchEncoding(ctxt, enc);
7952                     }
7953                 }
7954
7955                 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
7956                     (IS_BLANK_CH(NXT(5)))) {
7957                     xmlParseTextDecl(ctxt);
7958                 }
7959             }
7960         }
7961     }
7962     ctxt->hasPErefs = 1;
7963 }
7964
7965 /**
7966  * xmlLoadEntityContent:
7967  * @ctxt:  an XML parser context
7968  * @entity: an unloaded system entity
7969  *
7970  * Load the original content of the given system entity from the
7971  * ExternalID/SystemID given. This is to be used for Included in Literal
7972  * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
7973  *
7974  * Returns 0 in case of success and -1 in case of failure
7975  */
7976 static int
7977 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
7978     xmlParserInputPtr input;
7979     xmlBufferPtr buf;
7980     int l, c;
7981     int count = 0;
7982
7983     if ((ctxt == NULL) || (entity == NULL) ||
7984         ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
7985          (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
7986         (entity->content != NULL)) {
7987         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
7988                     "xmlLoadEntityContent parameter error");
7989         return(-1);
7990     }
7991
7992     if (xmlParserDebugEntities)
7993         xmlGenericError(xmlGenericErrorContext,
7994                 "Reading %s entity content input\n", entity->name);
7995
7996     buf = xmlBufferCreate();
7997     if (buf == NULL) {
7998         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
7999                     "xmlLoadEntityContent parameter error");
8000         return(-1);
8001     }
8002
8003     input = xmlNewEntityInputStream(ctxt, entity);
8004     if (input == NULL) {
8005         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8006                     "xmlLoadEntityContent input error");
8007         xmlBufferFree(buf);
8008         return(-1);
8009     }
8010
8011     /*
8012      * Push the entity as the current input, read char by char
8013      * saving to the buffer until the end of the entity or an error
8014      */
8015     if (xmlPushInput(ctxt, input) < 0) {
8016         xmlBufferFree(buf);
8017         return(-1);
8018     }
8019
8020     GROW;
8021     c = CUR_CHAR(l);
8022     while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
8023            (IS_CHAR(c))) {
8024         xmlBufferAdd(buf, ctxt->input->cur, l);
8025         if (count++ > XML_PARSER_CHUNK_SIZE) {
8026             count = 0;
8027             GROW;
8028             if (ctxt->instate == XML_PARSER_EOF) {
8029                 xmlBufferFree(buf);
8030                 return(-1);
8031             }
8032         }
8033         NEXTL(l);
8034         c = CUR_CHAR(l);
8035         if (c == 0) {
8036             count = 0;
8037             GROW;
8038             if (ctxt->instate == XML_PARSER_EOF) {
8039                 xmlBufferFree(buf);
8040                 return(-1);
8041             }
8042             c = CUR_CHAR(l);
8043         }
8044     }
8045
8046     if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
8047         xmlPopInput(ctxt);
8048     } else if (!IS_CHAR(c)) {
8049         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
8050                           "xmlLoadEntityContent: invalid char value %d\n",
8051                           c);
8052         xmlBufferFree(buf);
8053         return(-1);
8054     }
8055     entity->content = buf->content;
8056     buf->content = NULL;
8057     xmlBufferFree(buf);
8058
8059     return(0);
8060 }
8061
8062 /**
8063  * xmlParseStringPEReference:
8064  * @ctxt:  an XML parser context
8065  * @str:  a pointer to an index in the string
8066  *
8067  * parse PEReference declarations
8068  *
8069  * [69] PEReference ::= '%' Name ';'
8070  *
8071  * [ WFC: No Recursion ]
8072  * A parsed entity must not contain a recursive
8073  * reference to itself, either directly or indirectly.
8074  *
8075  * [ WFC: Entity Declared ]
8076  * In a document without any DTD, a document with only an internal DTD
8077  * subset which contains no parameter entity references, or a document
8078  * with "standalone='yes'", ...  ... The declaration of a parameter
8079  * entity must precede any reference to it...
8080  *
8081  * [ VC: Entity Declared ]
8082  * In a document with an external subset or external parameter entities
8083  * with "standalone='no'", ...  ... The declaration of a parameter entity
8084  * must precede any reference to it...
8085  *
8086  * [ WFC: In DTD ]
8087  * Parameter-entity references may only appear in the DTD.
8088  * NOTE: misleading but this is handled.
8089  *
8090  * Returns the string of the entity content.
8091  *         str is updated to the current value of the index
8092  */
8093 static xmlEntityPtr
8094 xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
8095     const xmlChar *ptr;
8096     xmlChar cur;
8097     xmlChar *name;
8098     xmlEntityPtr entity = NULL;
8099
8100     if ((str == NULL) || (*str == NULL)) return(NULL);
8101     ptr = *str;
8102     cur = *ptr;
8103     if (cur != '%')
8104         return(NULL);
8105     ptr++;
8106     name = xmlParseStringName(ctxt, &ptr);
8107     if (name == NULL) {
8108         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8109                        "xmlParseStringPEReference: no name\n");
8110         *str = ptr;
8111         return(NULL);
8112     }
8113     cur = *ptr;
8114     if (cur != ';') {
8115         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
8116         xmlFree(name);
8117         *str = ptr;
8118         return(NULL);
8119     }
8120     ptr++;
8121
8122     /*
8123      * Increate the number of entity references parsed
8124      */
8125     ctxt->nbentities++;
8126
8127     /*
8128      * Request the entity from SAX
8129      */
8130     if ((ctxt->sax != NULL) &&
8131         (ctxt->sax->getParameterEntity != NULL))
8132         entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
8133     if (ctxt->instate == XML_PARSER_EOF) {
8134         xmlFree(name);
8135         *str = ptr;
8136         return(NULL);
8137     }
8138     if (entity == NULL) {
8139         /*
8140          * [ WFC: Entity Declared ]
8141          * In a document without any DTD, a document with only an
8142          * internal DTD subset which contains no parameter entity
8143          * references, or a document with "standalone='yes'", ...
8144          * ... The declaration of a parameter entity must precede
8145          * any reference to it...
8146          */
8147         if ((ctxt->standalone == 1) ||
8148             ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
8149             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
8150                  "PEReference: %%%s; not found\n", name);
8151         } else {
8152             /*
8153              * [ VC: Entity Declared ]
8154              * In a document with an external subset or external
8155              * parameter entities with "standalone='no'", ...
8156              * ... The declaration of a parameter entity must
8157              * precede any reference to it...
8158              */
8159             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8160                           "PEReference: %%%s; not found\n",
8161                           name, NULL);
8162             ctxt->valid = 0;
8163         }
8164         xmlParserEntityCheck(ctxt, 0, NULL, 0);
8165     } else {
8166         /*
8167          * Internal checking in case the entity quest barfed
8168          */
8169         if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
8170             (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
8171             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8172                           "%%%s; is not a parameter entity\n",
8173                           name, NULL);
8174         }
8175     }
8176     ctxt->hasPErefs = 1;
8177     xmlFree(name);
8178     *str = ptr;
8179     return(entity);
8180 }
8181
8182 /**
8183  * xmlParseDocTypeDecl:
8184  * @ctxt:  an XML parser context
8185  *
8186  * parse a DOCTYPE declaration
8187  *
8188  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
8189  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8190  *
8191  * [ VC: Root Element Type ]
8192  * The Name in the document type declaration must match the element
8193  * type of the root element.
8194  */
8195
8196 void
8197 xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
8198     const xmlChar *name = NULL;
8199     xmlChar *ExternalID = NULL;
8200     xmlChar *URI = NULL;
8201
8202     /*
8203      * We know that '<!DOCTYPE' has been detected.
8204      */
8205     SKIP(9);
8206
8207     SKIP_BLANKS;
8208
8209     /*
8210      * Parse the DOCTYPE name.
8211      */
8212     name = xmlParseName(ctxt);
8213     if (name == NULL) {
8214         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8215                        "xmlParseDocTypeDecl : no DOCTYPE name !\n");
8216     }
8217     ctxt->intSubName = name;
8218
8219     SKIP_BLANKS;
8220
8221     /*
8222      * Check for SystemID and ExternalID
8223      */
8224     URI = xmlParseExternalID(ctxt, &ExternalID, 1);
8225
8226     if ((URI != NULL) || (ExternalID != NULL)) {
8227         ctxt->hasExternalSubset = 1;
8228     }
8229     ctxt->extSubURI = URI;
8230     ctxt->extSubSystem = ExternalID;
8231
8232     SKIP_BLANKS;
8233
8234     /*
8235      * Create and update the internal subset.
8236      */
8237     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
8238         (!ctxt->disableSAX))
8239         ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
8240     if (ctxt->instate == XML_PARSER_EOF)
8241         return;
8242
8243     /*
8244      * Is there any internal subset declarations ?
8245      * they are handled separately in xmlParseInternalSubset()
8246      */
8247     if (RAW == '[')
8248         return;
8249
8250     /*
8251      * We should be at the end of the DOCTYPE declaration.
8252      */
8253     if (RAW != '>') {
8254         xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8255     }
8256     NEXT;
8257 }
8258
8259 /**
8260  * xmlParseInternalSubset:
8261  * @ctxt:  an XML parser context
8262  *
8263  * parse the internal subset declaration
8264  *
8265  * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8266  */
8267
8268 static void
8269 xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
8270     /*
8271      * Is there any DTD definition ?
8272      */
8273     if (RAW == '[') {
8274         int baseInputNr = ctxt->inputNr;
8275         ctxt->instate = XML_PARSER_DTD;
8276         NEXT;
8277         /*
8278          * Parse the succession of Markup declarations and
8279          * PEReferences.
8280          * Subsequence (markupdecl | PEReference | S)*
8281          */
8282         while (((RAW != ']') || (ctxt->inputNr > baseInputNr)) &&
8283                (ctxt->instate != XML_PARSER_EOF)) {
8284             const xmlChar *check = CUR_PTR;
8285             unsigned int cons = ctxt->input->consumed;
8286
8287             SKIP_BLANKS;
8288             xmlParseMarkupDecl(ctxt);
8289             xmlParsePEReference(ctxt);
8290
8291             if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
8292                 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8293              "xmlParseInternalSubset: error detected in Markup declaration\n");
8294                 if (ctxt->inputNr > baseInputNr)
8295                     xmlPopInput(ctxt);
8296                 else
8297                     break;
8298             }
8299         }
8300         if (RAW == ']') {
8301             NEXT;
8302             SKIP_BLANKS;
8303         }
8304     }
8305
8306     /*
8307      * We should be at the end of the DOCTYPE declaration.
8308      */
8309     if (RAW != '>') {
8310         xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8311         return;
8312     }
8313     NEXT;
8314 }
8315
8316 #ifdef LIBXML_SAX1_ENABLED
8317 /**
8318  * xmlParseAttribute:
8319  * @ctxt:  an XML parser context
8320  * @value:  a xmlChar ** used to store the value of the attribute
8321  *
8322  * parse an attribute
8323  *
8324  * [41] Attribute ::= Name Eq AttValue
8325  *
8326  * [ WFC: No External Entity References ]
8327  * Attribute values cannot contain direct or indirect entity references
8328  * to external entities.
8329  *
8330  * [ WFC: No < in Attribute Values ]
8331  * The replacement text of any entity referred to directly or indirectly in
8332  * an attribute value (other than "&lt;") must not contain a <.
8333  *
8334  * [ VC: Attribute Value Type ]
8335  * The attribute must have been declared; the value must be of the type
8336  * declared for it.
8337  *
8338  * [25] Eq ::= S? '=' S?
8339  *
8340  * With namespace:
8341  *
8342  * [NS 11] Attribute ::= QName Eq AttValue
8343  *
8344  * Also the case QName == xmlns:??? is handled independently as a namespace
8345  * definition.
8346  *
8347  * Returns the attribute name, and the value in *value.
8348  */
8349
8350 const xmlChar *
8351 xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
8352     const xmlChar *name;
8353     xmlChar *val;
8354
8355     *value = NULL;
8356     GROW;
8357     name = xmlParseName(ctxt);
8358     if (name == NULL) {
8359         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8360                        "error parsing attribute name\n");
8361         return(NULL);
8362     }
8363
8364     /*
8365      * read the value
8366      */
8367     SKIP_BLANKS;
8368     if (RAW == '=') {
8369         NEXT;
8370         SKIP_BLANKS;
8371         val = xmlParseAttValue(ctxt);
8372         ctxt->instate = XML_PARSER_CONTENT;
8373     } else {
8374         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8375                "Specification mandates value for attribute %s\n", name);
8376         return(NULL);
8377     }
8378
8379     /*
8380      * Check that xml:lang conforms to the specification
8381      * No more registered as an error, just generate a warning now
8382      * since this was deprecated in XML second edition
8383      */
8384     if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
8385         if (!xmlCheckLanguageID(val)) {
8386             xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
8387                           "Malformed value for xml:lang : %s\n",
8388                           val, NULL);
8389         }
8390     }
8391
8392     /*
8393      * Check that xml:space conforms to the specification
8394      */
8395     if (xmlStrEqual(name, BAD_CAST "xml:space")) {
8396         if (xmlStrEqual(val, BAD_CAST "default"))
8397             *(ctxt->space) = 0;
8398         else if (xmlStrEqual(val, BAD_CAST "preserve"))
8399             *(ctxt->space) = 1;
8400         else {
8401                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
8402 "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
8403                                  val, NULL);
8404         }
8405     }
8406
8407     *value = val;
8408     return(name);
8409 }
8410
8411 /**
8412  * xmlParseStartTag:
8413  * @ctxt:  an XML parser context
8414  *
8415  * parse a start of tag either for rule element or
8416  * EmptyElement. In both case we don't parse the tag closing chars.
8417  *
8418  * [40] STag ::= '<' Name (S Attribute)* S? '>'
8419  *
8420  * [ WFC: Unique Att Spec ]
8421  * No attribute name may appear more than once in the same start-tag or
8422  * empty-element tag.
8423  *
8424  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
8425  *
8426  * [ WFC: Unique Att Spec ]
8427  * No attribute name may appear more than once in the same start-tag or
8428  * empty-element tag.
8429  *
8430  * With namespace:
8431  *
8432  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
8433  *
8434  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
8435  *
8436  * Returns the element name parsed
8437  */
8438
8439 const xmlChar *
8440 xmlParseStartTag(xmlParserCtxtPtr ctxt) {
8441     const xmlChar *name;
8442     const xmlChar *attname;
8443     xmlChar *attvalue;
8444     const xmlChar **atts = ctxt->atts;
8445     int nbatts = 0;
8446     int maxatts = ctxt->maxatts;
8447     int i;
8448
8449     if (RAW != '<') return(NULL);
8450     NEXT1;
8451
8452     name = xmlParseName(ctxt);
8453     if (name == NULL) {
8454         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8455              "xmlParseStartTag: invalid element name\n");
8456         return(NULL);
8457     }
8458
8459     /*
8460      * Now parse the attributes, it ends up with the ending
8461      *
8462      * (S Attribute)* S?
8463      */
8464     SKIP_BLANKS;
8465     GROW;
8466
8467     while (((RAW != '>') &&
8468            ((RAW != '/') || (NXT(1) != '>')) &&
8469            (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
8470         const xmlChar *q = CUR_PTR;
8471         unsigned int cons = ctxt->input->consumed;
8472
8473         attname = xmlParseAttribute(ctxt, &attvalue);
8474         if ((attname != NULL) && (attvalue != NULL)) {
8475             /*
8476              * [ WFC: Unique Att Spec ]
8477              * No attribute name may appear more than once in the same
8478              * start-tag or empty-element tag.
8479              */
8480             for (i = 0; i < nbatts;i += 2) {
8481                 if (xmlStrEqual(atts[i], attname)) {
8482                     xmlErrAttributeDup(ctxt, NULL, attname);
8483                     xmlFree(attvalue);
8484                     goto failed;
8485                 }
8486             }
8487             /*
8488              * Add the pair to atts
8489              */
8490             if (atts == NULL) {
8491                 maxatts = 22; /* allow for 10 attrs by default */
8492                 atts = (const xmlChar **)
8493                        xmlMalloc(maxatts * sizeof(xmlChar *));
8494                 if (atts == NULL) {
8495                     xmlErrMemory(ctxt, NULL);
8496                     if (attvalue != NULL)
8497                         xmlFree(attvalue);
8498                     goto failed;
8499                 }
8500                 ctxt->atts = atts;
8501                 ctxt->maxatts = maxatts;
8502             } else if (nbatts + 4 > maxatts) {
8503                 const xmlChar **n;
8504
8505                 maxatts *= 2;
8506                 n = (const xmlChar **) xmlRealloc((void *) atts,
8507                                              maxatts * sizeof(const xmlChar *));
8508                 if (n == NULL) {
8509                     xmlErrMemory(ctxt, NULL);
8510                     if (attvalue != NULL)
8511                         xmlFree(attvalue);
8512                     goto failed;
8513                 }
8514                 atts = n;
8515                 ctxt->atts = atts;
8516                 ctxt->maxatts = maxatts;
8517             }
8518             atts[nbatts++] = attname;
8519             atts[nbatts++] = attvalue;
8520             atts[nbatts] = NULL;
8521             atts[nbatts + 1] = NULL;
8522         } else {
8523             if (attvalue != NULL)
8524                 xmlFree(attvalue);
8525         }
8526
8527 failed:
8528
8529         GROW
8530         if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
8531             break;
8532         if (SKIP_BLANKS == 0) {
8533             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
8534                            "attributes construct error\n");
8535         }
8536         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
8537             (attname == NULL) && (attvalue == NULL)) {
8538             xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
8539                            "xmlParseStartTag: problem parsing attributes\n");
8540             break;
8541         }
8542         SHRINK;
8543         GROW;
8544     }
8545
8546     /*
8547      * SAX: Start of Element !
8548      */
8549     if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
8550         (!ctxt->disableSAX)) {
8551         if (nbatts > 0)
8552             ctxt->sax->startElement(ctxt->userData, name, atts);
8553         else
8554             ctxt->sax->startElement(ctxt->userData, name, NULL);
8555     }
8556
8557     if (atts != NULL) {
8558         /* Free only the content strings */
8559         for (i = 1;i < nbatts;i+=2)
8560             if (atts[i] != NULL)
8561                xmlFree((xmlChar *) atts[i]);
8562     }
8563     return(name);
8564 }
8565
8566 /**
8567  * xmlParseEndTag1:
8568  * @ctxt:  an XML parser context
8569  * @line:  line of the start tag
8570  * @nsNr:  number of namespaces on the start tag
8571  *
8572  * parse an end of tag
8573  *
8574  * [42] ETag ::= '</' Name S? '>'
8575  *
8576  * With namespace
8577  *
8578  * [NS 9] ETag ::= '</' QName S? '>'
8579  */
8580
8581 static void
8582 xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
8583     const xmlChar *name;
8584
8585     GROW;
8586     if ((RAW != '<') || (NXT(1) != '/')) {
8587         xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
8588                        "xmlParseEndTag: '</' not found\n");
8589         return;
8590     }
8591     SKIP(2);
8592
8593     name = xmlParseNameAndCompare(ctxt,ctxt->name);
8594
8595     /*
8596      * We should definitely be at the ending "S? '>'" part
8597      */
8598     GROW;
8599     SKIP_BLANKS;
8600     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
8601         xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
8602     } else
8603         NEXT1;
8604
8605     /*
8606      * [ WFC: Element Type Match ]
8607      * The Name in an element's end-tag must match the element type in the
8608      * start-tag.
8609      *
8610      */
8611     if (name != (xmlChar*)1) {
8612         if (name == NULL) name = BAD_CAST "unparseable";
8613         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
8614                      "Opening and ending tag mismatch: %s line %d and %s\n",
8615                                 ctxt->name, line, name);
8616     }
8617
8618     /*
8619      * SAX: End of Tag
8620      */
8621     if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
8622         (!ctxt->disableSAX))
8623         ctxt->sax->endElement(ctxt->userData, ctxt->name);
8624
8625     namePop(ctxt);
8626     spacePop(ctxt);
8627     return;
8628 }
8629
8630 /**
8631  * xmlParseEndTag:
8632  * @ctxt:  an XML parser context
8633  *
8634  * parse an end of tag
8635  *
8636  * [42] ETag ::= '</' Name S? '>'
8637  *
8638  * With namespace
8639  *
8640  * [NS 9] ETag ::= '</' QName S? '>'
8641  */
8642
8643 void
8644 xmlParseEndTag(xmlParserCtxtPtr ctxt) {
8645     xmlParseEndTag1(ctxt, 0);
8646 }
8647 #endif /* LIBXML_SAX1_ENABLED */
8648
8649 /************************************************************************
8650  *                                                                      *
8651  *                    SAX 2 specific operations                         *
8652  *                                                                      *
8653  ************************************************************************/
8654
8655 /*
8656  * xmlGetNamespace:
8657  * @ctxt:  an XML parser context
8658  * @prefix:  the prefix to lookup
8659  *
8660  * Lookup the namespace name for the @prefix (which ca be NULL)
8661  * The prefix must come from the @ctxt->dict dictionary
8662  *
8663  * Returns the namespace name or NULL if not bound
8664  */
8665 static const xmlChar *
8666 xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
8667     int i;
8668
8669     if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
8670     for (i = ctxt->nsNr - 2;i >= 0;i-=2)
8671         if (ctxt->nsTab[i] == prefix) {
8672             if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
8673                 return(NULL);
8674             return(ctxt->nsTab[i + 1]);
8675         }
8676     return(NULL);
8677 }
8678
8679 /**
8680  * xmlParseQName:
8681  * @ctxt:  an XML parser context
8682  * @prefix:  pointer to store the prefix part
8683  *
8684  * parse an XML Namespace QName
8685  *
8686  * [6]  QName  ::= (Prefix ':')? LocalPart
8687  * [7]  Prefix  ::= NCName
8688  * [8]  LocalPart  ::= NCName
8689  *
8690  * Returns the Name parsed or NULL
8691  */
8692
8693 static const xmlChar *
8694 xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
8695     const xmlChar *l, *p;
8696
8697     GROW;
8698
8699     l = xmlParseNCName(ctxt);
8700     if (l == NULL) {
8701         if (CUR == ':') {
8702             l = xmlParseName(ctxt);
8703             if (l != NULL) {
8704                 xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8705                          "Failed to parse QName '%s'\n", l, NULL, NULL);
8706                 *prefix = NULL;
8707                 return(l);
8708             }
8709         }
8710         return(NULL);
8711     }
8712     if (CUR == ':') {
8713         NEXT;
8714         p = l;
8715         l = xmlParseNCName(ctxt);
8716         if (l == NULL) {
8717             xmlChar *tmp;
8718
8719             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8720                      "Failed to parse QName '%s:'\n", p, NULL, NULL);
8721             l = xmlParseNmtoken(ctxt);
8722             if (l == NULL)
8723                 tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
8724             else {
8725                 tmp = xmlBuildQName(l, p, NULL, 0);
8726                 xmlFree((char *)l);
8727             }
8728             p = xmlDictLookup(ctxt->dict, tmp, -1);
8729             if (tmp != NULL) xmlFree(tmp);
8730             *prefix = NULL;
8731             return(p);
8732         }
8733         if (CUR == ':') {
8734             xmlChar *tmp;
8735
8736             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8737                      "Failed to parse QName '%s:%s:'\n", p, l, NULL);
8738             NEXT;
8739             tmp = (xmlChar *) xmlParseName(ctxt);
8740             if (tmp != NULL) {
8741                 tmp = xmlBuildQName(tmp, l, NULL, 0);
8742                 l = xmlDictLookup(ctxt->dict, tmp, -1);
8743                 if (tmp != NULL) xmlFree(tmp);
8744                 *prefix = p;
8745                 return(l);
8746             }
8747             tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
8748             l = xmlDictLookup(ctxt->dict, tmp, -1);
8749             if (tmp != NULL) xmlFree(tmp);
8750             *prefix = p;
8751             return(l);
8752         }
8753         *prefix = p;
8754     } else
8755         *prefix = NULL;
8756     return(l);
8757 }
8758
8759 /**
8760  * xmlParseQNameAndCompare:
8761  * @ctxt:  an XML parser context
8762  * @name:  the localname
8763  * @prefix:  the prefix, if any.
8764  *
8765  * parse an XML name and compares for match
8766  * (specialized for endtag parsing)
8767  *
8768  * Returns NULL for an illegal name, (xmlChar*) 1 for success
8769  * and the name for mismatch
8770  */
8771
8772 static const xmlChar *
8773 xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
8774                         xmlChar const *prefix) {
8775     const xmlChar *cmp;
8776     const xmlChar *in;
8777     const xmlChar *ret;
8778     const xmlChar *prefix2;
8779
8780     if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
8781
8782     GROW;
8783     in = ctxt->input->cur;
8784
8785     cmp = prefix;
8786     while (*in != 0 && *in == *cmp) {
8787         ++in;
8788         ++cmp;
8789     }
8790     if ((*cmp == 0) && (*in == ':')) {
8791         in++;
8792         cmp = name;
8793         while (*in != 0 && *in == *cmp) {
8794             ++in;
8795             ++cmp;
8796         }
8797         if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
8798             /* success */
8799             ctxt->input->cur = in;
8800             return((const xmlChar*) 1);
8801         }
8802     }
8803     /*
8804      * all strings coms from the dictionary, equality can be done directly
8805      */
8806     ret = xmlParseQName (ctxt, &prefix2);
8807     if ((ret == name) && (prefix == prefix2))
8808         return((const xmlChar*) 1);
8809     return ret;
8810 }
8811
8812 /**
8813  * xmlParseAttValueInternal:
8814  * @ctxt:  an XML parser context
8815  * @len:  attribute len result
8816  * @alloc:  whether the attribute was reallocated as a new string
8817  * @normalize:  if 1 then further non-CDATA normalization must be done
8818  *
8819  * parse a value for an attribute.
8820  * NOTE: if no normalization is needed, the routine will return pointers
8821  *       directly from the data buffer.
8822  *
8823  * 3.3.3 Attribute-Value Normalization:
8824  * Before the value of an attribute is passed to the application or
8825  * checked for validity, the XML processor must normalize it as follows:
8826  * - a character reference is processed by appending the referenced
8827  *   character to the attribute value
8828  * - an entity reference is processed by recursively processing the
8829  *   replacement text of the entity
8830  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
8831  *   appending #x20 to the normalized value, except that only a single
8832  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
8833  *   parsed entity or the literal entity value of an internal parsed entity
8834  * - other characters are processed by appending them to the normalized value
8835  * If the declared value is not CDATA, then the XML processor must further
8836  * process the normalized attribute value by discarding any leading and
8837  * trailing space (#x20) characters, and by replacing sequences of space
8838  * (#x20) characters by a single space (#x20) character.
8839  * All attributes for which no declaration has been read should be treated
8840  * by a non-validating parser as if declared CDATA.
8841  *
8842  * Returns the AttValue parsed or NULL. The value has to be freed by the
8843  *     caller if it was copied, this can be detected by val[*len] == 0.
8844  */
8845
8846 static xmlChar *
8847 xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
8848                          int normalize)
8849 {
8850     xmlChar limit = 0;
8851     const xmlChar *in = NULL, *start, *end, *last;
8852     xmlChar *ret = NULL;
8853     int line, col;
8854
8855     GROW;
8856     in = (xmlChar *) CUR_PTR;
8857     line = ctxt->input->line;
8858     col = ctxt->input->col;
8859     if (*in != '"' && *in != '\'') {
8860         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
8861         return (NULL);
8862     }
8863     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
8864
8865     /*
8866      * try to handle in this routine the most common case where no
8867      * allocation of a new string is required and where content is
8868      * pure ASCII.
8869      */
8870     limit = *in++;
8871     col++;
8872     end = ctxt->input->end;
8873     start = in;
8874     if (in >= end) {
8875         const xmlChar *oldbase = ctxt->input->base;
8876         GROW;
8877         if (oldbase != ctxt->input->base) {
8878             long delta = ctxt->input->base - oldbase;
8879             start = start + delta;
8880             in = in + delta;
8881         }
8882         end = ctxt->input->end;
8883     }
8884     if (normalize) {
8885         /*
8886          * Skip any leading spaces
8887          */
8888         while ((in < end) && (*in != limit) &&
8889                ((*in == 0x20) || (*in == 0x9) ||
8890                 (*in == 0xA) || (*in == 0xD))) {
8891             if (*in == 0xA) {
8892                 line++; col = 1;
8893             } else {
8894                 col++;
8895             }
8896             in++;
8897             start = in;
8898             if (in >= end) {
8899                 const xmlChar *oldbase = ctxt->input->base;
8900                 GROW;
8901                 if (ctxt->instate == XML_PARSER_EOF)
8902                     return(NULL);
8903                 if (oldbase != ctxt->input->base) {
8904                     long delta = ctxt->input->base - oldbase;
8905                     start = start + delta;
8906                     in = in + delta;
8907                 }
8908                 end = ctxt->input->end;
8909                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
8910                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8911                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8912                                    "AttValue length too long\n");
8913                     return(NULL);
8914                 }
8915             }
8916         }
8917         while ((in < end) && (*in != limit) && (*in >= 0x20) &&
8918                (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
8919             col++;
8920             if ((*in++ == 0x20) && (*in == 0x20)) break;
8921             if (in >= end) {
8922                 const xmlChar *oldbase = ctxt->input->base;
8923                 GROW;
8924                 if (ctxt->instate == XML_PARSER_EOF)
8925                     return(NULL);
8926                 if (oldbase != ctxt->input->base) {
8927                     long delta = ctxt->input->base - oldbase;
8928                     start = start + delta;
8929                     in = in + delta;
8930                 }
8931                 end = ctxt->input->end;
8932                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
8933                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8934                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8935                                    "AttValue length too long\n");
8936                     return(NULL);
8937                 }
8938             }
8939         }
8940         last = in;
8941         /*
8942          * skip the trailing blanks
8943          */
8944         while ((last[-1] == 0x20) && (last > start)) last--;
8945         while ((in < end) && (*in != limit) &&
8946                ((*in == 0x20) || (*in == 0x9) ||
8947                 (*in == 0xA) || (*in == 0xD))) {
8948             if (*in == 0xA) {
8949                 line++, col = 1;
8950             } else {
8951                 col++;
8952             }
8953             in++;
8954             if (in >= end) {
8955                 const xmlChar *oldbase = ctxt->input->base;
8956                 GROW;
8957                 if (ctxt->instate == XML_PARSER_EOF)
8958                     return(NULL);
8959                 if (oldbase != ctxt->input->base) {
8960                     long delta = ctxt->input->base - oldbase;
8961                     start = start + delta;
8962                     in = in + delta;
8963                     last = last + delta;
8964                 }
8965                 end = ctxt->input->end;
8966                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
8967                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8968                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8969                                    "AttValue length too long\n");
8970                     return(NULL);
8971                 }
8972             }
8973         }
8974         if (((in - start) > XML_MAX_TEXT_LENGTH) &&
8975             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8976             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8977                            "AttValue length too long\n");
8978             return(NULL);
8979         }
8980         if (*in != limit) goto need_complex;
8981     } else {
8982         while ((in < end) && (*in != limit) && (*in >= 0x20) &&
8983                (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
8984             in++;
8985             col++;
8986             if (in >= end) {
8987                 const xmlChar *oldbase = ctxt->input->base;
8988                 GROW;
8989                 if (ctxt->instate == XML_PARSER_EOF)
8990                     return(NULL);
8991                 if (oldbase != ctxt->input->base) {
8992                     long delta = ctxt->input->base - oldbase;
8993                     start = start + delta;
8994                     in = in + delta;
8995                 }
8996                 end = ctxt->input->end;
8997                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
8998                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8999                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9000                                    "AttValue length too long\n");
9001                     return(NULL);
9002                 }
9003             }
9004         }
9005         last = in;
9006         if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9007             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9008             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9009                            "AttValue length too long\n");
9010             return(NULL);
9011         }
9012         if (*in != limit) goto need_complex;
9013     }
9014     in++;
9015     col++;
9016     if (len != NULL) {
9017         *len = last - start;
9018         ret = (xmlChar *) start;
9019     } else {
9020         if (alloc) *alloc = 1;
9021         ret = xmlStrndup(start, last - start);
9022     }
9023     CUR_PTR = in;
9024     ctxt->input->line = line;
9025     ctxt->input->col = col;
9026     if (alloc) *alloc = 0;
9027     return ret;
9028 need_complex:
9029     if (alloc) *alloc = 1;
9030     return xmlParseAttValueComplex(ctxt, len, normalize);
9031 }
9032
9033 /**
9034  * xmlParseAttribute2:
9035  * @ctxt:  an XML parser context
9036  * @pref:  the element prefix
9037  * @elem:  the element name
9038  * @prefix:  a xmlChar ** used to store the value of the attribute prefix
9039  * @value:  a xmlChar ** used to store the value of the attribute
9040  * @len:  an int * to save the length of the attribute
9041  * @alloc:  an int * to indicate if the attribute was allocated
9042  *
9043  * parse an attribute in the new SAX2 framework.
9044  *
9045  * Returns the attribute name, and the value in *value, .
9046  */
9047
9048 static const xmlChar *
9049 xmlParseAttribute2(xmlParserCtxtPtr ctxt,
9050                    const xmlChar * pref, const xmlChar * elem,
9051                    const xmlChar ** prefix, xmlChar ** value,
9052                    int *len, int *alloc)
9053 {
9054     const xmlChar *name;
9055     xmlChar *val, *internal_val = NULL;
9056     int normalize = 0;
9057
9058     *value = NULL;
9059     GROW;
9060     name = xmlParseQName(ctxt, prefix);
9061     if (name == NULL) {
9062         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9063                        "error parsing attribute name\n");
9064         return (NULL);
9065     }
9066
9067     /*
9068      * get the type if needed
9069      */
9070     if (ctxt->attsSpecial != NULL) {
9071         int type;
9072
9073         type = (int) (ptrdiff_t) xmlHashQLookup2(ctxt->attsSpecial,
9074                                                  pref, elem, *prefix, name);
9075         if (type != 0)
9076             normalize = 1;
9077     }
9078
9079     /*
9080      * read the value
9081      */
9082     SKIP_BLANKS;
9083     if (RAW == '=') {
9084         NEXT;
9085         SKIP_BLANKS;
9086         val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
9087         if (normalize) {
9088             /*
9089              * Sometimes a second normalisation pass for spaces is needed
9090              * but that only happens if charrefs or entities refernces
9091              * have been used in the attribute value, i.e. the attribute
9092              * value have been extracted in an allocated string already.
9093              */
9094             if (*alloc) {
9095                 const xmlChar *val2;
9096
9097                 val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
9098                 if ((val2 != NULL) && (val2 != val)) {
9099                     xmlFree(val);
9100                     val = (xmlChar *) val2;
9101                 }
9102             }
9103         }
9104         ctxt->instate = XML_PARSER_CONTENT;
9105     } else {
9106         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
9107                           "Specification mandates value for attribute %s\n",
9108                           name);
9109         return (NULL);
9110     }
9111
9112     if (*prefix == ctxt->str_xml) {
9113         /*
9114          * Check that xml:lang conforms to the specification
9115          * No more registered as an error, just generate a warning now
9116          * since this was deprecated in XML second edition
9117          */
9118         if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
9119             internal_val = xmlStrndup(val, *len);
9120             if (!xmlCheckLanguageID(internal_val)) {
9121                 xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
9122                               "Malformed value for xml:lang : %s\n",
9123                               internal_val, NULL);
9124             }
9125         }
9126
9127         /*
9128          * Check that xml:space conforms to the specification
9129          */
9130         if (xmlStrEqual(name, BAD_CAST "space")) {
9131             internal_val = xmlStrndup(val, *len);
9132             if (xmlStrEqual(internal_val, BAD_CAST "default"))
9133                 *(ctxt->space) = 0;
9134             else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
9135                 *(ctxt->space) = 1;
9136             else {
9137                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
9138                               "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
9139                               internal_val, NULL);
9140             }
9141         }
9142         if (internal_val) {
9143             xmlFree(internal_val);
9144         }
9145     }
9146
9147     *value = val;
9148     return (name);
9149 }
9150 /**
9151  * xmlParseStartTag2:
9152  * @ctxt:  an XML parser context
9153  *
9154  * parse a start of tag either for rule element or
9155  * EmptyElement. In both case we don't parse the tag closing chars.
9156  * This routine is called when running SAX2 parsing
9157  *
9158  * [40] STag ::= '<' Name (S Attribute)* S? '>'
9159  *
9160  * [ WFC: Unique Att Spec ]
9161  * No attribute name may appear more than once in the same start-tag or
9162  * empty-element tag.
9163  *
9164  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
9165  *
9166  * [ WFC: Unique Att Spec ]
9167  * No attribute name may appear more than once in the same start-tag or
9168  * empty-element tag.
9169  *
9170  * With namespace:
9171  *
9172  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
9173  *
9174  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
9175  *
9176  * Returns the element name parsed
9177  */
9178
9179 static const xmlChar *
9180 xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
9181                   const xmlChar **URI, int *tlen) {
9182     const xmlChar *localname;
9183     const xmlChar *prefix;
9184     const xmlChar *attname;
9185     const xmlChar *aprefix;
9186     const xmlChar *nsname;
9187     xmlChar *attvalue;
9188     const xmlChar **atts = ctxt->atts;
9189     int maxatts = ctxt->maxatts;
9190     int nratts, nbatts, nbdef, inputid;
9191     int i, j, nbNs, attval;
9192     unsigned long cur;
9193     int nsNr = ctxt->nsNr;
9194
9195     if (RAW != '<') return(NULL);
9196     NEXT1;
9197
9198     /*
9199      * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
9200      *       point since the attribute values may be stored as pointers to
9201      *       the buffer and calling SHRINK would destroy them !
9202      *       The Shrinking is only possible once the full set of attribute
9203      *       callbacks have been done.
9204      */
9205     SHRINK;
9206     cur = ctxt->input->cur - ctxt->input->base;
9207     inputid = ctxt->input->id;
9208     nbatts = 0;
9209     nratts = 0;
9210     nbdef = 0;
9211     nbNs = 0;
9212     attval = 0;
9213     /* Forget any namespaces added during an earlier parse of this element. */
9214     ctxt->nsNr = nsNr;
9215
9216     localname = xmlParseQName(ctxt, &prefix);
9217     if (localname == NULL) {
9218         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9219                        "StartTag: invalid element name\n");
9220         return(NULL);
9221     }
9222     *tlen = ctxt->input->cur - ctxt->input->base - cur;
9223
9224     /*
9225      * Now parse the attributes, it ends up with the ending
9226      *
9227      * (S Attribute)* S?
9228      */
9229     SKIP_BLANKS;
9230     GROW;
9231
9232     while (((RAW != '>') &&
9233            ((RAW != '/') || (NXT(1) != '>')) &&
9234            (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
9235         const xmlChar *q = CUR_PTR;
9236         unsigned int cons = ctxt->input->consumed;
9237         int len = -1, alloc = 0;
9238
9239         attname = xmlParseAttribute2(ctxt, prefix, localname,
9240                                      &aprefix, &attvalue, &len, &alloc);
9241         if ((attname == NULL) || (attvalue == NULL))
9242             goto next_attr;
9243         if (len < 0) len = xmlStrlen(attvalue);
9244
9245         if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9246             const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9247             xmlURIPtr uri;
9248
9249             if (URL == NULL) {
9250                 xmlErrMemory(ctxt, "dictionary allocation failure");
9251                 if ((attvalue != NULL) && (alloc != 0))
9252                     xmlFree(attvalue);
9253                 return(NULL);
9254             }
9255             if (*URL != 0) {
9256                 uri = xmlParseURI((const char *) URL);
9257                 if (uri == NULL) {
9258                     xmlNsErr(ctxt, XML_WAR_NS_URI,
9259                              "xmlns: '%s' is not a valid URI\n",
9260                                        URL, NULL, NULL);
9261                 } else {
9262                     if (uri->scheme == NULL) {
9263                         xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9264                                   "xmlns: URI %s is not absolute\n",
9265                                   URL, NULL, NULL);
9266                     }
9267                     xmlFreeURI(uri);
9268                 }
9269                 if (URL == ctxt->str_xml_ns) {
9270                     if (attname != ctxt->str_xml) {
9271                         xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9272                      "xml namespace URI cannot be the default namespace\n",
9273                                  NULL, NULL, NULL);
9274                     }
9275                     goto next_attr;
9276                 }
9277                 if ((len == 29) &&
9278                     (xmlStrEqual(URL,
9279                              BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9280                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9281                          "reuse of the xmlns namespace name is forbidden\n",
9282                              NULL, NULL, NULL);
9283                     goto next_attr;
9284                 }
9285             }
9286             /*
9287              * check that it's not a defined namespace
9288              */
9289             for (j = 1;j <= nbNs;j++)
9290                 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9291                     break;
9292             if (j <= nbNs)
9293                 xmlErrAttributeDup(ctxt, NULL, attname);
9294             else
9295                 if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
9296
9297         } else if (aprefix == ctxt->str_xmlns) {
9298             const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9299             xmlURIPtr uri;
9300
9301             if (attname == ctxt->str_xml) {
9302                 if (URL != ctxt->str_xml_ns) {
9303                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9304                              "xml namespace prefix mapped to wrong URI\n",
9305                              NULL, NULL, NULL);
9306                 }
9307                 /*
9308                  * Do not keep a namespace definition node
9309                  */
9310                 goto next_attr;
9311             }
9312             if (URL == ctxt->str_xml_ns) {
9313                 if (attname != ctxt->str_xml) {
9314                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9315                              "xml namespace URI mapped to wrong prefix\n",
9316                              NULL, NULL, NULL);
9317                 }
9318                 goto next_attr;
9319             }
9320             if (attname == ctxt->str_xmlns) {
9321                 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9322                          "redefinition of the xmlns prefix is forbidden\n",
9323                          NULL, NULL, NULL);
9324                 goto next_attr;
9325             }
9326             if ((len == 29) &&
9327                 (xmlStrEqual(URL,
9328                              BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9329                 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9330                          "reuse of the xmlns namespace name is forbidden\n",
9331                          NULL, NULL, NULL);
9332                 goto next_attr;
9333             }
9334             if ((URL == NULL) || (URL[0] == 0)) {
9335                 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9336                          "xmlns:%s: Empty XML namespace is not allowed\n",
9337                               attname, NULL, NULL);
9338                 goto next_attr;
9339             } else {
9340                 uri = xmlParseURI((const char *) URL);
9341                 if (uri == NULL) {
9342                     xmlNsErr(ctxt, XML_WAR_NS_URI,
9343                          "xmlns:%s: '%s' is not a valid URI\n",
9344                                        attname, URL, NULL);
9345                 } else {
9346                     if ((ctxt->pedantic) && (uri->scheme == NULL)) {
9347                         xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9348                                   "xmlns:%s: URI %s is not absolute\n",
9349                                   attname, URL, NULL);
9350                     }
9351                     xmlFreeURI(uri);
9352                 }
9353             }
9354
9355             /*
9356              * check that it's not a defined namespace
9357              */
9358             for (j = 1;j <= nbNs;j++)
9359                 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9360                     break;
9361             if (j <= nbNs)
9362                 xmlErrAttributeDup(ctxt, aprefix, attname);
9363             else
9364                 if (nsPush(ctxt, attname, URL) > 0) nbNs++;
9365
9366         } else {
9367             /*
9368              * Add the pair to atts
9369              */
9370             if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9371                 if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9372                     goto next_attr;
9373                 }
9374                 maxatts = ctxt->maxatts;
9375                 atts = ctxt->atts;
9376             }
9377             ctxt->attallocs[nratts++] = alloc;
9378             atts[nbatts++] = attname;
9379             atts[nbatts++] = aprefix;
9380             /*
9381              * The namespace URI field is used temporarily to point at the
9382              * base of the current input buffer for non-alloced attributes.
9383              * When the input buffer is reallocated, all the pointers become
9384              * invalid, but they can be reconstructed later.
9385              */
9386             if (alloc)
9387                 atts[nbatts++] = NULL;
9388             else
9389                 atts[nbatts++] = ctxt->input->base;
9390             atts[nbatts++] = attvalue;
9391             attvalue += len;
9392             atts[nbatts++] = attvalue;
9393             /*
9394              * tag if some deallocation is needed
9395              */
9396             if (alloc != 0) attval = 1;
9397             attvalue = NULL; /* moved into atts */
9398         }
9399
9400 next_attr:
9401         if ((attvalue != NULL) && (alloc != 0)) {
9402             xmlFree(attvalue);
9403             attvalue = NULL;
9404         }
9405
9406         GROW
9407         if (ctxt->instate == XML_PARSER_EOF)
9408             break;
9409         if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
9410             break;
9411         if (SKIP_BLANKS == 0) {
9412             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9413                            "attributes construct error\n");
9414             break;
9415         }
9416         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
9417             (attname == NULL) && (attvalue == NULL)) {
9418             xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9419                  "xmlParseStartTag: problem parsing attributes\n");
9420             break;
9421         }
9422         GROW;
9423     }
9424
9425     if (ctxt->input->id != inputid) {
9426         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9427                     "Unexpected change of input\n");
9428         localname = NULL;
9429         goto done;
9430     }
9431
9432     /* Reconstruct attribute value pointers. */
9433     for (i = 0, j = 0; j < nratts; i += 5, j++) {
9434         if (atts[i+2] != NULL) {
9435             /*
9436              * Arithmetic on dangling pointers is technically undefined
9437              * behavior, but well...
9438              */
9439             ptrdiff_t offset = ctxt->input->base - atts[i+2];
9440             atts[i+2]  = NULL;    /* Reset repurposed namespace URI */
9441             atts[i+3] += offset;  /* value */
9442             atts[i+4] += offset;  /* valuend */
9443         }
9444     }
9445
9446     /*
9447      * The attributes defaulting
9448      */
9449     if (ctxt->attsDefault != NULL) {
9450         xmlDefAttrsPtr defaults;
9451
9452         defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
9453         if (defaults != NULL) {
9454             for (i = 0;i < defaults->nbAttrs;i++) {
9455                 attname = defaults->values[5 * i];
9456                 aprefix = defaults->values[5 * i + 1];
9457
9458                 /*
9459                  * special work for namespaces defaulted defs
9460                  */
9461                 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9462                     /*
9463                      * check that it's not a defined namespace
9464                      */
9465                     for (j = 1;j <= nbNs;j++)
9466                         if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9467                             break;
9468                     if (j <= nbNs) continue;
9469
9470                     nsname = xmlGetNamespace(ctxt, NULL);
9471                     if (nsname != defaults->values[5 * i + 2]) {
9472                         if (nsPush(ctxt, NULL,
9473                                    defaults->values[5 * i + 2]) > 0)
9474                             nbNs++;
9475                     }
9476                 } else if (aprefix == ctxt->str_xmlns) {
9477                     /*
9478                      * check that it's not a defined namespace
9479                      */
9480                     for (j = 1;j <= nbNs;j++)
9481                         if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9482                             break;
9483                     if (j <= nbNs) continue;
9484
9485                     nsname = xmlGetNamespace(ctxt, attname);
9486                     if (nsname != defaults->values[2]) {
9487                         if (nsPush(ctxt, attname,
9488                                    defaults->values[5 * i + 2]) > 0)
9489                             nbNs++;
9490                     }
9491                 } else {
9492                     /*
9493                      * check that it's not a defined attribute
9494                      */
9495                     for (j = 0;j < nbatts;j+=5) {
9496                         if ((attname == atts[j]) && (aprefix == atts[j+1]))
9497                             break;
9498                     }
9499                     if (j < nbatts) continue;
9500
9501                     if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9502                         if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9503                             return(NULL);
9504                         }
9505                         maxatts = ctxt->maxatts;
9506                         atts = ctxt->atts;
9507                     }
9508                     atts[nbatts++] = attname;
9509                     atts[nbatts++] = aprefix;
9510                     if (aprefix == NULL)
9511                         atts[nbatts++] = NULL;
9512                     else
9513                         atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
9514                     atts[nbatts++] = defaults->values[5 * i + 2];
9515                     atts[nbatts++] = defaults->values[5 * i + 3];
9516                     if ((ctxt->standalone == 1) &&
9517                         (defaults->values[5 * i + 4] != NULL)) {
9518                         xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
9519           "standalone: attribute %s on %s defaulted from external subset\n",
9520                                          attname, localname);
9521                     }
9522                     nbdef++;
9523                 }
9524             }
9525         }
9526     }
9527
9528     /*
9529      * The attributes checkings
9530      */
9531     for (i = 0; i < nbatts;i += 5) {
9532         /*
9533         * The default namespace does not apply to attribute names.
9534         */
9535         if (atts[i + 1] != NULL) {
9536             nsname = xmlGetNamespace(ctxt, atts[i + 1]);
9537             if (nsname == NULL) {
9538                 xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9539                     "Namespace prefix %s for %s on %s is not defined\n",
9540                     atts[i + 1], atts[i], localname);
9541             }
9542             atts[i + 2] = nsname;
9543         } else
9544             nsname = NULL;
9545         /*
9546          * [ WFC: Unique Att Spec ]
9547          * No attribute name may appear more than once in the same
9548          * start-tag or empty-element tag.
9549          * As extended by the Namespace in XML REC.
9550          */
9551         for (j = 0; j < i;j += 5) {
9552             if (atts[i] == atts[j]) {
9553                 if (atts[i+1] == atts[j+1]) {
9554                     xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
9555                     break;
9556                 }
9557                 if ((nsname != NULL) && (atts[j + 2] == nsname)) {
9558                     xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
9559                              "Namespaced Attribute %s in '%s' redefined\n",
9560                              atts[i], nsname, NULL);
9561                     break;
9562                 }
9563             }
9564         }
9565     }
9566
9567     nsname = xmlGetNamespace(ctxt, prefix);
9568     if ((prefix != NULL) && (nsname == NULL)) {
9569         xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9570                  "Namespace prefix %s on %s is not defined\n",
9571                  prefix, localname, NULL);
9572     }
9573     *pref = prefix;
9574     *URI = nsname;
9575
9576     /*
9577      * SAX: Start of Element !
9578      */
9579     if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
9580         (!ctxt->disableSAX)) {
9581         if (nbNs > 0)
9582             ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9583                           nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
9584                           nbatts / 5, nbdef, atts);
9585         else
9586             ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9587                           nsname, 0, NULL, nbatts / 5, nbdef, atts);
9588     }
9589
9590 done:
9591     /*
9592      * Free up attribute allocated strings if needed
9593      */
9594     if (attval != 0) {
9595         for (i = 3,j = 0; j < nratts;i += 5,j++)
9596             if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9597                 xmlFree((xmlChar *) atts[i]);
9598     }
9599
9600     return(localname);
9601 }
9602
9603 /**
9604  * xmlParseEndTag2:
9605  * @ctxt:  an XML parser context
9606  * @line:  line of the start tag
9607  * @nsNr:  number of namespaces on the start tag
9608  *
9609  * parse an end of tag
9610  *
9611  * [42] ETag ::= '</' Name S? '>'
9612  *
9613  * With namespace
9614  *
9615  * [NS 9] ETag ::= '</' QName S? '>'
9616  */
9617
9618 static void
9619 xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
9620                 const xmlChar *URI, int line, int nsNr, int tlen) {
9621     const xmlChar *name;
9622     size_t curLength;
9623
9624     GROW;
9625     if ((RAW != '<') || (NXT(1) != '/')) {
9626         xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
9627         return;
9628     }
9629     SKIP(2);
9630
9631     curLength = ctxt->input->end - ctxt->input->cur;
9632     if ((tlen > 0) && (curLength >= (size_t)tlen) &&
9633         (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
9634         if ((curLength >= (size_t)(tlen + 1)) &&
9635             (ctxt->input->cur[tlen] == '>')) {
9636             ctxt->input->cur += tlen + 1;
9637             ctxt->input->col += tlen + 1;
9638             goto done;
9639         }
9640         ctxt->input->cur += tlen;
9641         ctxt->input->col += tlen;
9642         name = (xmlChar*)1;
9643     } else {
9644         if (prefix == NULL)
9645             name = xmlParseNameAndCompare(ctxt, ctxt->name);
9646         else
9647             name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
9648     }
9649
9650     /*
9651      * We should definitely be at the ending "S? '>'" part
9652      */
9653     GROW;
9654     if (ctxt->instate == XML_PARSER_EOF)
9655         return;
9656     SKIP_BLANKS;
9657     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
9658         xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
9659     } else
9660         NEXT1;
9661
9662     /*
9663      * [ WFC: Element Type Match ]
9664      * The Name in an element's end-tag must match the element type in the
9665      * start-tag.
9666      *
9667      */
9668     if (name != (xmlChar*)1) {
9669         if (name == NULL) name = BAD_CAST "unparseable";
9670         if ((line == 0) && (ctxt->node != NULL))
9671             line = ctxt->node->line;
9672         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
9673                      "Opening and ending tag mismatch: %s line %d and %s\n",
9674                                 ctxt->name, line, name);
9675     }
9676
9677     /*
9678      * SAX: End of Tag
9679      */
9680 done:
9681     if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9682         (!ctxt->disableSAX))
9683         ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
9684
9685     spacePop(ctxt);
9686     if (nsNr != 0)
9687         nsPop(ctxt, nsNr);
9688     return;
9689 }
9690
9691 /**
9692  * xmlParseCDSect:
9693  * @ctxt:  an XML parser context
9694  *
9695  * Parse escaped pure raw content.
9696  *
9697  * [18] CDSect ::= CDStart CData CDEnd
9698  *
9699  * [19] CDStart ::= '<![CDATA['
9700  *
9701  * [20] Data ::= (Char* - (Char* ']]>' Char*))
9702  *
9703  * [21] CDEnd ::= ']]>'
9704  */
9705 void
9706 xmlParseCDSect(xmlParserCtxtPtr ctxt) {
9707     xmlChar *buf = NULL;
9708     int len = 0;
9709     int size = XML_PARSER_BUFFER_SIZE;
9710     int r, rl;
9711     int s, sl;
9712     int cur, l;
9713     int count = 0;
9714
9715     /* Check 2.6.0 was NXT(0) not RAW */
9716     if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9717         SKIP(9);
9718     } else
9719         return;
9720
9721     ctxt->instate = XML_PARSER_CDATA_SECTION;
9722     r = CUR_CHAR(rl);
9723     if (!IS_CHAR(r)) {
9724         xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9725         ctxt->instate = XML_PARSER_CONTENT;
9726         return;
9727     }
9728     NEXTL(rl);
9729     s = CUR_CHAR(sl);
9730     if (!IS_CHAR(s)) {
9731         xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9732         ctxt->instate = XML_PARSER_CONTENT;
9733         return;
9734     }
9735     NEXTL(sl);
9736     cur = CUR_CHAR(l);
9737     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
9738     if (buf == NULL) {
9739         xmlErrMemory(ctxt, NULL);
9740         return;
9741     }
9742     while (IS_CHAR(cur) &&
9743            ((r != ']') || (s != ']') || (cur != '>'))) {
9744         if (len + 5 >= size) {
9745             xmlChar *tmp;
9746
9747             if ((size > XML_MAX_TEXT_LENGTH) &&
9748                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9749                 xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9750                              "CData section too big found", NULL);
9751                 xmlFree (buf);
9752                 return;
9753             }
9754             tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
9755             if (tmp == NULL) {
9756                 xmlFree(buf);
9757                 xmlErrMemory(ctxt, NULL);
9758                 return;
9759             }
9760             buf = tmp;
9761             size *= 2;
9762         }
9763         COPY_BUF(rl,buf,len,r);
9764         r = s;
9765         rl = sl;
9766         s = cur;
9767         sl = l;
9768         count++;
9769         if (count > 50) {
9770             GROW;
9771             if (ctxt->instate == XML_PARSER_EOF) {
9772                 xmlFree(buf);
9773                 return;
9774             }
9775             count = 0;
9776         }
9777         NEXTL(l);
9778         cur = CUR_CHAR(l);
9779     }
9780     buf[len] = 0;
9781     ctxt->instate = XML_PARSER_CONTENT;
9782     if (cur != '>') {
9783         xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9784                              "CData section not finished\n%.50s\n", buf);
9785         xmlFree(buf);
9786         return;
9787     }
9788     NEXTL(l);
9789
9790     /*
9791      * OK the buffer is to be consumed as cdata.
9792      */
9793     if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
9794         if (ctxt->sax->cdataBlock != NULL)
9795             ctxt->sax->cdataBlock(ctxt->userData, buf, len);
9796         else if (ctxt->sax->characters != NULL)
9797             ctxt->sax->characters(ctxt->userData, buf, len);
9798     }
9799     xmlFree(buf);
9800 }
9801
9802 /**
9803  * xmlParseContent:
9804  * @ctxt:  an XML parser context
9805  *
9806  * Parse a content:
9807  *
9808  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
9809  */
9810
9811 void
9812 xmlParseContent(xmlParserCtxtPtr ctxt) {
9813     GROW;
9814     while ((RAW != 0) &&
9815            ((RAW != '<') || (NXT(1) != '/')) &&
9816            (ctxt->instate != XML_PARSER_EOF)) {
9817         const xmlChar *test = CUR_PTR;
9818         unsigned int cons = ctxt->input->consumed;
9819         const xmlChar *cur = ctxt->input->cur;
9820
9821         /*
9822          * First case : a Processing Instruction.
9823          */
9824         if ((*cur == '<') && (cur[1] == '?')) {
9825             xmlParsePI(ctxt);
9826         }
9827
9828         /*
9829          * Second case : a CDSection
9830          */
9831         /* 2.6.0 test was *cur not RAW */
9832         else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9833             xmlParseCDSect(ctxt);
9834         }
9835
9836         /*
9837          * Third case :  a comment
9838          */
9839         else if ((*cur == '<') && (NXT(1) == '!') &&
9840                  (NXT(2) == '-') && (NXT(3) == '-')) {
9841             xmlParseComment(ctxt);
9842             ctxt->instate = XML_PARSER_CONTENT;
9843         }
9844
9845         /*
9846          * Fourth case :  a sub-element.
9847          */
9848         else if (*cur == '<') {
9849             xmlParseElement(ctxt);
9850         }
9851
9852         /*
9853          * Fifth case : a reference. If if has not been resolved,
9854          *    parsing returns it's Name, create the node
9855          */
9856
9857         else if (*cur == '&') {
9858             xmlParseReference(ctxt);
9859         }
9860
9861         /*
9862          * Last case, text. Note that References are handled directly.
9863          */
9864         else {
9865             xmlParseCharData(ctxt, 0);
9866         }
9867
9868         GROW;
9869         SHRINK;
9870
9871         if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
9872             xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9873                         "detected an error in element content\n");
9874             xmlHaltParser(ctxt);
9875             break;
9876         }
9877     }
9878 }
9879
9880 /**
9881  * xmlParseElement:
9882  * @ctxt:  an XML parser context
9883  *
9884  * parse an XML element, this is highly recursive
9885  *
9886  * [39] element ::= EmptyElemTag | STag content ETag
9887  *
9888  * [ WFC: Element Type Match ]
9889  * The Name in an element's end-tag must match the element type in the
9890  * start-tag.
9891  *
9892  */
9893
9894 void
9895 xmlParseElement(xmlParserCtxtPtr ctxt) {
9896     const xmlChar *name;
9897     const xmlChar *prefix = NULL;
9898     const xmlChar *URI = NULL;
9899     xmlParserNodeInfo node_info;
9900     int line, tlen = 0;
9901     xmlNodePtr ret;
9902     int nsNr = ctxt->nsNr;
9903
9904     if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
9905         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9906         xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
9907                  "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
9908                           xmlParserMaxDepth);
9909         xmlHaltParser(ctxt);
9910         return;
9911     }
9912
9913     /* Capture start position */
9914     if (ctxt->record_info) {
9915         node_info.begin_pos = ctxt->input->consumed +
9916                           (CUR_PTR - ctxt->input->base);
9917         node_info.begin_line = ctxt->input->line;
9918     }
9919
9920     if (ctxt->spaceNr == 0)
9921         spacePush(ctxt, -1);
9922     else if (*ctxt->space == -2)
9923         spacePush(ctxt, -1);
9924     else
9925         spacePush(ctxt, *ctxt->space);
9926
9927     line = ctxt->input->line;
9928 #ifdef LIBXML_SAX1_ENABLED
9929     if (ctxt->sax2)
9930 #endif /* LIBXML_SAX1_ENABLED */
9931         name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
9932 #ifdef LIBXML_SAX1_ENABLED
9933     else
9934         name = xmlParseStartTag(ctxt);
9935 #endif /* LIBXML_SAX1_ENABLED */
9936     if (ctxt->instate == XML_PARSER_EOF)
9937         return;
9938     if (name == NULL) {
9939         spacePop(ctxt);
9940         return;
9941     }
9942     namePush(ctxt, name);
9943     ret = ctxt->node;
9944
9945 #ifdef LIBXML_VALID_ENABLED
9946     /*
9947      * [ VC: Root Element Type ]
9948      * The Name in the document type declaration must match the element
9949      * type of the root element.
9950      */
9951     if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
9952         ctxt->node && (ctxt->node == ctxt->myDoc->children))
9953         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
9954 #endif /* LIBXML_VALID_ENABLED */
9955
9956     /*
9957      * Check for an Empty Element.
9958      */
9959     if ((RAW == '/') && (NXT(1) == '>')) {
9960         SKIP(2);
9961         if (ctxt->sax2) {
9962             if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9963                 (!ctxt->disableSAX))
9964                 ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
9965 #ifdef LIBXML_SAX1_ENABLED
9966         } else {
9967             if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
9968                 (!ctxt->disableSAX))
9969                 ctxt->sax->endElement(ctxt->userData, name);
9970 #endif /* LIBXML_SAX1_ENABLED */
9971         }
9972         namePop(ctxt);
9973         spacePop(ctxt);
9974         if (nsNr != ctxt->nsNr)
9975             nsPop(ctxt, ctxt->nsNr - nsNr);
9976         if ( ret != NULL && ctxt->record_info ) {
9977            node_info.end_pos = ctxt->input->consumed +
9978                               (CUR_PTR - ctxt->input->base);
9979            node_info.end_line = ctxt->input->line;
9980            node_info.node = ret;
9981            xmlParserAddNodeInfo(ctxt, &node_info);
9982         }
9983         return;
9984     }
9985     if (RAW == '>') {
9986         NEXT1;
9987     } else {
9988         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
9989                      "Couldn't find end of Start Tag %s line %d\n",
9990                                 name, line, NULL);
9991
9992         /*
9993          * end of parsing of this node.
9994          */
9995         nodePop(ctxt);
9996         namePop(ctxt);
9997         spacePop(ctxt);
9998         if (nsNr != ctxt->nsNr)
9999             nsPop(ctxt, ctxt->nsNr - nsNr);
10000
10001         /*
10002          * Capture end position and add node
10003          */
10004         if ( ret != NULL && ctxt->record_info ) {
10005            node_info.end_pos = ctxt->input->consumed +
10006                               (CUR_PTR - ctxt->input->base);
10007            node_info.end_line = ctxt->input->line;
10008            node_info.node = ret;
10009            xmlParserAddNodeInfo(ctxt, &node_info);
10010         }
10011         return;
10012     }
10013
10014     /*
10015      * Parse the content of the element:
10016      */
10017     xmlParseContent(ctxt);
10018     if (ctxt->instate == XML_PARSER_EOF)
10019         return;
10020     if (!IS_BYTE_CHAR(RAW)) {
10021         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
10022          "Premature end of data in tag %s line %d\n",
10023                                 name, line, NULL);
10024
10025         /*
10026          * end of parsing of this node.
10027          */
10028         nodePop(ctxt);
10029         namePop(ctxt);
10030         spacePop(ctxt);
10031         if (nsNr != ctxt->nsNr)
10032             nsPop(ctxt, ctxt->nsNr - nsNr);
10033         return;
10034     }
10035
10036     /*
10037      * parse the end of tag: '</' should be here.
10038      */
10039     if (ctxt->sax2) {
10040         xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
10041         namePop(ctxt);
10042     }
10043 #ifdef LIBXML_SAX1_ENABLED
10044       else
10045         xmlParseEndTag1(ctxt, line);
10046 #endif /* LIBXML_SAX1_ENABLED */
10047
10048     /*
10049      * Capture end position and add node
10050      */
10051     if ( ret != NULL && ctxt->record_info ) {
10052        node_info.end_pos = ctxt->input->consumed +
10053                           (CUR_PTR - ctxt->input->base);
10054        node_info.end_line = ctxt->input->line;
10055        node_info.node = ret;
10056        xmlParserAddNodeInfo(ctxt, &node_info);
10057     }
10058 }
10059
10060 /**
10061  * xmlParseVersionNum:
10062  * @ctxt:  an XML parser context
10063  *
10064  * parse the XML version value.
10065  *
10066  * [26] VersionNum ::= '1.' [0-9]+
10067  *
10068  * In practice allow [0-9].[0-9]+ at that level
10069  *
10070  * Returns the string giving the XML version number, or NULL
10071  */
10072 xmlChar *
10073 xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
10074     xmlChar *buf = NULL;
10075     int len = 0;
10076     int size = 10;
10077     xmlChar cur;
10078
10079     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
10080     if (buf == NULL) {
10081         xmlErrMemory(ctxt, NULL);
10082         return(NULL);
10083     }
10084     cur = CUR;
10085     if (!((cur >= '0') && (cur <= '9'))) {
10086         xmlFree(buf);
10087         return(NULL);
10088     }
10089     buf[len++] = cur;
10090     NEXT;
10091     cur=CUR;
10092     if (cur != '.') {
10093         xmlFree(buf);
10094         return(NULL);
10095     }
10096     buf[len++] = cur;
10097     NEXT;
10098     cur=CUR;
10099     while ((cur >= '0') && (cur <= '9')) {
10100         if (len + 1 >= size) {
10101             xmlChar *tmp;
10102
10103             size *= 2;
10104             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
10105             if (tmp == NULL) {
10106                 xmlFree(buf);
10107                 xmlErrMemory(ctxt, NULL);
10108                 return(NULL);
10109             }
10110             buf = tmp;
10111         }
10112         buf[len++] = cur;
10113         NEXT;
10114         cur=CUR;
10115     }
10116     buf[len] = 0;
10117     return(buf);
10118 }
10119
10120 /**
10121  * xmlParseVersionInfo:
10122  * @ctxt:  an XML parser context
10123  *
10124  * parse the XML version.
10125  *
10126  * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
10127  *
10128  * [25] Eq ::= S? '=' S?
10129  *
10130  * Returns the version string, e.g. "1.0"
10131  */
10132
10133 xmlChar *
10134 xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
10135     xmlChar *version = NULL;
10136
10137     if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
10138         SKIP(7);
10139         SKIP_BLANKS;
10140         if (RAW != '=') {
10141             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10142             return(NULL);
10143         }
10144         NEXT;
10145         SKIP_BLANKS;
10146         if (RAW == '"') {
10147             NEXT;
10148             version = xmlParseVersionNum(ctxt);
10149             if (RAW != '"') {
10150                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10151             } else
10152                 NEXT;
10153         } else if (RAW == '\''){
10154             NEXT;
10155             version = xmlParseVersionNum(ctxt);
10156             if (RAW != '\'') {
10157                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10158             } else
10159                 NEXT;
10160         } else {
10161             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10162         }
10163     }
10164     return(version);
10165 }
10166
10167 /**
10168  * xmlParseEncName:
10169  * @ctxt:  an XML parser context
10170  *
10171  * parse the XML encoding name
10172  *
10173  * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
10174  *
10175  * Returns the encoding name value or NULL
10176  */
10177 xmlChar *
10178 xmlParseEncName(xmlParserCtxtPtr ctxt) {
10179     xmlChar *buf = NULL;
10180     int len = 0;
10181     int size = 10;
10182     xmlChar cur;
10183
10184     cur = CUR;
10185     if (((cur >= 'a') && (cur <= 'z')) ||
10186         ((cur >= 'A') && (cur <= 'Z'))) {
10187         buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
10188         if (buf == NULL) {
10189             xmlErrMemory(ctxt, NULL);
10190             return(NULL);
10191         }
10192
10193         buf[len++] = cur;
10194         NEXT;
10195         cur = CUR;
10196         while (((cur >= 'a') && (cur <= 'z')) ||
10197                ((cur >= 'A') && (cur <= 'Z')) ||
10198                ((cur >= '0') && (cur <= '9')) ||
10199                (cur == '.') || (cur == '_') ||
10200                (cur == '-')) {
10201             if (len + 1 >= size) {
10202                 xmlChar *tmp;
10203
10204                 size *= 2;
10205                 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
10206                 if (tmp == NULL) {
10207                     xmlErrMemory(ctxt, NULL);
10208                     xmlFree(buf);
10209                     return(NULL);
10210                 }
10211                 buf = tmp;
10212             }
10213             buf[len++] = cur;
10214             NEXT;
10215             cur = CUR;
10216             if (cur == 0) {
10217                 SHRINK;
10218                 GROW;
10219                 cur = CUR;
10220             }
10221         }
10222         buf[len] = 0;
10223     } else {
10224         xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
10225     }
10226     return(buf);
10227 }
10228
10229 /**
10230  * xmlParseEncodingDecl:
10231  * @ctxt:  an XML parser context
10232  *
10233  * parse the XML encoding declaration
10234  *
10235  * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
10236  *
10237  * this setups the conversion filters.
10238  *
10239  * Returns the encoding value or NULL
10240  */
10241
10242 const xmlChar *
10243 xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
10244     xmlChar *encoding = NULL;
10245
10246     SKIP_BLANKS;
10247     if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
10248         SKIP(8);
10249         SKIP_BLANKS;
10250         if (RAW != '=') {
10251             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10252             return(NULL);
10253         }
10254         NEXT;
10255         SKIP_BLANKS;
10256         if (RAW == '"') {
10257             NEXT;
10258             encoding = xmlParseEncName(ctxt);
10259             if (RAW != '"') {
10260                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10261                 xmlFree((xmlChar *) encoding);
10262                 return(NULL);
10263             } else
10264                 NEXT;
10265         } else if (RAW == '\''){
10266             NEXT;
10267             encoding = xmlParseEncName(ctxt);
10268             if (RAW != '\'') {
10269                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10270                 xmlFree((xmlChar *) encoding);
10271                 return(NULL);
10272             } else
10273                 NEXT;
10274         } else {
10275             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10276         }
10277
10278         /*
10279          * Non standard parsing, allowing the user to ignore encoding
10280          */
10281         if (ctxt->options & XML_PARSE_IGNORE_ENC) {
10282             xmlFree((xmlChar *) encoding);
10283             return(NULL);
10284         }
10285
10286         /*
10287          * UTF-16 encoding stwich has already taken place at this stage,
10288          * more over the little-endian/big-endian selection is already done
10289          */
10290         if ((encoding != NULL) &&
10291             ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
10292              (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
10293             /*
10294              * If no encoding was passed to the parser, that we are
10295              * using UTF-16 and no decoder is present i.e. the
10296              * document is apparently UTF-8 compatible, then raise an
10297              * encoding mismatch fatal error
10298              */
10299             if ((ctxt->encoding == NULL) &&
10300                 (ctxt->input->buf != NULL) &&
10301                 (ctxt->input->buf->encoder == NULL)) {
10302                 xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
10303                   "Document labelled UTF-16 but has UTF-8 content\n");
10304             }
10305             if (ctxt->encoding != NULL)
10306                 xmlFree((xmlChar *) ctxt->encoding);
10307             ctxt->encoding = encoding;
10308         }
10309         /*
10310          * UTF-8 encoding is handled natively
10311          */
10312         else if ((encoding != NULL) &&
10313             ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
10314              (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
10315             if (ctxt->encoding != NULL)
10316                 xmlFree((xmlChar *) ctxt->encoding);
10317             ctxt->encoding = encoding;
10318         }
10319         else if (encoding != NULL) {
10320             xmlCharEncodingHandlerPtr handler;
10321
10322             if (ctxt->input->encoding != NULL)
10323                 xmlFree((xmlChar *) ctxt->input->encoding);
10324             ctxt->input->encoding = encoding;
10325
10326             handler = xmlFindCharEncodingHandler((const char *) encoding);
10327             if (handler != NULL) {
10328                 if (xmlSwitchToEncoding(ctxt, handler) < 0) {
10329                     /* failed to convert */
10330                     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
10331                     return(NULL);
10332                 }
10333             } else {
10334                 xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
10335                         "Unsupported encoding %s\n", encoding);
10336                 return(NULL);
10337             }
10338         }
10339     }
10340     return(encoding);
10341 }
10342
10343 /**
10344  * xmlParseSDDecl:
10345  * @ctxt:  an XML parser context
10346  *
10347  * parse the XML standalone declaration
10348  *
10349  * [32] SDDecl ::= S 'standalone' Eq
10350  *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
10351  *
10352  * [ VC: Standalone Document Declaration ]
10353  * TODO The standalone document declaration must have the value "no"
10354  * if any external markup declarations contain declarations of:
10355  *  - attributes with default values, if elements to which these
10356  *    attributes apply appear in the document without specifications
10357  *    of values for these attributes, or
10358  *  - entities (other than amp, lt, gt, apos, quot), if references
10359  *    to those entities appear in the document, or
10360  *  - attributes with values subject to normalization, where the
10361  *    attribute appears in the document with a value which will change
10362  *    as a result of normalization, or
10363  *  - element types with element content, if white space occurs directly
10364  *    within any instance of those types.
10365  *
10366  * Returns:
10367  *   1 if standalone="yes"
10368  *   0 if standalone="no"
10369  *  -2 if standalone attribute is missing or invalid
10370  *        (A standalone value of -2 means that the XML declaration was found,
10371  *         but no value was specified for the standalone attribute).
10372  */
10373
10374 int
10375 xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
10376     int standalone = -2;
10377
10378     SKIP_BLANKS;
10379     if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
10380         SKIP(10);
10381         SKIP_BLANKS;
10382         if (RAW != '=') {
10383             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10384             return(standalone);
10385         }
10386         NEXT;
10387         SKIP_BLANKS;
10388         if (RAW == '\''){
10389             NEXT;
10390             if ((RAW == 'n') && (NXT(1) == 'o')) {
10391                 standalone = 0;
10392                 SKIP(2);
10393             } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10394                        (NXT(2) == 's')) {
10395                 standalone = 1;
10396                 SKIP(3);
10397             } else {
10398                 xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10399             }
10400             if (RAW != '\'') {
10401                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10402             } else
10403                 NEXT;
10404         } else if (RAW == '"'){
10405             NEXT;
10406             if ((RAW == 'n') && (NXT(1) == 'o')) {
10407                 standalone = 0;
10408                 SKIP(2);
10409             } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10410                        (NXT(2) == 's')) {
10411                 standalone = 1;
10412                 SKIP(3);
10413             } else {
10414                 xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10415             }
10416             if (RAW != '"') {
10417                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10418             } else
10419                 NEXT;
10420         } else {
10421             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10422         }
10423     }
10424     return(standalone);
10425 }
10426
10427 /**
10428  * xmlParseXMLDecl:
10429  * @ctxt:  an XML parser context
10430  *
10431  * parse an XML declaration header
10432  *
10433  * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
10434  */
10435
10436 void
10437 xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
10438     xmlChar *version;
10439
10440     /*
10441      * This value for standalone indicates that the document has an
10442      * XML declaration but it does not have a standalone attribute.
10443      * It will be overwritten later if a standalone attribute is found.
10444      */
10445     ctxt->input->standalone = -2;
10446
10447     /*
10448      * We know that '<?xml' is here.
10449      */
10450     SKIP(5);
10451
10452     if (!IS_BLANK_CH(RAW)) {
10453         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
10454                        "Blank needed after '<?xml'\n");
10455     }
10456     SKIP_BLANKS;
10457
10458     /*
10459      * We must have the VersionInfo here.
10460      */
10461     version = xmlParseVersionInfo(ctxt);
10462     if (version == NULL) {
10463         xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
10464     } else {
10465         if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
10466             /*
10467              * Changed here for XML-1.0 5th edition
10468              */
10469             if (ctxt->options & XML_PARSE_OLD10) {
10470                 xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10471                                   "Unsupported version '%s'\n",
10472                                   version);
10473             } else {
10474                 if ((version[0] == '1') && ((version[1] == '.'))) {
10475                     xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
10476                                   "Unsupported version '%s'\n",
10477                                   version, NULL);
10478                 } else {
10479                     xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10480                                       "Unsupported version '%s'\n",
10481                                       version);
10482                 }
10483             }
10484         }
10485         if (ctxt->version != NULL)
10486             xmlFree((void *) ctxt->version);
10487         ctxt->version = version;
10488     }
10489
10490     /*
10491      * We may have the encoding declaration
10492      */
10493     if (!IS_BLANK_CH(RAW)) {
10494         if ((RAW == '?') && (NXT(1) == '>')) {
10495             SKIP(2);
10496             return;
10497         }
10498         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10499     }
10500     xmlParseEncodingDecl(ctxt);
10501     if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
10502          (ctxt->instate == XML_PARSER_EOF)) {
10503         /*
10504          * The XML REC instructs us to stop parsing right here
10505          */
10506         return;
10507     }
10508
10509     /*
10510      * We may have the standalone status.
10511      */
10512     if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
10513         if ((RAW == '?') && (NXT(1) == '>')) {
10514             SKIP(2);
10515             return;
10516         }
10517         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10518     }
10519
10520     /*
10521      * We can grow the input buffer freely at that point
10522      */
10523     GROW;
10524
10525     SKIP_BLANKS;
10526     ctxt->input->standalone = xmlParseSDDecl(ctxt);
10527
10528     SKIP_BLANKS;
10529     if ((RAW == '?') && (NXT(1) == '>')) {
10530         SKIP(2);
10531     } else if (RAW == '>') {
10532         /* Deprecated old WD ... */
10533         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10534         NEXT;
10535     } else {
10536         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10537         MOVETO_ENDTAG(CUR_PTR);
10538         NEXT;
10539     }
10540 }
10541
10542 /**
10543  * xmlParseMisc:
10544  * @ctxt:  an XML parser context
10545  *
10546  * parse an XML Misc* optional field.
10547  *
10548  * [27] Misc ::= Comment | PI |  S
10549  */
10550
10551 void
10552 xmlParseMisc(xmlParserCtxtPtr ctxt) {
10553     while ((ctxt->instate != XML_PARSER_EOF) &&
10554            (((RAW == '<') && (NXT(1) == '?')) ||
10555             (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
10556             IS_BLANK_CH(CUR))) {
10557         if ((RAW == '<') && (NXT(1) == '?')) {
10558             xmlParsePI(ctxt);
10559         } else if (IS_BLANK_CH(CUR)) {
10560             NEXT;
10561         } else
10562             xmlParseComment(ctxt);
10563     }
10564 }
10565
10566 /**
10567  * xmlParseDocument:
10568  * @ctxt:  an XML parser context
10569  *
10570  * parse an XML document (and build a tree if using the standard SAX
10571  * interface).
10572  *
10573  * [1] document ::= prolog element Misc*
10574  *
10575  * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
10576  *
10577  * Returns 0, -1 in case of error. the parser context is augmented
10578  *                as a result of the parsing.
10579  */
10580
10581 int
10582 xmlParseDocument(xmlParserCtxtPtr ctxt) {
10583     xmlChar start[4];
10584     xmlCharEncoding enc;
10585
10586     xmlInitParser();
10587
10588     if ((ctxt == NULL) || (ctxt->input == NULL))
10589         return(-1);
10590
10591     GROW;
10592
10593     /*
10594      * SAX: detecting the level.
10595      */
10596     xmlDetectSAX2(ctxt);
10597
10598     /*
10599      * SAX: beginning of the document processing.
10600      */
10601     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10602         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10603     if (ctxt->instate == XML_PARSER_EOF)
10604         return(-1);
10605
10606     if ((ctxt->encoding == NULL) &&
10607         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
10608         /*
10609          * Get the 4 first bytes and decode the charset
10610          * if enc != XML_CHAR_ENCODING_NONE
10611          * plug some encoding conversion routines.
10612          */
10613         start[0] = RAW;
10614         start[1] = NXT(1);
10615         start[2] = NXT(2);
10616         start[3] = NXT(3);
10617         enc = xmlDetectCharEncoding(&start[0], 4);
10618         if (enc != XML_CHAR_ENCODING_NONE) {
10619             xmlSwitchEncoding(ctxt, enc);
10620         }
10621     }
10622
10623
10624     if (CUR == 0) {
10625         xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10626         return(-1);
10627     }
10628
10629     /*
10630      * Check for the XMLDecl in the Prolog.
10631      * do not GROW here to avoid the detected encoder to decode more
10632      * than just the first line, unless the amount of data is really
10633      * too small to hold "<?xml version="1.0" encoding="foo"
10634      */
10635     if ((ctxt->input->end - ctxt->input->cur) < 35) {
10636        GROW;
10637     }
10638     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10639
10640         /*
10641          * Note that we will switch encoding on the fly.
10642          */
10643         xmlParseXMLDecl(ctxt);
10644         if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
10645             (ctxt->instate == XML_PARSER_EOF)) {
10646             /*
10647              * The XML REC instructs us to stop parsing right here
10648              */
10649             return(-1);
10650         }
10651         ctxt->standalone = ctxt->input->standalone;
10652         SKIP_BLANKS;
10653     } else {
10654         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10655     }
10656     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10657         ctxt->sax->startDocument(ctxt->userData);
10658     if (ctxt->instate == XML_PARSER_EOF)
10659         return(-1);
10660     if ((ctxt->myDoc != NULL) && (ctxt->input != NULL) &&
10661         (ctxt->input->buf != NULL) && (ctxt->input->buf->compressed >= 0)) {
10662         ctxt->myDoc->compression = ctxt->input->buf->compressed;
10663     }
10664
10665     /*
10666      * The Misc part of the Prolog
10667      */
10668     GROW;
10669     xmlParseMisc(ctxt);
10670
10671     /*
10672      * Then possibly doc type declaration(s) and more Misc
10673      * (doctypedecl Misc*)?
10674      */
10675     GROW;
10676     if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
10677
10678         ctxt->inSubset = 1;
10679         xmlParseDocTypeDecl(ctxt);
10680         if (RAW == '[') {
10681             ctxt->instate = XML_PARSER_DTD;
10682             xmlParseInternalSubset(ctxt);
10683             if (ctxt->instate == XML_PARSER_EOF)
10684                 return(-1);
10685         }
10686
10687         /*
10688          * Create and update the external subset.
10689          */
10690         ctxt->inSubset = 2;
10691         if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
10692             (!ctxt->disableSAX))
10693             ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
10694                                       ctxt->extSubSystem, ctxt->extSubURI);
10695         if (ctxt->instate == XML_PARSER_EOF)
10696             return(-1);
10697         ctxt->inSubset = 0;
10698
10699         xmlCleanSpecialAttr(ctxt);
10700
10701         ctxt->instate = XML_PARSER_PROLOG;
10702         xmlParseMisc(ctxt);
10703     }
10704
10705     /*
10706      * Time to start parsing the tree itself
10707      */
10708     GROW;
10709     if (RAW != '<') {
10710         xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
10711                        "Start tag expected, '<' not found\n");
10712     } else {
10713         ctxt->instate = XML_PARSER_CONTENT;
10714         xmlParseElement(ctxt);
10715         ctxt->instate = XML_PARSER_EPILOG;
10716
10717
10718         /*
10719          * The Misc part at the end
10720          */
10721         xmlParseMisc(ctxt);
10722
10723         if (RAW != 0) {
10724             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10725         }
10726         ctxt->instate = XML_PARSER_EOF;
10727     }
10728
10729     /*
10730      * SAX: end of the document processing.
10731      */
10732     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10733         ctxt->sax->endDocument(ctxt->userData);
10734
10735     /*
10736      * Remove locally kept entity definitions if the tree was not built
10737      */
10738     if ((ctxt->myDoc != NULL) &&
10739         (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
10740         xmlFreeDoc(ctxt->myDoc);
10741         ctxt->myDoc = NULL;
10742     }
10743
10744     if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
10745         ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
10746         if (ctxt->valid)
10747             ctxt->myDoc->properties |= XML_DOC_DTDVALID;
10748         if (ctxt->nsWellFormed)
10749             ctxt->myDoc->properties |= XML_DOC_NSVALID;
10750         if (ctxt->options & XML_PARSE_OLD10)
10751             ctxt->myDoc->properties |= XML_DOC_OLD10;
10752     }
10753     if (! ctxt->wellFormed) {
10754         ctxt->valid = 0;
10755         return(-1);
10756     }
10757     return(0);
10758 }
10759
10760 /**
10761  * xmlParseExtParsedEnt:
10762  * @ctxt:  an XML parser context
10763  *
10764  * parse a general parsed entity
10765  * An external general parsed entity is well-formed if it matches the
10766  * production labeled extParsedEnt.
10767  *
10768  * [78] extParsedEnt ::= TextDecl? content
10769  *
10770  * Returns 0, -1 in case of error. the parser context is augmented
10771  *                as a result of the parsing.
10772  */
10773
10774 int
10775 xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
10776     xmlChar start[4];
10777     xmlCharEncoding enc;
10778
10779     if ((ctxt == NULL) || (ctxt->input == NULL))
10780         return(-1);
10781
10782     xmlDefaultSAXHandlerInit();
10783
10784     xmlDetectSAX2(ctxt);
10785
10786     GROW;
10787
10788     /*
10789      * SAX: beginning of the document processing.
10790      */
10791     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10792         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10793
10794     /*
10795      * Get the 4 first bytes and decode the charset
10796      * if enc != XML_CHAR_ENCODING_NONE
10797      * plug some encoding conversion routines.
10798      */
10799     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
10800         start[0] = RAW;
10801         start[1] = NXT(1);
10802         start[2] = NXT(2);
10803         start[3] = NXT(3);
10804         enc = xmlDetectCharEncoding(start, 4);
10805         if (enc != XML_CHAR_ENCODING_NONE) {
10806             xmlSwitchEncoding(ctxt, enc);
10807         }
10808     }
10809
10810
10811     if (CUR == 0) {
10812         xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10813     }
10814
10815     /*
10816      * Check for the XMLDecl in the Prolog.
10817      */
10818     GROW;
10819     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10820
10821         /*
10822          * Note that we will switch encoding on the fly.
10823          */
10824         xmlParseXMLDecl(ctxt);
10825         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10826             /*
10827              * The XML REC instructs us to stop parsing right here
10828              */
10829             return(-1);
10830         }
10831         SKIP_BLANKS;
10832     } else {
10833         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10834     }
10835     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10836         ctxt->sax->startDocument(ctxt->userData);
10837     if (ctxt->instate == XML_PARSER_EOF)
10838         return(-1);
10839
10840     /*
10841      * Doing validity checking on chunk doesn't make sense
10842      */
10843     ctxt->instate = XML_PARSER_CONTENT;
10844     ctxt->validate = 0;
10845     ctxt->loadsubset = 0;
10846     ctxt->depth = 0;
10847
10848     xmlParseContent(ctxt);
10849     if (ctxt->instate == XML_PARSER_EOF)
10850         return(-1);
10851
10852     if ((RAW == '<') && (NXT(1) == '/')) {
10853         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
10854     } else if (RAW != 0) {
10855         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
10856     }
10857
10858     /*
10859      * SAX: end of the document processing.
10860      */
10861     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10862         ctxt->sax->endDocument(ctxt->userData);
10863
10864     if (! ctxt->wellFormed) return(-1);
10865     return(0);
10866 }
10867
10868 #ifdef LIBXML_PUSH_ENABLED
10869 /************************************************************************
10870  *                                                                      *
10871  *              Progressive parsing interfaces                          *
10872  *                                                                      *
10873  ************************************************************************/
10874
10875 /**
10876  * xmlParseLookupSequence:
10877  * @ctxt:  an XML parser context
10878  * @first:  the first char to lookup
10879  * @next:  the next char to lookup or zero
10880  * @third:  the next char to lookup or zero
10881  *
10882  * Try to find if a sequence (first, next, third) or  just (first next) or
10883  * (first) is available in the input stream.
10884  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
10885  * to avoid rescanning sequences of bytes, it DOES change the state of the
10886  * parser, do not use liberally.
10887  *
10888  * Returns the index to the current parsing point if the full sequence
10889  *      is available, -1 otherwise.
10890  */
10891 static int
10892 xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
10893                        xmlChar next, xmlChar third) {
10894     int base, len;
10895     xmlParserInputPtr in;
10896     const xmlChar *buf;
10897
10898     in = ctxt->input;
10899     if (in == NULL) return(-1);
10900     base = in->cur - in->base;
10901     if (base < 0) return(-1);
10902     if (ctxt->checkIndex > base)
10903         base = ctxt->checkIndex;
10904     if (in->buf == NULL) {
10905         buf = in->base;
10906         len = in->length;
10907     } else {
10908         buf = xmlBufContent(in->buf->buffer);
10909         len = xmlBufUse(in->buf->buffer);
10910     }
10911     /* take into account the sequence length */
10912     if (third) len -= 2;
10913     else if (next) len --;
10914     for (;base < len;base++) {
10915         if (buf[base] == first) {
10916             if (third != 0) {
10917                 if ((buf[base + 1] != next) ||
10918                     (buf[base + 2] != third)) continue;
10919             } else if (next != 0) {
10920                 if (buf[base + 1] != next) continue;
10921             }
10922             ctxt->checkIndex = 0;
10923 #ifdef DEBUG_PUSH
10924             if (next == 0)
10925                 xmlGenericError(xmlGenericErrorContext,
10926                         "PP: lookup '%c' found at %d\n",
10927                         first, base);
10928             else if (third == 0)
10929                 xmlGenericError(xmlGenericErrorContext,
10930                         "PP: lookup '%c%c' found at %d\n",
10931                         first, next, base);
10932             else
10933                 xmlGenericError(xmlGenericErrorContext,
10934                         "PP: lookup '%c%c%c' found at %d\n",
10935                         first, next, third, base);
10936 #endif
10937             return(base - (in->cur - in->base));
10938         }
10939     }
10940     ctxt->checkIndex = base;
10941 #ifdef DEBUG_PUSH
10942     if (next == 0)
10943         xmlGenericError(xmlGenericErrorContext,
10944                 "PP: lookup '%c' failed\n", first);
10945     else if (third == 0)
10946         xmlGenericError(xmlGenericErrorContext,
10947                 "PP: lookup '%c%c' failed\n", first, next);
10948     else
10949         xmlGenericError(xmlGenericErrorContext,
10950                 "PP: lookup '%c%c%c' failed\n", first, next, third);
10951 #endif
10952     return(-1);
10953 }
10954
10955 /**
10956  * xmlParseGetLasts:
10957  * @ctxt:  an XML parser context
10958  * @lastlt:  pointer to store the last '<' from the input
10959  * @lastgt:  pointer to store the last '>' from the input
10960  *
10961  * Lookup the last < and > in the current chunk
10962  */
10963 static void
10964 xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
10965                  const xmlChar **lastgt) {
10966     const xmlChar *tmp;
10967
10968     if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
10969         xmlGenericError(xmlGenericErrorContext,
10970                     "Internal error: xmlParseGetLasts\n");
10971         return;
10972     }
10973     if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
10974         tmp = ctxt->input->end;
10975         tmp--;
10976         while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
10977         if (tmp < ctxt->input->base) {
10978             *lastlt = NULL;
10979             *lastgt = NULL;
10980         } else {
10981             *lastlt = tmp;
10982             tmp++;
10983             while ((tmp < ctxt->input->end) && (*tmp != '>')) {
10984                 if (*tmp == '\'') {
10985                     tmp++;
10986                     while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
10987                     if (tmp < ctxt->input->end) tmp++;
10988                 } else if (*tmp == '"') {
10989                     tmp++;
10990                     while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
10991                     if (tmp < ctxt->input->end) tmp++;
10992                 } else
10993                     tmp++;
10994             }
10995             if (tmp < ctxt->input->end)
10996                 *lastgt = tmp;
10997             else {
10998                 tmp = *lastlt;
10999                 tmp--;
11000                 while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
11001                 if (tmp >= ctxt->input->base)
11002                     *lastgt = tmp;
11003                 else
11004                     *lastgt = NULL;
11005             }
11006         }
11007     } else {
11008         *lastlt = NULL;
11009         *lastgt = NULL;
11010     }
11011 }
11012 /**
11013  * xmlCheckCdataPush:
11014  * @cur: pointer to the block of characters
11015  * @len: length of the block in bytes
11016  * @complete: 1 if complete CDATA block is passed in, 0 if partial block
11017  *
11018  * Check that the block of characters is okay as SCdata content [20]
11019  *
11020  * Returns the number of bytes to pass if okay, a negative index where an
11021  *         UTF-8 error occurred otherwise
11022  */
11023 static int
11024 xmlCheckCdataPush(const xmlChar *utf, int len, int complete) {
11025     int ix;
11026     unsigned char c;
11027     int codepoint;
11028
11029     if ((utf == NULL) || (len <= 0))
11030         return(0);
11031
11032     for (ix = 0; ix < len;) {      /* string is 0-terminated */
11033         c = utf[ix];
11034         if ((c & 0x80) == 0x00) {       /* 1-byte code, starts with 10 */
11035             if (c >= 0x20)
11036                 ix++;
11037             else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
11038                 ix++;
11039             else
11040                 return(-ix);
11041         } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
11042             if (ix + 2 > len) return(complete ? -ix : ix);
11043             if ((utf[ix+1] & 0xc0 ) != 0x80)
11044                 return(-ix);
11045             codepoint = (utf[ix] & 0x1f) << 6;
11046             codepoint |= utf[ix+1] & 0x3f;
11047             if (!xmlIsCharQ(codepoint))
11048                 return(-ix);
11049             ix += 2;
11050         } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
11051             if (ix + 3 > len) return(complete ? -ix : ix);
11052             if (((utf[ix+1] & 0xc0) != 0x80) ||
11053                 ((utf[ix+2] & 0xc0) != 0x80))
11054                     return(-ix);
11055             codepoint = (utf[ix] & 0xf) << 12;
11056             codepoint |= (utf[ix+1] & 0x3f) << 6;
11057             codepoint |= utf[ix+2] & 0x3f;
11058             if (!xmlIsCharQ(codepoint))
11059                 return(-ix);
11060             ix += 3;
11061         } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
11062             if (ix + 4 > len) return(complete ? -ix : ix);
11063             if (((utf[ix+1] & 0xc0) != 0x80) ||
11064                 ((utf[ix+2] & 0xc0) != 0x80) ||
11065                 ((utf[ix+3] & 0xc0) != 0x80))
11066                     return(-ix);
11067             codepoint = (utf[ix] & 0x7) << 18;
11068             codepoint |= (utf[ix+1] & 0x3f) << 12;
11069             codepoint |= (utf[ix+2] & 0x3f) << 6;
11070             codepoint |= utf[ix+3] & 0x3f;
11071             if (!xmlIsCharQ(codepoint))
11072                 return(-ix);
11073             ix += 4;
11074         } else                          /* unknown encoding */
11075             return(-ix);
11076       }
11077       return(ix);
11078 }
11079
11080 /**
11081  * xmlParseTryOrFinish:
11082  * @ctxt:  an XML parser context
11083  * @terminate:  last chunk indicator
11084  *
11085  * Try to progress on parsing
11086  *
11087  * Returns zero if no parsing was possible
11088  */
11089 static int
11090 xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
11091     int ret = 0;
11092     int avail, tlen;
11093     xmlChar cur, next;
11094     const xmlChar *lastlt, *lastgt;
11095
11096     if (ctxt->input == NULL)
11097         return(0);
11098
11099 #ifdef DEBUG_PUSH
11100     switch (ctxt->instate) {
11101         case XML_PARSER_EOF:
11102             xmlGenericError(xmlGenericErrorContext,
11103                     "PP: try EOF\n"); break;
11104         case XML_PARSER_START:
11105             xmlGenericError(xmlGenericErrorContext,
11106                     "PP: try START\n"); break;
11107         case XML_PARSER_MISC:
11108             xmlGenericError(xmlGenericErrorContext,
11109                     "PP: try MISC\n");break;
11110         case XML_PARSER_COMMENT:
11111             xmlGenericError(xmlGenericErrorContext,
11112                     "PP: try COMMENT\n");break;
11113         case XML_PARSER_PROLOG:
11114             xmlGenericError(xmlGenericErrorContext,
11115                     "PP: try PROLOG\n");break;
11116         case XML_PARSER_START_TAG:
11117             xmlGenericError(xmlGenericErrorContext,
11118                     "PP: try START_TAG\n");break;
11119         case XML_PARSER_CONTENT:
11120             xmlGenericError(xmlGenericErrorContext,
11121                     "PP: try CONTENT\n");break;
11122         case XML_PARSER_CDATA_SECTION:
11123             xmlGenericError(xmlGenericErrorContext,
11124                     "PP: try CDATA_SECTION\n");break;
11125         case XML_PARSER_END_TAG:
11126             xmlGenericError(xmlGenericErrorContext,
11127                     "PP: try END_TAG\n");break;
11128         case XML_PARSER_ENTITY_DECL:
11129             xmlGenericError(xmlGenericErrorContext,
11130                     "PP: try ENTITY_DECL\n");break;
11131         case XML_PARSER_ENTITY_VALUE:
11132             xmlGenericError(xmlGenericErrorContext,
11133                     "PP: try ENTITY_VALUE\n");break;
11134         case XML_PARSER_ATTRIBUTE_VALUE:
11135             xmlGenericError(xmlGenericErrorContext,
11136                     "PP: try ATTRIBUTE_VALUE\n");break;
11137         case XML_PARSER_DTD:
11138             xmlGenericError(xmlGenericErrorContext,
11139                     "PP: try DTD\n");break;
11140         case XML_PARSER_EPILOG:
11141             xmlGenericError(xmlGenericErrorContext,
11142                     "PP: try EPILOG\n");break;
11143         case XML_PARSER_PI:
11144             xmlGenericError(xmlGenericErrorContext,
11145                     "PP: try PI\n");break;
11146         case XML_PARSER_IGNORE:
11147             xmlGenericError(xmlGenericErrorContext,
11148                     "PP: try IGNORE\n");break;
11149     }
11150 #endif
11151
11152     if ((ctxt->input != NULL) &&
11153         (ctxt->input->cur - ctxt->input->base > 4096)) {
11154         xmlSHRINK(ctxt);
11155         ctxt->checkIndex = 0;
11156     }
11157     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11158
11159     while (ctxt->instate != XML_PARSER_EOF) {
11160         if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11161             return(0);
11162
11163         if (ctxt->input == NULL) break;
11164         if (ctxt->input->buf == NULL)
11165             avail = ctxt->input->length -
11166                     (ctxt->input->cur - ctxt->input->base);
11167         else {
11168             /*
11169              * If we are operating on converted input, try to flush
11170              * remainng chars to avoid them stalling in the non-converted
11171              * buffer. But do not do this in document start where
11172              * encoding="..." may not have been read and we work on a
11173              * guessed encoding.
11174              */
11175             if ((ctxt->instate != XML_PARSER_START) &&
11176                 (ctxt->input->buf->raw != NULL) &&
11177                 (xmlBufIsEmpty(ctxt->input->buf->raw) == 0)) {
11178                 size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
11179                                                  ctxt->input);
11180                 size_t current = ctxt->input->cur - ctxt->input->base;
11181
11182                 xmlParserInputBufferPush(ctxt->input->buf, 0, "");
11183                 xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
11184                                       base, current);
11185             }
11186             avail = xmlBufUse(ctxt->input->buf->buffer) -
11187                     (ctxt->input->cur - ctxt->input->base);
11188         }
11189         if (avail < 1)
11190             goto done;
11191         switch (ctxt->instate) {
11192             case XML_PARSER_EOF:
11193                 /*
11194                  * Document parsing is done !
11195                  */
11196                 goto done;
11197             case XML_PARSER_START:
11198                 if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
11199                     xmlChar start[4];
11200                     xmlCharEncoding enc;
11201
11202                     /*
11203                      * Very first chars read from the document flow.
11204                      */
11205                     if (avail < 4)
11206                         goto done;
11207
11208                     /*
11209                      * Get the 4 first bytes and decode the charset
11210                      * if enc != XML_CHAR_ENCODING_NONE
11211                      * plug some encoding conversion routines,
11212                      * else xmlSwitchEncoding will set to (default)
11213                      * UTF8.
11214                      */
11215                     start[0] = RAW;
11216                     start[1] = NXT(1);
11217                     start[2] = NXT(2);
11218                     start[3] = NXT(3);
11219                     enc = xmlDetectCharEncoding(start, 4);
11220                     xmlSwitchEncoding(ctxt, enc);
11221                     break;
11222                 }
11223
11224                 if (avail < 2)
11225                     goto done;
11226                 cur = ctxt->input->cur[0];
11227                 next = ctxt->input->cur[1];
11228                 if (cur == 0) {
11229                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11230                         ctxt->sax->setDocumentLocator(ctxt->userData,
11231                                                       &xmlDefaultSAXLocator);
11232                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11233                     xmlHaltParser(ctxt);
11234 #ifdef DEBUG_PUSH
11235                     xmlGenericError(xmlGenericErrorContext,
11236                             "PP: entering EOF\n");
11237 #endif
11238                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11239                         ctxt->sax->endDocument(ctxt->userData);
11240                     goto done;
11241                 }
11242                 if ((cur == '<') && (next == '?')) {
11243                     /* PI or XML decl */
11244                     if (avail < 5) return(ret);
11245                     if ((!terminate) &&
11246                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11247                         return(ret);
11248                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11249                         ctxt->sax->setDocumentLocator(ctxt->userData,
11250                                                       &xmlDefaultSAXLocator);
11251                     if ((ctxt->input->cur[2] == 'x') &&
11252                         (ctxt->input->cur[3] == 'm') &&
11253                         (ctxt->input->cur[4] == 'l') &&
11254                         (IS_BLANK_CH(ctxt->input->cur[5]))) {
11255                         ret += 5;
11256 #ifdef DEBUG_PUSH
11257                         xmlGenericError(xmlGenericErrorContext,
11258                                 "PP: Parsing XML Decl\n");
11259 #endif
11260                         xmlParseXMLDecl(ctxt);
11261                         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
11262                             /*
11263                              * The XML REC instructs us to stop parsing right
11264                              * here
11265                              */
11266                             xmlHaltParser(ctxt);
11267                             return(0);
11268                         }
11269                         ctxt->standalone = ctxt->input->standalone;
11270                         if ((ctxt->encoding == NULL) &&
11271                             (ctxt->input->encoding != NULL))
11272                             ctxt->encoding = xmlStrdup(ctxt->input->encoding);
11273                         if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11274                             (!ctxt->disableSAX))
11275                             ctxt->sax->startDocument(ctxt->userData);
11276                         ctxt->instate = XML_PARSER_MISC;
11277 #ifdef DEBUG_PUSH
11278                         xmlGenericError(xmlGenericErrorContext,
11279                                 "PP: entering MISC\n");
11280 #endif
11281                     } else {
11282                         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11283                         if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11284                             (!ctxt->disableSAX))
11285                             ctxt->sax->startDocument(ctxt->userData);
11286                         ctxt->instate = XML_PARSER_MISC;
11287 #ifdef DEBUG_PUSH
11288                         xmlGenericError(xmlGenericErrorContext,
11289                                 "PP: entering MISC\n");
11290 #endif
11291                     }
11292                 } else {
11293                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11294                         ctxt->sax->setDocumentLocator(ctxt->userData,
11295                                                       &xmlDefaultSAXLocator);
11296                     ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11297                     if (ctxt->version == NULL) {
11298                         xmlErrMemory(ctxt, NULL);
11299                         break;
11300                     }
11301                     if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11302                         (!ctxt->disableSAX))
11303                         ctxt->sax->startDocument(ctxt->userData);
11304                     ctxt->instate = XML_PARSER_MISC;
11305 #ifdef DEBUG_PUSH
11306                     xmlGenericError(xmlGenericErrorContext,
11307                             "PP: entering MISC\n");
11308 #endif
11309                 }
11310                 break;
11311             case XML_PARSER_START_TAG: {
11312                 const xmlChar *name;
11313                 const xmlChar *prefix = NULL;
11314                 const xmlChar *URI = NULL;
11315                 int nsNr = ctxt->nsNr;
11316
11317                 if ((avail < 2) && (ctxt->inputNr == 1))
11318                     goto done;
11319                 cur = ctxt->input->cur[0];
11320                 if (cur != '<') {
11321                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11322                     xmlHaltParser(ctxt);
11323                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11324                         ctxt->sax->endDocument(ctxt->userData);
11325                     goto done;
11326                 }
11327                 if (!terminate) {
11328                     if (ctxt->progressive) {
11329                         /* > can be found unescaped in attribute values */
11330                         if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11331                             goto done;
11332                     } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11333                         goto done;
11334                     }
11335                 }
11336                 if (ctxt->spaceNr == 0)
11337                     spacePush(ctxt, -1);
11338                 else if (*ctxt->space == -2)
11339                     spacePush(ctxt, -1);
11340                 else
11341                     spacePush(ctxt, *ctxt->space);
11342 #ifdef LIBXML_SAX1_ENABLED
11343                 if (ctxt->sax2)
11344 #endif /* LIBXML_SAX1_ENABLED */
11345                     name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
11346 #ifdef LIBXML_SAX1_ENABLED
11347                 else
11348                     name = xmlParseStartTag(ctxt);
11349 #endif /* LIBXML_SAX1_ENABLED */
11350                 if (ctxt->instate == XML_PARSER_EOF)
11351                     goto done;
11352                 if (name == NULL) {
11353                     spacePop(ctxt);
11354                     xmlHaltParser(ctxt);
11355                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11356                         ctxt->sax->endDocument(ctxt->userData);
11357                     goto done;
11358                 }
11359 #ifdef LIBXML_VALID_ENABLED
11360                 /*
11361                  * [ VC: Root Element Type ]
11362                  * The Name in the document type declaration must match
11363                  * the element type of the root element.
11364                  */
11365                 if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
11366                     ctxt->node && (ctxt->node == ctxt->myDoc->children))
11367                     ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
11368 #endif /* LIBXML_VALID_ENABLED */
11369
11370                 /*
11371                  * Check for an Empty Element.
11372                  */
11373                 if ((RAW == '/') && (NXT(1) == '>')) {
11374                     SKIP(2);
11375
11376                     if (ctxt->sax2) {
11377                         if ((ctxt->sax != NULL) &&
11378                             (ctxt->sax->endElementNs != NULL) &&
11379                             (!ctxt->disableSAX))
11380                             ctxt->sax->endElementNs(ctxt->userData, name,
11381                                                     prefix, URI);
11382                         if (ctxt->nsNr - nsNr > 0)
11383                             nsPop(ctxt, ctxt->nsNr - nsNr);
11384 #ifdef LIBXML_SAX1_ENABLED
11385                     } else {
11386                         if ((ctxt->sax != NULL) &&
11387                             (ctxt->sax->endElement != NULL) &&
11388                             (!ctxt->disableSAX))
11389                             ctxt->sax->endElement(ctxt->userData, name);
11390 #endif /* LIBXML_SAX1_ENABLED */
11391                     }
11392                     if (ctxt->instate == XML_PARSER_EOF)
11393                         goto done;
11394                     spacePop(ctxt);
11395                     if (ctxt->nameNr == 0) {
11396                         ctxt->instate = XML_PARSER_EPILOG;
11397                     } else {
11398                         ctxt->instate = XML_PARSER_CONTENT;
11399                     }
11400                     ctxt->progressive = 1;
11401                     break;
11402                 }
11403                 if (RAW == '>') {
11404                     NEXT;
11405                 } else {
11406                     xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
11407                                          "Couldn't find end of Start Tag %s\n",
11408                                          name);
11409                     nodePop(ctxt);
11410                     spacePop(ctxt);
11411                 }
11412                 if (ctxt->sax2)
11413                     nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
11414 #ifdef LIBXML_SAX1_ENABLED
11415                 else
11416                     namePush(ctxt, name);
11417 #endif /* LIBXML_SAX1_ENABLED */
11418
11419                 ctxt->instate = XML_PARSER_CONTENT;
11420                 ctxt->progressive = 1;
11421                 break;
11422             }
11423             case XML_PARSER_CONTENT: {
11424                 const xmlChar *test;
11425                 unsigned int cons;
11426                 if ((avail < 2) && (ctxt->inputNr == 1))
11427                     goto done;
11428                 cur = ctxt->input->cur[0];
11429                 next = ctxt->input->cur[1];
11430
11431                 test = CUR_PTR;
11432                 cons = ctxt->input->consumed;
11433                 if ((cur == '<') && (next == '/')) {
11434                     ctxt->instate = XML_PARSER_END_TAG;
11435                     break;
11436                 } else if ((cur == '<') && (next == '?')) {
11437                     if ((!terminate) &&
11438                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11439                         ctxt->progressive = XML_PARSER_PI;
11440                         goto done;
11441                     }
11442                     xmlParsePI(ctxt);
11443                     ctxt->instate = XML_PARSER_CONTENT;
11444                     ctxt->progressive = 1;
11445                 } else if ((cur == '<') && (next != '!')) {
11446                     ctxt->instate = XML_PARSER_START_TAG;
11447                     break;
11448                 } else if ((cur == '<') && (next == '!') &&
11449                            (ctxt->input->cur[2] == '-') &&
11450                            (ctxt->input->cur[3] == '-')) {
11451                     int term;
11452
11453                     if (avail < 4)
11454                         goto done;
11455                     ctxt->input->cur += 4;
11456                     term = xmlParseLookupSequence(ctxt, '-', '-', '>');
11457                     ctxt->input->cur -= 4;
11458                     if ((!terminate) && (term < 0)) {
11459                         ctxt->progressive = XML_PARSER_COMMENT;
11460                         goto done;
11461                     }
11462                     xmlParseComment(ctxt);
11463                     ctxt->instate = XML_PARSER_CONTENT;
11464                     ctxt->progressive = 1;
11465                 } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
11466                     (ctxt->input->cur[2] == '[') &&
11467                     (ctxt->input->cur[3] == 'C') &&
11468                     (ctxt->input->cur[4] == 'D') &&
11469                     (ctxt->input->cur[5] == 'A') &&
11470                     (ctxt->input->cur[6] == 'T') &&
11471                     (ctxt->input->cur[7] == 'A') &&
11472                     (ctxt->input->cur[8] == '[')) {
11473                     SKIP(9);
11474                     ctxt->instate = XML_PARSER_CDATA_SECTION;
11475                     break;
11476                 } else if ((cur == '<') && (next == '!') &&
11477                            (avail < 9)) {
11478                     goto done;
11479                 } else if (cur == '&') {
11480                     if ((!terminate) &&
11481                         (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
11482                         goto done;
11483                     xmlParseReference(ctxt);
11484                 } else {
11485                     /* TODO Avoid the extra copy, handle directly !!! */
11486                     /*
11487                      * Goal of the following test is:
11488                      *  - minimize calls to the SAX 'character' callback
11489                      *    when they are mergeable
11490                      *  - handle an problem for isBlank when we only parse
11491                      *    a sequence of blank chars and the next one is
11492                      *    not available to check against '<' presence.
11493                      *  - tries to homogenize the differences in SAX
11494                      *    callbacks between the push and pull versions
11495                      *    of the parser.
11496                      */
11497                     if ((ctxt->inputNr == 1) &&
11498                         (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
11499                         if (!terminate) {
11500                             if (ctxt->progressive) {
11501                                 if ((lastlt == NULL) ||
11502                                     (ctxt->input->cur > lastlt))
11503                                     goto done;
11504                             } else if (xmlParseLookupSequence(ctxt,
11505                                                               '<', 0, 0) < 0) {
11506                                 goto done;
11507                             }
11508                         }
11509                     }
11510                     ctxt->checkIndex = 0;
11511                     xmlParseCharData(ctxt, 0);
11512                 }
11513                 if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
11514                     xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
11515                                 "detected an error in element content\n");
11516                     xmlHaltParser(ctxt);
11517                     break;
11518                 }
11519                 break;
11520             }
11521             case XML_PARSER_END_TAG:
11522                 if (avail < 2)
11523                     goto done;
11524                 if (!terminate) {
11525                     if (ctxt->progressive) {
11526                         /* > can be found unescaped in attribute values */
11527                         if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11528                             goto done;
11529                     } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11530                         goto done;
11531                     }
11532                 }
11533                 if (ctxt->sax2) {
11534                     xmlParseEndTag2(ctxt,
11535                             (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
11536                             (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
11537                             (int) (ptrdiff_t)
11538                                 ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
11539                     nameNsPop(ctxt);
11540                 }
11541 #ifdef LIBXML_SAX1_ENABLED
11542                   else
11543                     xmlParseEndTag1(ctxt, 0);
11544 #endif /* LIBXML_SAX1_ENABLED */
11545                 if (ctxt->instate == XML_PARSER_EOF) {
11546                     /* Nothing */
11547                 } else if (ctxt->nameNr == 0) {
11548                     ctxt->instate = XML_PARSER_EPILOG;
11549                 } else {
11550                     ctxt->instate = XML_PARSER_CONTENT;
11551                 }
11552                 break;
11553             case XML_PARSER_CDATA_SECTION: {
11554                 /*
11555                  * The Push mode need to have the SAX callback for
11556                  * cdataBlock merge back contiguous callbacks.
11557                  */
11558                 int base;
11559
11560                 base = xmlParseLookupSequence(ctxt, ']', ']', '>');
11561                 if (base < 0) {
11562                     if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
11563                         int tmp;
11564
11565                         tmp = xmlCheckCdataPush(ctxt->input->cur,
11566                                                 XML_PARSER_BIG_BUFFER_SIZE, 0);
11567                         if (tmp < 0) {
11568                             tmp = -tmp;
11569                             ctxt->input->cur += tmp;
11570                             goto encoding_error;
11571                         }
11572                         if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
11573                             if (ctxt->sax->cdataBlock != NULL)
11574                                 ctxt->sax->cdataBlock(ctxt->userData,
11575                                                       ctxt->input->cur, tmp);
11576                             else if (ctxt->sax->characters != NULL)
11577                                 ctxt->sax->characters(ctxt->userData,
11578                                                       ctxt->input->cur, tmp);
11579                         }
11580                         if (ctxt->instate == XML_PARSER_EOF)
11581                             goto done;
11582                         SKIPL(tmp);
11583                         ctxt->checkIndex = 0;
11584                     }
11585                     goto done;
11586                 } else {
11587                     int tmp;
11588
11589                     tmp = xmlCheckCdataPush(ctxt->input->cur, base, 1);
11590                     if ((tmp < 0) || (tmp != base)) {
11591                         tmp = -tmp;
11592                         ctxt->input->cur += tmp;
11593                         goto encoding_error;
11594                     }
11595                     if ((ctxt->sax != NULL) && (base == 0) &&
11596                         (ctxt->sax->cdataBlock != NULL) &&
11597                         (!ctxt->disableSAX)) {
11598                         /*
11599                          * Special case to provide identical behaviour
11600                          * between pull and push parsers on enpty CDATA
11601                          * sections
11602                          */
11603                          if ((ctxt->input->cur - ctxt->input->base >= 9) &&
11604                              (!strncmp((const char *)&ctxt->input->cur[-9],
11605                                        "<![CDATA[", 9)))
11606                              ctxt->sax->cdataBlock(ctxt->userData,
11607                                                    BAD_CAST "", 0);
11608                     } else if ((ctxt->sax != NULL) && (base > 0) &&
11609                         (!ctxt->disableSAX)) {
11610                         if (ctxt->sax->cdataBlock != NULL)
11611                             ctxt->sax->cdataBlock(ctxt->userData,
11612                                                   ctxt->input->cur, base);
11613                         else if (ctxt->sax->characters != NULL)
11614                             ctxt->sax->characters(ctxt->userData,
11615                                                   ctxt->input->cur, base);
11616                     }
11617                     if (ctxt->instate == XML_PARSER_EOF)
11618                         goto done;
11619                     SKIPL(base + 3);
11620                     ctxt->checkIndex = 0;
11621                     ctxt->instate = XML_PARSER_CONTENT;
11622 #ifdef DEBUG_PUSH
11623                     xmlGenericError(xmlGenericErrorContext,
11624                             "PP: entering CONTENT\n");
11625 #endif
11626                 }
11627                 break;
11628             }
11629             case XML_PARSER_MISC:
11630                 SKIP_BLANKS;
11631                 if (ctxt->input->buf == NULL)
11632                     avail = ctxt->input->length -
11633                             (ctxt->input->cur - ctxt->input->base);
11634                 else
11635                     avail = xmlBufUse(ctxt->input->buf->buffer) -
11636                             (ctxt->input->cur - ctxt->input->base);
11637                 if (avail < 2)
11638                     goto done;
11639                 cur = ctxt->input->cur[0];
11640                 next = ctxt->input->cur[1];
11641                 if ((cur == '<') && (next == '?')) {
11642                     if ((!terminate) &&
11643                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11644                         ctxt->progressive = XML_PARSER_PI;
11645                         goto done;
11646                     }
11647 #ifdef DEBUG_PUSH
11648                     xmlGenericError(xmlGenericErrorContext,
11649                             "PP: Parsing PI\n");
11650 #endif
11651                     xmlParsePI(ctxt);
11652                     if (ctxt->instate == XML_PARSER_EOF)
11653                         goto done;
11654                     ctxt->instate = XML_PARSER_MISC;
11655                     ctxt->progressive = 1;
11656                     ctxt->checkIndex = 0;
11657                 } else if ((cur == '<') && (next == '!') &&
11658                     (ctxt->input->cur[2] == '-') &&
11659                     (ctxt->input->cur[3] == '-')) {
11660                     if ((!terminate) &&
11661                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11662                         ctxt->progressive = XML_PARSER_COMMENT;
11663                         goto done;
11664                     }
11665 #ifdef DEBUG_PUSH
11666                     xmlGenericError(xmlGenericErrorContext,
11667                             "PP: Parsing Comment\n");
11668 #endif
11669                     xmlParseComment(ctxt);
11670                     if (ctxt->instate == XML_PARSER_EOF)
11671                         goto done;
11672                     ctxt->instate = XML_PARSER_MISC;
11673                     ctxt->progressive = 1;
11674                     ctxt->checkIndex = 0;
11675                 } else if ((cur == '<') && (next == '!') &&
11676                     (ctxt->input->cur[2] == 'D') &&
11677                     (ctxt->input->cur[3] == 'O') &&
11678                     (ctxt->input->cur[4] == 'C') &&
11679                     (ctxt->input->cur[5] == 'T') &&
11680                     (ctxt->input->cur[6] == 'Y') &&
11681                     (ctxt->input->cur[7] == 'P') &&
11682                     (ctxt->input->cur[8] == 'E')) {
11683                     if ((!terminate) &&
11684                         (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0)) {
11685                         ctxt->progressive = XML_PARSER_DTD;
11686                         goto done;
11687                     }
11688 #ifdef DEBUG_PUSH
11689                     xmlGenericError(xmlGenericErrorContext,
11690                             "PP: Parsing internal subset\n");
11691 #endif
11692                     ctxt->inSubset = 1;
11693                     ctxt->progressive = 0;
11694                     ctxt->checkIndex = 0;
11695                     xmlParseDocTypeDecl(ctxt);
11696                     if (ctxt->instate == XML_PARSER_EOF)
11697                         goto done;
11698                     if (RAW == '[') {
11699                         ctxt->instate = XML_PARSER_DTD;
11700 #ifdef DEBUG_PUSH
11701                         xmlGenericError(xmlGenericErrorContext,
11702                                 "PP: entering DTD\n");
11703 #endif
11704                     } else {
11705                         /*
11706                          * Create and update the external subset.
11707                          */
11708                         ctxt->inSubset = 2;
11709                         if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11710                             (ctxt->sax->externalSubset != NULL))
11711                             ctxt->sax->externalSubset(ctxt->userData,
11712                                     ctxt->intSubName, ctxt->extSubSystem,
11713                                     ctxt->extSubURI);
11714                         ctxt->inSubset = 0;
11715                         xmlCleanSpecialAttr(ctxt);
11716                         ctxt->instate = XML_PARSER_PROLOG;
11717 #ifdef DEBUG_PUSH
11718                         xmlGenericError(xmlGenericErrorContext,
11719                                 "PP: entering PROLOG\n");
11720 #endif
11721                     }
11722                 } else if ((cur == '<') && (next == '!') &&
11723                            (avail < 9)) {
11724                     goto done;
11725                 } else {
11726                     ctxt->instate = XML_PARSER_START_TAG;
11727                     ctxt->progressive = XML_PARSER_START_TAG;
11728                     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11729 #ifdef DEBUG_PUSH
11730                     xmlGenericError(xmlGenericErrorContext,
11731                             "PP: entering START_TAG\n");
11732 #endif
11733                 }
11734                 break;
11735             case XML_PARSER_PROLOG:
11736                 SKIP_BLANKS;
11737                 if (ctxt->input->buf == NULL)
11738                     avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11739                 else
11740                     avail = xmlBufUse(ctxt->input->buf->buffer) -
11741                             (ctxt->input->cur - ctxt->input->base);
11742                 if (avail < 2)
11743                     goto done;
11744                 cur = ctxt->input->cur[0];
11745                 next = ctxt->input->cur[1];
11746                 if ((cur == '<') && (next == '?')) {
11747                     if ((!terminate) &&
11748                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11749                         ctxt->progressive = XML_PARSER_PI;
11750                         goto done;
11751                     }
11752 #ifdef DEBUG_PUSH
11753                     xmlGenericError(xmlGenericErrorContext,
11754                             "PP: Parsing PI\n");
11755 #endif
11756                     xmlParsePI(ctxt);
11757                     if (ctxt->instate == XML_PARSER_EOF)
11758                         goto done;
11759                     ctxt->instate = XML_PARSER_PROLOG;
11760                     ctxt->progressive = 1;
11761                 } else if ((cur == '<') && (next == '!') &&
11762                     (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11763                     if ((!terminate) &&
11764                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11765                         ctxt->progressive = XML_PARSER_COMMENT;
11766                         goto done;
11767                     }
11768 #ifdef DEBUG_PUSH
11769                     xmlGenericError(xmlGenericErrorContext,
11770                             "PP: Parsing Comment\n");
11771 #endif
11772                     xmlParseComment(ctxt);
11773                     if (ctxt->instate == XML_PARSER_EOF)
11774                         goto done;
11775                     ctxt->instate = XML_PARSER_PROLOG;
11776                     ctxt->progressive = 1;
11777                 } else if ((cur == '<') && (next == '!') &&
11778                            (avail < 4)) {
11779                     goto done;
11780                 } else {
11781                     ctxt->instate = XML_PARSER_START_TAG;
11782                     if (ctxt->progressive == 0)
11783                         ctxt->progressive = XML_PARSER_START_TAG;
11784                     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11785 #ifdef DEBUG_PUSH
11786                     xmlGenericError(xmlGenericErrorContext,
11787                             "PP: entering START_TAG\n");
11788 #endif
11789                 }
11790                 break;
11791             case XML_PARSER_EPILOG:
11792                 SKIP_BLANKS;
11793                 if (ctxt->input->buf == NULL)
11794                     avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11795                 else
11796                     avail = xmlBufUse(ctxt->input->buf->buffer) -
11797                             (ctxt->input->cur - ctxt->input->base);
11798                 if (avail < 2)
11799                     goto done;
11800                 cur = ctxt->input->cur[0];
11801                 next = ctxt->input->cur[1];
11802                 if ((cur == '<') && (next == '?')) {
11803                     if ((!terminate) &&
11804                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11805                         ctxt->progressive = XML_PARSER_PI;
11806                         goto done;
11807                     }
11808 #ifdef DEBUG_PUSH
11809                     xmlGenericError(xmlGenericErrorContext,
11810                             "PP: Parsing PI\n");
11811 #endif
11812                     xmlParsePI(ctxt);
11813                     if (ctxt->instate == XML_PARSER_EOF)
11814                         goto done;
11815                     ctxt->instate = XML_PARSER_EPILOG;
11816                     ctxt->progressive = 1;
11817                 } else if ((cur == '<') && (next == '!') &&
11818                     (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11819                     if ((!terminate) &&
11820                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11821                         ctxt->progressive = XML_PARSER_COMMENT;
11822                         goto done;
11823                     }
11824 #ifdef DEBUG_PUSH
11825                     xmlGenericError(xmlGenericErrorContext,
11826                             "PP: Parsing Comment\n");
11827 #endif
11828                     xmlParseComment(ctxt);
11829                     if (ctxt->instate == XML_PARSER_EOF)
11830                         goto done;
11831                     ctxt->instate = XML_PARSER_EPILOG;
11832                     ctxt->progressive = 1;
11833                 } else if ((cur == '<') && (next == '!') &&
11834                            (avail < 4)) {
11835                     goto done;
11836                 } else {
11837                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11838                     xmlHaltParser(ctxt);
11839 #ifdef DEBUG_PUSH
11840                     xmlGenericError(xmlGenericErrorContext,
11841                             "PP: entering EOF\n");
11842 #endif
11843                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11844                         ctxt->sax->endDocument(ctxt->userData);
11845                     goto done;
11846                 }
11847                 break;
11848             case XML_PARSER_DTD: {
11849                 /*
11850                  * Sorry but progressive parsing of the internal subset
11851                  * is not expected to be supported. We first check that
11852                  * the full content of the internal subset is available and
11853                  * the parsing is launched only at that point.
11854                  * Internal subset ends up with "']' S? '>'" in an unescaped
11855                  * section and not in a ']]>' sequence which are conditional
11856                  * sections (whoever argued to keep that crap in XML deserve
11857                  * a place in hell !).
11858                  */
11859                 int base, i;
11860                 xmlChar *buf;
11861                 xmlChar quote = 0;
11862                 size_t use;
11863
11864                 base = ctxt->input->cur - ctxt->input->base;
11865                 if (base < 0) return(0);
11866                 if (ctxt->checkIndex > base)
11867                     base = ctxt->checkIndex;
11868                 buf = xmlBufContent(ctxt->input->buf->buffer);
11869                 use = xmlBufUse(ctxt->input->buf->buffer);
11870                 for (;(unsigned int) base < use; base++) {
11871                     if (quote != 0) {
11872                         if (buf[base] == quote)
11873                             quote = 0;
11874                         continue;
11875                     }
11876                     if ((quote == 0) && (buf[base] == '<')) {
11877                         int found  = 0;
11878                         /* special handling of comments */
11879                         if (((unsigned int) base + 4 < use) &&
11880                             (buf[base + 1] == '!') &&
11881                             (buf[base + 2] == '-') &&
11882                             (buf[base + 3] == '-')) {
11883                             for (;(unsigned int) base + 3 < use; base++) {
11884                                 if ((buf[base] == '-') &&
11885                                     (buf[base + 1] == '-') &&
11886                                     (buf[base + 2] == '>')) {
11887                                     found = 1;
11888                                     base += 2;
11889                                     break;
11890                                 }
11891                             }
11892                             if (!found) {
11893 #if 0
11894                                 fprintf(stderr, "unfinished comment\n");
11895 #endif
11896                                 break; /* for */
11897                             }
11898                             continue;
11899                         }
11900                     }
11901                     if (buf[base] == '"') {
11902                         quote = '"';
11903                         continue;
11904                     }
11905                     if (buf[base] == '\'') {
11906                         quote = '\'';
11907                         continue;
11908                     }
11909                     if (buf[base] == ']') {
11910 #if 0
11911                         fprintf(stderr, "%c%c%c%c: ", buf[base],
11912                                 buf[base + 1], buf[base + 2], buf[base + 3]);
11913 #endif
11914                         if ((unsigned int) base +1 >= use)
11915                             break;
11916                         if (buf[base + 1] == ']') {
11917                             /* conditional crap, skip both ']' ! */
11918                             base++;
11919                             continue;
11920                         }
11921                         for (i = 1; (unsigned int) base + i < use; i++) {
11922                             if (buf[base + i] == '>') {
11923 #if 0
11924                                 fprintf(stderr, "found\n");
11925 #endif
11926                                 goto found_end_int_subset;
11927                             }
11928                             if (!IS_BLANK_CH(buf[base + i])) {
11929 #if 0
11930                                 fprintf(stderr, "not found\n");
11931 #endif
11932                                 goto not_end_of_int_subset;
11933                             }
11934                         }
11935 #if 0
11936                         fprintf(stderr, "end of stream\n");
11937 #endif
11938                         break;
11939
11940                     }
11941 not_end_of_int_subset:
11942                     continue; /* for */
11943                 }
11944                 /*
11945                  * We didn't found the end of the Internal subset
11946                  */
11947                 if (quote == 0)
11948                     ctxt->checkIndex = base;
11949                 else
11950                     ctxt->checkIndex = 0;
11951 #ifdef DEBUG_PUSH
11952                 if (next == 0)
11953                     xmlGenericError(xmlGenericErrorContext,
11954                             "PP: lookup of int subset end filed\n");
11955 #endif
11956                 goto done;
11957
11958 found_end_int_subset:
11959                 ctxt->checkIndex = 0;
11960                 xmlParseInternalSubset(ctxt);
11961                 if (ctxt->instate == XML_PARSER_EOF)
11962                     goto done;
11963                 ctxt->inSubset = 2;
11964                 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11965                     (ctxt->sax->externalSubset != NULL))
11966                     ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
11967                             ctxt->extSubSystem, ctxt->extSubURI);
11968                 ctxt->inSubset = 0;
11969                 xmlCleanSpecialAttr(ctxt);
11970                 if (ctxt->instate == XML_PARSER_EOF)
11971                     goto done;
11972                 ctxt->instate = XML_PARSER_PROLOG;
11973                 ctxt->checkIndex = 0;
11974 #ifdef DEBUG_PUSH
11975                 xmlGenericError(xmlGenericErrorContext,
11976                         "PP: entering PROLOG\n");
11977 #endif
11978                 break;
11979             }
11980             case XML_PARSER_COMMENT:
11981                 xmlGenericError(xmlGenericErrorContext,
11982                         "PP: internal error, state == COMMENT\n");
11983                 ctxt->instate = XML_PARSER_CONTENT;
11984 #ifdef DEBUG_PUSH
11985                 xmlGenericError(xmlGenericErrorContext,
11986                         "PP: entering CONTENT\n");
11987 #endif
11988                 break;
11989             case XML_PARSER_IGNORE:
11990                 xmlGenericError(xmlGenericErrorContext,
11991                         "PP: internal error, state == IGNORE");
11992                 ctxt->instate = XML_PARSER_DTD;
11993 #ifdef DEBUG_PUSH
11994                 xmlGenericError(xmlGenericErrorContext,
11995                         "PP: entering DTD\n");
11996 #endif
11997                 break;
11998             case XML_PARSER_PI:
11999                 xmlGenericError(xmlGenericErrorContext,
12000                         "PP: internal error, state == PI\n");
12001                 ctxt->instate = XML_PARSER_CONTENT;
12002 #ifdef DEBUG_PUSH
12003                 xmlGenericError(xmlGenericErrorContext,
12004                         "PP: entering CONTENT\n");
12005 #endif
12006                 break;
12007             case XML_PARSER_ENTITY_DECL:
12008                 xmlGenericError(xmlGenericErrorContext,
12009                         "PP: internal error, state == ENTITY_DECL\n");
12010                 ctxt->instate = XML_PARSER_DTD;
12011 #ifdef DEBUG_PUSH
12012                 xmlGenericError(xmlGenericErrorContext,
12013                         "PP: entering DTD\n");
12014 #endif
12015                 break;
12016             case XML_PARSER_ENTITY_VALUE:
12017                 xmlGenericError(xmlGenericErrorContext,
12018                         "PP: internal error, state == ENTITY_VALUE\n");
12019                 ctxt->instate = XML_PARSER_CONTENT;
12020 #ifdef DEBUG_PUSH
12021                 xmlGenericError(xmlGenericErrorContext,
12022                         "PP: entering DTD\n");
12023 #endif
12024                 break;
12025             case XML_PARSER_ATTRIBUTE_VALUE:
12026                 xmlGenericError(xmlGenericErrorContext,
12027                         "PP: internal error, state == ATTRIBUTE_VALUE\n");
12028                 ctxt->instate = XML_PARSER_START_TAG;
12029 #ifdef DEBUG_PUSH
12030                 xmlGenericError(xmlGenericErrorContext,
12031                         "PP: entering START_TAG\n");
12032 #endif
12033                 break;
12034             case XML_PARSER_SYSTEM_LITERAL:
12035                 xmlGenericError(xmlGenericErrorContext,
12036                         "PP: internal error, state == SYSTEM_LITERAL\n");
12037                 ctxt->instate = XML_PARSER_START_TAG;
12038 #ifdef DEBUG_PUSH
12039                 xmlGenericError(xmlGenericErrorContext,
12040                         "PP: entering START_TAG\n");
12041 #endif
12042                 break;
12043             case XML_PARSER_PUBLIC_LITERAL:
12044                 xmlGenericError(xmlGenericErrorContext,
12045                         "PP: internal error, state == PUBLIC_LITERAL\n");
12046                 ctxt->instate = XML_PARSER_START_TAG;
12047 #ifdef DEBUG_PUSH
12048                 xmlGenericError(xmlGenericErrorContext,
12049                         "PP: entering START_TAG\n");
12050 #endif
12051                 break;
12052         }
12053     }
12054 done:
12055 #ifdef DEBUG_PUSH
12056     xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
12057 #endif
12058     return(ret);
12059 encoding_error:
12060     {
12061         char buffer[150];
12062
12063         snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
12064                         ctxt->input->cur[0], ctxt->input->cur[1],
12065                         ctxt->input->cur[2], ctxt->input->cur[3]);
12066         __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
12067                      "Input is not proper UTF-8, indicate encoding !\n%s",
12068                      BAD_CAST buffer, NULL);
12069     }
12070     return(0);
12071 }
12072
12073 /**
12074  * xmlParseCheckTransition:
12075  * @ctxt:  an XML parser context
12076  * @chunk:  a char array
12077  * @size:  the size in byte of the chunk
12078  *
12079  * Check depending on the current parser state if the chunk given must be
12080  * processed immediately or one need more data to advance on parsing.
12081  *
12082  * Returns -1 in case of error, 0 if the push is not needed and 1 if needed
12083  */
12084 static int
12085 xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
12086     if ((ctxt == NULL) || (chunk == NULL) || (size < 0))
12087         return(-1);
12088     if (ctxt->instate == XML_PARSER_START_TAG) {
12089         if (memchr(chunk, '>', size) != NULL)
12090             return(1);
12091         return(0);
12092     }
12093     if (ctxt->progressive == XML_PARSER_COMMENT) {
12094         if (memchr(chunk, '>', size) != NULL)
12095             return(1);
12096         return(0);
12097     }
12098     if (ctxt->instate == XML_PARSER_CDATA_SECTION) {
12099         if (memchr(chunk, '>', size) != NULL)
12100             return(1);
12101         return(0);
12102     }
12103     if (ctxt->progressive == XML_PARSER_PI) {
12104         if (memchr(chunk, '>', size) != NULL)
12105             return(1);
12106         return(0);
12107     }
12108     if (ctxt->instate == XML_PARSER_END_TAG) {
12109         if (memchr(chunk, '>', size) != NULL)
12110             return(1);
12111         return(0);
12112     }
12113     if ((ctxt->progressive == XML_PARSER_DTD) ||
12114         (ctxt->instate == XML_PARSER_DTD)) {
12115         if (memchr(chunk, '>', size) != NULL)
12116             return(1);
12117         return(0);
12118     }
12119     return(1);
12120 }
12121
12122 /**
12123  * xmlParseChunk:
12124  * @ctxt:  an XML parser context
12125  * @chunk:  an char array
12126  * @size:  the size in byte of the chunk
12127  * @terminate:  last chunk indicator
12128  *
12129  * Parse a Chunk of memory
12130  *
12131  * Returns zero if no error, the xmlParserErrors otherwise.
12132  */
12133 int
12134 xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
12135               int terminate) {
12136     int end_in_lf = 0;
12137     int remain = 0;
12138     size_t old_avail = 0;
12139     size_t avail = 0;
12140
12141     if (ctxt == NULL)
12142         return(XML_ERR_INTERNAL_ERROR);
12143     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12144         return(ctxt->errNo);
12145     if (ctxt->instate == XML_PARSER_EOF)
12146         return(-1);
12147     if (ctxt->instate == XML_PARSER_START)
12148         xmlDetectSAX2(ctxt);
12149     if ((size > 0) && (chunk != NULL) && (!terminate) &&
12150         (chunk[size - 1] == '\r')) {
12151         end_in_lf = 1;
12152         size--;
12153     }
12154
12155 xmldecl_done:
12156
12157     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
12158         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
12159         size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12160         size_t cur = ctxt->input->cur - ctxt->input->base;
12161         int res;
12162
12163         old_avail = xmlBufUse(ctxt->input->buf->buffer);
12164         /*
12165          * Specific handling if we autodetected an encoding, we should not
12166          * push more than the first line ... which depend on the encoding
12167          * And only push the rest once the final encoding was detected
12168          */
12169         if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
12170             (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
12171             unsigned int len = 45;
12172
12173             if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12174                                BAD_CAST "UTF-16")) ||
12175                 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12176                                BAD_CAST "UTF16")))
12177                 len = 90;
12178             else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12179                                     BAD_CAST "UCS-4")) ||
12180                      (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12181                                     BAD_CAST "UCS4")))
12182                 len = 180;
12183
12184             if (ctxt->input->buf->rawconsumed < len)
12185                 len -= ctxt->input->buf->rawconsumed;
12186
12187             /*
12188              * Change size for reading the initial declaration only
12189              * if size is greater than len. Otherwise, memmove in xmlBufferAdd
12190              * will blindly copy extra bytes from memory.
12191              */
12192             if ((unsigned int) size > len) {
12193                 remain = size - len;
12194                 size = len;
12195             } else {
12196                 remain = 0;
12197             }
12198         }
12199         res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12200         if (res < 0) {
12201             ctxt->errNo = XML_PARSER_EOF;
12202             xmlHaltParser(ctxt);
12203             return (XML_PARSER_EOF);
12204         }
12205         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12206 #ifdef DEBUG_PUSH
12207         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12208 #endif
12209
12210     } else if (ctxt->instate != XML_PARSER_EOF) {
12211         if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
12212             xmlParserInputBufferPtr in = ctxt->input->buf;
12213             if ((in->encoder != NULL) && (in->buffer != NULL) &&
12214                     (in->raw != NULL)) {
12215                 int nbchars;
12216                 size_t base = xmlBufGetInputBase(in->buffer, ctxt->input);
12217                 size_t current = ctxt->input->cur - ctxt->input->base;
12218
12219                 nbchars = xmlCharEncInput(in, terminate);
12220                 if (nbchars < 0) {
12221                     /* TODO 2.6.0 */
12222                     xmlGenericError(xmlGenericErrorContext,
12223                                     "xmlParseChunk: encoder error\n");
12224                     return(XML_ERR_INVALID_ENCODING);
12225                 }
12226                 xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
12227             }
12228         }
12229     }
12230     if (remain != 0) {
12231         xmlParseTryOrFinish(ctxt, 0);
12232     } else {
12233         if ((ctxt->input != NULL) && (ctxt->input->buf != NULL))
12234             avail = xmlBufUse(ctxt->input->buf->buffer);
12235         /*
12236          * Depending on the current state it may not be such
12237          * a good idea to try parsing if there is nothing in the chunk
12238          * which would be worth doing a parser state transition and we
12239          * need to wait for more data
12240          */
12241         if ((terminate) || (avail > XML_MAX_TEXT_LENGTH) ||
12242             (old_avail == 0) || (avail == 0) ||
12243             (xmlParseCheckTransition(ctxt,
12244                        (const char *)&ctxt->input->base[old_avail],
12245                                      avail - old_avail)))
12246             xmlParseTryOrFinish(ctxt, terminate);
12247     }
12248     if (ctxt->instate == XML_PARSER_EOF)
12249         return(ctxt->errNo);
12250
12251     if ((ctxt->input != NULL) &&
12252          (((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
12253          ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
12254         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
12255         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
12256         xmlHaltParser(ctxt);
12257     }
12258     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12259         return(ctxt->errNo);
12260
12261     if (remain != 0) {
12262         chunk += size;
12263         size = remain;
12264         remain = 0;
12265         goto xmldecl_done;
12266     }
12267     if ((end_in_lf == 1) && (ctxt->input != NULL) &&
12268         (ctxt->input->buf != NULL)) {
12269         size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
12270                                          ctxt->input);
12271         size_t current = ctxt->input->cur - ctxt->input->base;
12272
12273         xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
12274
12275         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
12276                               base, current);
12277     }
12278     if (terminate) {
12279         /*
12280          * Check for termination
12281          */
12282         int cur_avail = 0;
12283
12284         if (ctxt->input != NULL) {
12285             if (ctxt->input->buf == NULL)
12286                 cur_avail = ctxt->input->length -
12287                             (ctxt->input->cur - ctxt->input->base);
12288             else
12289                 cur_avail = xmlBufUse(ctxt->input->buf->buffer) -
12290                                       (ctxt->input->cur - ctxt->input->base);
12291         }
12292
12293         if ((ctxt->instate != XML_PARSER_EOF) &&
12294             (ctxt->instate != XML_PARSER_EPILOG)) {
12295             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12296         }
12297         if ((ctxt->instate == XML_PARSER_EPILOG) && (cur_avail > 0)) {
12298             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12299         }
12300         if (ctxt->instate != XML_PARSER_EOF) {
12301             if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
12302                 ctxt->sax->endDocument(ctxt->userData);
12303         }
12304         ctxt->instate = XML_PARSER_EOF;
12305     }
12306     if (ctxt->wellFormed == 0)
12307         return((xmlParserErrors) ctxt->errNo);
12308     else
12309         return(0);
12310 }
12311
12312 /************************************************************************
12313  *                                                                      *
12314  *              I/O front end functions to the parser                   *
12315  *                                                                      *
12316  ************************************************************************/
12317
12318 /**
12319  * xmlCreatePushParserCtxt:
12320  * @sax:  a SAX handler
12321  * @user_data:  The user data returned on SAX callbacks
12322  * @chunk:  a pointer to an array of chars
12323  * @size:  number of chars in the array
12324  * @filename:  an optional file name or URI
12325  *
12326  * Create a parser context for using the XML parser in push mode.
12327  * If @buffer and @size are non-NULL, the data is used to detect
12328  * the encoding.  The remaining characters will be parsed so they
12329  * don't need to be fed in again through xmlParseChunk.
12330  * To allow content encoding detection, @size should be >= 4
12331  * The value of @filename is used for fetching external entities
12332  * and error/warning reports.
12333  *
12334  * Returns the new parser context or NULL
12335  */
12336
12337 xmlParserCtxtPtr
12338 xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12339                         const char *chunk, int size, const char *filename) {
12340     xmlParserCtxtPtr ctxt;
12341     xmlParserInputPtr inputStream;
12342     xmlParserInputBufferPtr buf;
12343     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
12344
12345     /*
12346      * plug some encoding conversion routines
12347      */
12348     if ((chunk != NULL) && (size >= 4))
12349         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
12350
12351     buf = xmlAllocParserInputBuffer(enc);
12352     if (buf == NULL) return(NULL);
12353
12354     ctxt = xmlNewParserCtxt();
12355     if (ctxt == NULL) {
12356         xmlErrMemory(NULL, "creating parser: out of memory\n");
12357         xmlFreeParserInputBuffer(buf);
12358         return(NULL);
12359     }
12360     ctxt->dictNames = 1;
12361     ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
12362     if (ctxt->pushTab == NULL) {
12363         xmlErrMemory(ctxt, NULL);
12364         xmlFreeParserInputBuffer(buf);
12365         xmlFreeParserCtxt(ctxt);
12366         return(NULL);
12367     }
12368     if (sax != NULL) {
12369 #ifdef LIBXML_SAX1_ENABLED
12370         if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12371 #endif /* LIBXML_SAX1_ENABLED */
12372             xmlFree(ctxt->sax);
12373         ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12374         if (ctxt->sax == NULL) {
12375             xmlErrMemory(ctxt, NULL);
12376             xmlFreeParserInputBuffer(buf);
12377             xmlFreeParserCtxt(ctxt);
12378             return(NULL);
12379         }
12380         memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12381         if (sax->initialized == XML_SAX2_MAGIC)
12382             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12383         else
12384             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12385         if (user_data != NULL)
12386             ctxt->userData = user_data;
12387     }
12388     if (filename == NULL) {
12389         ctxt->directory = NULL;
12390     } else {
12391         ctxt->directory = xmlParserGetDirectory(filename);
12392     }
12393
12394     inputStream = xmlNewInputStream(ctxt);
12395     if (inputStream == NULL) {
12396         xmlFreeParserCtxt(ctxt);
12397         xmlFreeParserInputBuffer(buf);
12398         return(NULL);
12399     }
12400
12401     if (filename == NULL)
12402         inputStream->filename = NULL;
12403     else {
12404         inputStream->filename = (char *)
12405             xmlCanonicPath((const xmlChar *) filename);
12406         if (inputStream->filename == NULL) {
12407             xmlFreeParserCtxt(ctxt);
12408             xmlFreeParserInputBuffer(buf);
12409             return(NULL);
12410         }
12411     }
12412     inputStream->buf = buf;
12413     xmlBufResetInput(inputStream->buf->buffer, inputStream);
12414     inputPush(ctxt, inputStream);
12415
12416     /*
12417      * If the caller didn't provide an initial 'chunk' for determining
12418      * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
12419      * that it can be automatically determined later
12420      */
12421     if ((size == 0) || (chunk == NULL)) {
12422         ctxt->charset = XML_CHAR_ENCODING_NONE;
12423     } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
12424         size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12425         size_t cur = ctxt->input->cur - ctxt->input->base;
12426
12427         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12428
12429         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12430 #ifdef DEBUG_PUSH
12431         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12432 #endif
12433     }
12434
12435     if (enc != XML_CHAR_ENCODING_NONE) {
12436         xmlSwitchEncoding(ctxt, enc);
12437     }
12438
12439     return(ctxt);
12440 }
12441 #endif /* LIBXML_PUSH_ENABLED */
12442
12443 /**
12444  * xmlHaltParser:
12445  * @ctxt:  an XML parser context
12446  *
12447  * Blocks further parser processing don't override error
12448  * for internal use
12449  */
12450 static void
12451 xmlHaltParser(xmlParserCtxtPtr ctxt) {
12452     if (ctxt == NULL)
12453         return;
12454     ctxt->instate = XML_PARSER_EOF;
12455     ctxt->disableSAX = 1;
12456     while (ctxt->inputNr > 1)
12457         xmlFreeInputStream(inputPop(ctxt));
12458     if (ctxt->input != NULL) {
12459         /*
12460          * in case there was a specific allocation deallocate before
12461          * overriding base
12462          */
12463         if (ctxt->input->free != NULL) {
12464             ctxt->input->free((xmlChar *) ctxt->input->base);
12465             ctxt->input->free = NULL;
12466         }
12467         ctxt->input->cur = BAD_CAST"";
12468         ctxt->input->base = ctxt->input->cur;
12469         ctxt->input->end = ctxt->input->cur;
12470     }
12471 }
12472
12473 /**
12474  * xmlStopParser:
12475  * @ctxt:  an XML parser context
12476  *
12477  * Blocks further parser processing
12478  */
12479 void
12480 xmlStopParser(xmlParserCtxtPtr ctxt) {
12481     if (ctxt == NULL)
12482         return;
12483     xmlHaltParser(ctxt);
12484     ctxt->errNo = XML_ERR_USER_STOP;
12485 }
12486
12487 /**
12488  * xmlCreateIOParserCtxt:
12489  * @sax:  a SAX handler
12490  * @user_data:  The user data returned on SAX callbacks
12491  * @ioread:  an I/O read function
12492  * @ioclose:  an I/O close function
12493  * @ioctx:  an I/O handler
12494  * @enc:  the charset encoding if known
12495  *
12496  * Create a parser context for using the XML parser with an existing
12497  * I/O stream
12498  *
12499  * Returns the new parser context or NULL
12500  */
12501 xmlParserCtxtPtr
12502 xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12503         xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
12504         void *ioctx, xmlCharEncoding enc) {
12505     xmlParserCtxtPtr ctxt;
12506     xmlParserInputPtr inputStream;
12507     xmlParserInputBufferPtr buf;
12508
12509     if (ioread == NULL) return(NULL);
12510
12511     buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
12512     if (buf == NULL) {
12513         if (ioclose != NULL)
12514             ioclose(ioctx);
12515         return (NULL);
12516     }
12517
12518     ctxt = xmlNewParserCtxt();
12519     if (ctxt == NULL) {
12520         xmlFreeParserInputBuffer(buf);
12521         return(NULL);
12522     }
12523     if (sax != NULL) {
12524 #ifdef LIBXML_SAX1_ENABLED
12525         if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12526 #endif /* LIBXML_SAX1_ENABLED */
12527             xmlFree(ctxt->sax);
12528         ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12529         if (ctxt->sax == NULL) {
12530             xmlErrMemory(ctxt, NULL);
12531             xmlFreeParserCtxt(ctxt);
12532             return(NULL);
12533         }
12534         memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12535         if (sax->initialized == XML_SAX2_MAGIC)
12536             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12537         else
12538             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12539         if (user_data != NULL)
12540             ctxt->userData = user_data;
12541     }
12542
12543     inputStream = xmlNewIOInputStream(ctxt, buf, enc);
12544     if (inputStream == NULL) {
12545         xmlFreeParserCtxt(ctxt);
12546         return(NULL);
12547     }
12548     inputPush(ctxt, inputStream);
12549
12550     return(ctxt);
12551 }
12552
12553 #ifdef LIBXML_VALID_ENABLED
12554 /************************************************************************
12555  *                                                                      *
12556  *              Front ends when parsing a DTD                           *
12557  *                                                                      *
12558  ************************************************************************/
12559
12560 /**
12561  * xmlIOParseDTD:
12562  * @sax:  the SAX handler block or NULL
12563  * @input:  an Input Buffer
12564  * @enc:  the charset encoding if known
12565  *
12566  * Load and parse a DTD
12567  *
12568  * Returns the resulting xmlDtdPtr or NULL in case of error.
12569  * @input will be freed by the function in any case.
12570  */
12571
12572 xmlDtdPtr
12573 xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
12574               xmlCharEncoding enc) {
12575     xmlDtdPtr ret = NULL;
12576     xmlParserCtxtPtr ctxt;
12577     xmlParserInputPtr pinput = NULL;
12578     xmlChar start[4];
12579
12580     if (input == NULL)
12581         return(NULL);
12582
12583     ctxt = xmlNewParserCtxt();
12584     if (ctxt == NULL) {
12585         xmlFreeParserInputBuffer(input);
12586         return(NULL);
12587     }
12588
12589     /* We are loading a DTD */
12590     ctxt->options |= XML_PARSE_DTDLOAD;
12591
12592     /*
12593      * Set-up the SAX context
12594      */
12595     if (sax != NULL) {
12596         if (ctxt->sax != NULL)
12597             xmlFree(ctxt->sax);
12598         ctxt->sax = sax;
12599         ctxt->userData = ctxt;
12600     }
12601     xmlDetectSAX2(ctxt);
12602
12603     /*
12604      * generate a parser input from the I/O handler
12605      */
12606
12607     pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
12608     if (pinput == NULL) {
12609         if (sax != NULL) ctxt->sax = NULL;
12610         xmlFreeParserInputBuffer(input);
12611         xmlFreeParserCtxt(ctxt);
12612         return(NULL);
12613     }
12614
12615     /*
12616      * plug some encoding conversion routines here.
12617      */
12618     if (xmlPushInput(ctxt, pinput) < 0) {
12619         if (sax != NULL) ctxt->sax = NULL;
12620         xmlFreeParserCtxt(ctxt);
12621         return(NULL);
12622     }
12623     if (enc != XML_CHAR_ENCODING_NONE) {
12624         xmlSwitchEncoding(ctxt, enc);
12625     }
12626
12627     pinput->filename = NULL;
12628     pinput->line = 1;
12629     pinput->col = 1;
12630     pinput->base = ctxt->input->cur;
12631     pinput->cur = ctxt->input->cur;
12632     pinput->free = NULL;
12633
12634     /*
12635      * let's parse that entity knowing it's an external subset.
12636      */
12637     ctxt->inSubset = 2;
12638     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12639     if (ctxt->myDoc == NULL) {
12640         xmlErrMemory(ctxt, "New Doc failed");
12641         return(NULL);
12642     }
12643     ctxt->myDoc->properties = XML_DOC_INTERNAL;
12644     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12645                                        BAD_CAST "none", BAD_CAST "none");
12646
12647     if ((enc == XML_CHAR_ENCODING_NONE) &&
12648         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
12649         /*
12650          * Get the 4 first bytes and decode the charset
12651          * if enc != XML_CHAR_ENCODING_NONE
12652          * plug some encoding conversion routines.
12653          */
12654         start[0] = RAW;
12655         start[1] = NXT(1);
12656         start[2] = NXT(2);
12657         start[3] = NXT(3);
12658         enc = xmlDetectCharEncoding(start, 4);
12659         if (enc != XML_CHAR_ENCODING_NONE) {
12660             xmlSwitchEncoding(ctxt, enc);
12661         }
12662     }
12663
12664     xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
12665
12666     if (ctxt->myDoc != NULL) {
12667         if (ctxt->wellFormed) {
12668             ret = ctxt->myDoc->extSubset;
12669             ctxt->myDoc->extSubset = NULL;
12670             if (ret != NULL) {
12671                 xmlNodePtr tmp;
12672
12673                 ret->doc = NULL;
12674                 tmp = ret->children;
12675                 while (tmp != NULL) {
12676                     tmp->doc = NULL;
12677                     tmp = tmp->next;
12678                 }
12679             }
12680         } else {
12681             ret = NULL;
12682         }
12683         xmlFreeDoc(ctxt->myDoc);
12684         ctxt->myDoc = NULL;
12685     }
12686     if (sax != NULL) ctxt->sax = NULL;
12687     xmlFreeParserCtxt(ctxt);
12688
12689     return(ret);
12690 }
12691
12692 /**
12693  * xmlSAXParseDTD:
12694  * @sax:  the SAX handler block
12695  * @ExternalID:  a NAME* containing the External ID of the DTD
12696  * @SystemID:  a NAME* containing the URL to the DTD
12697  *
12698  * Load and parse an external subset.
12699  *
12700  * Returns the resulting xmlDtdPtr or NULL in case of error.
12701  */
12702
12703 xmlDtdPtr
12704 xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
12705                           const xmlChar *SystemID) {
12706     xmlDtdPtr ret = NULL;
12707     xmlParserCtxtPtr ctxt;
12708     xmlParserInputPtr input = NULL;
12709     xmlCharEncoding enc;
12710     xmlChar* systemIdCanonic;
12711
12712     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
12713
12714     ctxt = xmlNewParserCtxt();
12715     if (ctxt == NULL) {
12716         return(NULL);
12717     }
12718
12719     /* We are loading a DTD */
12720     ctxt->options |= XML_PARSE_DTDLOAD;
12721
12722     /*
12723      * Set-up the SAX context
12724      */
12725     if (sax != NULL) {
12726         if (ctxt->sax != NULL)
12727             xmlFree(ctxt->sax);
12728         ctxt->sax = sax;
12729         ctxt->userData = ctxt;
12730     }
12731
12732     /*
12733      * Canonicalise the system ID
12734      */
12735     systemIdCanonic = xmlCanonicPath(SystemID);
12736     if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
12737         xmlFreeParserCtxt(ctxt);
12738         return(NULL);
12739     }
12740
12741     /*
12742      * Ask the Entity resolver to load the damn thing
12743      */
12744
12745     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
12746         input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
12747                                          systemIdCanonic);
12748     if (input == NULL) {
12749         if (sax != NULL) ctxt->sax = NULL;
12750         xmlFreeParserCtxt(ctxt);
12751         if (systemIdCanonic != NULL)
12752             xmlFree(systemIdCanonic);
12753         return(NULL);
12754     }
12755
12756     /*
12757      * plug some encoding conversion routines here.
12758      */
12759     if (xmlPushInput(ctxt, input) < 0) {
12760         if (sax != NULL) ctxt->sax = NULL;
12761         xmlFreeParserCtxt(ctxt);
12762         if (systemIdCanonic != NULL)
12763             xmlFree(systemIdCanonic);
12764         return(NULL);
12765     }
12766     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12767         enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
12768         xmlSwitchEncoding(ctxt, enc);
12769     }
12770
12771     if (input->filename == NULL)
12772         input->filename = (char *) systemIdCanonic;
12773     else
12774         xmlFree(systemIdCanonic);
12775     input->line = 1;
12776     input->col = 1;
12777     input->base = ctxt->input->cur;
12778     input->cur = ctxt->input->cur;
12779     input->free = NULL;
12780
12781     /*
12782      * let's parse that entity knowing it's an external subset.
12783      */
12784     ctxt->inSubset = 2;
12785     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12786     if (ctxt->myDoc == NULL) {
12787         xmlErrMemory(ctxt, "New Doc failed");
12788         if (sax != NULL) ctxt->sax = NULL;
12789         xmlFreeParserCtxt(ctxt);
12790         return(NULL);
12791     }
12792     ctxt->myDoc->properties = XML_DOC_INTERNAL;
12793     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12794                                        ExternalID, SystemID);
12795     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
12796
12797     if (ctxt->myDoc != NULL) {
12798         if (ctxt->wellFormed) {
12799             ret = ctxt->myDoc->extSubset;
12800             ctxt->myDoc->extSubset = NULL;
12801             if (ret != NULL) {
12802                 xmlNodePtr tmp;
12803
12804                 ret->doc = NULL;
12805                 tmp = ret->children;
12806                 while (tmp != NULL) {
12807                     tmp->doc = NULL;
12808                     tmp = tmp->next;
12809                 }
12810             }
12811         } else {
12812             ret = NULL;
12813         }
12814         xmlFreeDoc(ctxt->myDoc);
12815         ctxt->myDoc = NULL;
12816     }
12817     if (sax != NULL) ctxt->sax = NULL;
12818     xmlFreeParserCtxt(ctxt);
12819
12820     return(ret);
12821 }
12822
12823
12824 /**
12825  * xmlParseDTD:
12826  * @ExternalID:  a NAME* containing the External ID of the DTD
12827  * @SystemID:  a NAME* containing the URL to the DTD
12828  *
12829  * Load and parse an external subset.
12830  *
12831  * Returns the resulting xmlDtdPtr or NULL in case of error.
12832  */
12833
12834 xmlDtdPtr
12835 xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
12836     return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
12837 }
12838 #endif /* LIBXML_VALID_ENABLED */
12839
12840 /************************************************************************
12841  *                                                                      *
12842  *              Front ends when parsing an Entity                       *
12843  *                                                                      *
12844  ************************************************************************/
12845
12846 /**
12847  * xmlParseCtxtExternalEntity:
12848  * @ctx:  the existing parsing context
12849  * @URL:  the URL for the entity to load
12850  * @ID:  the System ID for the entity to load
12851  * @lst:  the return value for the set of parsed nodes
12852  *
12853  * Parse an external general entity within an existing parsing context
12854  * An external general parsed entity is well-formed if it matches the
12855  * production labeled extParsedEnt.
12856  *
12857  * [78] extParsedEnt ::= TextDecl? content
12858  *
12859  * Returns 0 if the entity is well formed, -1 in case of args problem and
12860  *    the parser error code otherwise
12861  */
12862
12863 int
12864 xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
12865                        const xmlChar *ID, xmlNodePtr *lst) {
12866     xmlParserCtxtPtr ctxt;
12867     xmlDocPtr newDoc;
12868     xmlNodePtr newRoot;
12869     xmlSAXHandlerPtr oldsax = NULL;
12870     int ret = 0;
12871     xmlChar start[4];
12872     xmlCharEncoding enc;
12873
12874     if (ctx == NULL) return(-1);
12875
12876     if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
12877         (ctx->depth > 1024)) {
12878         return(XML_ERR_ENTITY_LOOP);
12879     }
12880
12881     if (lst != NULL)
12882         *lst = NULL;
12883     if ((URL == NULL) && (ID == NULL))
12884         return(-1);
12885     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
12886         return(-1);
12887
12888     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
12889     if (ctxt == NULL) {
12890         return(-1);
12891     }
12892
12893     oldsax = ctxt->sax;
12894     ctxt->sax = ctx->sax;
12895     xmlDetectSAX2(ctxt);
12896     newDoc = xmlNewDoc(BAD_CAST "1.0");
12897     if (newDoc == NULL) {
12898         xmlFreeParserCtxt(ctxt);
12899         return(-1);
12900     }
12901     newDoc->properties = XML_DOC_INTERNAL;
12902     if (ctx->myDoc->dict) {
12903         newDoc->dict = ctx->myDoc->dict;
12904         xmlDictReference(newDoc->dict);
12905     }
12906     if (ctx->myDoc != NULL) {
12907         newDoc->intSubset = ctx->myDoc->intSubset;
12908         newDoc->extSubset = ctx->myDoc->extSubset;
12909     }
12910     if (ctx->myDoc->URL != NULL) {
12911         newDoc->URL = xmlStrdup(ctx->myDoc->URL);
12912     }
12913     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
12914     if (newRoot == NULL) {
12915         ctxt->sax = oldsax;
12916         xmlFreeParserCtxt(ctxt);
12917         newDoc->intSubset = NULL;
12918         newDoc->extSubset = NULL;
12919         xmlFreeDoc(newDoc);
12920         return(-1);
12921     }
12922     xmlAddChild((xmlNodePtr) newDoc, newRoot);
12923     nodePush(ctxt, newDoc->children);
12924     if (ctx->myDoc == NULL) {
12925         ctxt->myDoc = newDoc;
12926     } else {
12927         ctxt->myDoc = ctx->myDoc;
12928         newDoc->children->doc = ctx->myDoc;
12929     }
12930
12931     /*
12932      * Get the 4 first bytes and decode the charset
12933      * if enc != XML_CHAR_ENCODING_NONE
12934      * plug some encoding conversion routines.
12935      */
12936     GROW
12937     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12938         start[0] = RAW;
12939         start[1] = NXT(1);
12940         start[2] = NXT(2);
12941         start[3] = NXT(3);
12942         enc = xmlDetectCharEncoding(start, 4);
12943         if (enc != XML_CHAR_ENCODING_NONE) {
12944             xmlSwitchEncoding(ctxt, enc);
12945         }
12946     }
12947
12948     /*
12949      * Parse a possible text declaration first
12950      */
12951     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
12952         xmlParseTextDecl(ctxt);
12953         /*
12954          * An XML-1.0 document can't reference an entity not XML-1.0
12955          */
12956         if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
12957             (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
12958             xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
12959                            "Version mismatch between document and entity\n");
12960         }
12961     }
12962
12963     /*
12964      * If the user provided its own SAX callbacks then reuse the
12965      * useData callback field, otherwise the expected setup in a
12966      * DOM builder is to have userData == ctxt
12967      */
12968     if (ctx->userData == ctx)
12969         ctxt->userData = ctxt;
12970     else
12971         ctxt->userData = ctx->userData;
12972
12973     /*
12974      * Doing validity checking on chunk doesn't make sense
12975      */
12976     ctxt->instate = XML_PARSER_CONTENT;
12977     ctxt->validate = ctx->validate;
12978     ctxt->valid = ctx->valid;
12979     ctxt->loadsubset = ctx->loadsubset;
12980     ctxt->depth = ctx->depth + 1;
12981     ctxt->replaceEntities = ctx->replaceEntities;
12982     if (ctxt->validate) {
12983         ctxt->vctxt.error = ctx->vctxt.error;
12984         ctxt->vctxt.warning = ctx->vctxt.warning;
12985     } else {
12986         ctxt->vctxt.error = NULL;
12987         ctxt->vctxt.warning = NULL;
12988     }
12989     ctxt->vctxt.nodeTab = NULL;
12990     ctxt->vctxt.nodeNr = 0;
12991     ctxt->vctxt.nodeMax = 0;
12992     ctxt->vctxt.node = NULL;
12993     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
12994     ctxt->dict = ctx->dict;
12995     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
12996     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
12997     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
12998     ctxt->dictNames = ctx->dictNames;
12999     ctxt->attsDefault = ctx->attsDefault;
13000     ctxt->attsSpecial = ctx->attsSpecial;
13001     ctxt->linenumbers = ctx->linenumbers;
13002
13003     xmlParseContent(ctxt);
13004
13005     ctx->validate = ctxt->validate;
13006     ctx->valid = ctxt->valid;
13007     if ((RAW == '<') && (NXT(1) == '/')) {
13008         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13009     } else if (RAW != 0) {
13010         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13011     }
13012     if (ctxt->node != newDoc->children) {
13013         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13014     }
13015
13016     if (!ctxt->wellFormed) {
13017         if (ctxt->errNo == 0)
13018             ret = 1;
13019         else
13020             ret = ctxt->errNo;
13021     } else {
13022         if (lst != NULL) {
13023             xmlNodePtr cur;
13024
13025             /*
13026              * Return the newly created nodeset after unlinking it from
13027              * they pseudo parent.
13028              */
13029             cur = newDoc->children->children;
13030             *lst = cur;
13031             while (cur != NULL) {
13032                 cur->parent = NULL;
13033                 cur = cur->next;
13034             }
13035             newDoc->children->children = NULL;
13036         }
13037         ret = 0;
13038     }
13039     ctxt->sax = oldsax;
13040     ctxt->dict = NULL;
13041     ctxt->attsDefault = NULL;
13042     ctxt->attsSpecial = NULL;
13043     xmlFreeParserCtxt(ctxt);
13044     newDoc->intSubset = NULL;
13045     newDoc->extSubset = NULL;
13046     xmlFreeDoc(newDoc);
13047
13048     return(ret);
13049 }
13050
13051 /**
13052  * xmlParseExternalEntityPrivate:
13053  * @doc:  the document the chunk pertains to
13054  * @oldctxt:  the previous parser context if available
13055  * @sax:  the SAX handler bloc (possibly NULL)
13056  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13057  * @depth:  Used for loop detection, use 0
13058  * @URL:  the URL for the entity to load
13059  * @ID:  the System ID for the entity to load
13060  * @list:  the return value for the set of parsed nodes
13061  *
13062  * Private version of xmlParseExternalEntity()
13063  *
13064  * Returns 0 if the entity is well formed, -1 in case of args problem and
13065  *    the parser error code otherwise
13066  */
13067
13068 static xmlParserErrors
13069 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
13070                       xmlSAXHandlerPtr sax,
13071                       void *user_data, int depth, const xmlChar *URL,
13072                       const xmlChar *ID, xmlNodePtr *list) {
13073     xmlParserCtxtPtr ctxt;
13074     xmlDocPtr newDoc;
13075     xmlNodePtr newRoot;
13076     xmlSAXHandlerPtr oldsax = NULL;
13077     xmlParserErrors ret = XML_ERR_OK;
13078     xmlChar start[4];
13079     xmlCharEncoding enc;
13080
13081     if (((depth > 40) &&
13082         ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
13083         (depth > 1024)) {
13084         return(XML_ERR_ENTITY_LOOP);
13085     }
13086
13087     if (list != NULL)
13088         *list = NULL;
13089     if ((URL == NULL) && (ID == NULL))
13090         return(XML_ERR_INTERNAL_ERROR);
13091     if (doc == NULL)
13092         return(XML_ERR_INTERNAL_ERROR);
13093
13094
13095     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
13096     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
13097     ctxt->userData = ctxt;
13098     if (oldctxt != NULL) {
13099         ctxt->_private = oldctxt->_private;
13100         ctxt->loadsubset = oldctxt->loadsubset;
13101         ctxt->validate = oldctxt->validate;
13102         ctxt->external = oldctxt->external;
13103         ctxt->record_info = oldctxt->record_info;
13104         ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
13105         ctxt->node_seq.length = oldctxt->node_seq.length;
13106         ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
13107     } else {
13108         /*
13109          * Doing validity checking on chunk without context
13110          * doesn't make sense
13111          */
13112         ctxt->_private = NULL;
13113         ctxt->validate = 0;
13114         ctxt->external = 2;
13115         ctxt->loadsubset = 0;
13116     }
13117     if (sax != NULL) {
13118         oldsax = ctxt->sax;
13119         ctxt->sax = sax;
13120         if (user_data != NULL)
13121             ctxt->userData = user_data;
13122     }
13123     xmlDetectSAX2(ctxt);
13124     newDoc = xmlNewDoc(BAD_CAST "1.0");
13125     if (newDoc == NULL) {
13126         ctxt->node_seq.maximum = 0;
13127         ctxt->node_seq.length = 0;
13128         ctxt->node_seq.buffer = NULL;
13129         xmlFreeParserCtxt(ctxt);
13130         return(XML_ERR_INTERNAL_ERROR);
13131     }
13132     newDoc->properties = XML_DOC_INTERNAL;
13133     newDoc->intSubset = doc->intSubset;
13134     newDoc->extSubset = doc->extSubset;
13135     newDoc->dict = doc->dict;
13136     xmlDictReference(newDoc->dict);
13137
13138     if (doc->URL != NULL) {
13139         newDoc->URL = xmlStrdup(doc->URL);
13140     }
13141     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13142     if (newRoot == NULL) {
13143         if (sax != NULL)
13144             ctxt->sax = oldsax;
13145         ctxt->node_seq.maximum = 0;
13146         ctxt->node_seq.length = 0;
13147         ctxt->node_seq.buffer = NULL;
13148         xmlFreeParserCtxt(ctxt);
13149         newDoc->intSubset = NULL;
13150         newDoc->extSubset = NULL;
13151         xmlFreeDoc(newDoc);
13152         return(XML_ERR_INTERNAL_ERROR);
13153     }
13154     xmlAddChild((xmlNodePtr) newDoc, newRoot);
13155     nodePush(ctxt, newDoc->children);
13156     ctxt->myDoc = doc;
13157     newRoot->doc = doc;
13158
13159     /*
13160      * Get the 4 first bytes and decode the charset
13161      * if enc != XML_CHAR_ENCODING_NONE
13162      * plug some encoding conversion routines.
13163      */
13164     GROW;
13165     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
13166         start[0] = RAW;
13167         start[1] = NXT(1);
13168         start[2] = NXT(2);
13169         start[3] = NXT(3);
13170         enc = xmlDetectCharEncoding(start, 4);
13171         if (enc != XML_CHAR_ENCODING_NONE) {
13172             xmlSwitchEncoding(ctxt, enc);
13173         }
13174     }
13175
13176     /*
13177      * Parse a possible text declaration first
13178      */
13179     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
13180         xmlParseTextDecl(ctxt);
13181     }
13182
13183     ctxt->instate = XML_PARSER_CONTENT;
13184     ctxt->depth = depth;
13185
13186     xmlParseContent(ctxt);
13187
13188     if ((RAW == '<') && (NXT(1) == '/')) {
13189         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13190     } else if (RAW != 0) {
13191         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13192     }
13193     if (ctxt->node != newDoc->children) {
13194         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13195     }
13196
13197     if (!ctxt->wellFormed) {
13198         if (ctxt->errNo == 0)
13199             ret = XML_ERR_INTERNAL_ERROR;
13200         else
13201             ret = (xmlParserErrors)ctxt->errNo;
13202     } else {
13203         if (list != NULL) {
13204             xmlNodePtr cur;
13205
13206             /*
13207              * Return the newly created nodeset after unlinking it from
13208              * they pseudo parent.
13209              */
13210             cur = newDoc->children->children;
13211             *list = cur;
13212             while (cur != NULL) {
13213                 cur->parent = NULL;
13214                 cur = cur->next;
13215             }
13216             newDoc->children->children = NULL;
13217         }
13218         ret = XML_ERR_OK;
13219     }
13220
13221     /*
13222      * Record in the parent context the number of entities replacement
13223      * done when parsing that reference.
13224      */
13225     if (oldctxt != NULL)
13226         oldctxt->nbentities += ctxt->nbentities;
13227
13228     /*
13229      * Also record the size of the entity parsed
13230      */
13231     if (ctxt->input != NULL && oldctxt != NULL) {
13232         oldctxt->sizeentities += ctxt->input->consumed;
13233         oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
13234     }
13235     /*
13236      * And record the last error if any
13237      */
13238     if ((oldctxt != NULL) && (ctxt->lastError.code != XML_ERR_OK))
13239         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13240
13241     if (sax != NULL)
13242         ctxt->sax = oldsax;
13243     if (oldctxt != NULL) {
13244         oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
13245         oldctxt->node_seq.length = ctxt->node_seq.length;
13246         oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
13247     }
13248     ctxt->node_seq.maximum = 0;
13249     ctxt->node_seq.length = 0;
13250     ctxt->node_seq.buffer = NULL;
13251     xmlFreeParserCtxt(ctxt);
13252     newDoc->intSubset = NULL;
13253     newDoc->extSubset = NULL;
13254     xmlFreeDoc(newDoc);
13255
13256     return(ret);
13257 }
13258
13259 #ifdef LIBXML_SAX1_ENABLED
13260 /**
13261  * xmlParseExternalEntity:
13262  * @doc:  the document the chunk pertains to
13263  * @sax:  the SAX handler bloc (possibly NULL)
13264  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13265  * @depth:  Used for loop detection, use 0
13266  * @URL:  the URL for the entity to load
13267  * @ID:  the System ID for the entity to load
13268  * @lst:  the return value for the set of parsed nodes
13269  *
13270  * Parse an external general entity
13271  * An external general parsed entity is well-formed if it matches the
13272  * production labeled extParsedEnt.
13273  *
13274  * [78] extParsedEnt ::= TextDecl? content
13275  *
13276  * Returns 0 if the entity is well formed, -1 in case of args problem and
13277  *    the parser error code otherwise
13278  */
13279
13280 int
13281 xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
13282           int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
13283     return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
13284                                        ID, lst));
13285 }
13286
13287 /**
13288  * xmlParseBalancedChunkMemory:
13289  * @doc:  the document the chunk pertains to
13290  * @sax:  the SAX handler bloc (possibly NULL)
13291  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13292  * @depth:  Used for loop detection, use 0
13293  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13294  * @lst:  the return value for the set of parsed nodes
13295  *
13296  * Parse a well-balanced chunk of an XML document
13297  * called by the parser
13298  * The allowed sequence for the Well Balanced Chunk is the one defined by
13299  * the content production in the XML grammar:
13300  *
13301  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13302  *
13303  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13304  *    the parser error code otherwise
13305  */
13306
13307 int
13308 xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13309      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
13310     return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
13311                                                 depth, string, lst, 0 );
13312 }
13313 #endif /* LIBXML_SAX1_ENABLED */
13314
13315 /**
13316  * xmlParseBalancedChunkMemoryInternal:
13317  * @oldctxt:  the existing parsing context
13318  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13319  * @user_data:  the user data field for the parser context
13320  * @lst:  the return value for the set of parsed nodes
13321  *
13322  *
13323  * Parse a well-balanced chunk of an XML document
13324  * called by the parser
13325  * The allowed sequence for the Well Balanced Chunk is the one defined by
13326  * the content production in the XML grammar:
13327  *
13328  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13329  *
13330  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13331  * error code otherwise
13332  *
13333  * In case recover is set to 1, the nodelist will not be empty even if
13334  * the parsed chunk is not well balanced.
13335  */
13336 static xmlParserErrors
13337 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
13338         const xmlChar *string, void *user_data, xmlNodePtr *lst) {
13339     xmlParserCtxtPtr ctxt;
13340     xmlDocPtr newDoc = NULL;
13341     xmlNodePtr newRoot;
13342     xmlSAXHandlerPtr oldsax = NULL;
13343     xmlNodePtr content = NULL;
13344     xmlNodePtr last = NULL;
13345     int size;
13346     xmlParserErrors ret = XML_ERR_OK;
13347 #ifdef SAX2
13348     int i;
13349 #endif
13350
13351     if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
13352         (oldctxt->depth >  1024)) {
13353         return(XML_ERR_ENTITY_LOOP);
13354     }
13355
13356
13357     if (lst != NULL)
13358         *lst = NULL;
13359     if (string == NULL)
13360         return(XML_ERR_INTERNAL_ERROR);
13361
13362     size = xmlStrlen(string);
13363
13364     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13365     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
13366     if (user_data != NULL)
13367         ctxt->userData = user_data;
13368     else
13369         ctxt->userData = ctxt;
13370     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
13371     ctxt->dict = oldctxt->dict;
13372     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13373     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13374     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13375
13376 #ifdef SAX2
13377     /* propagate namespaces down the entity */
13378     for (i = 0;i < oldctxt->nsNr;i += 2) {
13379         nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
13380     }
13381 #endif
13382
13383     oldsax = ctxt->sax;
13384     ctxt->sax = oldctxt->sax;
13385     xmlDetectSAX2(ctxt);
13386     ctxt->replaceEntities = oldctxt->replaceEntities;
13387     ctxt->options = oldctxt->options;
13388
13389     ctxt->_private = oldctxt->_private;
13390     if (oldctxt->myDoc == NULL) {
13391         newDoc = xmlNewDoc(BAD_CAST "1.0");
13392         if (newDoc == NULL) {
13393             ctxt->sax = oldsax;
13394             ctxt->dict = NULL;
13395             xmlFreeParserCtxt(ctxt);
13396             return(XML_ERR_INTERNAL_ERROR);
13397         }
13398         newDoc->properties = XML_DOC_INTERNAL;
13399         newDoc->dict = ctxt->dict;
13400         xmlDictReference(newDoc->dict);
13401         ctxt->myDoc = newDoc;
13402     } else {
13403         ctxt->myDoc = oldctxt->myDoc;
13404         content = ctxt->myDoc->children;
13405         last = ctxt->myDoc->last;
13406     }
13407     newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
13408     if (newRoot == NULL) {
13409         ctxt->sax = oldsax;
13410         ctxt->dict = NULL;
13411         xmlFreeParserCtxt(ctxt);
13412         if (newDoc != NULL) {
13413             xmlFreeDoc(newDoc);
13414         }
13415         return(XML_ERR_INTERNAL_ERROR);
13416     }
13417     ctxt->myDoc->children = NULL;
13418     ctxt->myDoc->last = NULL;
13419     xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
13420     nodePush(ctxt, ctxt->myDoc->children);
13421     ctxt->instate = XML_PARSER_CONTENT;
13422     ctxt->depth = oldctxt->depth + 1;
13423
13424     ctxt->validate = 0;
13425     ctxt->loadsubset = oldctxt->loadsubset;
13426     if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
13427         /*
13428          * ID/IDREF registration will be done in xmlValidateElement below
13429          */
13430         ctxt->loadsubset |= XML_SKIP_IDS;
13431     }
13432     ctxt->dictNames = oldctxt->dictNames;
13433     ctxt->attsDefault = oldctxt->attsDefault;
13434     ctxt->attsSpecial = oldctxt->attsSpecial;
13435
13436     xmlParseContent(ctxt);
13437     if ((RAW == '<') && (NXT(1) == '/')) {
13438         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13439     } else if (RAW != 0) {
13440         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13441     }
13442     if (ctxt->node != ctxt->myDoc->children) {
13443         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13444     }
13445
13446     if (!ctxt->wellFormed) {
13447         if (ctxt->errNo == 0)
13448             ret = XML_ERR_INTERNAL_ERROR;
13449         else
13450             ret = (xmlParserErrors)ctxt->errNo;
13451     } else {
13452       ret = XML_ERR_OK;
13453     }
13454
13455     if ((lst != NULL) && (ret == XML_ERR_OK)) {
13456         xmlNodePtr cur;
13457
13458         /*
13459          * Return the newly created nodeset after unlinking it from
13460          * they pseudo parent.
13461          */
13462         cur = ctxt->myDoc->children->children;
13463         *lst = cur;
13464         while (cur != NULL) {
13465 #ifdef LIBXML_VALID_ENABLED
13466             if ((oldctxt->validate) && (oldctxt->wellFormed) &&
13467                 (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
13468                 (cur->type == XML_ELEMENT_NODE)) {
13469                 oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
13470                         oldctxt->myDoc, cur);
13471             }
13472 #endif /* LIBXML_VALID_ENABLED */
13473             cur->parent = NULL;
13474             cur = cur->next;
13475         }
13476         ctxt->myDoc->children->children = NULL;
13477     }
13478     if (ctxt->myDoc != NULL) {
13479         xmlFreeNode(ctxt->myDoc->children);
13480         ctxt->myDoc->children = content;
13481         ctxt->myDoc->last = last;
13482     }
13483
13484     /*
13485      * Record in the parent context the number of entities replacement
13486      * done when parsing that reference.
13487      */
13488     if (oldctxt != NULL)
13489         oldctxt->nbentities += ctxt->nbentities;
13490
13491     /*
13492      * Also record the last error if any
13493      */
13494     if (ctxt->lastError.code != XML_ERR_OK)
13495         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13496
13497     ctxt->sax = oldsax;
13498     ctxt->dict = NULL;
13499     ctxt->attsDefault = NULL;
13500     ctxt->attsSpecial = NULL;
13501     xmlFreeParserCtxt(ctxt);
13502     if (newDoc != NULL) {
13503         xmlFreeDoc(newDoc);
13504     }
13505
13506     return(ret);
13507 }
13508
13509 /**
13510  * xmlParseInNodeContext:
13511  * @node:  the context node
13512  * @data:  the input string
13513  * @datalen:  the input string length in bytes
13514  * @options:  a combination of xmlParserOption
13515  * @lst:  the return value for the set of parsed nodes
13516  *
13517  * Parse a well-balanced chunk of an XML document
13518  * within the context (DTD, namespaces, etc ...) of the given node.
13519  *
13520  * The allowed sequence for the data is a Well Balanced Chunk defined by
13521  * the content production in the XML grammar:
13522  *
13523  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13524  *
13525  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13526  * error code otherwise
13527  */
13528 xmlParserErrors
13529 xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
13530                       int options, xmlNodePtr *lst) {
13531 #ifdef SAX2
13532     xmlParserCtxtPtr ctxt;
13533     xmlDocPtr doc = NULL;
13534     xmlNodePtr fake, cur;
13535     int nsnr = 0;
13536
13537     xmlParserErrors ret = XML_ERR_OK;
13538
13539     /*
13540      * check all input parameters, grab the document
13541      */
13542     if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
13543         return(XML_ERR_INTERNAL_ERROR);
13544     switch (node->type) {
13545         case XML_ELEMENT_NODE:
13546         case XML_ATTRIBUTE_NODE:
13547         case XML_TEXT_NODE:
13548         case XML_CDATA_SECTION_NODE:
13549         case XML_ENTITY_REF_NODE:
13550         case XML_PI_NODE:
13551         case XML_COMMENT_NODE:
13552         case XML_DOCUMENT_NODE:
13553         case XML_HTML_DOCUMENT_NODE:
13554             break;
13555         default:
13556             return(XML_ERR_INTERNAL_ERROR);
13557
13558     }
13559     while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
13560            (node->type != XML_DOCUMENT_NODE) &&
13561            (node->type != XML_HTML_DOCUMENT_NODE))
13562         node = node->parent;
13563     if (node == NULL)
13564         return(XML_ERR_INTERNAL_ERROR);
13565     if (node->type == XML_ELEMENT_NODE)
13566         doc = node->doc;
13567     else
13568         doc = (xmlDocPtr) node;
13569     if (doc == NULL)
13570         return(XML_ERR_INTERNAL_ERROR);
13571
13572     /*
13573      * allocate a context and set-up everything not related to the
13574      * node position in the tree
13575      */
13576     if (doc->type == XML_DOCUMENT_NODE)
13577         ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
13578 #ifdef LIBXML_HTML_ENABLED
13579     else if (doc->type == XML_HTML_DOCUMENT_NODE) {
13580         ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
13581         /*
13582          * When parsing in context, it makes no sense to add implied
13583          * elements like html/body/etc...
13584          */
13585         options |= HTML_PARSE_NOIMPLIED;
13586     }
13587 #endif
13588     else
13589         return(XML_ERR_INTERNAL_ERROR);
13590
13591     if (ctxt == NULL)
13592         return(XML_ERR_NO_MEMORY);
13593
13594     /*
13595      * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
13596      * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
13597      * we must wait until the last moment to free the original one.
13598      */
13599     if (doc->dict != NULL) {
13600         if (ctxt->dict != NULL)
13601             xmlDictFree(ctxt->dict);
13602         ctxt->dict = doc->dict;
13603     } else
13604         options |= XML_PARSE_NODICT;
13605
13606     if (doc->encoding != NULL) {
13607         xmlCharEncodingHandlerPtr hdlr;
13608
13609         if (ctxt->encoding != NULL)
13610             xmlFree((xmlChar *) ctxt->encoding);
13611         ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
13612
13613         hdlr = xmlFindCharEncodingHandler((const char *) doc->encoding);
13614         if (hdlr != NULL) {
13615             xmlSwitchToEncoding(ctxt, hdlr);
13616         } else {
13617             return(XML_ERR_UNSUPPORTED_ENCODING);
13618         }
13619     }
13620
13621     xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13622     xmlDetectSAX2(ctxt);
13623     ctxt->myDoc = doc;
13624     /* parsing in context, i.e. as within existing content */
13625     ctxt->instate = XML_PARSER_CONTENT;
13626
13627     fake = xmlNewComment(NULL);
13628     if (fake == NULL) {
13629         xmlFreeParserCtxt(ctxt);
13630         return(XML_ERR_NO_MEMORY);
13631     }
13632     xmlAddChild(node, fake);
13633
13634     if (node->type == XML_ELEMENT_NODE) {
13635         nodePush(ctxt, node);
13636         /*
13637          * initialize the SAX2 namespaces stack
13638          */
13639         cur = node;
13640         while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
13641             xmlNsPtr ns = cur->nsDef;
13642             const xmlChar *iprefix, *ihref;
13643
13644             while (ns != NULL) {
13645                 if (ctxt->dict) {
13646                     iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
13647                     ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
13648                 } else {
13649                     iprefix = ns->prefix;
13650                     ihref = ns->href;
13651                 }
13652
13653                 if (xmlGetNamespace(ctxt, iprefix) == NULL) {
13654                     nsPush(ctxt, iprefix, ihref);
13655                     nsnr++;
13656                 }
13657                 ns = ns->next;
13658             }
13659             cur = cur->parent;
13660         }
13661     }
13662
13663     if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
13664         /*
13665          * ID/IDREF registration will be done in xmlValidateElement below
13666          */
13667         ctxt->loadsubset |= XML_SKIP_IDS;
13668     }
13669
13670 #ifdef LIBXML_HTML_ENABLED
13671     if (doc->type == XML_HTML_DOCUMENT_NODE)
13672         __htmlParseContent(ctxt);
13673     else
13674 #endif
13675         xmlParseContent(ctxt);
13676
13677     nsPop(ctxt, nsnr);
13678     if ((RAW == '<') && (NXT(1) == '/')) {
13679         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13680     } else if (RAW != 0) {
13681         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13682     }
13683     if ((ctxt->node != NULL) && (ctxt->node != node)) {
13684         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13685         ctxt->wellFormed = 0;
13686     }
13687
13688     if (!ctxt->wellFormed) {
13689         if (ctxt->errNo == 0)
13690             ret = XML_ERR_INTERNAL_ERROR;
13691         else
13692             ret = (xmlParserErrors)ctxt->errNo;
13693     } else {
13694         ret = XML_ERR_OK;
13695     }
13696
13697     /*
13698      * Return the newly created nodeset after unlinking it from
13699      * the pseudo sibling.
13700      */
13701
13702     cur = fake->next;
13703     fake->next = NULL;
13704     node->last = fake;
13705
13706     if (cur != NULL) {
13707         cur->prev = NULL;
13708     }
13709
13710     *lst = cur;
13711
13712     while (cur != NULL) {
13713         cur->parent = NULL;
13714         cur = cur->next;
13715     }
13716
13717     xmlUnlinkNode(fake);
13718     xmlFreeNode(fake);
13719
13720
13721     if (ret != XML_ERR_OK) {
13722         xmlFreeNodeList(*lst);
13723         *lst = NULL;
13724     }
13725
13726     if (doc->dict != NULL)
13727         ctxt->dict = NULL;
13728     xmlFreeParserCtxt(ctxt);
13729
13730     return(ret);
13731 #else /* !SAX2 */
13732     return(XML_ERR_INTERNAL_ERROR);
13733 #endif
13734 }
13735
13736 #ifdef LIBXML_SAX1_ENABLED
13737 /**
13738  * xmlParseBalancedChunkMemoryRecover:
13739  * @doc:  the document the chunk pertains to
13740  * @sax:  the SAX handler bloc (possibly NULL)
13741  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13742  * @depth:  Used for loop detection, use 0
13743  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13744  * @lst:  the return value for the set of parsed nodes
13745  * @recover: return nodes even if the data is broken (use 0)
13746  *
13747  *
13748  * Parse a well-balanced chunk of an XML document
13749  * called by the parser
13750  * The allowed sequence for the Well Balanced Chunk is the one defined by
13751  * the content production in the XML grammar:
13752  *
13753  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13754  *
13755  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13756  *    the parser error code otherwise
13757  *
13758  * In case recover is set to 1, the nodelist will not be empty even if
13759  * the parsed chunk is not well balanced, assuming the parsing succeeded to
13760  * some extent.
13761  */
13762 int
13763 xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13764      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
13765      int recover) {
13766     xmlParserCtxtPtr ctxt;
13767     xmlDocPtr newDoc;
13768     xmlSAXHandlerPtr oldsax = NULL;
13769     xmlNodePtr content, newRoot;
13770     int size;
13771     int ret = 0;
13772
13773     if (depth > 40) {
13774         return(XML_ERR_ENTITY_LOOP);
13775     }
13776
13777
13778     if (lst != NULL)
13779         *lst = NULL;
13780     if (string == NULL)
13781         return(-1);
13782
13783     size = xmlStrlen(string);
13784
13785     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13786     if (ctxt == NULL) return(-1);
13787     ctxt->userData = ctxt;
13788     if (sax != NULL) {
13789         oldsax = ctxt->sax;
13790         ctxt->sax = sax;
13791         if (user_data != NULL)
13792             ctxt->userData = user_data;
13793     }
13794     newDoc = xmlNewDoc(BAD_CAST "1.0");
13795     if (newDoc == NULL) {
13796         xmlFreeParserCtxt(ctxt);
13797         return(-1);
13798     }
13799     newDoc->properties = XML_DOC_INTERNAL;
13800     if ((doc != NULL) && (doc->dict != NULL)) {
13801         xmlDictFree(ctxt->dict);
13802         ctxt->dict = doc->dict;
13803         xmlDictReference(ctxt->dict);
13804         ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13805         ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13806         ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13807         ctxt->dictNames = 1;
13808     } else {
13809         xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
13810     }
13811     if (doc != NULL) {
13812         newDoc->intSubset = doc->intSubset;
13813         newDoc->extSubset = doc->extSubset;
13814     }
13815     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13816     if (newRoot == NULL) {
13817         if (sax != NULL)
13818             ctxt->sax = oldsax;
13819         xmlFreeParserCtxt(ctxt);
13820         newDoc->intSubset = NULL;
13821         newDoc->extSubset = NULL;
13822         xmlFreeDoc(newDoc);
13823         return(-1);
13824     }
13825     xmlAddChild((xmlNodePtr) newDoc, newRoot);
13826     nodePush(ctxt, newRoot);
13827     if (doc == NULL) {
13828         ctxt->myDoc = newDoc;
13829     } else {
13830         ctxt->myDoc = newDoc;
13831         newDoc->children->doc = doc;
13832         /* Ensure that doc has XML spec namespace */
13833         xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
13834         newDoc->oldNs = doc->oldNs;
13835     }
13836     ctxt->instate = XML_PARSER_CONTENT;
13837     ctxt->depth = depth;
13838
13839     /*
13840      * Doing validity checking on chunk doesn't make sense
13841      */
13842     ctxt->validate = 0;
13843     ctxt->loadsubset = 0;
13844     xmlDetectSAX2(ctxt);
13845
13846     if ( doc != NULL ){
13847         content = doc->children;
13848         doc->children = NULL;
13849         xmlParseContent(ctxt);
13850         doc->children = content;
13851     }
13852     else {
13853         xmlParseContent(ctxt);
13854     }
13855     if ((RAW == '<') && (NXT(1) == '/')) {
13856         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13857     } else if (RAW != 0) {
13858         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13859     }
13860     if (ctxt->node != newDoc->children) {
13861         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13862     }
13863
13864     if (!ctxt->wellFormed) {
13865         if (ctxt->errNo == 0)
13866             ret = 1;
13867         else
13868             ret = ctxt->errNo;
13869     } else {
13870       ret = 0;
13871     }
13872
13873     if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
13874         xmlNodePtr cur;
13875
13876         /*
13877          * Return the newly created nodeset after unlinking it from
13878          * they pseudo parent.
13879          */
13880         cur = newDoc->children->children;
13881         *lst = cur;
13882         while (cur != NULL) {
13883             xmlSetTreeDoc(cur, doc);
13884             cur->parent = NULL;
13885             cur = cur->next;
13886         }
13887         newDoc->children->children = NULL;
13888     }
13889
13890     if (sax != NULL)
13891         ctxt->sax = oldsax;
13892     xmlFreeParserCtxt(ctxt);
13893     newDoc->intSubset = NULL;
13894     newDoc->extSubset = NULL;
13895     newDoc->oldNs = NULL;
13896     xmlFreeDoc(newDoc);
13897
13898     return(ret);
13899 }
13900
13901 /**
13902  * xmlSAXParseEntity:
13903  * @sax:  the SAX handler block
13904  * @filename:  the filename
13905  *
13906  * parse an XML external entity out of context and build a tree.
13907  * It use the given SAX function block to handle the parsing callback.
13908  * If sax is NULL, fallback to the default DOM tree building routines.
13909  *
13910  * [78] extParsedEnt ::= TextDecl? content
13911  *
13912  * This correspond to a "Well Balanced" chunk
13913  *
13914  * Returns the resulting document tree
13915  */
13916
13917 xmlDocPtr
13918 xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
13919     xmlDocPtr ret;
13920     xmlParserCtxtPtr ctxt;
13921
13922     ctxt = xmlCreateFileParserCtxt(filename);
13923     if (ctxt == NULL) {
13924         return(NULL);
13925     }
13926     if (sax != NULL) {
13927         if (ctxt->sax != NULL)
13928             xmlFree(ctxt->sax);
13929         ctxt->sax = sax;
13930         ctxt->userData = NULL;
13931     }
13932
13933     xmlParseExtParsedEnt(ctxt);
13934
13935     if (ctxt->wellFormed)
13936         ret = ctxt->myDoc;
13937     else {
13938         ret = NULL;
13939         xmlFreeDoc(ctxt->myDoc);
13940         ctxt->myDoc = NULL;
13941     }
13942     if (sax != NULL)
13943         ctxt->sax = NULL;
13944     xmlFreeParserCtxt(ctxt);
13945
13946     return(ret);
13947 }
13948
13949 /**
13950  * xmlParseEntity:
13951  * @filename:  the filename
13952  *
13953  * parse an XML external entity out of context and build a tree.
13954  *
13955  * [78] extParsedEnt ::= TextDecl? content
13956  *
13957  * This correspond to a "Well Balanced" chunk
13958  *
13959  * Returns the resulting document tree
13960  */
13961
13962 xmlDocPtr
13963 xmlParseEntity(const char *filename) {
13964     return(xmlSAXParseEntity(NULL, filename));
13965 }
13966 #endif /* LIBXML_SAX1_ENABLED */
13967
13968 /**
13969  * xmlCreateEntityParserCtxtInternal:
13970  * @URL:  the entity URL
13971  * @ID:  the entity PUBLIC ID
13972  * @base:  a possible base for the target URI
13973  * @pctx:  parser context used to set options on new context
13974  *
13975  * Create a parser context for an external entity
13976  * Automatic support for ZLIB/Compress compressed document is provided
13977  * by default if found at compile-time.
13978  *
13979  * Returns the new parser context or NULL
13980  */
13981 static xmlParserCtxtPtr
13982 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
13983                           const xmlChar *base, xmlParserCtxtPtr pctx) {
13984     xmlParserCtxtPtr ctxt;
13985     xmlParserInputPtr inputStream;
13986     char *directory = NULL;
13987     xmlChar *uri;
13988
13989     ctxt = xmlNewParserCtxt();
13990     if (ctxt == NULL) {
13991         return(NULL);
13992     }
13993
13994     if (pctx != NULL) {
13995         ctxt->options = pctx->options;
13996         ctxt->_private = pctx->_private;
13997     }
13998
13999     uri = xmlBuildURI(URL, base);
14000
14001     if (uri == NULL) {
14002         inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
14003         if (inputStream == NULL) {
14004             xmlFreeParserCtxt(ctxt);
14005             return(NULL);
14006         }
14007
14008         inputPush(ctxt, inputStream);
14009
14010         if ((ctxt->directory == NULL) && (directory == NULL))
14011             directory = xmlParserGetDirectory((char *)URL);
14012         if ((ctxt->directory == NULL) && (directory != NULL))
14013             ctxt->directory = directory;
14014     } else {
14015         inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
14016         if (inputStream == NULL) {
14017             xmlFree(uri);
14018             xmlFreeParserCtxt(ctxt);
14019             return(NULL);
14020         }
14021
14022         inputPush(ctxt, inputStream);
14023
14024         if ((ctxt->directory == NULL) && (directory == NULL))
14025             directory = xmlParserGetDirectory((char *)uri);
14026         if ((ctxt->directory == NULL) && (directory != NULL))
14027             ctxt->directory = directory;
14028         xmlFree(uri);
14029     }
14030     return(ctxt);
14031 }
14032
14033 /**
14034  * xmlCreateEntityParserCtxt:
14035  * @URL:  the entity URL
14036  * @ID:  the entity PUBLIC ID
14037  * @base:  a possible base for the target URI
14038  *
14039  * Create a parser context for an external entity
14040  * Automatic support for ZLIB/Compress compressed document is provided
14041  * by default if found at compile-time.
14042  *
14043  * Returns the new parser context or NULL
14044  */
14045 xmlParserCtxtPtr
14046 xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
14047                           const xmlChar *base) {
14048     return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
14049
14050 }
14051
14052 /************************************************************************
14053  *                                                                      *
14054  *              Front ends when parsing from a file                     *
14055  *                                                                      *
14056  ************************************************************************/
14057
14058 /**
14059  * xmlCreateURLParserCtxt:
14060  * @filename:  the filename or URL
14061  * @options:  a combination of xmlParserOption
14062  *
14063  * Create a parser context for a file or URL content.
14064  * Automatic support for ZLIB/Compress compressed document is provided
14065  * by default if found at compile-time and for file accesses
14066  *
14067  * Returns the new parser context or NULL
14068  */
14069 xmlParserCtxtPtr
14070 xmlCreateURLParserCtxt(const char *filename, int options)
14071 {
14072     xmlParserCtxtPtr ctxt;
14073     xmlParserInputPtr inputStream;
14074     char *directory = NULL;
14075
14076     ctxt = xmlNewParserCtxt();
14077     if (ctxt == NULL) {
14078         xmlErrMemory(NULL, "cannot allocate parser context");
14079         return(NULL);
14080     }
14081
14082     if (options)
14083         xmlCtxtUseOptionsInternal(ctxt, options, NULL);
14084     ctxt->linenumbers = 1;
14085
14086     inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
14087     if (inputStream == NULL) {
14088         xmlFreeParserCtxt(ctxt);
14089         return(NULL);
14090     }
14091
14092     inputPush(ctxt, inputStream);
14093     if ((ctxt->directory == NULL) && (directory == NULL))
14094         directory = xmlParserGetDirectory(filename);
14095     if ((ctxt->directory == NULL) && (directory != NULL))
14096         ctxt->directory = directory;
14097
14098     return(ctxt);
14099 }
14100
14101 /**
14102  * xmlCreateFileParserCtxt:
14103  * @filename:  the filename
14104  *
14105  * Create a parser context for a file content.
14106  * Automatic support for ZLIB/Compress compressed document is provided
14107  * by default if found at compile-time.
14108  *
14109  * Returns the new parser context or NULL
14110  */
14111 xmlParserCtxtPtr
14112 xmlCreateFileParserCtxt(const char *filename)
14113 {
14114     return(xmlCreateURLParserCtxt(filename, 0));
14115 }
14116
14117 #ifdef LIBXML_SAX1_ENABLED
14118 /**
14119  * xmlSAXParseFileWithData:
14120  * @sax:  the SAX handler block
14121  * @filename:  the filename
14122  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14123  *             documents
14124  * @data:  the userdata
14125  *
14126  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14127  * compressed document is provided by default if found at compile-time.
14128  * It use the given SAX function block to handle the parsing callback.
14129  * If sax is NULL, fallback to the default DOM tree building routines.
14130  *
14131  * User data (void *) is stored within the parser context in the
14132  * context's _private member, so it is available nearly everywhere in libxml
14133  *
14134  * Returns the resulting document tree
14135  */
14136
14137 xmlDocPtr
14138 xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
14139                         int recovery, void *data) {
14140     xmlDocPtr ret;
14141     xmlParserCtxtPtr ctxt;
14142
14143     xmlInitParser();
14144
14145     ctxt = xmlCreateFileParserCtxt(filename);
14146     if (ctxt == NULL) {
14147         return(NULL);
14148     }
14149     if (sax != NULL) {
14150         if (ctxt->sax != NULL)
14151             xmlFree(ctxt->sax);
14152         ctxt->sax = sax;
14153     }
14154     xmlDetectSAX2(ctxt);
14155     if (data!=NULL) {
14156         ctxt->_private = data;
14157     }
14158
14159     if (ctxt->directory == NULL)
14160         ctxt->directory = xmlParserGetDirectory(filename);
14161
14162     ctxt->recovery = recovery;
14163
14164     xmlParseDocument(ctxt);
14165
14166     if ((ctxt->wellFormed) || recovery) {
14167         ret = ctxt->myDoc;
14168         if (ret != NULL) {
14169             if (ctxt->input->buf->compressed > 0)
14170                 ret->compression = 9;
14171             else
14172                 ret->compression = ctxt->input->buf->compressed;
14173         }
14174     }
14175     else {
14176        ret = NULL;
14177        xmlFreeDoc(ctxt->myDoc);
14178        ctxt->myDoc = NULL;
14179     }
14180     if (sax != NULL)
14181         ctxt->sax = NULL;
14182     xmlFreeParserCtxt(ctxt);
14183
14184     return(ret);
14185 }
14186
14187 /**
14188  * xmlSAXParseFile:
14189  * @sax:  the SAX handler block
14190  * @filename:  the filename
14191  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14192  *             documents
14193  *
14194  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14195  * compressed document is provided by default if found at compile-time.
14196  * It use the given SAX function block to handle the parsing callback.
14197  * If sax is NULL, fallback to the default DOM tree building routines.
14198  *
14199  * Returns the resulting document tree
14200  */
14201
14202 xmlDocPtr
14203 xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
14204                           int recovery) {
14205     return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
14206 }
14207
14208 /**
14209  * xmlRecoverDoc:
14210  * @cur:  a pointer to an array of xmlChar
14211  *
14212  * parse an XML in-memory document and build a tree.
14213  * In the case the document is not Well Formed, a attempt to build a
14214  * tree is tried anyway
14215  *
14216  * Returns the resulting document tree or NULL in case of failure
14217  */
14218
14219 xmlDocPtr
14220 xmlRecoverDoc(const xmlChar *cur) {
14221     return(xmlSAXParseDoc(NULL, cur, 1));
14222 }
14223
14224 /**
14225  * xmlParseFile:
14226  * @filename:  the filename
14227  *
14228  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14229  * compressed document is provided by default if found at compile-time.
14230  *
14231  * Returns the resulting document tree if the file was wellformed,
14232  * NULL otherwise.
14233  */
14234
14235 xmlDocPtr
14236 xmlParseFile(const char *filename) {
14237     return(xmlSAXParseFile(NULL, filename, 0));
14238 }
14239
14240 /**
14241  * xmlRecoverFile:
14242  * @filename:  the filename
14243  *
14244  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14245  * compressed document is provided by default if found at compile-time.
14246  * In the case the document is not Well Formed, it attempts to build
14247  * a tree anyway
14248  *
14249  * Returns the resulting document tree or NULL in case of failure
14250  */
14251
14252 xmlDocPtr
14253 xmlRecoverFile(const char *filename) {
14254     return(xmlSAXParseFile(NULL, filename, 1));
14255 }
14256
14257
14258 /**
14259  * xmlSetupParserForBuffer:
14260  * @ctxt:  an XML parser context
14261  * @buffer:  a xmlChar * buffer
14262  * @filename:  a file name
14263  *
14264  * Setup the parser context to parse a new buffer; Clears any prior
14265  * contents from the parser context. The buffer parameter must not be
14266  * NULL, but the filename parameter can be
14267  */
14268 void
14269 xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
14270                              const char* filename)
14271 {
14272     xmlParserInputPtr input;
14273
14274     if ((ctxt == NULL) || (buffer == NULL))
14275         return;
14276
14277     input = xmlNewInputStream(ctxt);
14278     if (input == NULL) {
14279         xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
14280         xmlClearParserCtxt(ctxt);
14281         return;
14282     }
14283
14284     xmlClearParserCtxt(ctxt);
14285     if (filename != NULL)
14286         input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
14287     input->base = buffer;
14288     input->cur = buffer;
14289     input->end = &buffer[xmlStrlen(buffer)];
14290     inputPush(ctxt, input);
14291 }
14292
14293 /**
14294  * xmlSAXUserParseFile:
14295  * @sax:  a SAX handler
14296  * @user_data:  The user data returned on SAX callbacks
14297  * @filename:  a file name
14298  *
14299  * parse an XML file and call the given SAX handler routines.
14300  * Automatic support for ZLIB/Compress compressed document is provided
14301  *
14302  * Returns 0 in case of success or a error number otherwise
14303  */
14304 int
14305 xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
14306                     const char *filename) {
14307     int ret = 0;
14308     xmlParserCtxtPtr ctxt;
14309
14310     ctxt = xmlCreateFileParserCtxt(filename);
14311     if (ctxt == NULL) return -1;
14312     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14313         xmlFree(ctxt->sax);
14314     ctxt->sax = sax;
14315     xmlDetectSAX2(ctxt);
14316
14317     if (user_data != NULL)
14318         ctxt->userData = user_data;
14319
14320     xmlParseDocument(ctxt);
14321
14322     if (ctxt->wellFormed)
14323         ret = 0;
14324     else {
14325         if (ctxt->errNo != 0)
14326             ret = ctxt->errNo;
14327         else
14328             ret = -1;
14329     }
14330     if (sax != NULL)
14331         ctxt->sax = NULL;
14332     if (ctxt->myDoc != NULL) {
14333         xmlFreeDoc(ctxt->myDoc);
14334         ctxt->myDoc = NULL;
14335     }
14336     xmlFreeParserCtxt(ctxt);
14337
14338     return ret;
14339 }
14340 #endif /* LIBXML_SAX1_ENABLED */
14341
14342 /************************************************************************
14343  *                                                                      *
14344  *              Front ends when parsing from memory                     *
14345  *                                                                      *
14346  ************************************************************************/
14347
14348 /**
14349  * xmlCreateMemoryParserCtxt:
14350  * @buffer:  a pointer to a char array
14351  * @size:  the size of the array
14352  *
14353  * Create a parser context for an XML in-memory document.
14354  *
14355  * Returns the new parser context or NULL
14356  */
14357 xmlParserCtxtPtr
14358 xmlCreateMemoryParserCtxt(const char *buffer, int size) {
14359     xmlParserCtxtPtr ctxt;
14360     xmlParserInputPtr input;
14361     xmlParserInputBufferPtr buf;
14362
14363     if (buffer == NULL)
14364         return(NULL);
14365     if (size <= 0)
14366         return(NULL);
14367
14368     ctxt = xmlNewParserCtxt();
14369     if (ctxt == NULL)
14370         return(NULL);
14371
14372     /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
14373     buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
14374     if (buf == NULL) {
14375         xmlFreeParserCtxt(ctxt);
14376         return(NULL);
14377     }
14378
14379     input = xmlNewInputStream(ctxt);
14380     if (input == NULL) {
14381         xmlFreeParserInputBuffer(buf);
14382         xmlFreeParserCtxt(ctxt);
14383         return(NULL);
14384     }
14385
14386     input->filename = NULL;
14387     input->buf = buf;
14388     xmlBufResetInput(input->buf->buffer, input);
14389
14390     inputPush(ctxt, input);
14391     return(ctxt);
14392 }
14393
14394 #ifdef LIBXML_SAX1_ENABLED
14395 /**
14396  * xmlSAXParseMemoryWithData:
14397  * @sax:  the SAX handler block
14398  * @buffer:  an pointer to a char array
14399  * @size:  the size of the array
14400  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14401  *             documents
14402  * @data:  the userdata
14403  *
14404  * parse an XML in-memory block and use the given SAX function block
14405  * to handle the parsing callback. If sax is NULL, fallback to the default
14406  * DOM tree building routines.
14407  *
14408  * User data (void *) is stored within the parser context in the
14409  * context's _private member, so it is available nearly everywhere in libxml
14410  *
14411  * Returns the resulting document tree
14412  */
14413
14414 xmlDocPtr
14415 xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
14416                   int size, int recovery, void *data) {
14417     xmlDocPtr ret;
14418     xmlParserCtxtPtr ctxt;
14419
14420     xmlInitParser();
14421
14422     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14423     if (ctxt == NULL) return(NULL);
14424     if (sax != NULL) {
14425         if (ctxt->sax != NULL)
14426             xmlFree(ctxt->sax);
14427         ctxt->sax = sax;
14428     }
14429     xmlDetectSAX2(ctxt);
14430     if (data!=NULL) {
14431         ctxt->_private=data;
14432     }
14433
14434     ctxt->recovery = recovery;
14435
14436     xmlParseDocument(ctxt);
14437
14438     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14439     else {
14440        ret = NULL;
14441        xmlFreeDoc(ctxt->myDoc);
14442        ctxt->myDoc = NULL;
14443     }
14444     if (sax != NULL)
14445         ctxt->sax = NULL;
14446     xmlFreeParserCtxt(ctxt);
14447
14448     return(ret);
14449 }
14450
14451 /**
14452  * xmlSAXParseMemory:
14453  * @sax:  the SAX handler block
14454  * @buffer:  an pointer to a char array
14455  * @size:  the size of the array
14456  * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
14457  *             documents
14458  *
14459  * parse an XML in-memory block and use the given SAX function block
14460  * to handle the parsing callback. If sax is NULL, fallback to the default
14461  * DOM tree building routines.
14462  *
14463  * Returns the resulting document tree
14464  */
14465 xmlDocPtr
14466 xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
14467                   int size, int recovery) {
14468     return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
14469 }
14470
14471 /**
14472  * xmlParseMemory:
14473  * @buffer:  an pointer to a char array
14474  * @size:  the size of the array
14475  *
14476  * parse an XML in-memory block and build a tree.
14477  *
14478  * Returns the resulting document tree
14479  */
14480
14481 xmlDocPtr xmlParseMemory(const char *buffer, int size) {
14482    return(xmlSAXParseMemory(NULL, buffer, size, 0));
14483 }
14484
14485 /**
14486  * xmlRecoverMemory:
14487  * @buffer:  an pointer to a char array
14488  * @size:  the size of the array
14489  *
14490  * parse an XML in-memory block and build a tree.
14491  * In the case the document is not Well Formed, an attempt to
14492  * build a tree is tried anyway
14493  *
14494  * Returns the resulting document tree or NULL in case of error
14495  */
14496
14497 xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
14498    return(xmlSAXParseMemory(NULL, buffer, size, 1));
14499 }
14500
14501 /**
14502  * xmlSAXUserParseMemory:
14503  * @sax:  a SAX handler
14504  * @user_data:  The user data returned on SAX callbacks
14505  * @buffer:  an in-memory XML document input
14506  * @size:  the length of the XML document in bytes
14507  *
14508  * A better SAX parsing routine.
14509  * parse an XML in-memory buffer and call the given SAX handler routines.
14510  *
14511  * Returns 0 in case of success or a error number otherwise
14512  */
14513 int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
14514                           const char *buffer, int size) {
14515     int ret = 0;
14516     xmlParserCtxtPtr ctxt;
14517
14518     xmlInitParser();
14519
14520     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14521     if (ctxt == NULL) return -1;
14522     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14523         xmlFree(ctxt->sax);
14524     ctxt->sax = sax;
14525     xmlDetectSAX2(ctxt);
14526
14527     if (user_data != NULL)
14528         ctxt->userData = user_data;
14529
14530     xmlParseDocument(ctxt);
14531
14532     if (ctxt->wellFormed)
14533         ret = 0;
14534     else {
14535         if (ctxt->errNo != 0)
14536             ret = ctxt->errNo;
14537         else
14538             ret = -1;
14539     }
14540     if (sax != NULL)
14541         ctxt->sax = NULL;
14542     if (ctxt->myDoc != NULL) {
14543         xmlFreeDoc(ctxt->myDoc);
14544         ctxt->myDoc = NULL;
14545     }
14546     xmlFreeParserCtxt(ctxt);
14547
14548     return ret;
14549 }
14550 #endif /* LIBXML_SAX1_ENABLED */
14551
14552 /**
14553  * xmlCreateDocParserCtxt:
14554  * @cur:  a pointer to an array of xmlChar
14555  *
14556  * Creates a parser context for an XML in-memory document.
14557  *
14558  * Returns the new parser context or NULL
14559  */
14560 xmlParserCtxtPtr
14561 xmlCreateDocParserCtxt(const xmlChar *cur) {
14562     int len;
14563
14564     if (cur == NULL)
14565         return(NULL);
14566     len = xmlStrlen(cur);
14567     return(xmlCreateMemoryParserCtxt((const char *)cur, len));
14568 }
14569
14570 #ifdef LIBXML_SAX1_ENABLED
14571 /**
14572  * xmlSAXParseDoc:
14573  * @sax:  the SAX handler block
14574  * @cur:  a pointer to an array of xmlChar
14575  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14576  *             documents
14577  *
14578  * parse an XML in-memory document and build a tree.
14579  * It use the given SAX function block to handle the parsing callback.
14580  * If sax is NULL, fallback to the default DOM tree building routines.
14581  *
14582  * Returns the resulting document tree
14583  */
14584
14585 xmlDocPtr
14586 xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
14587     xmlDocPtr ret;
14588     xmlParserCtxtPtr ctxt;
14589     xmlSAXHandlerPtr oldsax = NULL;
14590
14591     if (cur == NULL) return(NULL);
14592
14593
14594     ctxt = xmlCreateDocParserCtxt(cur);
14595     if (ctxt == NULL) return(NULL);
14596     if (sax != NULL) {
14597         oldsax = ctxt->sax;
14598         ctxt->sax = sax;
14599         ctxt->userData = NULL;
14600     }
14601     xmlDetectSAX2(ctxt);
14602
14603     xmlParseDocument(ctxt);
14604     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14605     else {
14606        ret = NULL;
14607        xmlFreeDoc(ctxt->myDoc);
14608        ctxt->myDoc = NULL;
14609     }
14610     if (sax != NULL)
14611         ctxt->sax = oldsax;
14612     xmlFreeParserCtxt(ctxt);
14613
14614     return(ret);
14615 }
14616
14617 /**
14618  * xmlParseDoc:
14619  * @cur:  a pointer to an array of xmlChar
14620  *
14621  * parse an XML in-memory document and build a tree.
14622  *
14623  * Returns the resulting document tree
14624  */
14625
14626 xmlDocPtr
14627 xmlParseDoc(const xmlChar *cur) {
14628     return(xmlSAXParseDoc(NULL, cur, 0));
14629 }
14630 #endif /* LIBXML_SAX1_ENABLED */
14631
14632 #ifdef LIBXML_LEGACY_ENABLED
14633 /************************************************************************
14634  *                                                                      *
14635  *      Specific function to keep track of entities references          *
14636  *      and used by the XSLT debugger                                   *
14637  *                                                                      *
14638  ************************************************************************/
14639
14640 static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
14641
14642 /**
14643  * xmlAddEntityReference:
14644  * @ent : A valid entity
14645  * @firstNode : A valid first node for children of entity
14646  * @lastNode : A valid last node of children entity
14647  *
14648  * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
14649  */
14650 static void
14651 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
14652                       xmlNodePtr lastNode)
14653 {
14654     if (xmlEntityRefFunc != NULL) {
14655         (*xmlEntityRefFunc) (ent, firstNode, lastNode);
14656     }
14657 }
14658
14659
14660 /**
14661  * xmlSetEntityReferenceFunc:
14662  * @func: A valid function
14663  *
14664  * Set the function to call call back when a xml reference has been made
14665  */
14666 void
14667 xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
14668 {
14669     xmlEntityRefFunc = func;
14670 }
14671 #endif /* LIBXML_LEGACY_ENABLED */
14672
14673 /************************************************************************
14674  *                                                                      *
14675  *                              Miscellaneous                           *
14676  *                                                                      *
14677  ************************************************************************/
14678
14679 #ifdef LIBXML_XPATH_ENABLED
14680 #include <libxml/xpath.h>
14681 #endif
14682
14683 extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
14684 static int xmlParserInitialized = 0;
14685
14686 /**
14687  * xmlInitParser:
14688  *
14689  * Initialization function for the XML parser.
14690  * This is not reentrant. Call once before processing in case of
14691  * use in multithreaded programs.
14692  */
14693
14694 void
14695 xmlInitParser(void) {
14696     if (xmlParserInitialized != 0)
14697         return;
14698
14699 #ifdef LIBXML_THREAD_ENABLED
14700     __xmlGlobalInitMutexLock();
14701     if (xmlParserInitialized == 0) {
14702 #endif
14703         xmlInitThreads();
14704         xmlInitGlobals();
14705         if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
14706             (xmlGenericError == NULL))
14707             initGenericErrorDefaultFunc(NULL);
14708         xmlInitMemory();
14709         xmlInitializeDict();
14710         xmlInitCharEncodingHandlers();
14711         xmlDefaultSAXHandlerInit();
14712         xmlRegisterDefaultInputCallbacks();
14713 #ifdef LIBXML_OUTPUT_ENABLED
14714         xmlRegisterDefaultOutputCallbacks();
14715 #endif /* LIBXML_OUTPUT_ENABLED */
14716 #ifdef LIBXML_HTML_ENABLED
14717         htmlInitAutoClose();
14718         htmlDefaultSAXHandlerInit();
14719 #endif
14720 #ifdef LIBXML_XPATH_ENABLED
14721         xmlXPathInit();
14722 #endif
14723         xmlParserInitialized = 1;
14724 #ifdef LIBXML_THREAD_ENABLED
14725     }
14726     __xmlGlobalInitMutexUnlock();
14727 #endif
14728 }
14729
14730 /**
14731  * xmlCleanupParser:
14732  *
14733  * This function name is somewhat misleading. It does not clean up
14734  * parser state, it cleans up memory allocated by the library itself.
14735  * It is a cleanup function for the XML library. It tries to reclaim all
14736  * related global memory allocated for the library processing.
14737  * It doesn't deallocate any document related memory. One should
14738  * call xmlCleanupParser() only when the process has finished using
14739  * the library and all XML/HTML documents built with it.
14740  * See also xmlInitParser() which has the opposite function of preparing
14741  * the library for operations.
14742  *
14743  * WARNING: if your application is multithreaded or has plugin support
14744  *          calling this may crash the application if another thread or
14745  *          a plugin is still using libxml2. It's sometimes very hard to
14746  *          guess if libxml2 is in use in the application, some libraries
14747  *          or plugins may use it without notice. In case of doubt abstain
14748  *          from calling this function or do it just before calling exit()
14749  *          to avoid leak reports from valgrind !
14750  */
14751
14752 void
14753 xmlCleanupParser(void) {
14754     if (!xmlParserInitialized)
14755         return;
14756
14757     xmlCleanupCharEncodingHandlers();
14758 #ifdef LIBXML_CATALOG_ENABLED
14759     xmlCatalogCleanup();
14760 #endif
14761     xmlDictCleanup();
14762     xmlCleanupInputCallbacks();
14763 #ifdef LIBXML_OUTPUT_ENABLED
14764     xmlCleanupOutputCallbacks();
14765 #endif
14766 #ifdef LIBXML_SCHEMAS_ENABLED
14767     xmlSchemaCleanupTypes();
14768     xmlRelaxNGCleanupTypes();
14769 #endif
14770     xmlResetLastError();
14771     xmlCleanupGlobals();
14772     xmlCleanupThreads(); /* must be last if called not from the main thread */
14773     xmlCleanupMemory();
14774     xmlParserInitialized = 0;
14775 }
14776
14777 /************************************************************************
14778  *                                                                      *
14779  *      New set (2.6.0) of simpler and more flexible APIs               *
14780  *                                                                      *
14781  ************************************************************************/
14782
14783 /**
14784  * DICT_FREE:
14785  * @str:  a string
14786  *
14787  * Free a string if it is not owned by the "dict" dictionary in the
14788  * current scope
14789  */
14790 #define DICT_FREE(str)                                          \
14791         if ((str) && ((!dict) ||                                \
14792             (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
14793             xmlFree((char *)(str));
14794
14795 /**
14796  * xmlCtxtReset:
14797  * @ctxt: an XML parser context
14798  *
14799  * Reset a parser context
14800  */
14801 void
14802 xmlCtxtReset(xmlParserCtxtPtr ctxt)
14803 {
14804     xmlParserInputPtr input;
14805     xmlDictPtr dict;
14806
14807     if (ctxt == NULL)
14808         return;
14809
14810     dict = ctxt->dict;
14811
14812     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
14813         xmlFreeInputStream(input);
14814     }
14815     ctxt->inputNr = 0;
14816     ctxt->input = NULL;
14817
14818     ctxt->spaceNr = 0;
14819     if (ctxt->spaceTab != NULL) {
14820         ctxt->spaceTab[0] = -1;
14821         ctxt->space = &ctxt->spaceTab[0];
14822     } else {
14823         ctxt->space = NULL;
14824     }
14825
14826
14827     ctxt->nodeNr = 0;
14828     ctxt->node = NULL;
14829
14830     ctxt->nameNr = 0;
14831     ctxt->name = NULL;
14832
14833     DICT_FREE(ctxt->version);
14834     ctxt->version = NULL;
14835     DICT_FREE(ctxt->encoding);
14836     ctxt->encoding = NULL;
14837     DICT_FREE(ctxt->directory);
14838     ctxt->directory = NULL;
14839     DICT_FREE(ctxt->extSubURI);
14840     ctxt->extSubURI = NULL;
14841     DICT_FREE(ctxt->extSubSystem);
14842     ctxt->extSubSystem = NULL;
14843     if (ctxt->myDoc != NULL)
14844         xmlFreeDoc(ctxt->myDoc);
14845     ctxt->myDoc = NULL;
14846
14847     ctxt->standalone = -1;
14848     ctxt->hasExternalSubset = 0;
14849     ctxt->hasPErefs = 0;
14850     ctxt->html = 0;
14851     ctxt->external = 0;
14852     ctxt->instate = XML_PARSER_START;
14853     ctxt->token = 0;
14854
14855     ctxt->wellFormed = 1;
14856     ctxt->nsWellFormed = 1;
14857     ctxt->disableSAX = 0;
14858     ctxt->valid = 1;
14859 #if 0
14860     ctxt->vctxt.userData = ctxt;
14861     ctxt->vctxt.error = xmlParserValidityError;
14862     ctxt->vctxt.warning = xmlParserValidityWarning;
14863 #endif
14864     ctxt->record_info = 0;
14865     ctxt->nbChars = 0;
14866     ctxt->checkIndex = 0;
14867     ctxt->inSubset = 0;
14868     ctxt->errNo = XML_ERR_OK;
14869     ctxt->depth = 0;
14870     ctxt->charset = XML_CHAR_ENCODING_UTF8;
14871     ctxt->catalogs = NULL;
14872     ctxt->nbentities = 0;
14873     ctxt->sizeentities = 0;
14874     ctxt->sizeentcopy = 0;
14875     xmlInitNodeInfoSeq(&ctxt->node_seq);
14876
14877     if (ctxt->attsDefault != NULL) {
14878         xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
14879         ctxt->attsDefault = NULL;
14880     }
14881     if (ctxt->attsSpecial != NULL) {
14882         xmlHashFree(ctxt->attsSpecial, NULL);
14883         ctxt->attsSpecial = NULL;
14884     }
14885
14886 #ifdef LIBXML_CATALOG_ENABLED
14887     if (ctxt->catalogs != NULL)
14888         xmlCatalogFreeLocal(ctxt->catalogs);
14889 #endif
14890     if (ctxt->lastError.code != XML_ERR_OK)
14891         xmlResetError(&ctxt->lastError);
14892 }
14893
14894 /**
14895  * xmlCtxtResetPush:
14896  * @ctxt: an XML parser context
14897  * @chunk:  a pointer to an array of chars
14898  * @size:  number of chars in the array
14899  * @filename:  an optional file name or URI
14900  * @encoding:  the document encoding, or NULL
14901  *
14902  * Reset a push parser context
14903  *
14904  * Returns 0 in case of success and 1 in case of error
14905  */
14906 int
14907 xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
14908                  int size, const char *filename, const char *encoding)
14909 {
14910     xmlParserInputPtr inputStream;
14911     xmlParserInputBufferPtr buf;
14912     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
14913
14914     if (ctxt == NULL)
14915         return(1);
14916
14917     if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
14918         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
14919
14920     buf = xmlAllocParserInputBuffer(enc);
14921     if (buf == NULL)
14922         return(1);
14923
14924     if (ctxt == NULL) {
14925         xmlFreeParserInputBuffer(buf);
14926         return(1);
14927     }
14928
14929     xmlCtxtReset(ctxt);
14930
14931     if (ctxt->pushTab == NULL) {
14932         ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
14933                                             sizeof(xmlChar *));
14934         if (ctxt->pushTab == NULL) {
14935             xmlErrMemory(ctxt, NULL);
14936             xmlFreeParserInputBuffer(buf);
14937             return(1);
14938         }
14939     }
14940
14941     if (filename == NULL) {
14942         ctxt->directory = NULL;
14943     } else {
14944         ctxt->directory = xmlParserGetDirectory(filename);
14945     }
14946
14947     inputStream = xmlNewInputStream(ctxt);
14948     if (inputStream == NULL) {
14949         xmlFreeParserInputBuffer(buf);
14950         return(1);
14951     }
14952
14953     if (filename == NULL)
14954         inputStream->filename = NULL;
14955     else
14956         inputStream->filename = (char *)
14957             xmlCanonicPath((const xmlChar *) filename);
14958     inputStream->buf = buf;
14959     xmlBufResetInput(buf->buffer, inputStream);
14960
14961     inputPush(ctxt, inputStream);
14962
14963     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
14964         (ctxt->input->buf != NULL)) {
14965         size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
14966         size_t cur = ctxt->input->cur - ctxt->input->base;
14967
14968         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
14969
14970         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
14971 #ifdef DEBUG_PUSH
14972         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
14973 #endif
14974     }
14975
14976     if (encoding != NULL) {
14977         xmlCharEncodingHandlerPtr hdlr;
14978
14979         if (ctxt->encoding != NULL)
14980             xmlFree((xmlChar *) ctxt->encoding);
14981         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14982
14983         hdlr = xmlFindCharEncodingHandler(encoding);
14984         if (hdlr != NULL) {
14985             xmlSwitchToEncoding(ctxt, hdlr);
14986         } else {
14987             xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
14988                               "Unsupported encoding %s\n", BAD_CAST encoding);
14989         }
14990     } else if (enc != XML_CHAR_ENCODING_NONE) {
14991         xmlSwitchEncoding(ctxt, enc);
14992     }
14993
14994     return(0);
14995 }
14996
14997
14998 /**
14999  * xmlCtxtUseOptionsInternal:
15000  * @ctxt: an XML parser context
15001  * @options:  a combination of xmlParserOption
15002  * @encoding:  the user provided encoding to use
15003  *
15004  * Applies the options to the parser context
15005  *
15006  * Returns 0 in case of success, the set of unknown or unimplemented options
15007  *         in case of error.
15008  */
15009 static int
15010 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
15011 {
15012     if (ctxt == NULL)
15013         return(-1);
15014     if (encoding != NULL) {
15015         if (ctxt->encoding != NULL)
15016             xmlFree((xmlChar *) ctxt->encoding);
15017         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
15018     }
15019     if (options & XML_PARSE_RECOVER) {
15020         ctxt->recovery = 1;
15021         options -= XML_PARSE_RECOVER;
15022         ctxt->options |= XML_PARSE_RECOVER;
15023     } else
15024         ctxt->recovery = 0;
15025     if (options & XML_PARSE_DTDLOAD) {
15026         ctxt->loadsubset = XML_DETECT_IDS;
15027         options -= XML_PARSE_DTDLOAD;
15028         ctxt->options |= XML_PARSE_DTDLOAD;
15029     } else
15030         ctxt->loadsubset = 0;
15031     if (options & XML_PARSE_DTDATTR) {
15032         ctxt->loadsubset |= XML_COMPLETE_ATTRS;
15033         options -= XML_PARSE_DTDATTR;
15034         ctxt->options |= XML_PARSE_DTDATTR;
15035     }
15036     if (options & XML_PARSE_NOENT) {
15037         ctxt->replaceEntities = 1;
15038         /* ctxt->loadsubset |= XML_DETECT_IDS; */
15039         options -= XML_PARSE_NOENT;
15040         ctxt->options |= XML_PARSE_NOENT;
15041     } else
15042         ctxt->replaceEntities = 0;
15043     if (options & XML_PARSE_PEDANTIC) {
15044         ctxt->pedantic = 1;
15045         options -= XML_PARSE_PEDANTIC;
15046         ctxt->options |= XML_PARSE_PEDANTIC;
15047     } else
15048         ctxt->pedantic = 0;
15049     if (options & XML_PARSE_NOBLANKS) {
15050         ctxt->keepBlanks = 0;
15051         ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
15052         options -= XML_PARSE_NOBLANKS;
15053         ctxt->options |= XML_PARSE_NOBLANKS;
15054     } else
15055         ctxt->keepBlanks = 1;
15056     if (options & XML_PARSE_DTDVALID) {
15057         ctxt->validate = 1;
15058         if (options & XML_PARSE_NOWARNING)
15059             ctxt->vctxt.warning = NULL;
15060         if (options & XML_PARSE_NOERROR)
15061             ctxt->vctxt.error = NULL;
15062         options -= XML_PARSE_DTDVALID;
15063         ctxt->options |= XML_PARSE_DTDVALID;
15064     } else
15065         ctxt->validate = 0;
15066     if (options & XML_PARSE_NOWARNING) {
15067         ctxt->sax->warning = NULL;
15068         options -= XML_PARSE_NOWARNING;
15069     }
15070     if (options & XML_PARSE_NOERROR) {
15071         ctxt->sax->error = NULL;
15072         ctxt->sax->fatalError = NULL;
15073         options -= XML_PARSE_NOERROR;
15074     }
15075 #ifdef LIBXML_SAX1_ENABLED
15076     if (options & XML_PARSE_SAX1) {
15077         ctxt->sax->startElement = xmlSAX2StartElement;
15078         ctxt->sax->endElement = xmlSAX2EndElement;
15079         ctxt->sax->startElementNs = NULL;
15080         ctxt->sax->endElementNs = NULL;
15081         ctxt->sax->initialized = 1;
15082         options -= XML_PARSE_SAX1;
15083         ctxt->options |= XML_PARSE_SAX1;
15084     }
15085 #endif /* LIBXML_SAX1_ENABLED */
15086     if (options & XML_PARSE_NODICT) {
15087         ctxt->dictNames = 0;
15088         options -= XML_PARSE_NODICT;
15089         ctxt->options |= XML_PARSE_NODICT;
15090     } else {
15091         ctxt->dictNames = 1;
15092     }
15093     if (options & XML_PARSE_NOCDATA) {
15094         ctxt->sax->cdataBlock = NULL;
15095         options -= XML_PARSE_NOCDATA;
15096         ctxt->options |= XML_PARSE_NOCDATA;
15097     }
15098     if (options & XML_PARSE_NSCLEAN) {
15099         ctxt->options |= XML_PARSE_NSCLEAN;
15100         options -= XML_PARSE_NSCLEAN;
15101     }
15102     if (options & XML_PARSE_NONET) {
15103         ctxt->options |= XML_PARSE_NONET;
15104         options -= XML_PARSE_NONET;
15105     }
15106     if (options & XML_PARSE_COMPACT) {
15107         ctxt->options |= XML_PARSE_COMPACT;
15108         options -= XML_PARSE_COMPACT;
15109     }
15110     if (options & XML_PARSE_OLD10) {
15111         ctxt->options |= XML_PARSE_OLD10;
15112         options -= XML_PARSE_OLD10;
15113     }
15114     if (options & XML_PARSE_NOBASEFIX) {
15115         ctxt->options |= XML_PARSE_NOBASEFIX;
15116         options -= XML_PARSE_NOBASEFIX;
15117     }
15118     if (options & XML_PARSE_HUGE) {
15119         ctxt->options |= XML_PARSE_HUGE;
15120         options -= XML_PARSE_HUGE;
15121         if (ctxt->dict != NULL)
15122             xmlDictSetLimit(ctxt->dict, 0);
15123     }
15124     if (options & XML_PARSE_OLDSAX) {
15125         ctxt->options |= XML_PARSE_OLDSAX;
15126         options -= XML_PARSE_OLDSAX;
15127     }
15128     if (options & XML_PARSE_IGNORE_ENC) {
15129         ctxt->options |= XML_PARSE_IGNORE_ENC;
15130         options -= XML_PARSE_IGNORE_ENC;
15131     }
15132     if (options & XML_PARSE_BIG_LINES) {
15133         ctxt->options |= XML_PARSE_BIG_LINES;
15134         options -= XML_PARSE_BIG_LINES;
15135     }
15136     ctxt->linenumbers = 1;
15137     return (options);
15138 }
15139
15140 /**
15141  * xmlCtxtUseOptions:
15142  * @ctxt: an XML parser context
15143  * @options:  a combination of xmlParserOption
15144  *
15145  * Applies the options to the parser context
15146  *
15147  * Returns 0 in case of success, the set of unknown or unimplemented options
15148  *         in case of error.
15149  */
15150 int
15151 xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
15152 {
15153    return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
15154 }
15155
15156 /**
15157  * xmlDoRead:
15158  * @ctxt:  an XML parser context
15159  * @URL:  the base URL to use for the document
15160  * @encoding:  the document encoding, or NULL
15161  * @options:  a combination of xmlParserOption
15162  * @reuse:  keep the context for reuse
15163  *
15164  * Common front-end for the xmlRead functions
15165  *
15166  * Returns the resulting document tree or NULL
15167  */
15168 static xmlDocPtr
15169 xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
15170           int options, int reuse)
15171 {
15172     xmlDocPtr ret;
15173
15174     xmlCtxtUseOptionsInternal(ctxt, options, encoding);
15175     if (encoding != NULL) {
15176         xmlCharEncodingHandlerPtr hdlr;
15177
15178         hdlr = xmlFindCharEncodingHandler(encoding);
15179         if (hdlr != NULL)
15180             xmlSwitchToEncoding(ctxt, hdlr);
15181     }
15182     if ((URL != NULL) && (ctxt->input != NULL) &&
15183         (ctxt->input->filename == NULL))
15184         ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
15185     xmlParseDocument(ctxt);
15186     if ((ctxt->wellFormed) || ctxt->recovery)
15187         ret = ctxt->myDoc;
15188     else {
15189         ret = NULL;
15190         if (ctxt->myDoc != NULL) {
15191             xmlFreeDoc(ctxt->myDoc);
15192         }
15193     }
15194     ctxt->myDoc = NULL;
15195     if (!reuse) {
15196         xmlFreeParserCtxt(ctxt);
15197     }
15198
15199     return (ret);
15200 }
15201
15202 /**
15203  * xmlReadDoc:
15204  * @cur:  a pointer to a zero terminated string
15205  * @URL:  the base URL to use for the document
15206  * @encoding:  the document encoding, or NULL
15207  * @options:  a combination of xmlParserOption
15208  *
15209  * parse an XML in-memory document and build a tree.
15210  *
15211  * Returns the resulting document tree
15212  */
15213 xmlDocPtr
15214 xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
15215 {
15216     xmlParserCtxtPtr ctxt;
15217
15218     if (cur == NULL)
15219         return (NULL);
15220     xmlInitParser();
15221
15222     ctxt = xmlCreateDocParserCtxt(cur);
15223     if (ctxt == NULL)
15224         return (NULL);
15225     return (xmlDoRead(ctxt, URL, encoding, options, 0));
15226 }
15227
15228 /**
15229  * xmlReadFile:
15230  * @filename:  a file or URL
15231  * @encoding:  the document encoding, or NULL
15232  * @options:  a combination of xmlParserOption
15233  *
15234  * parse an XML file from the filesystem or the network.
15235  *
15236  * Returns the resulting document tree
15237  */
15238 xmlDocPtr
15239 xmlReadFile(const char *filename, const char *encoding, int options)
15240 {
15241     xmlParserCtxtPtr ctxt;
15242
15243     xmlInitParser();
15244     ctxt = xmlCreateURLParserCtxt(filename, options);
15245     if (ctxt == NULL)
15246         return (NULL);
15247     return (xmlDoRead(ctxt, NULL, encoding, options, 0));
15248 }
15249
15250 /**
15251  * xmlReadMemory:
15252  * @buffer:  a pointer to a char array
15253  * @size:  the size of the array
15254  * @URL:  the base URL to use for the document
15255  * @encoding:  the document encoding, or NULL
15256  * @options:  a combination of xmlParserOption
15257  *
15258  * parse an XML in-memory document and build a tree.
15259  *
15260  * Returns the resulting document tree
15261  */
15262 xmlDocPtr
15263 xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
15264 {
15265     xmlParserCtxtPtr ctxt;
15266
15267     xmlInitParser();
15268     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
15269     if (ctxt == NULL)
15270         return (NULL);
15271     return (xmlDoRead(ctxt, URL, encoding, options, 0));
15272 }
15273
15274 /**
15275  * xmlReadFd:
15276  * @fd:  an open file descriptor
15277  * @URL:  the base URL to use for the document
15278  * @encoding:  the document encoding, or NULL
15279  * @options:  a combination of xmlParserOption
15280  *
15281  * parse an XML from a file descriptor and build a tree.
15282  * NOTE that the file descriptor will not be closed when the
15283  *      reader is closed or reset.
15284  *
15285  * Returns the resulting document tree
15286  */
15287 xmlDocPtr
15288 xmlReadFd(int fd, const char *URL, const char *encoding, int options)
15289 {
15290     xmlParserCtxtPtr ctxt;
15291     xmlParserInputBufferPtr input;
15292     xmlParserInputPtr stream;
15293
15294     if (fd < 0)
15295         return (NULL);
15296     xmlInitParser();
15297
15298     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15299     if (input == NULL)
15300         return (NULL);
15301     input->closecallback = NULL;
15302     ctxt = xmlNewParserCtxt();
15303     if (ctxt == NULL) {
15304         xmlFreeParserInputBuffer(input);
15305         return (NULL);
15306     }
15307     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15308     if (stream == NULL) {
15309         xmlFreeParserInputBuffer(input);
15310         xmlFreeParserCtxt(ctxt);
15311         return (NULL);
15312     }
15313     inputPush(ctxt, stream);
15314     return (xmlDoRead(ctxt, URL, encoding, options, 0));
15315 }
15316
15317 /**
15318  * xmlReadIO:
15319  * @ioread:  an I/O read function
15320  * @ioclose:  an I/O close function
15321  * @ioctx:  an I/O handler
15322  * @URL:  the base URL to use for the document
15323  * @encoding:  the document encoding, or NULL
15324  * @options:  a combination of xmlParserOption
15325  *
15326  * parse an XML document from I/O functions and source and build a tree.
15327  *
15328  * Returns the resulting document tree
15329  */
15330 xmlDocPtr
15331 xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
15332           void *ioctx, const char *URL, const char *encoding, int options)
15333 {
15334     xmlParserCtxtPtr ctxt;
15335     xmlParserInputBufferPtr input;
15336     xmlParserInputPtr stream;
15337
15338     if (ioread == NULL)
15339         return (NULL);
15340     xmlInitParser();
15341
15342     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15343                                          XML_CHAR_ENCODING_NONE);
15344     if (input == NULL) {
15345         if (ioclose != NULL)
15346             ioclose(ioctx);
15347         return (NULL);
15348     }
15349     ctxt = xmlNewParserCtxt();
15350     if (ctxt == NULL) {
15351         xmlFreeParserInputBuffer(input);
15352         return (NULL);
15353     }
15354     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15355     if (stream == NULL) {
15356         xmlFreeParserInputBuffer(input);
15357         xmlFreeParserCtxt(ctxt);
15358         return (NULL);
15359     }
15360     inputPush(ctxt, stream);
15361     return (xmlDoRead(ctxt, URL, encoding, options, 0));
15362 }
15363
15364 /**
15365  * xmlCtxtReadDoc:
15366  * @ctxt:  an XML parser context
15367  * @cur:  a pointer to a zero terminated string
15368  * @URL:  the base URL to use for the document
15369  * @encoding:  the document encoding, or NULL
15370  * @options:  a combination of xmlParserOption
15371  *
15372  * parse an XML in-memory document and build a tree.
15373  * This reuses the existing @ctxt parser context
15374  *
15375  * Returns the resulting document tree
15376  */
15377 xmlDocPtr
15378 xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
15379                const char *URL, const char *encoding, int options)
15380 {
15381     xmlParserInputPtr stream;
15382
15383     if (cur == NULL)
15384         return (NULL);
15385     if (ctxt == NULL)
15386         return (NULL);
15387     xmlInitParser();
15388
15389     xmlCtxtReset(ctxt);
15390
15391     stream = xmlNewStringInputStream(ctxt, cur);
15392     if (stream == NULL) {
15393         return (NULL);
15394     }
15395     inputPush(ctxt, stream);
15396     return (xmlDoRead(ctxt, URL, encoding, options, 1));
15397 }
15398
15399 /**
15400  * xmlCtxtReadFile:
15401  * @ctxt:  an XML parser context
15402  * @filename:  a file or URL
15403  * @encoding:  the document encoding, or NULL
15404  * @options:  a combination of xmlParserOption
15405  *
15406  * parse an XML file from the filesystem or the network.
15407  * This reuses the existing @ctxt parser context
15408  *
15409  * Returns the resulting document tree
15410  */
15411 xmlDocPtr
15412 xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
15413                 const char *encoding, int options)
15414 {
15415     xmlParserInputPtr stream;
15416
15417     if (filename == NULL)
15418         return (NULL);
15419     if (ctxt == NULL)
15420         return (NULL);
15421     xmlInitParser();
15422
15423     xmlCtxtReset(ctxt);
15424
15425     stream = xmlLoadExternalEntity(filename, NULL, ctxt);
15426     if (stream == NULL) {
15427         return (NULL);
15428     }
15429     inputPush(ctxt, stream);
15430     return (xmlDoRead(ctxt, NULL, encoding, options, 1));
15431 }
15432
15433 /**
15434  * xmlCtxtReadMemory:
15435  * @ctxt:  an XML parser context
15436  * @buffer:  a pointer to a char array
15437  * @size:  the size of the array
15438  * @URL:  the base URL to use for the document
15439  * @encoding:  the document encoding, or NULL
15440  * @options:  a combination of xmlParserOption
15441  *
15442  * parse an XML in-memory document and build a tree.
15443  * This reuses the existing @ctxt parser context
15444  *
15445  * Returns the resulting document tree
15446  */
15447 xmlDocPtr
15448 xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
15449                   const char *URL, const char *encoding, int options)
15450 {
15451     xmlParserInputBufferPtr input;
15452     xmlParserInputPtr stream;
15453
15454     if (ctxt == NULL)
15455         return (NULL);
15456     if (buffer == NULL)
15457         return (NULL);
15458     xmlInitParser();
15459
15460     xmlCtxtReset(ctxt);
15461
15462     input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
15463     if (input == NULL) {
15464         return(NULL);
15465     }
15466
15467     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15468     if (stream == NULL) {
15469         xmlFreeParserInputBuffer(input);
15470         return(NULL);
15471     }
15472
15473     inputPush(ctxt, stream);
15474     return (xmlDoRead(ctxt, URL, encoding, options, 1));
15475 }
15476
15477 /**
15478  * xmlCtxtReadFd:
15479  * @ctxt:  an XML parser context
15480  * @fd:  an open file descriptor
15481  * @URL:  the base URL to use for the document
15482  * @encoding:  the document encoding, or NULL
15483  * @options:  a combination of xmlParserOption
15484  *
15485  * parse an XML from a file descriptor and build a tree.
15486  * This reuses the existing @ctxt parser context
15487  * NOTE that the file descriptor will not be closed when the
15488  *      reader is closed or reset.
15489  *
15490  * Returns the resulting document tree
15491  */
15492 xmlDocPtr
15493 xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
15494               const char *URL, const char *encoding, int options)
15495 {
15496     xmlParserInputBufferPtr input;
15497     xmlParserInputPtr stream;
15498
15499     if (fd < 0)
15500         return (NULL);
15501     if (ctxt == NULL)
15502         return (NULL);
15503     xmlInitParser();
15504
15505     xmlCtxtReset(ctxt);
15506
15507
15508     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15509     if (input == NULL)
15510         return (NULL);
15511     input->closecallback = NULL;
15512     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15513     if (stream == NULL) {
15514         xmlFreeParserInputBuffer(input);
15515         return (NULL);
15516     }
15517     inputPush(ctxt, stream);
15518     return (xmlDoRead(ctxt, URL, encoding, options, 1));
15519 }
15520
15521 /**
15522  * xmlCtxtReadIO:
15523  * @ctxt:  an XML parser context
15524  * @ioread:  an I/O read function
15525  * @ioclose:  an I/O close function
15526  * @ioctx:  an I/O handler
15527  * @URL:  the base URL to use for the document
15528  * @encoding:  the document encoding, or NULL
15529  * @options:  a combination of xmlParserOption
15530  *
15531  * parse an XML document from I/O functions and source and build a tree.
15532  * This reuses the existing @ctxt parser context
15533  *
15534  * Returns the resulting document tree
15535  */
15536 xmlDocPtr
15537 xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
15538               xmlInputCloseCallback ioclose, void *ioctx,
15539               const char *URL,
15540               const char *encoding, int options)
15541 {
15542     xmlParserInputBufferPtr input;
15543     xmlParserInputPtr stream;
15544
15545     if (ioread == NULL)
15546         return (NULL);
15547     if (ctxt == NULL)
15548         return (NULL);
15549     xmlInitParser();
15550
15551     xmlCtxtReset(ctxt);
15552
15553     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15554                                          XML_CHAR_ENCODING_NONE);
15555     if (input == NULL) {
15556         if (ioclose != NULL)
15557             ioclose(ioctx);
15558         return (NULL);
15559     }
15560     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15561     if (stream == NULL) {
15562         xmlFreeParserInputBuffer(input);
15563         return (NULL);
15564     }
15565     inputPush(ctxt, stream);
15566     return (xmlDoRead(ctxt, URL, encoding, options, 1));
15567 }
15568
15569 #define bottom_parser
15570 #include "elfgcchack.h"