Merge branch 'tizen_base' of ssh://review.tizen.org:29418/platform/upstream/libxml2...
[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 #define IN_LIBXML
34 #include "libxml.h"
35
36 #if defined(WIN32) && !defined (__CYGWIN__)
37 #define XML_DIR_SEP '\\'
38 #else
39 #define XML_DIR_SEP '/'
40 #endif
41
42 #include <stdlib.h>
43 #include <limits.h>
44 #include <string.h>
45 #include <stdarg.h>
46 #include <libxml/xmlmemory.h>
47 #include <libxml/threads.h>
48 #include <libxml/globals.h>
49 #include <libxml/tree.h>
50 #include <libxml/parser.h>
51 #include <libxml/parserInternals.h>
52 #include <libxml/valid.h>
53 #include <libxml/entities.h>
54 #include <libxml/xmlerror.h>
55 #include <libxml/encoding.h>
56 #include <libxml/xmlIO.h>
57 #include <libxml/uri.h>
58 #ifdef LIBXML_CATALOG_ENABLED
59 #include <libxml/catalog.h>
60 #endif
61 #ifdef LIBXML_SCHEMAS_ENABLED
62 #include <libxml/xmlschemastypes.h>
63 #include <libxml/relaxng.h>
64 #endif
65 #ifdef HAVE_CTYPE_H
66 #include <ctype.h>
67 #endif
68 #ifdef HAVE_STDLIB_H
69 #include <stdlib.h>
70 #endif
71 #ifdef HAVE_SYS_STAT_H
72 #include <sys/stat.h>
73 #endif
74 #ifdef HAVE_FCNTL_H
75 #include <fcntl.h>
76 #endif
77 #ifdef HAVE_UNISTD_H
78 #include <unistd.h>
79 #endif
80 #ifdef HAVE_ZLIB_H
81 #include <zlib.h>
82 #endif
83 #ifdef HAVE_LZMA_H
84 #include <lzma.h>
85 #endif
86
87 #include "buf.h"
88 #include "enc.h"
89
90 static void
91 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
92
93 static xmlParserCtxtPtr
94 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
95                           const xmlChar *base, xmlParserCtxtPtr pctx);
96
97 static void xmlHaltParser(xmlParserCtxtPtr ctxt);
98
99 /************************************************************************
100  *                                                                      *
101  *      Arbitrary limits set in the parser. See XML_PARSE_HUGE          *
102  *                                                                      *
103  ************************************************************************/
104
105 #define XML_PARSER_BIG_ENTITY 1000
106 #define XML_PARSER_LOT_ENTITY 5000
107
108 /*
109  * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
110  *    replacement over the size in byte of the input indicates that you have
111  *    and eponential behaviour. A value of 10 correspond to at least 3 entity
112  *    replacement per byte of input.
113  */
114 #define XML_PARSER_NON_LINEAR 10
115
116 /*
117  * xmlParserEntityCheck
118  *
119  * Function to check non-linear entity expansion behaviour
120  * This is here to detect and stop exponential linear entity expansion
121  * This is not a limitation of the parser but a safety
122  * boundary feature. It can be disabled with the XML_PARSE_HUGE
123  * parser option.
124  */
125 static int
126 xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
127                      xmlEntityPtr ent, size_t replacement)
128 {
129     size_t consumed = 0;
130
131     if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
132         return (0);
133     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
134         return (1);
135
136     /*
137      * This may look absurd but is needed to detect
138      * entities problems
139      */
140     if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
141         (ent->content != NULL) && (ent->checked == 0) &&
142         (ctxt->errNo != XML_ERR_ENTITY_LOOP)) {
143         unsigned long oldnbent = ctxt->nbentities;
144         xmlChar *rep;
145
146         ent->checked = 1;
147
148         ++ctxt->depth;
149         rep = xmlStringDecodeEntities(ctxt, ent->content,
150                                   XML_SUBSTITUTE_REF, 0, 0, 0);
151         --ctxt->depth;
152         if (ctxt->errNo == XML_ERR_ENTITY_LOOP) {
153             ent->content[0] = 0;
154         }
155
156         ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
157         if (rep != NULL) {
158             if (xmlStrchr(rep, '<'))
159                 ent->checked |= 1;
160             xmlFree(rep);
161             rep = NULL;
162         }
163     }
164     if (replacement != 0) {
165         if (replacement < XML_MAX_TEXT_LENGTH)
166             return(0);
167
168         /*
169          * If the volume of entity copy reaches 10 times the
170          * amount of parsed data and over the large text threshold
171          * then that's very likely to be an abuse.
172          */
173         if (ctxt->input != NULL) {
174             consumed = ctxt->input->consumed +
175                        (ctxt->input->cur - ctxt->input->base);
176         }
177         consumed += ctxt->sizeentities;
178
179         if (replacement < XML_PARSER_NON_LINEAR * consumed)
180             return(0);
181     } else if (size != 0) {
182         /*
183          * Do the check based on the replacement size of the entity
184          */
185         if (size < XML_PARSER_BIG_ENTITY)
186             return(0);
187
188         /*
189          * A limit on the amount of text data reasonably used
190          */
191         if (ctxt->input != NULL) {
192             consumed = ctxt->input->consumed +
193                 (ctxt->input->cur - ctxt->input->base);
194         }
195         consumed += ctxt->sizeentities;
196
197         if ((size < XML_PARSER_NON_LINEAR * consumed) &&
198             (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
199             return (0);
200     } else if (ent != NULL) {
201         /*
202          * use the number of parsed entities in the replacement
203          */
204         size = ent->checked / 2;
205
206         /*
207          * The amount of data parsed counting entities size only once
208          */
209         if (ctxt->input != NULL) {
210             consumed = ctxt->input->consumed +
211                 (ctxt->input->cur - ctxt->input->base);
212         }
213         consumed += ctxt->sizeentities;
214
215         /*
216          * Check the density of entities for the amount of data
217          * knowing an entity reference will take at least 3 bytes
218          */
219         if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
220             return (0);
221     } else {
222         /*
223          * strange we got no data for checking
224          */
225         if (((ctxt->lastError.code != XML_ERR_UNDECLARED_ENTITY) &&
226              (ctxt->lastError.code != XML_WAR_UNDECLARED_ENTITY)) ||
227             (ctxt->nbentities <= 10000))
228             return (0);
229     }
230     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
231     return (1);
232 }
233
234 /**
235  * xmlParserMaxDepth:
236  *
237  * arbitrary depth limit for the XML documents that we allow to
238  * process. This is not a limitation of the parser but a safety
239  * boundary feature. It can be disabled with the XML_PARSE_HUGE
240  * parser option.
241  */
242 unsigned int xmlParserMaxDepth = 256;
243
244
245
246 #define SAX2 1
247 #define XML_PARSER_BIG_BUFFER_SIZE 300
248 #define XML_PARSER_BUFFER_SIZE 100
249 #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
250
251 /**
252  * XML_PARSER_CHUNK_SIZE
253  *
254  * When calling GROW that's the minimal amount of data
255  * the parser expected to have received. It is not a hard
256  * limit but an optimization when reading strings like Names
257  * It is not strictly needed as long as inputs available characters
258  * are followed by 0, which should be provided by the I/O level
259  */
260 #define XML_PARSER_CHUNK_SIZE 100
261
262 /*
263  * List of XML prefixed PI allowed by W3C specs
264  */
265
266 static const char *xmlW3CPIs[] = {
267     "xml-stylesheet",
268     "xml-model",
269     NULL
270 };
271
272
273 /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
274 static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
275                                               const xmlChar **str);
276
277 static xmlParserErrors
278 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
279                       xmlSAXHandlerPtr sax,
280                       void *user_data, int depth, const xmlChar *URL,
281                       const xmlChar *ID, xmlNodePtr *list);
282
283 static int
284 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
285                           const char *encoding);
286 #ifdef LIBXML_LEGACY_ENABLED
287 static void
288 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
289                       xmlNodePtr lastNode);
290 #endif /* LIBXML_LEGACY_ENABLED */
291
292 static xmlParserErrors
293 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
294                       const xmlChar *string, void *user_data, xmlNodePtr *lst);
295
296 static int
297 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
298
299 /************************************************************************
300  *                                                                      *
301  *              Some factorized error routines                          *
302  *                                                                      *
303  ************************************************************************/
304
305 /**
306  * xmlErrAttributeDup:
307  * @ctxt:  an XML parser context
308  * @prefix:  the attribute prefix
309  * @localname:  the attribute localname
310  *
311  * Handle a redefinition of attribute error
312  */
313 static void
314 xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
315                    const xmlChar * localname)
316 {
317     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
318         (ctxt->instate == XML_PARSER_EOF))
319         return;
320     if (ctxt != NULL)
321         ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
322
323     if (prefix == NULL)
324         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
325                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
326                         (const char *) localname, NULL, NULL, 0, 0,
327                         "Attribute %s redefined\n", localname);
328     else
329         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
330                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
331                         (const char *) prefix, (const char *) localname,
332                         NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
333                         localname);
334     if (ctxt != NULL) {
335         ctxt->wellFormed = 0;
336         if (ctxt->recovery == 0)
337             ctxt->disableSAX = 1;
338     }
339 }
340
341 /**
342  * xmlFatalErr:
343  * @ctxt:  an XML parser context
344  * @error:  the error number
345  * @extra:  extra information string
346  *
347  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
348  */
349 static void
350 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
351 {
352     const char *errmsg;
353
354     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
355         (ctxt->instate == XML_PARSER_EOF))
356         return;
357     switch (error) {
358         case XML_ERR_INVALID_HEX_CHARREF:
359             errmsg = "CharRef: invalid hexadecimal value";
360             break;
361         case XML_ERR_INVALID_DEC_CHARREF:
362             errmsg = "CharRef: invalid decimal value";
363             break;
364         case XML_ERR_INVALID_CHARREF:
365             errmsg = "CharRef: invalid value";
366             break;
367         case XML_ERR_INTERNAL_ERROR:
368             errmsg = "internal error";
369             break;
370         case XML_ERR_PEREF_AT_EOF:
371             errmsg = "PEReference at end of document";
372             break;
373         case XML_ERR_PEREF_IN_PROLOG:
374             errmsg = "PEReference in prolog";
375             break;
376         case XML_ERR_PEREF_IN_EPILOG:
377             errmsg = "PEReference in epilog";
378             break;
379         case XML_ERR_PEREF_NO_NAME:
380             errmsg = "PEReference: no name";
381             break;
382         case XML_ERR_PEREF_SEMICOL_MISSING:
383             errmsg = "PEReference: expecting ';'";
384             break;
385         case XML_ERR_ENTITY_LOOP:
386             errmsg = "Detected an entity reference loop";
387             break;
388         case XML_ERR_ENTITY_NOT_STARTED:
389             errmsg = "EntityValue: \" or ' expected";
390             break;
391         case XML_ERR_ENTITY_PE_INTERNAL:
392             errmsg = "PEReferences forbidden in internal subset";
393             break;
394         case XML_ERR_ENTITY_NOT_FINISHED:
395             errmsg = "EntityValue: \" or ' expected";
396             break;
397         case XML_ERR_ATTRIBUTE_NOT_STARTED:
398             errmsg = "AttValue: \" or ' expected";
399             break;
400         case XML_ERR_LT_IN_ATTRIBUTE:
401             errmsg = "Unescaped '<' not allowed in attributes values";
402             break;
403         case XML_ERR_LITERAL_NOT_STARTED:
404             errmsg = "SystemLiteral \" or ' expected";
405             break;
406         case XML_ERR_LITERAL_NOT_FINISHED:
407             errmsg = "Unfinished System or Public ID \" or ' expected";
408             break;
409         case XML_ERR_MISPLACED_CDATA_END:
410             errmsg = "Sequence ']]>' not allowed in content";
411             break;
412         case XML_ERR_URI_REQUIRED:
413             errmsg = "SYSTEM or PUBLIC, the URI is missing";
414             break;
415         case XML_ERR_PUBID_REQUIRED:
416             errmsg = "PUBLIC, the Public Identifier is missing";
417             break;
418         case XML_ERR_HYPHEN_IN_COMMENT:
419             errmsg = "Comment must not contain '--' (double-hyphen)";
420             break;
421         case XML_ERR_PI_NOT_STARTED:
422             errmsg = "xmlParsePI : no target name";
423             break;
424         case XML_ERR_RESERVED_XML_NAME:
425             errmsg = "Invalid PI name";
426             break;
427         case XML_ERR_NOTATION_NOT_STARTED:
428             errmsg = "NOTATION: Name expected here";
429             break;
430         case XML_ERR_NOTATION_NOT_FINISHED:
431             errmsg = "'>' required to close NOTATION declaration";
432             break;
433         case XML_ERR_VALUE_REQUIRED:
434             errmsg = "Entity value required";
435             break;
436         case XML_ERR_URI_FRAGMENT:
437             errmsg = "Fragment not allowed";
438             break;
439         case XML_ERR_ATTLIST_NOT_STARTED:
440             errmsg = "'(' required to start ATTLIST enumeration";
441             break;
442         case XML_ERR_NMTOKEN_REQUIRED:
443             errmsg = "NmToken expected in ATTLIST enumeration";
444             break;
445         case XML_ERR_ATTLIST_NOT_FINISHED:
446             errmsg = "')' required to finish ATTLIST enumeration";
447             break;
448         case XML_ERR_MIXED_NOT_STARTED:
449             errmsg = "MixedContentDecl : '|' or ')*' expected";
450             break;
451         case XML_ERR_PCDATA_REQUIRED:
452             errmsg = "MixedContentDecl : '#PCDATA' expected";
453             break;
454         case XML_ERR_ELEMCONTENT_NOT_STARTED:
455             errmsg = "ContentDecl : Name or '(' expected";
456             break;
457         case XML_ERR_ELEMCONTENT_NOT_FINISHED:
458             errmsg = "ContentDecl : ',' '|' or ')' expected";
459             break;
460         case XML_ERR_PEREF_IN_INT_SUBSET:
461             errmsg =
462                 "PEReference: forbidden within markup decl in internal subset";
463             break;
464         case XML_ERR_GT_REQUIRED:
465             errmsg = "expected '>'";
466             break;
467         case XML_ERR_CONDSEC_INVALID:
468             errmsg = "XML conditional section '[' expected";
469             break;
470         case XML_ERR_EXT_SUBSET_NOT_FINISHED:
471             errmsg = "Content error in the external subset";
472             break;
473         case XML_ERR_CONDSEC_INVALID_KEYWORD:
474             errmsg =
475                 "conditional section INCLUDE or IGNORE keyword expected";
476             break;
477         case XML_ERR_CONDSEC_NOT_FINISHED:
478             errmsg = "XML conditional section not closed";
479             break;
480         case XML_ERR_XMLDECL_NOT_STARTED:
481             errmsg = "Text declaration '<?xml' required";
482             break;
483         case XML_ERR_XMLDECL_NOT_FINISHED:
484             errmsg = "parsing XML declaration: '?>' expected";
485             break;
486         case XML_ERR_EXT_ENTITY_STANDALONE:
487             errmsg = "external parsed entities cannot be standalone";
488             break;
489         case XML_ERR_ENTITYREF_SEMICOL_MISSING:
490             errmsg = "EntityRef: expecting ';'";
491             break;
492         case XML_ERR_DOCTYPE_NOT_FINISHED:
493             errmsg = "DOCTYPE improperly terminated";
494             break;
495         case XML_ERR_LTSLASH_REQUIRED:
496             errmsg = "EndTag: '</' not found";
497             break;
498         case XML_ERR_EQUAL_REQUIRED:
499             errmsg = "expected '='";
500             break;
501         case XML_ERR_STRING_NOT_CLOSED:
502             errmsg = "String not closed expecting \" or '";
503             break;
504         case XML_ERR_STRING_NOT_STARTED:
505             errmsg = "String not started expecting ' or \"";
506             break;
507         case XML_ERR_ENCODING_NAME:
508             errmsg = "Invalid XML encoding name";
509             break;
510         case XML_ERR_STANDALONE_VALUE:
511             errmsg = "standalone accepts only 'yes' or 'no'";
512             break;
513         case XML_ERR_DOCUMENT_EMPTY:
514             errmsg = "Document is empty";
515             break;
516         case XML_ERR_DOCUMENT_END:
517             errmsg = "Extra content at the end of the document";
518             break;
519         case XML_ERR_NOT_WELL_BALANCED:
520             errmsg = "chunk is not well balanced";
521             break;
522         case XML_ERR_EXTRA_CONTENT:
523             errmsg = "extra content at the end of well balanced chunk";
524             break;
525         case XML_ERR_VERSION_MISSING:
526             errmsg = "Malformed declaration expecting version";
527             break;
528         case XML_ERR_NAME_TOO_LONG:
529             errmsg = "Name too long use XML_PARSE_HUGE option";
530             break;
531 #if 0
532         case:
533             errmsg = "";
534             break;
535 #endif
536         default:
537             errmsg = "Unregistered error message";
538     }
539     if (ctxt != NULL)
540         ctxt->errNo = error;
541     if (info == NULL) {
542         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
543                         XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
544                         errmsg);
545     } else {
546         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
547                         XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
548                         errmsg, info);
549     }
550     if (ctxt != NULL) {
551         ctxt->wellFormed = 0;
552         if (ctxt->recovery == 0)
553             ctxt->disableSAX = 1;
554     }
555 }
556
557 /**
558  * xmlFatalErrMsg:
559  * @ctxt:  an XML parser context
560  * @error:  the error number
561  * @msg:  the error message
562  *
563  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
564  */
565 static void LIBXML_ATTR_FORMAT(3,0)
566 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
567                const char *msg)
568 {
569     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
570         (ctxt->instate == XML_PARSER_EOF))
571         return;
572     if (ctxt != NULL)
573         ctxt->errNo = error;
574     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
575                     XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
576     if (ctxt != NULL) {
577         ctxt->wellFormed = 0;
578         if (ctxt->recovery == 0)
579             ctxt->disableSAX = 1;
580     }
581 }
582
583 /**
584  * xmlWarningMsg:
585  * @ctxt:  an XML parser context
586  * @error:  the error number
587  * @msg:  the error message
588  * @str1:  extra data
589  * @str2:  extra data
590  *
591  * Handle a warning.
592  */
593 static void LIBXML_ATTR_FORMAT(3,0)
594 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
595               const char *msg, const xmlChar *str1, const xmlChar *str2)
596 {
597     xmlStructuredErrorFunc schannel = NULL;
598
599     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
600         (ctxt->instate == XML_PARSER_EOF))
601         return;
602     if ((ctxt != NULL) && (ctxt->sax != NULL) &&
603         (ctxt->sax->initialized == XML_SAX2_MAGIC))
604         schannel = ctxt->sax->serror;
605     if (ctxt != NULL) {
606         __xmlRaiseError(schannel,
607                     (ctxt->sax) ? ctxt->sax->warning : NULL,
608                     ctxt->userData,
609                     ctxt, NULL, XML_FROM_PARSER, error,
610                     XML_ERR_WARNING, NULL, 0,
611                     (const char *) str1, (const char *) str2, NULL, 0, 0,
612                     msg, (const char *) str1, (const char *) str2);
613     } else {
614         __xmlRaiseError(schannel, NULL, NULL,
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     }
620 }
621
622 /**
623  * xmlValidityError:
624  * @ctxt:  an XML parser context
625  * @error:  the error number
626  * @msg:  the error message
627  * @str1:  extra data
628  *
629  * Handle a validity error.
630  */
631 static void LIBXML_ATTR_FORMAT(3,0)
632 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
633               const char *msg, const xmlChar *str1, const xmlChar *str2)
634 {
635     xmlStructuredErrorFunc schannel = NULL;
636
637     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
638         (ctxt->instate == XML_PARSER_EOF))
639         return;
640     if (ctxt != NULL) {
641         ctxt->errNo = error;
642         if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
643             schannel = ctxt->sax->serror;
644     }
645     if (ctxt != NULL) {
646         __xmlRaiseError(schannel,
647                     ctxt->vctxt.error, ctxt->vctxt.userData,
648                     ctxt, NULL, XML_FROM_DTD, error,
649                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
650                     (const char *) str2, NULL, 0, 0,
651                     msg, (const char *) str1, (const char *) str2);
652         ctxt->valid = 0;
653     } else {
654         __xmlRaiseError(schannel, NULL, NULL,
655                     ctxt, NULL, XML_FROM_DTD, error,
656                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
657                     (const char *) str2, NULL, 0, 0,
658                     msg, (const char *) str1, (const char *) str2);
659     }
660 }
661
662 /**
663  * xmlFatalErrMsgInt:
664  * @ctxt:  an XML parser context
665  * @error:  the error number
666  * @msg:  the error message
667  * @val:  an integer value
668  *
669  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
670  */
671 static void LIBXML_ATTR_FORMAT(3,0)
672 xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
673                   const char *msg, int val)
674 {
675     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
676         (ctxt->instate == XML_PARSER_EOF))
677         return;
678     if (ctxt != NULL)
679         ctxt->errNo = error;
680     __xmlRaiseError(NULL, NULL, NULL,
681                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
682                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
683     if (ctxt != NULL) {
684         ctxt->wellFormed = 0;
685         if (ctxt->recovery == 0)
686             ctxt->disableSAX = 1;
687     }
688 }
689
690 /**
691  * xmlFatalErrMsgStrIntStr:
692  * @ctxt:  an XML parser context
693  * @error:  the error number
694  * @msg:  the error message
695  * @str1:  an string info
696  * @val:  an integer value
697  * @str2:  an string info
698  *
699  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
700  */
701 static void LIBXML_ATTR_FORMAT(3,0)
702 xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
703                   const char *msg, const xmlChar *str1, int val,
704                   const xmlChar *str2)
705 {
706     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
707         (ctxt->instate == XML_PARSER_EOF))
708         return;
709     if (ctxt != NULL)
710         ctxt->errNo = error;
711     __xmlRaiseError(NULL, NULL, NULL,
712                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
713                     NULL, 0, (const char *) str1, (const char *) str2,
714                     NULL, val, 0, msg, str1, val, str2);
715     if (ctxt != NULL) {
716         ctxt->wellFormed = 0;
717         if (ctxt->recovery == 0)
718             ctxt->disableSAX = 1;
719     }
720 }
721
722 /**
723  * xmlFatalErrMsgStr:
724  * @ctxt:  an XML parser context
725  * @error:  the error number
726  * @msg:  the error message
727  * @val:  a string value
728  *
729  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
730  */
731 static void LIBXML_ATTR_FORMAT(3,0)
732 xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
733                   const char *msg, const xmlChar * val)
734 {
735     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
736         (ctxt->instate == XML_PARSER_EOF))
737         return;
738     if (ctxt != NULL)
739         ctxt->errNo = error;
740     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
741                     XML_FROM_PARSER, error, XML_ERR_FATAL,
742                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
743                     val);
744     if (ctxt != NULL) {
745         ctxt->wellFormed = 0;
746         if (ctxt->recovery == 0)
747             ctxt->disableSAX = 1;
748     }
749 }
750
751 /**
752  * xmlErrMsgStr:
753  * @ctxt:  an XML parser context
754  * @error:  the error number
755  * @msg:  the error message
756  * @val:  a string value
757  *
758  * Handle a non fatal parser error
759  */
760 static void LIBXML_ATTR_FORMAT(3,0)
761 xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
762                   const char *msg, const xmlChar * val)
763 {
764     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
765         (ctxt->instate == XML_PARSER_EOF))
766         return;
767     if (ctxt != NULL)
768         ctxt->errNo = error;
769     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
770                     XML_FROM_PARSER, error, XML_ERR_ERROR,
771                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
772                     val);
773 }
774
775 /**
776  * xmlNsErr:
777  * @ctxt:  an XML parser context
778  * @error:  the error number
779  * @msg:  the message
780  * @info1:  extra information string
781  * @info2:  extra information string
782  *
783  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
784  */
785 static void LIBXML_ATTR_FORMAT(3,0)
786 xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
787          const char *msg,
788          const xmlChar * info1, const xmlChar * info2,
789          const xmlChar * info3)
790 {
791     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
792         (ctxt->instate == XML_PARSER_EOF))
793         return;
794     if (ctxt != NULL)
795         ctxt->errNo = error;
796     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
797                     XML_ERR_ERROR, NULL, 0, (const char *) info1,
798                     (const char *) info2, (const char *) info3, 0, 0, msg,
799                     info1, info2, info3);
800     if (ctxt != NULL)
801         ctxt->nsWellFormed = 0;
802 }
803
804 /**
805  * xmlNsWarn
806  * @ctxt:  an XML parser context
807  * @error:  the error number
808  * @msg:  the message
809  * @info1:  extra information string
810  * @info2:  extra information string
811  *
812  * Handle a namespace warning error
813  */
814 static void LIBXML_ATTR_FORMAT(3,0)
815 xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
816          const char *msg,
817          const xmlChar * info1, const xmlChar * info2,
818          const xmlChar * info3)
819 {
820     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
821         (ctxt->instate == XML_PARSER_EOF))
822         return;
823     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
824                     XML_ERR_WARNING, NULL, 0, (const char *) info1,
825                     (const char *) info2, (const char *) info3, 0, 0, msg,
826                     info1, info2, info3);
827 }
828
829 /************************************************************************
830  *                                                                      *
831  *              Library wide options                                    *
832  *                                                                      *
833  ************************************************************************/
834
835 /**
836   * xmlHasFeature:
837   * @feature: the feature to be examined
838   *
839   * Examines if the library has been compiled with a given feature.
840   *
841   * Returns a non-zero value if the feature exist, otherwise zero.
842   * Returns zero (0) if the feature does not exist or an unknown
843   * unknown feature is requested, non-zero otherwise.
844   */
845 int
846 xmlHasFeature(xmlFeature feature)
847 {
848     switch (feature) {
849         case XML_WITH_THREAD:
850 #ifdef LIBXML_THREAD_ENABLED
851             return(1);
852 #else
853             return(0);
854 #endif
855         case XML_WITH_TREE:
856 #ifdef LIBXML_TREE_ENABLED
857             return(1);
858 #else
859             return(0);
860 #endif
861         case XML_WITH_OUTPUT:
862 #ifdef LIBXML_OUTPUT_ENABLED
863             return(1);
864 #else
865             return(0);
866 #endif
867         case XML_WITH_PUSH:
868 #ifdef LIBXML_PUSH_ENABLED
869             return(1);
870 #else
871             return(0);
872 #endif
873         case XML_WITH_READER:
874 #ifdef LIBXML_READER_ENABLED
875             return(1);
876 #else
877             return(0);
878 #endif
879         case XML_WITH_PATTERN:
880 #ifdef LIBXML_PATTERN_ENABLED
881             return(1);
882 #else
883             return(0);
884 #endif
885         case XML_WITH_WRITER:
886 #ifdef LIBXML_WRITER_ENABLED
887             return(1);
888 #else
889             return(0);
890 #endif
891         case XML_WITH_SAX1:
892 #ifdef LIBXML_SAX1_ENABLED
893             return(1);
894 #else
895             return(0);
896 #endif
897         case XML_WITH_FTP:
898 #ifdef LIBXML_FTP_ENABLED
899             return(1);
900 #else
901             return(0);
902 #endif
903         case XML_WITH_HTTP:
904 #ifdef LIBXML_HTTP_ENABLED
905             return(1);
906 #else
907             return(0);
908 #endif
909         case XML_WITH_VALID:
910 #ifdef LIBXML_VALID_ENABLED
911             return(1);
912 #else
913             return(0);
914 #endif
915         case XML_WITH_HTML:
916 #ifdef LIBXML_HTML_ENABLED
917             return(1);
918 #else
919             return(0);
920 #endif
921         case XML_WITH_LEGACY:
922 #ifdef LIBXML_LEGACY_ENABLED
923             return(1);
924 #else
925             return(0);
926 #endif
927         case XML_WITH_C14N:
928 #ifdef LIBXML_C14N_ENABLED
929             return(1);
930 #else
931             return(0);
932 #endif
933         case XML_WITH_CATALOG:
934 #ifdef LIBXML_CATALOG_ENABLED
935             return(1);
936 #else
937             return(0);
938 #endif
939         case XML_WITH_XPATH:
940 #ifdef LIBXML_XPATH_ENABLED
941             return(1);
942 #else
943             return(0);
944 #endif
945         case XML_WITH_XPTR:
946 #ifdef LIBXML_XPTR_ENABLED
947             return(1);
948 #else
949             return(0);
950 #endif
951         case XML_WITH_XINCLUDE:
952 #ifdef LIBXML_XINCLUDE_ENABLED
953             return(1);
954 #else
955             return(0);
956 #endif
957         case XML_WITH_ICONV:
958 #ifdef LIBXML_ICONV_ENABLED
959             return(1);
960 #else
961             return(0);
962 #endif
963         case XML_WITH_ISO8859X:
964 #ifdef LIBXML_ISO8859X_ENABLED
965             return(1);
966 #else
967             return(0);
968 #endif
969         case XML_WITH_UNICODE:
970 #ifdef LIBXML_UNICODE_ENABLED
971             return(1);
972 #else
973             return(0);
974 #endif
975         case XML_WITH_REGEXP:
976 #ifdef LIBXML_REGEXP_ENABLED
977             return(1);
978 #else
979             return(0);
980 #endif
981         case XML_WITH_AUTOMATA:
982 #ifdef LIBXML_AUTOMATA_ENABLED
983             return(1);
984 #else
985             return(0);
986 #endif
987         case XML_WITH_EXPR:
988 #ifdef LIBXML_EXPR_ENABLED
989             return(1);
990 #else
991             return(0);
992 #endif
993         case XML_WITH_SCHEMAS:
994 #ifdef LIBXML_SCHEMAS_ENABLED
995             return(1);
996 #else
997             return(0);
998 #endif
999         case XML_WITH_SCHEMATRON:
1000 #ifdef LIBXML_SCHEMATRON_ENABLED
1001             return(1);
1002 #else
1003             return(0);
1004 #endif
1005         case XML_WITH_MODULES:
1006 #ifdef LIBXML_MODULES_ENABLED
1007             return(1);
1008 #else
1009             return(0);
1010 #endif
1011         case XML_WITH_DEBUG:
1012 #ifdef LIBXML_DEBUG_ENABLED
1013             return(1);
1014 #else
1015             return(0);
1016 #endif
1017         case XML_WITH_DEBUG_MEM:
1018 #ifdef DEBUG_MEMORY_LOCATION
1019             return(1);
1020 #else
1021             return(0);
1022 #endif
1023         case XML_WITH_DEBUG_RUN:
1024 #ifdef LIBXML_DEBUG_RUNTIME
1025             return(1);
1026 #else
1027             return(0);
1028 #endif
1029         case XML_WITH_ZLIB:
1030 #ifdef LIBXML_ZLIB_ENABLED
1031             return(1);
1032 #else
1033             return(0);
1034 #endif
1035         case XML_WITH_LZMA:
1036 #ifdef LIBXML_LZMA_ENABLED
1037             return(1);
1038 #else
1039             return(0);
1040 #endif
1041         case XML_WITH_ICU:
1042 #ifdef LIBXML_ICU_ENABLED
1043             return(1);
1044 #else
1045             return(0);
1046 #endif
1047         default:
1048             break;
1049      }
1050      return(0);
1051 }
1052
1053 /************************************************************************
1054  *                                                                      *
1055  *              SAX2 defaulted attributes handling                      *
1056  *                                                                      *
1057  ************************************************************************/
1058
1059 /**
1060  * xmlDetectSAX2:
1061  * @ctxt:  an XML parser context
1062  *
1063  * Do the SAX2 detection and specific intialization
1064  */
1065 static void
1066 xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
1067     if (ctxt == NULL) return;
1068 #ifdef LIBXML_SAX1_ENABLED
1069     if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
1070         ((ctxt->sax->startElementNs != NULL) ||
1071          (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
1072 #else
1073     ctxt->sax2 = 1;
1074 #endif /* LIBXML_SAX1_ENABLED */
1075
1076     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
1077     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
1078     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
1079     if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
1080                 (ctxt->str_xml_ns == NULL)) {
1081         xmlErrMemory(ctxt, NULL);
1082     }
1083 }
1084
1085 typedef struct _xmlDefAttrs xmlDefAttrs;
1086 typedef xmlDefAttrs *xmlDefAttrsPtr;
1087 struct _xmlDefAttrs {
1088     int nbAttrs;        /* number of defaulted attributes on that element */
1089     int maxAttrs;       /* the size of the array */
1090     const xmlChar *values[5]; /* array of localname/prefix/values/external */
1091 };
1092
1093 /**
1094  * xmlAttrNormalizeSpace:
1095  * @src: the source string
1096  * @dst: the target string
1097  *
1098  * Normalize the space in non CDATA attribute values:
1099  * If the attribute type is not CDATA, then the XML processor MUST further
1100  * process the normalized attribute value by discarding any leading and
1101  * trailing space (#x20) characters, and by replacing sequences of space
1102  * (#x20) characters by a single space (#x20) character.
1103  * Note that the size of dst need to be at least src, and if one doesn't need
1104  * to preserve dst (and it doesn't come from a dictionary or read-only) then
1105  * passing src as dst is just fine.
1106  *
1107  * Returns a pointer to the normalized value (dst) or NULL if no conversion
1108  *         is needed.
1109  */
1110 static xmlChar *
1111 xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
1112 {
1113     if ((src == NULL) || (dst == NULL))
1114         return(NULL);
1115
1116     while (*src == 0x20) src++;
1117     while (*src != 0) {
1118         if (*src == 0x20) {
1119             while (*src == 0x20) src++;
1120             if (*src != 0)
1121                 *dst++ = 0x20;
1122         } else {
1123             *dst++ = *src++;
1124         }
1125     }
1126     *dst = 0;
1127     if (dst == src)
1128        return(NULL);
1129     return(dst);
1130 }
1131
1132 /**
1133  * xmlAttrNormalizeSpace2:
1134  * @src: the source string
1135  *
1136  * Normalize the space in non CDATA attribute values, a slightly more complex
1137  * front end to avoid allocation problems when running on attribute values
1138  * coming from the input.
1139  *
1140  * Returns a pointer to the normalized value (dst) or NULL if no conversion
1141  *         is needed.
1142  */
1143 static const xmlChar *
1144 xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
1145 {
1146     int i;
1147     int remove_head = 0;
1148     int need_realloc = 0;
1149     const xmlChar *cur;
1150
1151     if ((ctxt == NULL) || (src == NULL) || (len == NULL))
1152         return(NULL);
1153     i = *len;
1154     if (i <= 0)
1155         return(NULL);
1156
1157     cur = src;
1158     while (*cur == 0x20) {
1159         cur++;
1160         remove_head++;
1161     }
1162     while (*cur != 0) {
1163         if (*cur == 0x20) {
1164             cur++;
1165             if ((*cur == 0x20) || (*cur == 0)) {
1166                 need_realloc = 1;
1167                 break;
1168             }
1169         } else
1170             cur++;
1171     }
1172     if (need_realloc) {
1173         xmlChar *ret;
1174
1175         ret = xmlStrndup(src + remove_head, i - remove_head + 1);
1176         if (ret == NULL) {
1177             xmlErrMemory(ctxt, NULL);
1178             return(NULL);
1179         }
1180         xmlAttrNormalizeSpace(ret, ret);
1181         *len = (int) strlen((const char *)ret);
1182         return(ret);
1183     } else if (remove_head) {
1184         *len -= remove_head;
1185         memmove(src, src + remove_head, 1 + *len);
1186         return(src);
1187     }
1188     return(NULL);
1189 }
1190
1191 /**
1192  * xmlAddDefAttrs:
1193  * @ctxt:  an XML parser context
1194  * @fullname:  the element fullname
1195  * @fullattr:  the attribute fullname
1196  * @value:  the attribute value
1197  *
1198  * Add a defaulted attribute for an element
1199  */
1200 static void
1201 xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
1202                const xmlChar *fullname,
1203                const xmlChar *fullattr,
1204                const xmlChar *value) {
1205     xmlDefAttrsPtr defaults;
1206     int len;
1207     const xmlChar *name;
1208     const xmlChar *prefix;
1209
1210     /*
1211      * Allows to detect attribute redefinitions
1212      */
1213     if (ctxt->attsSpecial != NULL) {
1214         if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1215             return;
1216     }
1217
1218     if (ctxt->attsDefault == NULL) {
1219         ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
1220         if (ctxt->attsDefault == NULL)
1221             goto mem_error;
1222     }
1223
1224     /*
1225      * split the element name into prefix:localname , the string found
1226      * are within the DTD and then not associated to namespace names.
1227      */
1228     name = xmlSplitQName3(fullname, &len);
1229     if (name == NULL) {
1230         name = xmlDictLookup(ctxt->dict, fullname, -1);
1231         prefix = NULL;
1232     } else {
1233         name = xmlDictLookup(ctxt->dict, name, -1);
1234         prefix = xmlDictLookup(ctxt->dict, fullname, len);
1235     }
1236
1237     /*
1238      * make sure there is some storage
1239      */
1240     defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
1241     if (defaults == NULL) {
1242         defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
1243                            (4 * 5) * sizeof(const xmlChar *));
1244         if (defaults == NULL)
1245             goto mem_error;
1246         defaults->nbAttrs = 0;
1247         defaults->maxAttrs = 4;
1248         if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1249                                 defaults, NULL) < 0) {
1250             xmlFree(defaults);
1251             goto mem_error;
1252         }
1253     } else if (defaults->nbAttrs >= defaults->maxAttrs) {
1254         xmlDefAttrsPtr temp;
1255
1256         temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
1257                        (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
1258         if (temp == NULL)
1259             goto mem_error;
1260         defaults = temp;
1261         defaults->maxAttrs *= 2;
1262         if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1263                                 defaults, NULL) < 0) {
1264             xmlFree(defaults);
1265             goto mem_error;
1266         }
1267     }
1268
1269     /*
1270      * Split the element name into prefix:localname , the string found
1271      * are within the DTD and hen not associated to namespace names.
1272      */
1273     name = xmlSplitQName3(fullattr, &len);
1274     if (name == NULL) {
1275         name = xmlDictLookup(ctxt->dict, fullattr, -1);
1276         prefix = NULL;
1277     } else {
1278         name = xmlDictLookup(ctxt->dict, name, -1);
1279         prefix = xmlDictLookup(ctxt->dict, fullattr, len);
1280     }
1281
1282     defaults->values[5 * defaults->nbAttrs] = name;
1283     defaults->values[5 * defaults->nbAttrs + 1] = prefix;
1284     /* intern the string and precompute the end */
1285     len = xmlStrlen(value);
1286     value = xmlDictLookup(ctxt->dict, value, len);
1287     defaults->values[5 * defaults->nbAttrs + 2] = value;
1288     defaults->values[5 * defaults->nbAttrs + 3] = value + len;
1289     if (ctxt->external)
1290         defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
1291     else
1292         defaults->values[5 * defaults->nbAttrs + 4] = NULL;
1293     defaults->nbAttrs++;
1294
1295     return;
1296
1297 mem_error:
1298     xmlErrMemory(ctxt, NULL);
1299     return;
1300 }
1301
1302 /**
1303  * xmlAddSpecialAttr:
1304  * @ctxt:  an XML parser context
1305  * @fullname:  the element fullname
1306  * @fullattr:  the attribute fullname
1307  * @type:  the attribute type
1308  *
1309  * Register this attribute type
1310  */
1311 static void
1312 xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
1313                   const xmlChar *fullname,
1314                   const xmlChar *fullattr,
1315                   int type)
1316 {
1317     if (ctxt->attsSpecial == NULL) {
1318         ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
1319         if (ctxt->attsSpecial == NULL)
1320             goto mem_error;
1321     }
1322
1323     if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1324         return;
1325
1326     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
1327                      (void *) (long) type);
1328     return;
1329
1330 mem_error:
1331     xmlErrMemory(ctxt, NULL);
1332     return;
1333 }
1334
1335 /**
1336  * xmlCleanSpecialAttrCallback:
1337  *
1338  * Removes CDATA attributes from the special attribute table
1339  */
1340 static void
1341 xmlCleanSpecialAttrCallback(void *payload, void *data,
1342                             const xmlChar *fullname, const xmlChar *fullattr,
1343                             const xmlChar *unused ATTRIBUTE_UNUSED) {
1344     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
1345
1346     if (((long) payload) == XML_ATTRIBUTE_CDATA) {
1347         xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
1348     }
1349 }
1350
1351 /**
1352  * xmlCleanSpecialAttr:
1353  * @ctxt:  an XML parser context
1354  *
1355  * Trim the list of attributes defined to remove all those of type
1356  * CDATA as they are not special. This call should be done when finishing
1357  * to parse the DTD and before starting to parse the document root.
1358  */
1359 static void
1360 xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
1361 {
1362     if (ctxt->attsSpecial == NULL)
1363         return;
1364
1365     xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
1366
1367     if (xmlHashSize(ctxt->attsSpecial) == 0) {
1368         xmlHashFree(ctxt->attsSpecial, NULL);
1369         ctxt->attsSpecial = NULL;
1370     }
1371     return;
1372 }
1373
1374 /**
1375  * xmlCheckLanguageID:
1376  * @lang:  pointer to the string value
1377  *
1378  * Checks that the value conforms to the LanguageID production:
1379  *
1380  * NOTE: this is somewhat deprecated, those productions were removed from
1381  *       the XML Second edition.
1382  *
1383  * [33] LanguageID ::= Langcode ('-' Subcode)*
1384  * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
1385  * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
1386  * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
1387  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
1388  * [38] Subcode ::= ([a-z] | [A-Z])+
1389  *
1390  * The current REC reference the sucessors of RFC 1766, currently 5646
1391  *
1392  * http://www.rfc-editor.org/rfc/rfc5646.txt
1393  * langtag       = language
1394  *                 ["-" script]
1395  *                 ["-" region]
1396  *                 *("-" variant)
1397  *                 *("-" extension)
1398  *                 ["-" privateuse]
1399  * language      = 2*3ALPHA            ; shortest ISO 639 code
1400  *                 ["-" extlang]       ; sometimes followed by
1401  *                                     ; extended language subtags
1402  *               / 4ALPHA              ; or reserved for future use
1403  *               / 5*8ALPHA            ; or registered language subtag
1404  *
1405  * extlang       = 3ALPHA              ; selected ISO 639 codes
1406  *                 *2("-" 3ALPHA)      ; permanently reserved
1407  *
1408  * script        = 4ALPHA              ; ISO 15924 code
1409  *
1410  * region        = 2ALPHA              ; ISO 3166-1 code
1411  *               / 3DIGIT              ; UN M.49 code
1412  *
1413  * variant       = 5*8alphanum         ; registered variants
1414  *               / (DIGIT 3alphanum)
1415  *
1416  * extension     = singleton 1*("-" (2*8alphanum))
1417  *
1418  *                                     ; Single alphanumerics
1419  *                                     ; "x" reserved for private use
1420  * singleton     = DIGIT               ; 0 - 9
1421  *               / %x41-57             ; A - W
1422  *               / %x59-5A             ; Y - Z
1423  *               / %x61-77             ; a - w
1424  *               / %x79-7A             ; y - z
1425  *
1426  * it sounds right to still allow Irregular i-xxx IANA and user codes too
1427  * The parser below doesn't try to cope with extension or privateuse
1428  * that could be added but that's not interoperable anyway
1429  *
1430  * Returns 1 if correct 0 otherwise
1431  **/
1432 int
1433 xmlCheckLanguageID(const xmlChar * lang)
1434 {
1435     const xmlChar *cur = lang, *nxt;
1436
1437     if (cur == NULL)
1438         return (0);
1439     if (((cur[0] == 'i') && (cur[1] == '-')) ||
1440         ((cur[0] == 'I') && (cur[1] == '-')) ||
1441         ((cur[0] == 'x') && (cur[1] == '-')) ||
1442         ((cur[0] == 'X') && (cur[1] == '-'))) {
1443         /*
1444          * Still allow IANA code and user code which were coming
1445          * from the previous version of the XML-1.0 specification
1446          * it's deprecated but we should not fail
1447          */
1448         cur += 2;
1449         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1450                ((cur[0] >= 'a') && (cur[0] <= 'z')))
1451             cur++;
1452         return(cur[0] == 0);
1453     }
1454     nxt = cur;
1455     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1456            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1457            nxt++;
1458     if (nxt - cur >= 4) {
1459         /*
1460          * Reserved
1461          */
1462         if ((nxt - cur > 8) || (nxt[0] != 0))
1463             return(0);
1464         return(1);
1465     }
1466     if (nxt - cur < 2)
1467         return(0);
1468     /* we got an ISO 639 code */
1469     if (nxt[0] == 0)
1470         return(1);
1471     if (nxt[0] != '-')
1472         return(0);
1473
1474     nxt++;
1475     cur = nxt;
1476     /* now we can have extlang or script or region or variant */
1477     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1478         goto region_m49;
1479
1480     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1481            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1482            nxt++;
1483     if (nxt - cur == 4)
1484         goto script;
1485     if (nxt - cur == 2)
1486         goto region;
1487     if ((nxt - cur >= 5) && (nxt - cur <= 8))
1488         goto variant;
1489     if (nxt - cur != 3)
1490         return(0);
1491     /* we parsed an extlang */
1492     if (nxt[0] == 0)
1493         return(1);
1494     if (nxt[0] != '-')
1495         return(0);
1496
1497     nxt++;
1498     cur = nxt;
1499     /* now we can have script or region or variant */
1500     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1501         goto region_m49;
1502
1503     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1504            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1505            nxt++;
1506     if (nxt - cur == 2)
1507         goto region;
1508     if ((nxt - cur >= 5) && (nxt - cur <= 8))
1509         goto variant;
1510     if (nxt - cur != 4)
1511         return(0);
1512     /* we parsed a script */
1513 script:
1514     if (nxt[0] == 0)
1515         return(1);
1516     if (nxt[0] != '-')
1517         return(0);
1518
1519     nxt++;
1520     cur = nxt;
1521     /* now we can have region or variant */
1522     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1523         goto region_m49;
1524
1525     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1526            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1527            nxt++;
1528
1529     if ((nxt - cur >= 5) && (nxt - cur <= 8))
1530         goto variant;
1531     if (nxt - cur != 2)
1532         return(0);
1533     /* we parsed a region */
1534 region:
1535     if (nxt[0] == 0)
1536         return(1);
1537     if (nxt[0] != '-')
1538         return(0);
1539
1540     nxt++;
1541     cur = nxt;
1542     /* now we can just have a variant */
1543     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1544            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1545            nxt++;
1546
1547     if ((nxt - cur < 5) || (nxt - cur > 8))
1548         return(0);
1549
1550     /* we parsed a variant */
1551 variant:
1552     if (nxt[0] == 0)
1553         return(1);
1554     if (nxt[0] != '-')
1555         return(0);
1556     /* extensions and private use subtags not checked */
1557     return (1);
1558
1559 region_m49:
1560     if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
1561         ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
1562         nxt += 3;
1563         goto region;
1564     }
1565     return(0);
1566 }
1567
1568 /************************************************************************
1569  *                                                                      *
1570  *              Parser stacks related functions and macros              *
1571  *                                                                      *
1572  ************************************************************************/
1573
1574 static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
1575                                             const xmlChar ** str);
1576
1577 #ifdef SAX2
1578 /**
1579  * nsPush:
1580  * @ctxt:  an XML parser context
1581  * @prefix:  the namespace prefix or NULL
1582  * @URL:  the namespace name
1583  *
1584  * Pushes a new parser namespace on top of the ns stack
1585  *
1586  * Returns -1 in case of error, -2 if the namespace should be discarded
1587  *         and the index in the stack otherwise.
1588  */
1589 static int
1590 nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
1591 {
1592     if (ctxt->options & XML_PARSE_NSCLEAN) {
1593         int i;
1594         for (i = ctxt->nsNr - 2;i >= 0;i -= 2) {
1595             if (ctxt->nsTab[i] == prefix) {
1596                 /* in scope */
1597                 if (ctxt->nsTab[i + 1] == URL)
1598                     return(-2);
1599                 /* out of scope keep it */
1600                 break;
1601             }
1602         }
1603     }
1604     if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
1605         ctxt->nsMax = 10;
1606         ctxt->nsNr = 0;
1607         ctxt->nsTab = (const xmlChar **)
1608                       xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
1609         if (ctxt->nsTab == NULL) {
1610             xmlErrMemory(ctxt, NULL);
1611             ctxt->nsMax = 0;
1612             return (-1);
1613         }
1614     } else if (ctxt->nsNr >= ctxt->nsMax) {
1615         const xmlChar ** tmp;
1616         ctxt->nsMax *= 2;
1617         tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
1618                                     ctxt->nsMax * sizeof(ctxt->nsTab[0]));
1619         if (tmp == NULL) {
1620             xmlErrMemory(ctxt, NULL);
1621             ctxt->nsMax /= 2;
1622             return (-1);
1623         }
1624         ctxt->nsTab = tmp;
1625     }
1626     ctxt->nsTab[ctxt->nsNr++] = prefix;
1627     ctxt->nsTab[ctxt->nsNr++] = URL;
1628     return (ctxt->nsNr);
1629 }
1630 /**
1631  * nsPop:
1632  * @ctxt: an XML parser context
1633  * @nr:  the number to pop
1634  *
1635  * Pops the top @nr parser prefix/namespace from the ns stack
1636  *
1637  * Returns the number of namespaces removed
1638  */
1639 static int
1640 nsPop(xmlParserCtxtPtr ctxt, int nr)
1641 {
1642     int i;
1643
1644     if (ctxt->nsTab == NULL) return(0);
1645     if (ctxt->nsNr < nr) {
1646         xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
1647         nr = ctxt->nsNr;
1648     }
1649     if (ctxt->nsNr <= 0)
1650         return (0);
1651
1652     for (i = 0;i < nr;i++) {
1653          ctxt->nsNr--;
1654          ctxt->nsTab[ctxt->nsNr] = NULL;
1655     }
1656     return(nr);
1657 }
1658 #endif
1659
1660 static int
1661 xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
1662     const xmlChar **atts;
1663     int *attallocs;
1664     int maxatts;
1665
1666     if (ctxt->atts == NULL) {
1667         maxatts = 55; /* allow for 10 attrs by default */
1668         atts = (const xmlChar **)
1669                xmlMalloc(maxatts * sizeof(xmlChar *));
1670         if (atts == NULL) goto mem_error;
1671         ctxt->atts = atts;
1672         attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
1673         if (attallocs == NULL) goto mem_error;
1674         ctxt->attallocs = attallocs;
1675         ctxt->maxatts = maxatts;
1676     } else if (nr + 5 > ctxt->maxatts) {
1677         maxatts = (nr + 5) * 2;
1678         atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
1679                                      maxatts * sizeof(const xmlChar *));
1680         if (atts == NULL) goto mem_error;
1681         ctxt->atts = atts;
1682         attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
1683                                      (maxatts / 5) * sizeof(int));
1684         if (attallocs == NULL) goto mem_error;
1685         ctxt->attallocs = attallocs;
1686         ctxt->maxatts = maxatts;
1687     }
1688     return(ctxt->maxatts);
1689 mem_error:
1690     xmlErrMemory(ctxt, NULL);
1691     return(-1);
1692 }
1693
1694 /**
1695  * inputPush:
1696  * @ctxt:  an XML parser context
1697  * @value:  the parser input
1698  *
1699  * Pushes a new parser input on top of the input stack
1700  *
1701  * Returns -1 in case of error, the index in the stack otherwise
1702  */
1703 int
1704 inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
1705 {
1706     if ((ctxt == NULL) || (value == NULL))
1707         return(-1);
1708     if (ctxt->inputNr >= ctxt->inputMax) {
1709         ctxt->inputMax *= 2;
1710         ctxt->inputTab =
1711             (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
1712                                              ctxt->inputMax *
1713                                              sizeof(ctxt->inputTab[0]));
1714         if (ctxt->inputTab == NULL) {
1715             xmlErrMemory(ctxt, NULL);
1716             xmlFreeInputStream(value);
1717             ctxt->inputMax /= 2;
1718             value = NULL;
1719             return (-1);
1720         }
1721     }
1722     ctxt->inputTab[ctxt->inputNr] = value;
1723     ctxt->input = value;
1724     return (ctxt->inputNr++);
1725 }
1726 /**
1727  * inputPop:
1728  * @ctxt: an XML parser context
1729  *
1730  * Pops the top parser input from the input stack
1731  *
1732  * Returns the input just removed
1733  */
1734 xmlParserInputPtr
1735 inputPop(xmlParserCtxtPtr ctxt)
1736 {
1737     xmlParserInputPtr ret;
1738
1739     if (ctxt == NULL)
1740         return(NULL);
1741     if (ctxt->inputNr <= 0)
1742         return (NULL);
1743     ctxt->inputNr--;
1744     if (ctxt->inputNr > 0)
1745         ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
1746     else
1747         ctxt->input = NULL;
1748     ret = ctxt->inputTab[ctxt->inputNr];
1749     ctxt->inputTab[ctxt->inputNr] = NULL;
1750     return (ret);
1751 }
1752 /**
1753  * nodePush:
1754  * @ctxt:  an XML parser context
1755  * @value:  the element node
1756  *
1757  * Pushes a new element node on top of the node stack
1758  *
1759  * Returns -1 in case of error, the index in the stack otherwise
1760  */
1761 int
1762 nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
1763 {
1764     if (ctxt == NULL) return(0);
1765     if (ctxt->nodeNr >= ctxt->nodeMax) {
1766         xmlNodePtr *tmp;
1767
1768         tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
1769                                       ctxt->nodeMax * 2 *
1770                                       sizeof(ctxt->nodeTab[0]));
1771         if (tmp == NULL) {
1772             xmlErrMemory(ctxt, NULL);
1773             return (-1);
1774         }
1775         ctxt->nodeTab = tmp;
1776         ctxt->nodeMax *= 2;
1777     }
1778     if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
1779         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
1780         xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
1781                  "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
1782                           xmlParserMaxDepth);
1783         xmlHaltParser(ctxt);
1784         return(-1);
1785     }
1786     ctxt->nodeTab[ctxt->nodeNr] = value;
1787     ctxt->node = value;
1788     return (ctxt->nodeNr++);
1789 }
1790
1791 /**
1792  * nodePop:
1793  * @ctxt: an XML parser context
1794  *
1795  * Pops the top element node from the node stack
1796  *
1797  * Returns the node just removed
1798  */
1799 xmlNodePtr
1800 nodePop(xmlParserCtxtPtr ctxt)
1801 {
1802     xmlNodePtr ret;
1803
1804     if (ctxt == NULL) return(NULL);
1805     if (ctxt->nodeNr <= 0)
1806         return (NULL);
1807     ctxt->nodeNr--;
1808     if (ctxt->nodeNr > 0)
1809         ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
1810     else
1811         ctxt->node = NULL;
1812     ret = ctxt->nodeTab[ctxt->nodeNr];
1813     ctxt->nodeTab[ctxt->nodeNr] = NULL;
1814     return (ret);
1815 }
1816
1817 #ifdef LIBXML_PUSH_ENABLED
1818 /**
1819  * nameNsPush:
1820  * @ctxt:  an XML parser context
1821  * @value:  the element name
1822  * @prefix:  the element prefix
1823  * @URI:  the element namespace name
1824  *
1825  * Pushes a new element name/prefix/URL on top of the name stack
1826  *
1827  * Returns -1 in case of error, the index in the stack otherwise
1828  */
1829 static int
1830 nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
1831            const xmlChar *prefix, const xmlChar *URI, int nsNr)
1832 {
1833     if (ctxt->nameNr >= ctxt->nameMax) {
1834         const xmlChar * *tmp;
1835         void **tmp2;
1836         ctxt->nameMax *= 2;
1837         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1838                                     ctxt->nameMax *
1839                                     sizeof(ctxt->nameTab[0]));
1840         if (tmp == NULL) {
1841             ctxt->nameMax /= 2;
1842             goto mem_error;
1843         }
1844         ctxt->nameTab = tmp;
1845         tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
1846                                     ctxt->nameMax * 3 *
1847                                     sizeof(ctxt->pushTab[0]));
1848         if (tmp2 == NULL) {
1849             ctxt->nameMax /= 2;
1850             goto mem_error;
1851         }
1852         ctxt->pushTab = tmp2;
1853     }
1854     ctxt->nameTab[ctxt->nameNr] = value;
1855     ctxt->name = value;
1856     ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
1857     ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
1858     ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
1859     return (ctxt->nameNr++);
1860 mem_error:
1861     xmlErrMemory(ctxt, NULL);
1862     return (-1);
1863 }
1864 /**
1865  * nameNsPop:
1866  * @ctxt: an XML parser context
1867  *
1868  * Pops the top element/prefix/URI name from the name stack
1869  *
1870  * Returns the name just removed
1871  */
1872 static const xmlChar *
1873 nameNsPop(xmlParserCtxtPtr ctxt)
1874 {
1875     const xmlChar *ret;
1876
1877     if (ctxt->nameNr <= 0)
1878         return (NULL);
1879     ctxt->nameNr--;
1880     if (ctxt->nameNr > 0)
1881         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1882     else
1883         ctxt->name = NULL;
1884     ret = ctxt->nameTab[ctxt->nameNr];
1885     ctxt->nameTab[ctxt->nameNr] = NULL;
1886     return (ret);
1887 }
1888 #endif /* LIBXML_PUSH_ENABLED */
1889
1890 /**
1891  * namePush:
1892  * @ctxt:  an XML parser context
1893  * @value:  the element name
1894  *
1895  * Pushes a new element name on top of the name stack
1896  *
1897  * Returns -1 in case of error, the index in the stack otherwise
1898  */
1899 int
1900 namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
1901 {
1902     if (ctxt == NULL) return (-1);
1903
1904     if (ctxt->nameNr >= ctxt->nameMax) {
1905         const xmlChar * *tmp;
1906         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1907                                     ctxt->nameMax * 2 *
1908                                     sizeof(ctxt->nameTab[0]));
1909         if (tmp == NULL) {
1910             goto mem_error;
1911         }
1912         ctxt->nameTab = tmp;
1913         ctxt->nameMax *= 2;
1914     }
1915     ctxt->nameTab[ctxt->nameNr] = value;
1916     ctxt->name = value;
1917     return (ctxt->nameNr++);
1918 mem_error:
1919     xmlErrMemory(ctxt, NULL);
1920     return (-1);
1921 }
1922 /**
1923  * namePop:
1924  * @ctxt: an XML parser context
1925  *
1926  * Pops the top element name from the name stack
1927  *
1928  * Returns the name just removed
1929  */
1930 const xmlChar *
1931 namePop(xmlParserCtxtPtr ctxt)
1932 {
1933     const xmlChar *ret;
1934
1935     if ((ctxt == NULL) || (ctxt->nameNr <= 0))
1936         return (NULL);
1937     ctxt->nameNr--;
1938     if (ctxt->nameNr > 0)
1939         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1940     else
1941         ctxt->name = NULL;
1942     ret = ctxt->nameTab[ctxt->nameNr];
1943     ctxt->nameTab[ctxt->nameNr] = NULL;
1944     return (ret);
1945 }
1946
1947 static int spacePush(xmlParserCtxtPtr ctxt, int val) {
1948     if (ctxt->spaceNr >= ctxt->spaceMax) {
1949         int *tmp;
1950
1951         ctxt->spaceMax *= 2;
1952         tmp = (int *) xmlRealloc(ctxt->spaceTab,
1953                                  ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
1954         if (tmp == NULL) {
1955             xmlErrMemory(ctxt, NULL);
1956             ctxt->spaceMax /=2;
1957             return(-1);
1958         }
1959         ctxt->spaceTab = tmp;
1960     }
1961     ctxt->spaceTab[ctxt->spaceNr] = val;
1962     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
1963     return(ctxt->spaceNr++);
1964 }
1965
1966 static int spacePop(xmlParserCtxtPtr ctxt) {
1967     int ret;
1968     if (ctxt->spaceNr <= 0) return(0);
1969     ctxt->spaceNr--;
1970     if (ctxt->spaceNr > 0)
1971         ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
1972     else
1973         ctxt->space = &ctxt->spaceTab[0];
1974     ret = ctxt->spaceTab[ctxt->spaceNr];
1975     ctxt->spaceTab[ctxt->spaceNr] = -1;
1976     return(ret);
1977 }
1978
1979 /*
1980  * Macros for accessing the content. Those should be used only by the parser,
1981  * and not exported.
1982  *
1983  * Dirty macros, i.e. one often need to make assumption on the context to
1984  * use them
1985  *
1986  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
1987  *           To be used with extreme caution since operations consuming
1988  *           characters may move the input buffer to a different location !
1989  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
1990  *           This should be used internally by the parser
1991  *           only to compare to ASCII values otherwise it would break when
1992  *           running with UTF-8 encoding.
1993  *   RAW     same as CUR but in the input buffer, bypass any token
1994  *           extraction that may have been done
1995  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
1996  *           to compare on ASCII based substring.
1997  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
1998  *           strings without newlines within the parser.
1999  *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII
2000  *           defined char within the parser.
2001  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
2002  *
2003  *   NEXT    Skip to the next character, this does the proper decoding
2004  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
2005  *   NEXTL(l) Skip the current unicode character of l xmlChars long.
2006  *   CUR_CHAR(l) returns the current unicode character (int), set l
2007  *           to the number of xmlChars used for the encoding [0-5].
2008  *   CUR_SCHAR  same but operate on a string instead of the context
2009  *   COPY_BUF  copy the current unicode char to the target buffer, increment
2010  *            the index
2011  *   GROW, SHRINK  handling of input buffers
2012  */
2013
2014 #define RAW (*ctxt->input->cur)
2015 #define CUR (*ctxt->input->cur)
2016 #define NXT(val) ctxt->input->cur[(val)]
2017 #define CUR_PTR ctxt->input->cur
2018 #define BASE_PTR ctxt->input->base
2019
2020 #define CMP4( s, c1, c2, c3, c4 ) \
2021   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
2022     ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
2023 #define CMP5( s, c1, c2, c3, c4, c5 ) \
2024   ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
2025 #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
2026   ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
2027 #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
2028   ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
2029 #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
2030   ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
2031 #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
2032   ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
2033     ((unsigned char *) s)[ 8 ] == c9 )
2034 #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
2035   ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
2036     ((unsigned char *) s)[ 9 ] == c10 )
2037
2038 #define SKIP(val) do {                                                  \
2039     ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);                   \
2040     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
2041     if ((*ctxt->input->cur == 0) &&                                     \
2042         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))            \
2043             xmlPopInput(ctxt);                                          \
2044   } while (0)
2045
2046 #define SKIPL(val) do {                                                 \
2047     int skipl;                                                          \
2048     for(skipl=0; skipl<val; skipl++) {                                  \
2049         if (*(ctxt->input->cur) == '\n') {                              \
2050         ctxt->input->line++; ctxt->input->col = 1;                      \
2051         } else ctxt->input->col++;                                      \
2052         ctxt->nbChars++;                                                \
2053         ctxt->input->cur++;                                             \
2054     }                                                                   \
2055     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
2056     if ((*ctxt->input->cur == 0) &&                                     \
2057         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))            \
2058             xmlPopInput(ctxt);                                          \
2059   } while (0)
2060
2061 #define SHRINK if ((ctxt->progressive == 0) &&                          \
2062                    (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
2063                    (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
2064         xmlSHRINK (ctxt);
2065
2066 static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
2067     xmlParserInputShrink(ctxt->input);
2068     if ((*ctxt->input->cur == 0) &&
2069         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
2070             xmlPopInput(ctxt);
2071   }
2072
2073 #define GROW if ((ctxt->progressive == 0) &&                            \
2074                  (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))   \
2075         xmlGROW (ctxt);
2076
2077 static void xmlGROW (xmlParserCtxtPtr ctxt) {
2078     unsigned long curEnd = ctxt->input->end - ctxt->input->cur;
2079     unsigned long curBase = ctxt->input->cur - ctxt->input->base;
2080
2081     if (((curEnd > (unsigned long) XML_MAX_LOOKUP_LIMIT) ||
2082          (curBase > (unsigned long) XML_MAX_LOOKUP_LIMIT)) &&
2083          ((ctxt->input->buf) && (ctxt->input->buf->readcallback != (xmlInputReadCallback) xmlNop)) &&
2084         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
2085         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
2086         xmlHaltParser(ctxt);
2087         return;
2088     }
2089     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2090     if ((ctxt->input->cur > ctxt->input->end) ||
2091         (ctxt->input->cur < ctxt->input->base)) {
2092         xmlHaltParser(ctxt);
2093         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "cur index out of bound");
2094         return;
2095     }
2096     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
2097         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
2098             xmlPopInput(ctxt);
2099 }
2100
2101 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
2102
2103 #define NEXT xmlNextChar(ctxt)
2104
2105 #define NEXT1 {                                                         \
2106         ctxt->input->col++;                                             \
2107         ctxt->input->cur++;                                             \
2108         ctxt->nbChars++;                                                \
2109         if (*ctxt->input->cur == 0)                                     \
2110             xmlParserInputGrow(ctxt->input, INPUT_CHUNK);               \
2111     }
2112
2113 #define NEXTL(l) do {                                                   \
2114     if (*(ctxt->input->cur) == '\n') {                                  \
2115         ctxt->input->line++; ctxt->input->col = 1;                      \
2116     } else ctxt->input->col++;                                          \
2117     ctxt->input->cur += l;                              \
2118     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
2119   } while (0)
2120
2121 #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
2122 #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
2123
2124 #define COPY_BUF(l,b,i,v)                                               \
2125     if (l == 1) b[i++] = (xmlChar) v;                                   \
2126     else i += xmlCopyCharMultiByte(&b[i],v)
2127
2128 /**
2129  * xmlSkipBlankChars:
2130  * @ctxt:  the XML parser context
2131  *
2132  * skip all blanks character found at that point in the input streams.
2133  * It pops up finished entities in the process if allowable at that point.
2134  *
2135  * Returns the number of space chars skipped
2136  */
2137
2138 int
2139 xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
2140     int res = 0;
2141
2142     /*
2143      * It's Okay to use CUR/NEXT here since all the blanks are on
2144      * the ASCII range.
2145      */
2146     if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
2147         const xmlChar *cur;
2148         /*
2149          * if we are in the document content, go really fast
2150          */
2151         cur = ctxt->input->cur;
2152         while (IS_BLANK_CH(*cur)) {
2153             if (*cur == '\n') {
2154                 ctxt->input->line++; ctxt->input->col = 1;
2155             } else {
2156                 ctxt->input->col++;
2157             }
2158             cur++;
2159             res++;
2160             if (*cur == 0) {
2161                 ctxt->input->cur = cur;
2162                 xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2163                 cur = ctxt->input->cur;
2164             }
2165         }
2166         ctxt->input->cur = cur;
2167     } else {
2168         int cur;
2169         do {
2170             cur = CUR;
2171             while ((IS_BLANK_CH(cur) && /* CHECKED tstblanks.xml */
2172                    (ctxt->instate != XML_PARSER_EOF))) {
2173                 NEXT;
2174                 cur = CUR;
2175                 res++;
2176             }
2177             while ((cur == 0) && (ctxt->inputNr > 1) &&
2178                    (ctxt->instate != XML_PARSER_COMMENT)) {
2179                 xmlPopInput(ctxt);
2180                 cur = CUR;
2181             }
2182             /*
2183              * Need to handle support of entities branching here
2184              */
2185             if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
2186         } while ((IS_BLANK(cur)) && /* CHECKED tstblanks.xml */
2187                  (ctxt->instate != XML_PARSER_EOF));
2188     }
2189     return(res);
2190 }
2191
2192 /************************************************************************
2193  *                                                                      *
2194  *              Commodity functions to handle entities                  *
2195  *                                                                      *
2196  ************************************************************************/
2197
2198 /**
2199  * xmlPopInput:
2200  * @ctxt:  an XML parser context
2201  *
2202  * xmlPopInput: the current input pointed by ctxt->input came to an end
2203  *          pop it and return the next char.
2204  *
2205  * Returns the current xmlChar in the parser context
2206  */
2207 xmlChar
2208 xmlPopInput(xmlParserCtxtPtr ctxt) {
2209     if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
2210     if (xmlParserDebugEntities)
2211         xmlGenericError(xmlGenericErrorContext,
2212                 "Popping input %d\n", ctxt->inputNr);
2213     xmlFreeInputStream(inputPop(ctxt));
2214     if ((*ctxt->input->cur == 0) &&
2215         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
2216             return(xmlPopInput(ctxt));
2217     return(CUR);
2218 }
2219
2220 /**
2221  * xmlPushInput:
2222  * @ctxt:  an XML parser context
2223  * @input:  an XML parser input fragment (entity, XML fragment ...).
2224  *
2225  * xmlPushInput: switch to a new input stream which is stacked on top
2226  *               of the previous one(s).
2227  * Returns -1 in case of error or the index in the input stack
2228  */
2229 int
2230 xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
2231     int ret;
2232     if (input == NULL) return(-1);
2233
2234     if (xmlParserDebugEntities) {
2235         if ((ctxt->input != NULL) && (ctxt->input->filename))
2236             xmlGenericError(xmlGenericErrorContext,
2237                     "%s(%d): ", ctxt->input->filename,
2238                     ctxt->input->line);
2239         xmlGenericError(xmlGenericErrorContext,
2240                 "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
2241     }
2242     ret = inputPush(ctxt, input);
2243     if (ctxt->instate == XML_PARSER_EOF)
2244         return(-1);
2245     GROW;
2246     return(ret);
2247 }
2248
2249 /**
2250  * xmlParseCharRef:
2251  * @ctxt:  an XML parser context
2252  *
2253  * parse Reference declarations
2254  *
2255  * [66] CharRef ::= '&#' [0-9]+ ';' |
2256  *                  '&#x' [0-9a-fA-F]+ ';'
2257  *
2258  * [ WFC: Legal Character ]
2259  * Characters referred to using character references must match the
2260  * production for Char.
2261  *
2262  * Returns the value parsed (as an int), 0 in case of error
2263  */
2264 int
2265 xmlParseCharRef(xmlParserCtxtPtr ctxt) {
2266     unsigned int val = 0;
2267     int count = 0;
2268     unsigned int outofrange = 0;
2269
2270     /*
2271      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
2272      */
2273     if ((RAW == '&') && (NXT(1) == '#') &&
2274         (NXT(2) == 'x')) {
2275         SKIP(3);
2276         GROW;
2277         while (RAW != ';') { /* loop blocked by count */
2278             if (count++ > 20) {
2279                 count = 0;
2280                 GROW;
2281                 if (ctxt->instate == XML_PARSER_EOF)
2282                     return(0);
2283             }
2284             if ((RAW >= '0') && (RAW <= '9'))
2285                 val = val * 16 + (CUR - '0');
2286             else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
2287                 val = val * 16 + (CUR - 'a') + 10;
2288             else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
2289                 val = val * 16 + (CUR - 'A') + 10;
2290             else {
2291                 xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2292                 val = 0;
2293                 break;
2294             }
2295             if (val > 0x10FFFF)
2296                 outofrange = val;
2297
2298             NEXT;
2299             count++;
2300         }
2301         if (RAW == ';') {
2302             /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2303             ctxt->input->col++;
2304             ctxt->nbChars ++;
2305             ctxt->input->cur++;
2306         }
2307     } else if  ((RAW == '&') && (NXT(1) == '#')) {
2308         SKIP(2);
2309         GROW;
2310         while (RAW != ';') { /* loop blocked by count */
2311             if (count++ > 20) {
2312                 count = 0;
2313                 GROW;
2314                 if (ctxt->instate == XML_PARSER_EOF)
2315                     return(0);
2316             }
2317             if ((RAW >= '0') && (RAW <= '9'))
2318                 val = val * 10 + (CUR - '0');
2319             else {
2320                 xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2321                 val = 0;
2322                 break;
2323             }
2324             if (val > 0x10FFFF)
2325                 outofrange = val;
2326
2327             NEXT;
2328             count++;
2329         }
2330         if (RAW == ';') {
2331             /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2332             ctxt->input->col++;
2333             ctxt->nbChars ++;
2334             ctxt->input->cur++;
2335         }
2336     } else {
2337         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2338     }
2339
2340     /*
2341      * [ WFC: Legal Character ]
2342      * Characters referred to using character references must match the
2343      * production for Char.
2344      */
2345     if ((IS_CHAR(val) && (outofrange == 0))) {
2346         return(val);
2347     } else {
2348         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2349                           "xmlParseCharRef: invalid xmlChar value %d\n",
2350                           val);
2351     }
2352     return(0);
2353 }
2354
2355 /**
2356  * xmlParseStringCharRef:
2357  * @ctxt:  an XML parser context
2358  * @str:  a pointer to an index in the string
2359  *
2360  * parse Reference declarations, variant parsing from a string rather
2361  * than an an input flow.
2362  *
2363  * [66] CharRef ::= '&#' [0-9]+ ';' |
2364  *                  '&#x' [0-9a-fA-F]+ ';'
2365  *
2366  * [ WFC: Legal Character ]
2367  * Characters referred to using character references must match the
2368  * production for Char.
2369  *
2370  * Returns the value parsed (as an int), 0 in case of error, str will be
2371  *         updated to the current value of the index
2372  */
2373 static int
2374 xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
2375     const xmlChar *ptr;
2376     xmlChar cur;
2377     unsigned int val = 0;
2378     unsigned int outofrange = 0;
2379
2380     if ((str == NULL) || (*str == NULL)) return(0);
2381     ptr = *str;
2382     cur = *ptr;
2383     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
2384         ptr += 3;
2385         cur = *ptr;
2386         while (cur != ';') { /* Non input consuming loop */
2387             if ((cur >= '0') && (cur <= '9'))
2388                 val = val * 16 + (cur - '0');
2389             else if ((cur >= 'a') && (cur <= 'f'))
2390                 val = val * 16 + (cur - 'a') + 10;
2391             else if ((cur >= 'A') && (cur <= 'F'))
2392                 val = val * 16 + (cur - 'A') + 10;
2393             else {
2394                 xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2395                 val = 0;
2396                 break;
2397             }
2398             if (val > 0x10FFFF)
2399                 outofrange = val;
2400
2401             ptr++;
2402             cur = *ptr;
2403         }
2404         if (cur == ';')
2405             ptr++;
2406     } else if  ((cur == '&') && (ptr[1] == '#')){
2407         ptr += 2;
2408         cur = *ptr;
2409         while (cur != ';') { /* Non input consuming loops */
2410             if ((cur >= '0') && (cur <= '9'))
2411                 val = val * 10 + (cur - '0');
2412             else {
2413                 xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2414                 val = 0;
2415                 break;
2416             }
2417             if (val > 0x10FFFF)
2418                 outofrange = val;
2419
2420             ptr++;
2421             cur = *ptr;
2422         }
2423         if (cur == ';')
2424             ptr++;
2425     } else {
2426         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2427         return(0);
2428     }
2429     *str = ptr;
2430
2431     /*
2432      * [ WFC: Legal Character ]
2433      * Characters referred to using character references must match the
2434      * production for Char.
2435      */
2436     if ((IS_CHAR(val) && (outofrange == 0))) {
2437         return(val);
2438     } else {
2439         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2440                           "xmlParseStringCharRef: invalid xmlChar value %d\n",
2441                           val);
2442     }
2443     return(0);
2444 }
2445
2446 /**
2447  * xmlNewBlanksWrapperInputStream:
2448  * @ctxt:  an XML parser context
2449  * @entity:  an Entity pointer
2450  *
2451  * Create a new input stream for wrapping
2452  * blanks around a PEReference
2453  *
2454  * Returns the new input stream or NULL
2455  */
2456
2457 static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
2458
2459 static xmlParserInputPtr
2460 xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
2461     xmlParserInputPtr input;
2462     xmlChar *buffer;
2463     size_t length;
2464     if (entity == NULL) {
2465         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
2466                     "xmlNewBlanksWrapperInputStream entity\n");
2467         return(NULL);
2468     }
2469     if (xmlParserDebugEntities)
2470         xmlGenericError(xmlGenericErrorContext,
2471                 "new blanks wrapper for entity: %s\n", entity->name);
2472     input = xmlNewInputStream(ctxt);
2473     if (input == NULL) {
2474         return(NULL);
2475     }
2476     length = xmlStrlen(entity->name) + 5;
2477     buffer = xmlMallocAtomic(length);
2478     if (buffer == NULL) {
2479         xmlErrMemory(ctxt, NULL);
2480         xmlFree(input);
2481         return(NULL);
2482     }
2483     buffer [0] = ' ';
2484     buffer [1] = '%';
2485     buffer [length-3] = ';';
2486     buffer [length-2] = ' ';
2487     buffer [length-1] = 0;
2488     memcpy(buffer + 2, entity->name, length - 5);
2489     input->free = deallocblankswrapper;
2490     input->base = buffer;
2491     input->cur = buffer;
2492     input->length = length;
2493     input->end = &buffer[length];
2494     return(input);
2495 }
2496
2497 /**
2498  * xmlParserHandlePEReference:
2499  * @ctxt:  the parser context
2500  *
2501  * [69] PEReference ::= '%' Name ';'
2502  *
2503  * [ WFC: No Recursion ]
2504  * A parsed entity must not contain a recursive
2505  * reference to itself, either directly or indirectly.
2506  *
2507  * [ WFC: Entity Declared ]
2508  * In a document without any DTD, a document with only an internal DTD
2509  * subset which contains no parameter entity references, or a document
2510  * with "standalone='yes'", ...  ... The declaration of a parameter
2511  * entity must precede any reference to it...
2512  *
2513  * [ VC: Entity Declared ]
2514  * In a document with an external subset or external parameter entities
2515  * with "standalone='no'", ...  ... The declaration of a parameter entity
2516  * must precede any reference to it...
2517  *
2518  * [ WFC: In DTD ]
2519  * Parameter-entity references may only appear in the DTD.
2520  * NOTE: misleading but this is handled.
2521  *
2522  * A PEReference may have been detected in the current input stream
2523  * the handling is done accordingly to
2524  *      http://www.w3.org/TR/REC-xml#entproc
2525  * i.e.
2526  *   - Included in literal in entity values
2527  *   - Included as Parameter Entity reference within DTDs
2528  */
2529 void
2530 xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
2531     const xmlChar *name;
2532     xmlEntityPtr entity = NULL;
2533     xmlParserInputPtr input;
2534
2535     if (RAW != '%') return;
2536     switch(ctxt->instate) {
2537         case XML_PARSER_CDATA_SECTION:
2538             return;
2539         case XML_PARSER_COMMENT:
2540             return;
2541         case XML_PARSER_START_TAG:
2542             return;
2543         case XML_PARSER_END_TAG:
2544             return;
2545         case XML_PARSER_EOF:
2546             xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
2547             return;
2548         case XML_PARSER_PROLOG:
2549         case XML_PARSER_START:
2550         case XML_PARSER_MISC:
2551             xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
2552             return;
2553         case XML_PARSER_ENTITY_DECL:
2554         case XML_PARSER_CONTENT:
2555         case XML_PARSER_ATTRIBUTE_VALUE:
2556         case XML_PARSER_PI:
2557         case XML_PARSER_SYSTEM_LITERAL:
2558         case XML_PARSER_PUBLIC_LITERAL:
2559             /* we just ignore it there */
2560             return;
2561         case XML_PARSER_EPILOG:
2562             xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
2563             return;
2564         case XML_PARSER_ENTITY_VALUE:
2565             /*
2566              * NOTE: in the case of entity values, we don't do the
2567              *       substitution here since we need the literal
2568              *       entity value to be able to save the internal
2569              *       subset of the document.
2570              *       This will be handled by xmlStringDecodeEntities
2571              */
2572             return;
2573         case XML_PARSER_DTD:
2574             /*
2575              * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
2576              * In the internal DTD subset, parameter-entity references
2577              * can occur only where markup declarations can occur, not
2578              * within markup declarations.
2579              * In that case this is handled in xmlParseMarkupDecl
2580              */
2581             if ((ctxt->external == 0) && (ctxt->inputNr == 1))
2582                 return;
2583             if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
2584                 return;
2585             break;
2586         case XML_PARSER_IGNORE:
2587             return;
2588     }
2589
2590     NEXT;
2591     name = xmlParseName(ctxt);
2592     if (xmlParserDebugEntities)
2593         xmlGenericError(xmlGenericErrorContext,
2594                 "PEReference: %s\n", name);
2595     if (name == NULL) {
2596         xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
2597     } else {
2598         if (RAW == ';') {
2599             NEXT;
2600             if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
2601                 entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
2602             if (ctxt->instate == XML_PARSER_EOF)
2603                 return;
2604             if (entity == NULL) {
2605
2606                 /*
2607                  * [ WFC: Entity Declared ]
2608                  * In a document without any DTD, a document with only an
2609                  * internal DTD subset which contains no parameter entity
2610                  * references, or a document with "standalone='yes'", ...
2611                  * ... The declaration of a parameter entity must precede
2612                  * any reference to it...
2613                  */
2614                 if ((ctxt->standalone == 1) ||
2615                     ((ctxt->hasExternalSubset == 0) &&
2616                      (ctxt->hasPErefs == 0))) {
2617                     xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
2618                          "PEReference: %%%s; not found\n", name);
2619                 } else {
2620                     /*
2621                      * [ VC: Entity Declared ]
2622                      * In a document with an external subset or external
2623                      * parameter entities with "standalone='no'", ...
2624                      * ... The declaration of a parameter entity must precede
2625                      * any reference to it...
2626                      */
2627                     if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
2628                         xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
2629                                          "PEReference: %%%s; not found\n",
2630                                          name, NULL);
2631                     } else
2632                         xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
2633                                       "PEReference: %%%s; not found\n",
2634                                       name, NULL);
2635                     ctxt->valid = 0;
2636                 }
2637                 xmlParserEntityCheck(ctxt, 0, NULL, 0);
2638             } else if (ctxt->input->free != deallocblankswrapper) {
2639                     input = xmlNewBlanksWrapperInputStream(ctxt, entity);
2640                     if (xmlPushInput(ctxt, input) < 0)
2641                         return;
2642             } else {
2643                 if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
2644                     (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
2645                     xmlChar start[4];
2646                     xmlCharEncoding enc;
2647
2648                     /*
2649                      * Note: external parameter entities will not be loaded, it
2650                      * is not required for a non-validating parser, unless the
2651                      * option of validating, or substituting entities were
2652                      * given. Doing so is far more secure as the parser will
2653                      * only process data coming from the document entity by
2654                      * default.
2655                      */
2656                     if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
2657                         ((ctxt->options & XML_PARSE_NOENT) == 0) &&
2658                         ((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
2659                         ((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
2660                         ((ctxt->options & XML_PARSE_DTDATTR) == 0) &&
2661                         (ctxt->replaceEntities == 0) &&
2662                         (ctxt->validate == 0))
2663                         return;
2664
2665                     /*
2666                      * handle the extra spaces added before and after
2667                      * c.f. http://www.w3.org/TR/REC-xml#as-PE
2668                      * this is done independently.
2669                      */
2670                     input = xmlNewEntityInputStream(ctxt, entity);
2671                     if (xmlPushInput(ctxt, input) < 0)
2672                         return;
2673
2674                     /*
2675                      * Get the 4 first bytes and decode the charset
2676                      * if enc != XML_CHAR_ENCODING_NONE
2677                      * plug some encoding conversion routines.
2678                      * Note that, since we may have some non-UTF8
2679                      * encoding (like UTF16, bug 135229), the 'length'
2680                      * is not known, but we can calculate based upon
2681                      * the amount of data in the buffer.
2682                      */
2683                     GROW
2684                     if (ctxt->instate == XML_PARSER_EOF)
2685                         return;
2686                     if ((ctxt->input->end - ctxt->input->cur)>=4) {
2687                         start[0] = RAW;
2688                         start[1] = NXT(1);
2689                         start[2] = NXT(2);
2690                         start[3] = NXT(3);
2691                         enc = xmlDetectCharEncoding(start, 4);
2692                         if (enc != XML_CHAR_ENCODING_NONE) {
2693                             xmlSwitchEncoding(ctxt, enc);
2694                         }
2695                     }
2696
2697                     if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
2698                         (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
2699                         (IS_BLANK_CH(NXT(5)))) {
2700                         xmlParseTextDecl(ctxt);
2701                     }
2702                 } else {
2703                     xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
2704                              "PEReference: %s is not a parameter entity\n",
2705                                       name);
2706                 }
2707             }
2708         } else {
2709             xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
2710         }
2711     }
2712 }
2713
2714 /*
2715  * Macro used to grow the current buffer.
2716  * buffer##_size is expected to be a size_t
2717  * mem_error: is expected to handle memory allocation failures
2718  */
2719 #define growBuffer(buffer, n) {                                         \
2720     xmlChar *tmp;                                                       \
2721     size_t new_size = buffer##_size * 2 + n;                            \
2722     if (new_size < buffer##_size) goto mem_error;                       \
2723     tmp = (xmlChar *) xmlRealloc(buffer, new_size);                     \
2724     if (tmp == NULL) goto mem_error;                                    \
2725     buffer = tmp;                                                       \
2726     buffer##_size = new_size;                                           \
2727 }
2728
2729 /**
2730  * xmlStringLenDecodeEntities:
2731  * @ctxt:  the parser context
2732  * @str:  the input string
2733  * @len: the string length
2734  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2735  * @end:  an end marker xmlChar, 0 if none
2736  * @end2:  an end marker xmlChar, 0 if none
2737  * @end3:  an end marker xmlChar, 0 if none
2738  *
2739  * Takes a entity string content and process to do the adequate substitutions.
2740  *
2741  * [67] Reference ::= EntityRef | CharRef
2742  *
2743  * [69] PEReference ::= '%' Name ';'
2744  *
2745  * Returns A newly allocated string with the substitution done. The caller
2746  *      must deallocate it !
2747  */
2748 xmlChar *
2749 xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2750                       int what, xmlChar end, xmlChar  end2, xmlChar end3) {
2751     xmlChar *buffer = NULL;
2752     size_t buffer_size = 0;
2753     size_t nbchars = 0;
2754
2755     xmlChar *current = NULL;
2756     xmlChar *rep = NULL;
2757     const xmlChar *last;
2758     xmlEntityPtr ent;
2759     int c,l;
2760
2761     if ((ctxt == NULL) || (str == NULL) || (len < 0))
2762         return(NULL);
2763     last = str + len;
2764
2765     if (((ctxt->depth > 40) &&
2766          ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2767         (ctxt->depth > 1024)) {
2768         xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2769         return(NULL);
2770     }
2771
2772     /*
2773      * allocate a translation buffer.
2774      */
2775     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
2776     buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
2777     if (buffer == NULL) goto mem_error;
2778
2779     /*
2780      * OK loop until we reach one of the ending char or a size limit.
2781      * we are operating on already parsed values.
2782      */
2783     if (str < last)
2784         c = CUR_SCHAR(str, l);
2785     else
2786         c = 0;
2787     while ((c != 0) && (c != end) && /* non input consuming loop */
2788            (c != end2) && (c != end3)) {
2789
2790         if (c == 0) break;
2791         if ((c == '&') && (str[1] == '#')) {
2792             int val = xmlParseStringCharRef(ctxt, &str);
2793             if (val != 0) {
2794                 COPY_BUF(0,buffer,nbchars,val);
2795             }
2796             if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2797                 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2798             }
2799         } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
2800             if (xmlParserDebugEntities)
2801                 xmlGenericError(xmlGenericErrorContext,
2802                         "String decoding Entity Reference: %.30s\n",
2803                         str);
2804             ent = xmlParseStringEntityRef(ctxt, &str);
2805             if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
2806                 (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
2807                 goto int_error;
2808             xmlParserEntityCheck(ctxt, 0, ent, 0);
2809             if (ent != NULL)
2810                 ctxt->nbentities += ent->checked / 2;
2811             if ((ent != NULL) &&
2812                 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
2813                 if (ent->content != NULL) {
2814                     COPY_BUF(0,buffer,nbchars,ent->content[0]);
2815                     if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2816                         growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2817                     }
2818                 } else {
2819                     xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
2820                             "predefined entity has no content\n");
2821                 }
2822             } else if ((ent != NULL) && (ent->content != NULL)) {
2823                 ctxt->depth++;
2824                 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2825                                               0, 0, 0);
2826                 ctxt->depth--;
2827
2828                 if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
2829                     (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
2830                     goto int_error;
2831
2832                 if (rep != NULL) {
2833                     current = rep;
2834                     while (*current != 0) { /* non input consuming loop */
2835                         buffer[nbchars++] = *current++;
2836                         if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2837                             if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
2838                                 goto int_error;
2839                             growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2840                         }
2841                     }
2842                     xmlFree(rep);
2843                     rep = NULL;
2844                 }
2845             } else if (ent != NULL) {
2846                 int i = xmlStrlen(ent->name);
2847                 const xmlChar *cur = ent->name;
2848
2849                 buffer[nbchars++] = '&';
2850                 if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
2851                     growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
2852                 }
2853                 for (;i > 0;i--)
2854                     buffer[nbchars++] = *cur++;
2855                 buffer[nbchars++] = ';';
2856             }
2857         } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
2858             if (xmlParserDebugEntities)
2859                 xmlGenericError(xmlGenericErrorContext,
2860                         "String decoding PE Reference: %.30s\n", str);
2861             ent = xmlParseStringPEReference(ctxt, &str);
2862             if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
2863                 goto int_error;
2864             xmlParserEntityCheck(ctxt, 0, ent, 0);
2865             if (ent != NULL)
2866                 ctxt->nbentities += ent->checked / 2;
2867             if (ent != NULL) {
2868                 if (ent->content == NULL) {
2869                     /*
2870                      * Note: external parsed entities will not be loaded,
2871                      * it is not required for a non-validating parser to
2872                      * complete external PEreferences coming from the
2873                      * internal subset
2874                      */
2875                     if (((ctxt->options & XML_PARSE_NOENT) != 0) ||
2876                         ((ctxt->options & XML_PARSE_DTDVALID) != 0) ||
2877                         (ctxt->validate != 0)) {
2878                         xmlLoadEntityContent(ctxt, ent);
2879                     } else {
2880                         xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
2881                   "not validating will not read content for PE entity %s\n",
2882                                       ent->name, NULL);
2883                     }
2884                 }
2885                 ctxt->depth++;
2886                 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2887                                               0, 0, 0);
2888                 ctxt->depth--;
2889                 if (rep != NULL) {
2890                     current = rep;
2891                     while (*current != 0) { /* non input consuming loop */
2892                         buffer[nbchars++] = *current++;
2893                         if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2894                             if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
2895                                 goto int_error;
2896                             growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2897                         }
2898                     }
2899                     xmlFree(rep);
2900                     rep = NULL;
2901                 }
2902             }
2903         } else {
2904             COPY_BUF(l,buffer,nbchars,c);
2905             str += l;
2906             if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2907                 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2908             }
2909         }
2910         if (str < last)
2911             c = CUR_SCHAR(str, l);
2912         else
2913             c = 0;
2914     }
2915     buffer[nbchars] = 0;
2916     return(buffer);
2917
2918 mem_error:
2919     xmlErrMemory(ctxt, NULL);
2920 int_error:
2921     if (rep != NULL)
2922         xmlFree(rep);
2923     if (buffer != NULL)
2924         xmlFree(buffer);
2925     return(NULL);
2926 }
2927
2928 /**
2929  * xmlStringDecodeEntities:
2930  * @ctxt:  the parser context
2931  * @str:  the input string
2932  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2933  * @end:  an end marker xmlChar, 0 if none
2934  * @end2:  an end marker xmlChar, 0 if none
2935  * @end3:  an end marker xmlChar, 0 if none
2936  *
2937  * Takes a entity string content and process to do the adequate substitutions.
2938  *
2939  * [67] Reference ::= EntityRef | CharRef
2940  *
2941  * [69] PEReference ::= '%' Name ';'
2942  *
2943  * Returns A newly allocated string with the substitution done. The caller
2944  *      must deallocate it !
2945  */
2946 xmlChar *
2947 xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
2948                         xmlChar end, xmlChar  end2, xmlChar end3) {
2949     if ((ctxt == NULL) || (str == NULL)) return(NULL);
2950     return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
2951            end, end2, end3));
2952 }
2953
2954 /************************************************************************
2955  *                                                                      *
2956  *              Commodity functions, cleanup needed ?                   *
2957  *                                                                      *
2958  ************************************************************************/
2959
2960 /**
2961  * areBlanks:
2962  * @ctxt:  an XML parser context
2963  * @str:  a xmlChar *
2964  * @len:  the size of @str
2965  * @blank_chars: we know the chars are blanks
2966  *
2967  * Is this a sequence of blank chars that one can ignore ?
2968  *
2969  * Returns 1 if ignorable 0 otherwise.
2970  */
2971
2972 static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2973                      int blank_chars) {
2974     int i, ret;
2975     xmlNodePtr lastChild;
2976
2977     /*
2978      * Don't spend time trying to differentiate them, the same callback is
2979      * used !
2980      */
2981     if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
2982         return(0);
2983
2984     /*
2985      * Check for xml:space value.
2986      */
2987     if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
2988         (*(ctxt->space) == -2))
2989         return(0);
2990
2991     /*
2992      * Check that the string is made of blanks
2993      */
2994     if (blank_chars == 0) {
2995         for (i = 0;i < len;i++)
2996             if (!(IS_BLANK_CH(str[i]))) return(0);
2997     }
2998
2999     /*
3000      * Look if the element is mixed content in the DTD if available
3001      */
3002     if (ctxt->node == NULL) return(0);
3003     if (ctxt->myDoc != NULL) {
3004         ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
3005         if (ret == 0) return(1);
3006         if (ret == 1) return(0);
3007     }
3008
3009     /*
3010      * Otherwise, heuristic :-\
3011      */
3012     if ((RAW != '<') && (RAW != 0xD)) return(0);
3013     if ((ctxt->node->children == NULL) &&
3014         (RAW == '<') && (NXT(1) == '/')) return(0);
3015
3016     lastChild = xmlGetLastChild(ctxt->node);
3017     if (lastChild == NULL) {
3018         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
3019             (ctxt->node->content != NULL)) return(0);
3020     } else if (xmlNodeIsText(lastChild))
3021         return(0);
3022     else if ((ctxt->node->children != NULL) &&
3023              (xmlNodeIsText(ctxt->node->children)))
3024         return(0);
3025     return(1);
3026 }
3027
3028 /************************************************************************
3029  *                                                                      *
3030  *              Extra stuff for namespace support                       *
3031  *      Relates to http://www.w3.org/TR/WD-xml-names                    *
3032  *                                                                      *
3033  ************************************************************************/
3034
3035 /**
3036  * xmlSplitQName:
3037  * @ctxt:  an XML parser context
3038  * @name:  an XML parser context
3039  * @prefix:  a xmlChar **
3040  *
3041  * parse an UTF8 encoded XML qualified name string
3042  *
3043  * [NS 5] QName ::= (Prefix ':')? LocalPart
3044  *
3045  * [NS 6] Prefix ::= NCName
3046  *
3047  * [NS 7] LocalPart ::= NCName
3048  *
3049  * Returns the local part, and prefix is updated
3050  *   to get the Prefix if any.
3051  */
3052
3053 xmlChar *
3054 xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
3055     xmlChar buf[XML_MAX_NAMELEN + 5];
3056     xmlChar *buffer = NULL;
3057     int len = 0;
3058     int max = XML_MAX_NAMELEN;
3059     xmlChar *ret = NULL;
3060     const xmlChar *cur = name;
3061     int c;
3062
3063     if (prefix == NULL) return(NULL);
3064     *prefix = NULL;
3065
3066     if (cur == NULL) return(NULL);
3067
3068 #ifndef XML_XML_NAMESPACE
3069     /* xml: prefix is not really a namespace */
3070     if ((cur[0] == 'x') && (cur[1] == 'm') &&
3071         (cur[2] == 'l') && (cur[3] == ':'))
3072         return(xmlStrdup(name));
3073 #endif
3074
3075     /* nasty but well=formed */
3076     if (cur[0] == ':')
3077         return(xmlStrdup(name));
3078
3079     c = *cur++;
3080     while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
3081         buf[len++] = c;
3082         c = *cur++;
3083     }
3084     if (len >= max) {
3085         /*
3086          * Okay someone managed to make a huge name, so he's ready to pay
3087          * for the processing speed.
3088          */
3089         max = len * 2;
3090
3091         buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3092         if (buffer == NULL) {
3093             xmlErrMemory(ctxt, NULL);
3094             return(NULL);
3095         }
3096         memcpy(buffer, buf, len);
3097         while ((c != 0) && (c != ':')) { /* tested bigname.xml */
3098             if (len + 10 > max) {
3099                 xmlChar *tmp;
3100
3101                 max *= 2;
3102                 tmp = (xmlChar *) xmlRealloc(buffer,
3103                                                 max * sizeof(xmlChar));
3104                 if (tmp == NULL) {
3105                     xmlFree(buffer);
3106                     xmlErrMemory(ctxt, NULL);
3107                     return(NULL);
3108                 }
3109                 buffer = tmp;
3110             }
3111             buffer[len++] = c;
3112             c = *cur++;
3113         }
3114         buffer[len] = 0;
3115     }
3116
3117     if ((c == ':') && (*cur == 0)) {
3118         if (buffer != NULL)
3119             xmlFree(buffer);
3120         *prefix = NULL;
3121         return(xmlStrdup(name));
3122     }
3123
3124     if (buffer == NULL)
3125         ret = xmlStrndup(buf, len);
3126     else {
3127         ret = buffer;
3128         buffer = NULL;
3129         max = XML_MAX_NAMELEN;
3130     }
3131
3132
3133     if (c == ':') {
3134         c = *cur;
3135         *prefix = ret;
3136         if (c == 0) {
3137             return(xmlStrndup(BAD_CAST "", 0));
3138         }
3139         len = 0;
3140
3141         /*
3142          * Check that the first character is proper to start
3143          * a new name
3144          */
3145         if (!(((c >= 0x61) && (c <= 0x7A)) ||
3146               ((c >= 0x41) && (c <= 0x5A)) ||
3147               (c == '_') || (c == ':'))) {
3148             int l;
3149             int first = CUR_SCHAR(cur, l);
3150
3151             if (!IS_LETTER(first) && (first != '_')) {
3152                 xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
3153                             "Name %s is not XML Namespace compliant\n",
3154                                   name);
3155             }
3156         }
3157         cur++;
3158
3159         while ((c != 0) && (len < max)) { /* tested bigname2.xml */
3160             buf[len++] = c;
3161             c = *cur++;
3162         }
3163         if (len >= max) {
3164             /*
3165              * Okay someone managed to make a huge name, so he's ready to pay
3166              * for the processing speed.
3167              */
3168             max = len * 2;
3169
3170             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3171             if (buffer == NULL) {
3172                 xmlErrMemory(ctxt, NULL);
3173                 return(NULL);
3174             }
3175             memcpy(buffer, buf, len);
3176             while (c != 0) { /* tested bigname2.xml */
3177                 if (len + 10 > max) {
3178                     xmlChar *tmp;
3179
3180                     max *= 2;
3181                     tmp = (xmlChar *) xmlRealloc(buffer,
3182                                                     max * sizeof(xmlChar));
3183                     if (tmp == NULL) {
3184                         xmlErrMemory(ctxt, NULL);
3185                         xmlFree(buffer);
3186                         return(NULL);
3187                     }
3188                     buffer = tmp;
3189                 }
3190                 buffer[len++] = c;
3191                 c = *cur++;
3192             }
3193             buffer[len] = 0;
3194         }
3195
3196         if (buffer == NULL)
3197             ret = xmlStrndup(buf, len);
3198         else {
3199             ret = buffer;
3200         }
3201     }
3202
3203     return(ret);
3204 }
3205
3206 /************************************************************************
3207  *                                                                      *
3208  *                      The parser itself                               *
3209  *      Relates to http://www.w3.org/TR/REC-xml                         *
3210  *                                                                      *
3211  ************************************************************************/
3212
3213 /************************************************************************
3214  *                                                                      *
3215  *      Routines to parse Name, NCName and NmToken                      *
3216  *                                                                      *
3217  ************************************************************************/
3218 #ifdef DEBUG
3219 static unsigned long nbParseName = 0;
3220 static unsigned long nbParseNmToken = 0;
3221 static unsigned long nbParseNCName = 0;
3222 static unsigned long nbParseNCNameComplex = 0;
3223 static unsigned long nbParseNameComplex = 0;
3224 static unsigned long nbParseStringName = 0;
3225 #endif
3226
3227 /*
3228  * The two following functions are related to the change of accepted
3229  * characters for Name and NmToken in the Revision 5 of XML-1.0
3230  * They correspond to the modified production [4] and the new production [4a]
3231  * changes in that revision. Also note that the macros used for the
3232  * productions Letter, Digit, CombiningChar and Extender are not needed
3233  * anymore.
3234  * We still keep compatibility to pre-revision5 parsing semantic if the
3235  * new XML_PARSE_OLD10 option is given to the parser.
3236  */
3237 static int
3238 xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
3239     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3240         /*
3241          * Use the new checks of production [4] [4a] amd [5] of the
3242          * Update 5 of XML-1.0
3243          */
3244         if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3245             (((c >= 'a') && (c <= 'z')) ||
3246              ((c >= 'A') && (c <= 'Z')) ||
3247              (c == '_') || (c == ':') ||
3248              ((c >= 0xC0) && (c <= 0xD6)) ||
3249              ((c >= 0xD8) && (c <= 0xF6)) ||
3250              ((c >= 0xF8) && (c <= 0x2FF)) ||
3251              ((c >= 0x370) && (c <= 0x37D)) ||
3252              ((c >= 0x37F) && (c <= 0x1FFF)) ||
3253              ((c >= 0x200C) && (c <= 0x200D)) ||
3254              ((c >= 0x2070) && (c <= 0x218F)) ||
3255              ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3256              ((c >= 0x3001) && (c <= 0xD7FF)) ||
3257              ((c >= 0xF900) && (c <= 0xFDCF)) ||
3258              ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3259              ((c >= 0x10000) && (c <= 0xEFFFF))))
3260             return(1);
3261     } else {
3262         if (IS_LETTER(c) || (c == '_') || (c == ':'))
3263             return(1);
3264     }
3265     return(0);
3266 }
3267
3268 static int
3269 xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
3270     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3271         /*
3272          * Use the new checks of production [4] [4a] amd [5] of the
3273          * Update 5 of XML-1.0
3274          */
3275         if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3276             (((c >= 'a') && (c <= 'z')) ||
3277              ((c >= 'A') && (c <= 'Z')) ||
3278              ((c >= '0') && (c <= '9')) || /* !start */
3279              (c == '_') || (c == ':') ||
3280              (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3281              ((c >= 0xC0) && (c <= 0xD6)) ||
3282              ((c >= 0xD8) && (c <= 0xF6)) ||
3283              ((c >= 0xF8) && (c <= 0x2FF)) ||
3284              ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3285              ((c >= 0x370) && (c <= 0x37D)) ||
3286              ((c >= 0x37F) && (c <= 0x1FFF)) ||
3287              ((c >= 0x200C) && (c <= 0x200D)) ||
3288              ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3289              ((c >= 0x2070) && (c <= 0x218F)) ||
3290              ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3291              ((c >= 0x3001) && (c <= 0xD7FF)) ||
3292              ((c >= 0xF900) && (c <= 0xFDCF)) ||
3293              ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3294              ((c >= 0x10000) && (c <= 0xEFFFF))))
3295              return(1);
3296     } else {
3297         if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3298             (c == '.') || (c == '-') ||
3299             (c == '_') || (c == ':') ||
3300             (IS_COMBINING(c)) ||
3301             (IS_EXTENDER(c)))
3302             return(1);
3303     }
3304     return(0);
3305 }
3306
3307 static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
3308                                           int *len, int *alloc, int normalize);
3309
3310 static const xmlChar *
3311 xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
3312     int len = 0, l;
3313     int c;
3314     int count = 0;
3315
3316 #ifdef DEBUG
3317     nbParseNameComplex++;
3318 #endif
3319
3320     /*
3321      * Handler for more complex cases
3322      */
3323     GROW;
3324     if (ctxt->instate == XML_PARSER_EOF)
3325         return(NULL);
3326     c = CUR_CHAR(l);
3327     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3328         /*
3329          * Use the new checks of production [4] [4a] amd [5] of the
3330          * Update 5 of XML-1.0
3331          */
3332         if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3333             (!(((c >= 'a') && (c <= 'z')) ||
3334                ((c >= 'A') && (c <= 'Z')) ||
3335                (c == '_') || (c == ':') ||
3336                ((c >= 0xC0) && (c <= 0xD6)) ||
3337                ((c >= 0xD8) && (c <= 0xF6)) ||
3338                ((c >= 0xF8) && (c <= 0x2FF)) ||
3339                ((c >= 0x370) && (c <= 0x37D)) ||
3340                ((c >= 0x37F) && (c <= 0x1FFF)) ||
3341                ((c >= 0x200C) && (c <= 0x200D)) ||
3342                ((c >= 0x2070) && (c <= 0x218F)) ||
3343                ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3344                ((c >= 0x3001) && (c <= 0xD7FF)) ||
3345                ((c >= 0xF900) && (c <= 0xFDCF)) ||
3346                ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3347                ((c >= 0x10000) && (c <= 0xEFFFF))))) {
3348             return(NULL);
3349         }
3350         len += l;
3351         NEXTL(l);
3352         c = CUR_CHAR(l);
3353         while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3354                (((c >= 'a') && (c <= 'z')) ||
3355                 ((c >= 'A') && (c <= 'Z')) ||
3356                 ((c >= '0') && (c <= '9')) || /* !start */
3357                 (c == '_') || (c == ':') ||
3358                 (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3359                 ((c >= 0xC0) && (c <= 0xD6)) ||
3360                 ((c >= 0xD8) && (c <= 0xF6)) ||
3361                 ((c >= 0xF8) && (c <= 0x2FF)) ||
3362                 ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3363                 ((c >= 0x370) && (c <= 0x37D)) ||
3364                 ((c >= 0x37F) && (c <= 0x1FFF)) ||
3365                 ((c >= 0x200C) && (c <= 0x200D)) ||
3366                 ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3367                 ((c >= 0x2070) && (c <= 0x218F)) ||
3368                 ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3369                 ((c >= 0x3001) && (c <= 0xD7FF)) ||
3370                 ((c >= 0xF900) && (c <= 0xFDCF)) ||
3371                 ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3372                 ((c >= 0x10000) && (c <= 0xEFFFF))
3373                 )) {
3374             if (count++ > XML_PARSER_CHUNK_SIZE) {
3375                 count = 0;
3376                 GROW;
3377                 if (ctxt->instate == XML_PARSER_EOF)
3378                     return(NULL);
3379             }
3380             len += l;
3381             NEXTL(l);
3382             c = CUR_CHAR(l);
3383         }
3384     } else {
3385         if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3386             (!IS_LETTER(c) && (c != '_') &&
3387              (c != ':'))) {
3388             return(NULL);
3389         }
3390         len += l;
3391         NEXTL(l);
3392         c = CUR_CHAR(l);
3393
3394         while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3395                ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3396                 (c == '.') || (c == '-') ||
3397                 (c == '_') || (c == ':') ||
3398                 (IS_COMBINING(c)) ||
3399                 (IS_EXTENDER(c)))) {
3400             if (count++ > XML_PARSER_CHUNK_SIZE) {
3401                 count = 0;
3402                 GROW;
3403                 if (ctxt->instate == XML_PARSER_EOF)
3404                     return(NULL);
3405             }
3406             len += l;
3407             NEXTL(l);
3408             c = CUR_CHAR(l);
3409             if (c == 0) {
3410                 count = 0;
3411                 GROW;
3412                 if (ctxt->instate == XML_PARSER_EOF)
3413                     return(NULL);
3414                 c = CUR_CHAR(l);
3415             }
3416         }
3417     }
3418     if ((len > XML_MAX_NAME_LENGTH) &&
3419         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3420         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3421         return(NULL);
3422     }
3423     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
3424         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
3425     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3426 }
3427
3428 /**
3429  * xmlParseName:
3430  * @ctxt:  an XML parser context
3431  *
3432  * parse an XML name.
3433  *
3434  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3435  *                  CombiningChar | Extender
3436  *
3437  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3438  *
3439  * [6] Names ::= Name (#x20 Name)*
3440  *
3441  * Returns the Name parsed or NULL
3442  */
3443
3444 const xmlChar *
3445 xmlParseName(xmlParserCtxtPtr ctxt) {
3446     const xmlChar *in;
3447     const xmlChar *ret;
3448     int count = 0;
3449
3450     GROW;
3451
3452 #ifdef DEBUG
3453     nbParseName++;
3454 #endif
3455
3456     /*
3457      * Accelerator for simple ASCII names
3458      */
3459     in = ctxt->input->cur;
3460     if (((*in >= 0x61) && (*in <= 0x7A)) ||
3461         ((*in >= 0x41) && (*in <= 0x5A)) ||
3462         (*in == '_') || (*in == ':')) {
3463         in++;
3464         while (((*in >= 0x61) && (*in <= 0x7A)) ||
3465                ((*in >= 0x41) && (*in <= 0x5A)) ||
3466                ((*in >= 0x30) && (*in <= 0x39)) ||
3467                (*in == '_') || (*in == '-') ||
3468                (*in == ':') || (*in == '.'))
3469             in++;
3470         if ((*in > 0) && (*in < 0x80)) {
3471             count = in - ctxt->input->cur;
3472             if ((count > XML_MAX_NAME_LENGTH) &&
3473                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3474                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3475                 return(NULL);
3476             }
3477             ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3478             ctxt->input->cur = in;
3479             ctxt->nbChars += count;
3480             ctxt->input->col += count;
3481             if (ret == NULL)
3482                 xmlErrMemory(ctxt, NULL);
3483             return(ret);
3484         }
3485     }
3486     /* accelerator for special cases */
3487     return(xmlParseNameComplex(ctxt));
3488 }
3489
3490 static const xmlChar *
3491 xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
3492     int len = 0, l;
3493     int c;
3494     int count = 0;
3495     size_t startPosition = 0;
3496
3497 #ifdef DEBUG
3498     nbParseNCNameComplex++;
3499 #endif
3500
3501     /*
3502      * Handler for more complex cases
3503      */
3504     GROW;
3505     startPosition = CUR_PTR - BASE_PTR;
3506     c = CUR_CHAR(l);
3507     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3508         (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
3509         return(NULL);
3510     }
3511
3512     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3513            (xmlIsNameChar(ctxt, c) && (c != ':'))) {
3514         if (count++ > XML_PARSER_CHUNK_SIZE) {
3515             if ((len > XML_MAX_NAME_LENGTH) &&
3516                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3517                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3518                 return(NULL);
3519             }
3520             count = 0;
3521             GROW;
3522             if (ctxt->instate == XML_PARSER_EOF)
3523                 return(NULL);
3524         }
3525         len += l;
3526         NEXTL(l);
3527         c = CUR_CHAR(l);
3528         if (c == 0) {
3529             count = 0;
3530             /*
3531              * when shrinking to extend the buffer we really need to preserve
3532              * the part of the name we already parsed. Hence rolling back
3533              * by current lenght.
3534              */
3535             ctxt->input->cur -= l;
3536             GROW;
3537             ctxt->input->cur += l;
3538             if (ctxt->instate == XML_PARSER_EOF)
3539                 return(NULL);
3540             c = CUR_CHAR(l);
3541         }
3542     }
3543     if ((len > XML_MAX_NAME_LENGTH) &&
3544         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3545         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3546         return(NULL);
3547     }
3548     return(xmlDictLookup(ctxt->dict, (BASE_PTR + startPosition), len));
3549 }
3550
3551 /**
3552  * xmlParseNCName:
3553  * @ctxt:  an XML parser context
3554  * @len:  length of the string parsed
3555  *
3556  * parse an XML name.
3557  *
3558  * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
3559  *                      CombiningChar | Extender
3560  *
3561  * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
3562  *
3563  * Returns the Name parsed or NULL
3564  */
3565
3566 static const xmlChar *
3567 xmlParseNCName(xmlParserCtxtPtr ctxt) {
3568     const xmlChar *in, *e;
3569     const xmlChar *ret;
3570     int count = 0;
3571
3572 #ifdef DEBUG
3573     nbParseNCName++;
3574 #endif
3575
3576     /*
3577      * Accelerator for simple ASCII names
3578      */
3579     in = ctxt->input->cur;
3580     e = ctxt->input->end;
3581     if ((((*in >= 0x61) && (*in <= 0x7A)) ||
3582          ((*in >= 0x41) && (*in <= 0x5A)) ||
3583          (*in == '_')) && (in < e)) {
3584         in++;
3585         while ((((*in >= 0x61) && (*in <= 0x7A)) ||
3586                 ((*in >= 0x41) && (*in <= 0x5A)) ||
3587                 ((*in >= 0x30) && (*in <= 0x39)) ||
3588                 (*in == '_') || (*in == '-') ||
3589                 (*in == '.')) && (in < e))
3590             in++;
3591         if (in >= e)
3592             goto complex;
3593         if ((*in > 0) && (*in < 0x80)) {
3594             count = in - ctxt->input->cur;
3595             if ((count > XML_MAX_NAME_LENGTH) &&
3596                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3597                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3598                 return(NULL);
3599             }
3600             ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3601             ctxt->input->cur = in;
3602             ctxt->nbChars += count;
3603             ctxt->input->col += count;
3604             if (ret == NULL) {
3605                 xmlErrMemory(ctxt, NULL);
3606             }
3607             return(ret);
3608         }
3609     }
3610 complex:
3611     return(xmlParseNCNameComplex(ctxt));
3612 }
3613
3614 /**
3615  * xmlParseNameAndCompare:
3616  * @ctxt:  an XML parser context
3617  *
3618  * parse an XML name and compares for match
3619  * (specialized for endtag parsing)
3620  *
3621  * Returns NULL for an illegal name, (xmlChar*) 1 for success
3622  * and the name for mismatch
3623  */
3624
3625 static const xmlChar *
3626 xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
3627     register const xmlChar *cmp = other;
3628     register const xmlChar *in;
3629     const xmlChar *ret;
3630
3631     GROW;
3632     if (ctxt->instate == XML_PARSER_EOF)
3633         return(NULL);
3634
3635     in = ctxt->input->cur;
3636     while (*in != 0 && *in == *cmp) {
3637         ++in;
3638         ++cmp;
3639         ctxt->input->col++;
3640     }
3641     if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
3642         /* success */
3643         ctxt->input->cur = in;
3644         return (const xmlChar*) 1;
3645     }
3646     /* failure (or end of input buffer), check with full function */
3647     ret = xmlParseName (ctxt);
3648     /* strings coming from the dictionary direct compare possible */
3649     if (ret == other) {
3650         return (const xmlChar*) 1;
3651     }
3652     return ret;
3653 }
3654
3655 /**
3656  * xmlParseStringName:
3657  * @ctxt:  an XML parser context
3658  * @str:  a pointer to the string pointer (IN/OUT)
3659  *
3660  * parse an XML name.
3661  *
3662  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3663  *                  CombiningChar | Extender
3664  *
3665  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3666  *
3667  * [6] Names ::= Name (#x20 Name)*
3668  *
3669  * Returns the Name parsed or NULL. The @str pointer
3670  * is updated to the current location in the string.
3671  */
3672
3673 static xmlChar *
3674 xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
3675     xmlChar buf[XML_MAX_NAMELEN + 5];
3676     const xmlChar *cur = *str;
3677     int len = 0, l;
3678     int c;
3679
3680 #ifdef DEBUG
3681     nbParseStringName++;
3682 #endif
3683
3684     c = CUR_SCHAR(cur, l);
3685     if (!xmlIsNameStartChar(ctxt, c)) {
3686         return(NULL);
3687     }
3688
3689     COPY_BUF(l,buf,len,c);
3690     cur += l;
3691     c = CUR_SCHAR(cur, l);
3692     while (xmlIsNameChar(ctxt, c)) {
3693         COPY_BUF(l,buf,len,c);
3694         cur += l;
3695         c = CUR_SCHAR(cur, l);
3696         if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
3697             /*
3698              * Okay someone managed to make a huge name, so he's ready to pay
3699              * for the processing speed.
3700              */
3701             xmlChar *buffer;
3702             int max = len * 2;
3703
3704             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3705             if (buffer == NULL) {
3706                 xmlErrMemory(ctxt, NULL);
3707                 return(NULL);
3708             }
3709             memcpy(buffer, buf, len);
3710             while (xmlIsNameChar(ctxt, c)) {
3711                 if (len + 10 > max) {
3712                     xmlChar *tmp;
3713
3714                     if ((len > XML_MAX_NAME_LENGTH) &&
3715                         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3716                         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3717                         xmlFree(buffer);
3718                         return(NULL);
3719                     }
3720                     max *= 2;
3721                     tmp = (xmlChar *) xmlRealloc(buffer,
3722                                                     max * sizeof(xmlChar));
3723                     if (tmp == NULL) {
3724                         xmlErrMemory(ctxt, NULL);
3725                         xmlFree(buffer);
3726                         return(NULL);
3727                     }
3728                     buffer = tmp;
3729                 }
3730                 COPY_BUF(l,buffer,len,c);
3731                 cur += l;
3732                 c = CUR_SCHAR(cur, l);
3733             }
3734             buffer[len] = 0;
3735             *str = cur;
3736             return(buffer);
3737         }
3738     }
3739     if ((len > XML_MAX_NAME_LENGTH) &&
3740         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3741         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3742         return(NULL);
3743     }
3744     *str = cur;
3745     return(xmlStrndup(buf, len));
3746 }
3747
3748 /**
3749  * xmlParseNmtoken:
3750  * @ctxt:  an XML parser context
3751  *
3752  * parse an XML Nmtoken.
3753  *
3754  * [7] Nmtoken ::= (NameChar)+
3755  *
3756  * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
3757  *
3758  * Returns the Nmtoken parsed or NULL
3759  */
3760
3761 xmlChar *
3762 xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
3763     xmlChar buf[XML_MAX_NAMELEN + 5];
3764     int len = 0, l;
3765     int c;
3766     int count = 0;
3767
3768 #ifdef DEBUG
3769     nbParseNmToken++;
3770 #endif
3771
3772     GROW;
3773     if (ctxt->instate == XML_PARSER_EOF)
3774         return(NULL);
3775     c = CUR_CHAR(l);
3776
3777     while (xmlIsNameChar(ctxt, c)) {
3778         if (count++ > XML_PARSER_CHUNK_SIZE) {
3779             count = 0;
3780             GROW;
3781         }
3782         COPY_BUF(l,buf,len,c);
3783         NEXTL(l);
3784         c = CUR_CHAR(l);
3785         if (c == 0) {
3786             count = 0;
3787             GROW;
3788             if (ctxt->instate == XML_PARSER_EOF)
3789                 return(NULL);
3790             c = CUR_CHAR(l);
3791         }
3792         if (len >= XML_MAX_NAMELEN) {
3793             /*
3794              * Okay someone managed to make a huge token, so he's ready to pay
3795              * for the processing speed.
3796              */
3797             xmlChar *buffer;
3798             int max = len * 2;
3799
3800             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3801             if (buffer == NULL) {
3802                 xmlErrMemory(ctxt, NULL);
3803                 return(NULL);
3804             }
3805             memcpy(buffer, buf, len);
3806             while (xmlIsNameChar(ctxt, c)) {
3807                 if (count++ > XML_PARSER_CHUNK_SIZE) {
3808                     count = 0;
3809                     GROW;
3810                     if (ctxt->instate == XML_PARSER_EOF) {
3811                         xmlFree(buffer);
3812                         return(NULL);
3813                     }
3814                 }
3815                 if (len + 10 > max) {
3816                     xmlChar *tmp;
3817
3818                     if ((max > XML_MAX_NAME_LENGTH) &&
3819                         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3820                         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3821                         xmlFree(buffer);
3822                         return(NULL);
3823                     }
3824                     max *= 2;
3825                     tmp = (xmlChar *) xmlRealloc(buffer,
3826                                                     max * sizeof(xmlChar));
3827                     if (tmp == NULL) {
3828                         xmlErrMemory(ctxt, NULL);
3829                         xmlFree(buffer);
3830                         return(NULL);
3831                     }
3832                     buffer = tmp;
3833                 }
3834                 COPY_BUF(l,buffer,len,c);
3835                 NEXTL(l);
3836                 c = CUR_CHAR(l);
3837             }
3838             buffer[len] = 0;
3839             return(buffer);
3840         }
3841     }
3842     if (len == 0)
3843         return(NULL);
3844     if ((len > XML_MAX_NAME_LENGTH) &&
3845         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3846         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3847         return(NULL);
3848     }
3849     return(xmlStrndup(buf, len));
3850 }
3851
3852 /**
3853  * xmlParseEntityValue:
3854  * @ctxt:  an XML parser context
3855  * @orig:  if non-NULL store a copy of the original entity value
3856  *
3857  * parse a value for ENTITY declarations
3858  *
3859  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
3860  *                     "'" ([^%&'] | PEReference | Reference)* "'"
3861  *
3862  * Returns the EntityValue parsed with reference substituted or NULL
3863  */
3864
3865 xmlChar *
3866 xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
3867     xmlChar *buf = NULL;
3868     int len = 0;
3869     int size = XML_PARSER_BUFFER_SIZE;
3870     int c, l;
3871     xmlChar stop;
3872     xmlChar *ret = NULL;
3873     const xmlChar *cur = NULL;
3874     xmlParserInputPtr input;
3875
3876     if (RAW == '"') stop = '"';
3877     else if (RAW == '\'') stop = '\'';
3878     else {
3879         xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
3880         return(NULL);
3881     }
3882     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3883     if (buf == NULL) {
3884         xmlErrMemory(ctxt, NULL);
3885         return(NULL);
3886     }
3887
3888     /*
3889      * The content of the entity definition is copied in a buffer.
3890      */
3891
3892     ctxt->instate = XML_PARSER_ENTITY_VALUE;
3893     input = ctxt->input;
3894     GROW;
3895     if (ctxt->instate == XML_PARSER_EOF) {
3896         xmlFree(buf);
3897         return(NULL);
3898     }
3899     NEXT;
3900     c = CUR_CHAR(l);
3901     /*
3902      * NOTE: 4.4.5 Included in Literal
3903      * When a parameter entity reference appears in a literal entity
3904      * value, ... a single or double quote character in the replacement
3905      * text is always treated as a normal data character and will not
3906      * terminate the literal.
3907      * In practice it means we stop the loop only when back at parsing
3908      * the initial entity and the quote is found
3909      */
3910     while (((IS_CHAR(c)) && ((c != stop) || /* checked */
3911             (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
3912         if (len + 5 >= size) {
3913             xmlChar *tmp;
3914
3915             size *= 2;
3916             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
3917             if (tmp == NULL) {
3918                 xmlErrMemory(ctxt, NULL);
3919                 xmlFree(buf);
3920                 return(NULL);
3921             }
3922             buf = tmp;
3923         }
3924         COPY_BUF(l,buf,len,c);
3925         NEXTL(l);
3926         /*
3927          * Pop-up of finished entities.
3928          */
3929         while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
3930             xmlPopInput(ctxt);
3931
3932         GROW;
3933         c = CUR_CHAR(l);
3934         if (c == 0) {
3935             GROW;
3936             c = CUR_CHAR(l);
3937         }
3938     }
3939     buf[len] = 0;
3940     if (ctxt->instate == XML_PARSER_EOF) {
3941         xmlFree(buf);
3942         return(NULL);
3943     }
3944
3945     /*
3946      * Raise problem w.r.t. '&' and '%' being used in non-entities
3947      * reference constructs. Note Charref will be handled in
3948      * xmlStringDecodeEntities()
3949      */
3950     cur = buf;
3951     while (*cur != 0) { /* non input consuming */
3952         if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
3953             xmlChar *name;
3954             xmlChar tmp = *cur;
3955
3956             cur++;
3957             name = xmlParseStringName(ctxt, &cur);
3958             if ((name == NULL) || (*cur != ';')) {
3959                 xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
3960             "EntityValue: '%c' forbidden except for entities references\n",
3961                                   tmp);
3962             }
3963             if ((tmp == '%') && (ctxt->inSubset == 1) &&
3964                 (ctxt->inputNr == 1)) {
3965                 xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
3966             }
3967             if (name != NULL)
3968                 xmlFree(name);
3969             if (*cur == 0)
3970                 break;
3971         }
3972         cur++;
3973     }
3974
3975     /*
3976      * Then PEReference entities are substituted.
3977      */
3978     if (c != stop) {
3979         xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
3980         xmlFree(buf);
3981     } else {
3982         NEXT;
3983         /*
3984          * NOTE: 4.4.7 Bypassed
3985          * When a general entity reference appears in the EntityValue in
3986          * an entity declaration, it is bypassed and left as is.
3987          * so XML_SUBSTITUTE_REF is not set here.
3988          */
3989         ++ctxt->depth;
3990         ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
3991                                       0, 0, 0);
3992         --ctxt->depth;
3993         if (orig != NULL)
3994             *orig = buf;
3995         else
3996             xmlFree(buf);
3997     }
3998
3999     return(ret);
4000 }
4001
4002 /**
4003  * xmlParseAttValueComplex:
4004  * @ctxt:  an XML parser context
4005  * @len:   the resulting attribute len
4006  * @normalize:  wether to apply the inner normalization
4007  *
4008  * parse a value for an attribute, this is the fallback function
4009  * of xmlParseAttValue() when the attribute parsing requires handling
4010  * of non-ASCII characters, or normalization compaction.
4011  *
4012  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
4013  */
4014 static xmlChar *
4015 xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
4016     xmlChar limit = 0;
4017     xmlChar *buf = NULL;
4018     xmlChar *rep = NULL;
4019     size_t len = 0;
4020     size_t buf_size = 0;
4021     int c, l, in_space = 0;
4022     xmlChar *current = NULL;
4023     xmlEntityPtr ent;
4024
4025     if (NXT(0) == '"') {
4026         ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
4027         limit = '"';
4028         NEXT;
4029     } else if (NXT(0) == '\'') {
4030         limit = '\'';
4031         ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
4032         NEXT;
4033     } else {
4034         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
4035         return(NULL);
4036     }
4037
4038     /*
4039      * allocate a translation buffer.
4040      */
4041     buf_size = XML_PARSER_BUFFER_SIZE;
4042     buf = (xmlChar *) xmlMallocAtomic(buf_size);
4043     if (buf == NULL) goto mem_error;
4044
4045     /*
4046      * OK loop until we reach one of the ending char or a size limit.
4047      */
4048     c = CUR_CHAR(l);
4049     while (((NXT(0) != limit) && /* checked */
4050             (IS_CHAR(c)) && (c != '<')) &&
4051             (ctxt->instate != XML_PARSER_EOF)) {
4052         /*
4053          * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
4054          * special option is given
4055          */
4056         if ((len > XML_MAX_TEXT_LENGTH) &&
4057             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4058             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4059                            "AttValue length too long\n");
4060             goto mem_error;
4061         }
4062         if (c == 0) break;
4063         if (c == '&') {
4064             in_space = 0;
4065             if (NXT(1) == '#') {
4066                 int val = xmlParseCharRef(ctxt);
4067
4068                 if (val == '&') {
4069                     if (ctxt->replaceEntities) {
4070                         if (len + 10 > buf_size) {
4071                             growBuffer(buf, 10);
4072                         }
4073                         buf[len++] = '&';
4074                     } else {
4075                         /*
4076                          * The reparsing will be done in xmlStringGetNodeList()
4077                          * called by the attribute() function in SAX.c
4078                          */
4079                         if (len + 10 > buf_size) {
4080                             growBuffer(buf, 10);
4081                         }
4082                         buf[len++] = '&';
4083                         buf[len++] = '#';
4084                         buf[len++] = '3';
4085                         buf[len++] = '8';
4086                         buf[len++] = ';';
4087                     }
4088                 } else if (val != 0) {
4089                     if (len + 10 > buf_size) {
4090                         growBuffer(buf, 10);
4091                     }
4092                     len += xmlCopyChar(0, &buf[len], val);
4093                 }
4094             } else {
4095                 ent = xmlParseEntityRef(ctxt);
4096                 ctxt->nbentities++;
4097                 if (ent != NULL)
4098                     ctxt->nbentities += ent->owner;
4099                 if ((ent != NULL) &&
4100                     (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
4101                     if (len + 10 > buf_size) {
4102                         growBuffer(buf, 10);
4103                     }
4104                     if ((ctxt->replaceEntities == 0) &&
4105                         (ent->content[0] == '&')) {
4106                         buf[len++] = '&';
4107                         buf[len++] = '#';
4108                         buf[len++] = '3';
4109                         buf[len++] = '8';
4110                         buf[len++] = ';';
4111                     } else {
4112                         buf[len++] = ent->content[0];
4113                     }
4114                 } else if ((ent != NULL) &&
4115                            (ctxt->replaceEntities != 0)) {
4116                     if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
4117                         ++ctxt->depth;
4118                         rep = xmlStringDecodeEntities(ctxt, ent->content,
4119                                                       XML_SUBSTITUTE_REF,
4120                                                       0, 0, 0);
4121                         --ctxt->depth;
4122                         if (rep != NULL) {
4123                             current = rep;
4124                             while (*current != 0) { /* non input consuming */
4125                                 if ((*current == 0xD) || (*current == 0xA) ||
4126                                     (*current == 0x9)) {
4127                                     buf[len++] = 0x20;
4128                                     current++;
4129                                 } else
4130                                     buf[len++] = *current++;
4131                                 if (len + 10 > buf_size) {
4132                                     growBuffer(buf, 10);
4133                                 }
4134                             }
4135                             xmlFree(rep);
4136                             rep = NULL;
4137                         }
4138                     } else {
4139                         if (len + 10 > buf_size) {
4140                             growBuffer(buf, 10);
4141                         }
4142                         if (ent->content != NULL)
4143                             buf[len++] = ent->content[0];
4144                     }
4145                 } else if (ent != NULL) {
4146                     int i = xmlStrlen(ent->name);
4147                     const xmlChar *cur = ent->name;
4148
4149                     /*
4150                      * This may look absurd but is needed to detect
4151                      * entities problems
4152                      */
4153                     if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
4154                         (ent->content != NULL) && (ent->checked == 0)) {
4155                         unsigned long oldnbent = ctxt->nbentities;
4156
4157                         ++ctxt->depth;
4158                         rep = xmlStringDecodeEntities(ctxt, ent->content,
4159                                                   XML_SUBSTITUTE_REF, 0, 0, 0);
4160                         --ctxt->depth;
4161
4162                         ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
4163                         if (rep != NULL) {
4164                             if (xmlStrchr(rep, '<'))
4165                                 ent->checked |= 1;
4166                             xmlFree(rep);
4167                             rep = NULL;
4168                         }
4169                     }
4170
4171                     /*
4172                      * Just output the reference
4173                      */
4174                     buf[len++] = '&';
4175                     while (len + i + 10 > buf_size) {
4176                         growBuffer(buf, i + 10);
4177                     }
4178                     for (;i > 0;i--)
4179                         buf[len++] = *cur++;
4180                     buf[len++] = ';';
4181                 }
4182             }
4183         } else {
4184             if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
4185                 if ((len != 0) || (!normalize)) {
4186                     if ((!normalize) || (!in_space)) {
4187                         COPY_BUF(l,buf,len,0x20);
4188                         while (len + 10 > buf_size) {
4189                             growBuffer(buf, 10);
4190                         }
4191                     }
4192                     in_space = 1;
4193                 }
4194             } else {
4195                 in_space = 0;
4196                 COPY_BUF(l,buf,len,c);
4197                 if (len + 10 > buf_size) {
4198                     growBuffer(buf, 10);
4199                 }
4200             }
4201             NEXTL(l);
4202         }
4203         GROW;
4204         c = CUR_CHAR(l);
4205     }
4206     if (ctxt->instate == XML_PARSER_EOF)
4207         goto error;
4208
4209     if ((in_space) && (normalize)) {
4210         while ((len > 0) && (buf[len - 1] == 0x20)) len--;
4211     }
4212     buf[len] = 0;
4213     if (RAW == '<') {
4214         xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
4215     } else if (RAW != limit) {
4216         if ((c != 0) && (!IS_CHAR(c))) {
4217             xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
4218                            "invalid character in attribute value\n");
4219         } else {
4220             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4221                            "AttValue: ' expected\n");
4222         }
4223     } else
4224         NEXT;
4225
4226     /*
4227      * There we potentially risk an overflow, don't allow attribute value of
4228      * length more than INT_MAX it is a very reasonnable assumption !
4229      */
4230     if (len >= INT_MAX) {
4231         xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4232                        "AttValue length too long\n");
4233         goto mem_error;
4234     }
4235
4236     if (attlen != NULL) *attlen = (int) len;
4237     return(buf);
4238
4239 mem_error:
4240     xmlErrMemory(ctxt, NULL);
4241 error:
4242     if (buf != NULL)
4243         xmlFree(buf);
4244     if (rep != NULL)
4245         xmlFree(rep);
4246     return(NULL);
4247 }
4248
4249 /**
4250  * xmlParseAttValue:
4251  * @ctxt:  an XML parser context
4252  *
4253  * parse a value for an attribute
4254  * Note: the parser won't do substitution of entities here, this
4255  * will be handled later in xmlStringGetNodeList
4256  *
4257  * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
4258  *                   "'" ([^<&'] | Reference)* "'"
4259  *
4260  * 3.3.3 Attribute-Value Normalization:
4261  * Before the value of an attribute is passed to the application or
4262  * checked for validity, the XML processor must normalize it as follows:
4263  * - a character reference is processed by appending the referenced
4264  *   character to the attribute value
4265  * - an entity reference is processed by recursively processing the
4266  *   replacement text of the entity
4267  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
4268  *   appending #x20 to the normalized value, except that only a single
4269  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
4270  *   parsed entity or the literal entity value of an internal parsed entity
4271  * - other characters are processed by appending them to the normalized value
4272  * If the declared value is not CDATA, then the XML processor must further
4273  * process the normalized attribute value by discarding any leading and
4274  * trailing space (#x20) characters, and by replacing sequences of space
4275  * (#x20) characters by a single space (#x20) character.
4276  * All attributes for which no declaration has been read should be treated
4277  * by a non-validating parser as if declared CDATA.
4278  *
4279  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
4280  */
4281
4282
4283 xmlChar *
4284 xmlParseAttValue(xmlParserCtxtPtr ctxt) {
4285     if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
4286     return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
4287 }
4288
4289 /**
4290  * xmlParseSystemLiteral:
4291  * @ctxt:  an XML parser context
4292  *
4293  * parse an XML Literal
4294  *
4295  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
4296  *
4297  * Returns the SystemLiteral parsed or NULL
4298  */
4299
4300 xmlChar *
4301 xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
4302     xmlChar *buf = NULL;
4303     int len = 0;
4304     int size = XML_PARSER_BUFFER_SIZE;
4305     int cur, l;
4306     xmlChar stop;
4307     int state = ctxt->instate;
4308     int count = 0;
4309
4310     SHRINK;
4311     if (RAW == '"') {
4312         NEXT;
4313         stop = '"';
4314     } else if (RAW == '\'') {
4315         NEXT;
4316         stop = '\'';
4317     } else {
4318         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4319         return(NULL);
4320     }
4321
4322     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4323     if (buf == NULL) {
4324         xmlErrMemory(ctxt, NULL);
4325         return(NULL);
4326     }
4327     ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
4328     cur = CUR_CHAR(l);
4329     while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
4330         if (len + 5 >= size) {
4331             xmlChar *tmp;
4332
4333             if ((size > XML_MAX_NAME_LENGTH) &&
4334                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4335                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
4336                 xmlFree(buf);
4337                 ctxt->instate = (xmlParserInputState) state;
4338                 return(NULL);
4339             }
4340             size *= 2;
4341             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4342             if (tmp == NULL) {
4343                 xmlFree(buf);
4344                 xmlErrMemory(ctxt, NULL);
4345                 ctxt->instate = (xmlParserInputState) state;
4346                 return(NULL);
4347             }
4348             buf = tmp;
4349         }
4350         count++;
4351         if (count > 50) {
4352             GROW;
4353             count = 0;
4354             if (ctxt->instate == XML_PARSER_EOF) {
4355                 xmlFree(buf);
4356                 return(NULL);
4357             }
4358         }
4359         COPY_BUF(l,buf,len,cur);
4360         NEXTL(l);
4361         cur = CUR_CHAR(l);
4362         if (cur == 0) {
4363             GROW;
4364             SHRINK;
4365             cur = CUR_CHAR(l);
4366         }
4367     }
4368     buf[len] = 0;
4369     ctxt->instate = (xmlParserInputState) state;
4370     if (!IS_CHAR(cur)) {
4371         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4372     } else {
4373         NEXT;
4374     }
4375     return(buf);
4376 }
4377
4378 /**
4379  * xmlParsePubidLiteral:
4380  * @ctxt:  an XML parser context
4381  *
4382  * parse an XML public literal
4383  *
4384  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
4385  *
4386  * Returns the PubidLiteral parsed or NULL.
4387  */
4388
4389 xmlChar *
4390 xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
4391     xmlChar *buf = NULL;
4392     int len = 0;
4393     int size = XML_PARSER_BUFFER_SIZE;
4394     xmlChar cur;
4395     xmlChar stop;
4396     int count = 0;
4397     xmlParserInputState oldstate = ctxt->instate;
4398
4399     SHRINK;
4400     if (RAW == '"') {
4401         NEXT;
4402         stop = '"';
4403     } else if (RAW == '\'') {
4404         NEXT;
4405         stop = '\'';
4406     } else {
4407         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4408         return(NULL);
4409     }
4410     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4411     if (buf == NULL) {
4412         xmlErrMemory(ctxt, NULL);
4413         return(NULL);
4414     }
4415     ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
4416     cur = CUR;
4417     while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
4418         if (len + 1 >= size) {
4419             xmlChar *tmp;
4420
4421             if ((size > XML_MAX_NAME_LENGTH) &&
4422                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4423                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
4424                 xmlFree(buf);
4425                 return(NULL);
4426             }
4427             size *= 2;
4428             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4429             if (tmp == NULL) {
4430                 xmlErrMemory(ctxt, NULL);
4431                 xmlFree(buf);
4432                 return(NULL);
4433             }
4434             buf = tmp;
4435         }
4436         buf[len++] = cur;
4437         count++;
4438         if (count > 50) {
4439             GROW;
4440             count = 0;
4441             if (ctxt->instate == XML_PARSER_EOF) {
4442                 xmlFree(buf);
4443                 return(NULL);
4444             }
4445         }
4446         NEXT;
4447         cur = CUR;
4448         if (cur == 0) {
4449             GROW;
4450             SHRINK;
4451             cur = CUR;
4452         }
4453     }
4454     buf[len] = 0;
4455     if (cur != stop) {
4456         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4457     } else {
4458         NEXT;
4459     }
4460     ctxt->instate = oldstate;
4461     return(buf);
4462 }
4463
4464 static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
4465
4466 /*
4467  * used for the test in the inner loop of the char data testing
4468  */
4469 static const unsigned char test_char_data[256] = {
4470     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4471     0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
4472     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4473     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4474     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
4475     0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
4476     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
4477     0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
4478     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
4479     0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
4480     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
4481     0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
4482     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
4483     0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
4484     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
4485     0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
4486     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
4487     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4488     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4489     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4490     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4491     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4492     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4493     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4494     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4495     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4496     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4497     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4498     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4499     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4500     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4501     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4502 };
4503
4504 /**
4505  * xmlParseCharData:
4506  * @ctxt:  an XML parser context
4507  * @cdata:  int indicating whether we are within a CDATA section
4508  *
4509  * parse a CharData section.
4510  * if we are within a CDATA section ']]>' marks an end of section.
4511  *
4512  * The right angle bracket (>) may be represented using the string "&gt;",
4513  * and must, for compatibility, be escaped using "&gt;" or a character
4514  * reference when it appears in the string "]]>" in content, when that
4515  * string is not marking the end of a CDATA section.
4516  *
4517  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
4518  */
4519
4520 void
4521 xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
4522     const xmlChar *in;
4523     int nbchar = 0;
4524     int line = ctxt->input->line;
4525     int col = ctxt->input->col;
4526     int ccol;
4527
4528     SHRINK;
4529     GROW;
4530     /*
4531      * Accelerated common case where input don't need to be
4532      * modified before passing it to the handler.
4533      */
4534     if (!cdata) {
4535         in = ctxt->input->cur;
4536         do {
4537 get_more_space:
4538             while (*in == 0x20) { in++; ctxt->input->col++; }
4539             if (*in == 0xA) {
4540                 do {
4541                     ctxt->input->line++; ctxt->input->col = 1;
4542                     in++;
4543                 } while (*in == 0xA);
4544                 goto get_more_space;
4545             }
4546             if (*in == '<') {
4547                 nbchar = in - ctxt->input->cur;
4548                 if (nbchar > 0) {
4549                     const xmlChar *tmp = ctxt->input->cur;
4550                     ctxt->input->cur = in;
4551
4552                     if ((ctxt->sax != NULL) &&
4553                         (ctxt->sax->ignorableWhitespace !=
4554                          ctxt->sax->characters)) {
4555                         if (areBlanks(ctxt, tmp, nbchar, 1)) {
4556                             if (ctxt->sax->ignorableWhitespace != NULL)
4557                                 ctxt->sax->ignorableWhitespace(ctxt->userData,
4558                                                        tmp, nbchar);
4559                         } else {
4560                             if (ctxt->sax->characters != NULL)
4561                                 ctxt->sax->characters(ctxt->userData,
4562                                                       tmp, nbchar);
4563                             if (*ctxt->space == -1)
4564                                 *ctxt->space = -2;
4565                         }
4566                     } else if ((ctxt->sax != NULL) &&
4567                                (ctxt->sax->characters != NULL)) {
4568                         ctxt->sax->characters(ctxt->userData,
4569                                               tmp, nbchar);
4570                     }
4571                 }
4572                 return;
4573             }
4574
4575 get_more:
4576             ccol = ctxt->input->col;
4577             while (test_char_data[*in]) {
4578                 in++;
4579                 ccol++;
4580             }
4581             ctxt->input->col = ccol;
4582             if (*in == 0xA) {
4583                 do {
4584                     ctxt->input->line++; ctxt->input->col = 1;
4585                     in++;
4586                 } while (*in == 0xA);
4587                 goto get_more;
4588             }
4589             if (*in == ']') {
4590                 if ((in[1] == ']') && (in[2] == '>')) {
4591                     xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4592                     ctxt->input->cur = in;
4593                     return;
4594                 }
4595                 in++;
4596                 ctxt->input->col++;
4597                 goto get_more;
4598             }
4599             nbchar = in - ctxt->input->cur;
4600             if (nbchar > 0) {
4601                 if ((ctxt->sax != NULL) &&
4602                     (ctxt->sax->ignorableWhitespace !=
4603                      ctxt->sax->characters) &&
4604                     (IS_BLANK_CH(*ctxt->input->cur))) {
4605                     const xmlChar *tmp = ctxt->input->cur;
4606                     ctxt->input->cur = in;
4607
4608                     if (areBlanks(ctxt, tmp, nbchar, 0)) {
4609                         if (ctxt->sax->ignorableWhitespace != NULL)
4610                             ctxt->sax->ignorableWhitespace(ctxt->userData,
4611                                                            tmp, nbchar);
4612                     } else {
4613                         if (ctxt->sax->characters != NULL)
4614                             ctxt->sax->characters(ctxt->userData,
4615                                                   tmp, nbchar);
4616                         if (*ctxt->space == -1)
4617                             *ctxt->space = -2;
4618                     }
4619                     line = ctxt->input->line;
4620                     col = ctxt->input->col;
4621                 } else if (ctxt->sax != NULL) {
4622                     if (ctxt->sax->characters != NULL)
4623                         ctxt->sax->characters(ctxt->userData,
4624                                               ctxt->input->cur, nbchar);
4625                     line = ctxt->input->line;
4626                     col = ctxt->input->col;
4627                 }
4628                 /* something really bad happened in the SAX callback */
4629                 if (ctxt->instate != XML_PARSER_CONTENT)
4630                     return;
4631             }
4632             ctxt->input->cur = in;
4633             if (*in == 0xD) {
4634                 in++;
4635                 if (*in == 0xA) {
4636                     ctxt->input->cur = in;
4637                     in++;
4638                     ctxt->input->line++; ctxt->input->col = 1;
4639                     continue; /* while */
4640                 }
4641                 in--;
4642             }
4643             if (*in == '<') {
4644                 return;
4645             }
4646             if (*in == '&') {
4647                 return;
4648             }
4649             SHRINK;
4650             GROW;
4651             if (ctxt->instate == XML_PARSER_EOF)
4652                 return;
4653             in = ctxt->input->cur;
4654         } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
4655         nbchar = 0;
4656     }
4657     ctxt->input->line = line;
4658     ctxt->input->col = col;
4659     xmlParseCharDataComplex(ctxt, cdata);
4660 }
4661
4662 /**
4663  * xmlParseCharDataComplex:
4664  * @ctxt:  an XML parser context
4665  * @cdata:  int indicating whether we are within a CDATA section
4666  *
4667  * parse a CharData section.this is the fallback function
4668  * of xmlParseCharData() when the parsing requires handling
4669  * of non-ASCII characters.
4670  */
4671 static void
4672 xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
4673     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
4674     int nbchar = 0;
4675     int cur, l;
4676     int count = 0;
4677
4678     SHRINK;
4679     GROW;
4680     cur = CUR_CHAR(l);
4681     while ((cur != '<') && /* checked */
4682            (cur != '&') &&
4683            (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
4684         if ((cur == ']') && (NXT(1) == ']') &&
4685             (NXT(2) == '>')) {
4686             if (cdata) break;
4687             else {
4688                 xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4689             }
4690         }
4691         COPY_BUF(l,buf,nbchar,cur);
4692         if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
4693             buf[nbchar] = 0;
4694
4695             /*
4696              * OK the segment is to be consumed as chars.
4697              */
4698             if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4699                 if (areBlanks(ctxt, buf, nbchar, 0)) {
4700                     if (ctxt->sax->ignorableWhitespace != NULL)
4701                         ctxt->sax->ignorableWhitespace(ctxt->userData,
4702                                                        buf, nbchar);
4703                 } else {
4704                     if (ctxt->sax->characters != NULL)
4705                         ctxt->sax->characters(ctxt->userData, buf, nbchar);
4706                     if ((ctxt->sax->characters !=
4707                          ctxt->sax->ignorableWhitespace) &&
4708                         (*ctxt->space == -1))
4709                         *ctxt->space = -2;
4710                 }
4711             }
4712             nbchar = 0;
4713             /* something really bad happened in the SAX callback */
4714             if (ctxt->instate != XML_PARSER_CONTENT)
4715                 return;
4716         }
4717         count++;
4718         if (count > 50) {
4719             GROW;
4720             count = 0;
4721             if (ctxt->instate == XML_PARSER_EOF)
4722                 return;
4723         }
4724         NEXTL(l);
4725         cur = CUR_CHAR(l);
4726     }
4727     if (nbchar != 0) {
4728         buf[nbchar] = 0;
4729         /*
4730          * OK the segment is to be consumed as chars.
4731          */
4732         if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4733             if (areBlanks(ctxt, buf, nbchar, 0)) {
4734                 if (ctxt->sax->ignorableWhitespace != NULL)
4735                     ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
4736             } else {
4737                 if (ctxt->sax->characters != NULL)
4738                     ctxt->sax->characters(ctxt->userData, buf, nbchar);
4739                 if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
4740                     (*ctxt->space == -1))
4741                     *ctxt->space = -2;
4742             }
4743         }
4744     }
4745     if ((cur != 0) && (!IS_CHAR(cur))) {
4746         /* Generate the error and skip the offending character */
4747         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4748                           "PCDATA invalid Char value %d\n",
4749                           cur);
4750         NEXTL(l);
4751     }
4752 }
4753
4754 /**
4755  * xmlParseExternalID:
4756  * @ctxt:  an XML parser context
4757  * @publicID:  a xmlChar** receiving PubidLiteral
4758  * @strict: indicate whether we should restrict parsing to only
4759  *          production [75], see NOTE below
4760  *
4761  * Parse an External ID or a Public ID
4762  *
4763  * NOTE: Productions [75] and [83] interact badly since [75] can generate
4764  *       'PUBLIC' S PubidLiteral S SystemLiteral
4765  *
4766  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
4767  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
4768  *
4769  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
4770  *
4771  * Returns the function returns SystemLiteral and in the second
4772  *                case publicID receives PubidLiteral, is strict is off
4773  *                it is possible to return NULL and have publicID set.
4774  */
4775
4776 xmlChar *
4777 xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
4778     xmlChar *URI = NULL;
4779
4780     SHRINK;
4781
4782     *publicID = NULL;
4783     if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
4784         SKIP(6);
4785         if (!IS_BLANK_CH(CUR)) {
4786             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4787                            "Space required after 'SYSTEM'\n");
4788         }
4789         SKIP_BLANKS;
4790         URI = xmlParseSystemLiteral(ctxt);
4791         if (URI == NULL) {
4792             xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4793         }
4794     } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
4795         SKIP(6);
4796         if (!IS_BLANK_CH(CUR)) {
4797             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4798                     "Space required after 'PUBLIC'\n");
4799         }
4800         SKIP_BLANKS;
4801         *publicID = xmlParsePubidLiteral(ctxt);
4802         if (*publicID == NULL) {
4803             xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
4804         }
4805         if (strict) {
4806             /*
4807              * We don't handle [83] so "S SystemLiteral" is required.
4808              */
4809             if (!IS_BLANK_CH(CUR)) {
4810                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4811                         "Space required after the Public Identifier\n");
4812             }
4813         } else {
4814             /*
4815              * We handle [83] so we return immediately, if
4816              * "S SystemLiteral" is not detected. From a purely parsing
4817              * point of view that's a nice mess.
4818              */
4819             const xmlChar *ptr;
4820             GROW;
4821
4822             ptr = CUR_PTR;
4823             if (!IS_BLANK_CH(*ptr)) return(NULL);
4824
4825             while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
4826             if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
4827         }
4828         SKIP_BLANKS;
4829         URI = xmlParseSystemLiteral(ctxt);
4830         if (URI == NULL) {
4831             xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4832         }
4833     }
4834     return(URI);
4835 }
4836
4837 /**
4838  * xmlParseCommentComplex:
4839  * @ctxt:  an XML parser context
4840  * @buf:  the already parsed part of the buffer
4841  * @len:  number of bytes filles in the buffer
4842  * @size:  allocated size of the buffer
4843  *
4844  * Skip an XML (SGML) comment <!-- .... -->
4845  *  The spec says that "For compatibility, the string "--" (double-hyphen)
4846  *  must not occur within comments. "
4847  * This is the slow routine in case the accelerator for ascii didn't work
4848  *
4849  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4850  */
4851 static void
4852 xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
4853                        size_t len, size_t size) {
4854     int q, ql;
4855     int r, rl;
4856     int cur, l;
4857     size_t count = 0;
4858     int inputid;
4859
4860     inputid = ctxt->input->id;
4861
4862     if (buf == NULL) {
4863         len = 0;
4864         size = XML_PARSER_BUFFER_SIZE;
4865         buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4866         if (buf == NULL) {
4867             xmlErrMemory(ctxt, NULL);
4868             return;
4869         }
4870     }
4871     GROW;       /* Assure there's enough input data */
4872     q = CUR_CHAR(ql);
4873     if (q == 0)
4874         goto not_terminated;
4875     if (!IS_CHAR(q)) {
4876         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4877                           "xmlParseComment: invalid xmlChar value %d\n",
4878                           q);
4879         xmlFree (buf);
4880         return;
4881     }
4882     NEXTL(ql);
4883     r = CUR_CHAR(rl);
4884     if (r == 0)
4885         goto not_terminated;
4886     if (!IS_CHAR(r)) {
4887         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4888                           "xmlParseComment: invalid xmlChar value %d\n",
4889                           q);
4890         xmlFree (buf);
4891         return;
4892     }
4893     NEXTL(rl);
4894     cur = CUR_CHAR(l);
4895     if (cur == 0)
4896         goto not_terminated;
4897     while (IS_CHAR(cur) && /* checked */
4898            ((cur != '>') ||
4899             (r != '-') || (q != '-'))) {
4900         if ((r == '-') && (q == '-')) {
4901             xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
4902         }
4903         if ((len > XML_MAX_TEXT_LENGTH) &&
4904             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4905             xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4906                          "Comment too big found", NULL);
4907             xmlFree (buf);
4908             return;
4909         }
4910         if (len + 5 >= size) {
4911             xmlChar *new_buf;
4912             size_t new_size;
4913
4914             new_size = size * 2;
4915             new_buf = (xmlChar *) xmlRealloc(buf, new_size);
4916             if (new_buf == NULL) {
4917                 xmlFree (buf);
4918                 xmlErrMemory(ctxt, NULL);
4919                 return;
4920             }
4921             buf = new_buf;
4922             size = new_size;
4923         }
4924         COPY_BUF(ql,buf,len,q);
4925         q = r;
4926         ql = rl;
4927         r = cur;
4928         rl = l;
4929
4930         count++;
4931         if (count > 50) {
4932             GROW;
4933             count = 0;
4934             if (ctxt->instate == XML_PARSER_EOF) {
4935                 xmlFree(buf);
4936                 return;
4937             }
4938         }
4939         NEXTL(l);
4940         cur = CUR_CHAR(l);
4941         if (cur == 0) {
4942             SHRINK;
4943             GROW;
4944             cur = CUR_CHAR(l);
4945         }
4946     }
4947     buf[len] = 0;
4948     if (cur == 0) {
4949         xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4950                              "Comment not terminated \n<!--%.50s\n", buf);
4951     } else if (!IS_CHAR(cur)) {
4952         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4953                           "xmlParseComment: invalid xmlChar value %d\n",
4954                           cur);
4955     } else {
4956         if (inputid != ctxt->input->id) {
4957             xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4958                 "Comment doesn't start and stop in the same entity\n");
4959         }
4960         NEXT;
4961         if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4962             (!ctxt->disableSAX))
4963             ctxt->sax->comment(ctxt->userData, buf);
4964     }
4965     xmlFree(buf);
4966     return;
4967 not_terminated:
4968     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4969                          "Comment not terminated\n", NULL);
4970     xmlFree(buf);
4971     return;
4972 }
4973
4974 /**
4975  * xmlParseComment:
4976  * @ctxt:  an XML parser context
4977  *
4978  * Skip an XML (SGML) comment <!-- .... -->
4979  *  The spec says that "For compatibility, the string "--" (double-hyphen)
4980  *  must not occur within comments. "
4981  *
4982  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4983  */
4984 void
4985 xmlParseComment(xmlParserCtxtPtr ctxt) {
4986     xmlChar *buf = NULL;
4987     size_t size = XML_PARSER_BUFFER_SIZE;
4988     size_t len = 0;
4989     xmlParserInputState state;
4990     const xmlChar *in;
4991     size_t nbchar = 0;
4992     int ccol;
4993     int inputid;
4994
4995     /*
4996      * Check that there is a comment right here.
4997      */
4998     if ((RAW != '<') || (NXT(1) != '!') ||
4999         (NXT(2) != '-') || (NXT(3) != '-')) return;
5000     state = ctxt->instate;
5001     ctxt->instate = XML_PARSER_COMMENT;
5002     inputid = ctxt->input->id;
5003     SKIP(4);
5004     SHRINK;
5005     GROW;
5006
5007     /*
5008      * Accelerated common case where input don't need to be
5009      * modified before passing it to the handler.
5010      */
5011     in = ctxt->input->cur;
5012     do {
5013         if (*in == 0xA) {
5014             do {
5015                 ctxt->input->line++; ctxt->input->col = 1;
5016                 in++;
5017             } while (*in == 0xA);
5018         }
5019 get_more:
5020         ccol = ctxt->input->col;
5021         while (((*in > '-') && (*in <= 0x7F)) ||
5022                ((*in >= 0x20) && (*in < '-')) ||
5023                (*in == 0x09)) {
5024                     in++;
5025                     ccol++;
5026         }
5027         ctxt->input->col = ccol;
5028         if (*in == 0xA) {
5029             do {
5030                 ctxt->input->line++; ctxt->input->col = 1;
5031                 in++;
5032             } while (*in == 0xA);
5033             goto get_more;
5034         }
5035         nbchar = in - ctxt->input->cur;
5036         /*
5037          * save current set of data
5038          */
5039         if (nbchar > 0) {
5040             if ((ctxt->sax != NULL) &&
5041                 (ctxt->sax->comment != NULL)) {
5042                 if (buf == NULL) {
5043                     if ((*in == '-') && (in[1] == '-'))
5044                         size = nbchar + 1;
5045                     else
5046                         size = XML_PARSER_BUFFER_SIZE + nbchar;
5047                     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
5048                     if (buf == NULL) {
5049                         xmlErrMemory(ctxt, NULL);
5050                         ctxt->instate = state;
5051                         return;
5052                     }
5053                     len = 0;
5054                 } else if (len + nbchar + 1 >= size) {
5055                     xmlChar *new_buf;
5056                     size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
5057                     new_buf = (xmlChar *) xmlRealloc(buf,
5058                                                      size * sizeof(xmlChar));
5059                     if (new_buf == NULL) {
5060                         xmlFree (buf);
5061                         xmlErrMemory(ctxt, NULL);
5062                         ctxt->instate = state;
5063                         return;
5064                     }
5065                     buf = new_buf;
5066                 }
5067                 memcpy(&buf[len], ctxt->input->cur, nbchar);
5068                 len += nbchar;
5069                 buf[len] = 0;
5070             }
5071         }
5072         if ((len > XML_MAX_TEXT_LENGTH) &&
5073             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
5074             xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
5075                          "Comment too big found", NULL);
5076             xmlFree (buf);
5077             return;
5078         }
5079         ctxt->input->cur = in;
5080         if (*in == 0xA) {
5081             in++;
5082             ctxt->input->line++; ctxt->input->col = 1;
5083         }
5084         if (*in == 0xD) {
5085             in++;
5086             if (*in == 0xA) {
5087                 ctxt->input->cur = in;
5088                 in++;
5089                 ctxt->input->line++; ctxt->input->col = 1;
5090                 continue; /* while */
5091             }
5092             in--;
5093         }
5094         SHRINK;
5095         GROW;
5096         if (ctxt->instate == XML_PARSER_EOF) {
5097             xmlFree(buf);
5098             return;
5099         }
5100         in = ctxt->input->cur;
5101         if (*in == '-') {
5102             if (in[1] == '-') {
5103                 if (in[2] == '>') {
5104                     if (ctxt->input->id != inputid) {
5105                         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5106                         "comment doesn't start and stop in the same entity\n");
5107                     }
5108                     SKIP(3);
5109                     if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
5110                         (!ctxt->disableSAX)) {
5111                         if (buf != NULL)
5112                             ctxt->sax->comment(ctxt->userData, buf);
5113                         else
5114                             ctxt->sax->comment(ctxt->userData, BAD_CAST "");
5115                     }
5116                     if (buf != NULL)
5117                         xmlFree(buf);
5118                     if (ctxt->instate != XML_PARSER_EOF)
5119                         ctxt->instate = state;
5120                     return;
5121                 }
5122                 if (buf != NULL) {
5123                     xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
5124                                       "Double hyphen within comment: "
5125                                       "<!--%.50s\n",
5126                                       buf);
5127                 } else
5128                     xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
5129                                       "Double hyphen within comment\n", NULL);
5130                 in++;
5131                 ctxt->input->col++;
5132             }
5133             in++;
5134             ctxt->input->col++;
5135             goto get_more;
5136         }
5137     } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
5138     xmlParseCommentComplex(ctxt, buf, len, size);
5139     ctxt->instate = state;
5140     return;
5141 }
5142
5143
5144 /**
5145  * xmlParsePITarget:
5146  * @ctxt:  an XML parser context
5147  *
5148  * parse the name of a PI
5149  *
5150  * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
5151  *
5152  * Returns the PITarget name or NULL
5153  */
5154
5155 const xmlChar *
5156 xmlParsePITarget(xmlParserCtxtPtr ctxt) {
5157     const xmlChar *name;
5158
5159     name = xmlParseName(ctxt);
5160     if ((name != NULL) &&
5161         ((name[0] == 'x') || (name[0] == 'X')) &&
5162         ((name[1] == 'm') || (name[1] == 'M')) &&
5163         ((name[2] == 'l') || (name[2] == 'L'))) {
5164         int i;
5165         if ((name[0] == 'x') && (name[1] == 'm') &&
5166             (name[2] == 'l') && (name[3] == 0)) {
5167             xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5168                  "XML declaration allowed only at the start of the document\n");
5169             return(name);
5170         } else if (name[3] == 0) {
5171             xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
5172             return(name);
5173         }
5174         for (i = 0;;i++) {
5175             if (xmlW3CPIs[i] == NULL) break;
5176             if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
5177                 return(name);
5178         }
5179         xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5180                       "xmlParsePITarget: invalid name prefix 'xml'\n",
5181                       NULL, NULL);
5182     }
5183     if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
5184         xmlNsErr(ctxt, XML_NS_ERR_COLON,
5185                  "colons are forbidden from PI names '%s'\n", name, NULL, NULL);
5186     }
5187     return(name);
5188 }
5189
5190 #ifdef LIBXML_CATALOG_ENABLED
5191 /**
5192  * xmlParseCatalogPI:
5193  * @ctxt:  an XML parser context
5194  * @catalog:  the PI value string
5195  *
5196  * parse an XML Catalog Processing Instruction.
5197  *
5198  * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
5199  *
5200  * Occurs only if allowed by the user and if happening in the Misc
5201  * part of the document before any doctype informations
5202  * This will add the given catalog to the parsing context in order
5203  * to be used if there is a resolution need further down in the document
5204  */
5205
5206 static void
5207 xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
5208     xmlChar *URL = NULL;
5209     const xmlChar *tmp, *base;
5210     xmlChar marker;
5211
5212     tmp = catalog;
5213     while (IS_BLANK_CH(*tmp)) tmp++;
5214     if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
5215         goto error;
5216     tmp += 7;
5217     while (IS_BLANK_CH(*tmp)) tmp++;
5218     if (*tmp != '=') {
5219         return;
5220     }
5221     tmp++;
5222     while (IS_BLANK_CH(*tmp)) tmp++;
5223     marker = *tmp;
5224     if ((marker != '\'') && (marker != '"'))
5225         goto error;
5226     tmp++;
5227     base = tmp;
5228     while ((*tmp != 0) && (*tmp != marker)) tmp++;
5229     if (*tmp == 0)
5230         goto error;
5231     URL = xmlStrndup(base, tmp - base);
5232     tmp++;
5233     while (IS_BLANK_CH(*tmp)) tmp++;
5234     if (*tmp != 0)
5235         goto error;
5236
5237     if (URL != NULL) {
5238         ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
5239         xmlFree(URL);
5240     }
5241     return;
5242
5243 error:
5244     xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
5245                   "Catalog PI syntax error: %s\n",
5246                   catalog, NULL);
5247     if (URL != NULL)
5248         xmlFree(URL);
5249 }
5250 #endif
5251
5252 /**
5253  * xmlParsePI:
5254  * @ctxt:  an XML parser context
5255  *
5256  * parse an XML Processing Instruction.
5257  *
5258  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
5259  *
5260  * The processing is transfered to SAX once parsed.
5261  */
5262
5263 void
5264 xmlParsePI(xmlParserCtxtPtr ctxt) {
5265     xmlChar *buf = NULL;
5266     size_t len = 0;
5267     size_t size = XML_PARSER_BUFFER_SIZE;
5268     int cur, l;
5269     const xmlChar *target;
5270     xmlParserInputState state;
5271     int count = 0;
5272
5273     if ((RAW == '<') && (NXT(1) == '?')) {
5274         xmlParserInputPtr input = ctxt->input;
5275         state = ctxt->instate;
5276         ctxt->instate = XML_PARSER_PI;
5277         /*
5278          * this is a Processing Instruction.
5279          */
5280         SKIP(2);
5281         SHRINK;
5282
5283         /*
5284          * Parse the target name and check for special support like
5285          * namespace.
5286          */
5287         target = xmlParsePITarget(ctxt);
5288         if (target != NULL) {
5289             if ((RAW == '?') && (NXT(1) == '>')) {
5290                 if (input != ctxt->input) {
5291                     xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5292             "PI declaration doesn't start and stop in the same entity\n");
5293                 }
5294                 SKIP(2);
5295
5296                 /*
5297                  * SAX: PI detected.
5298                  */
5299                 if ((ctxt->sax) && (!ctxt->disableSAX) &&
5300                     (ctxt->sax->processingInstruction != NULL))
5301                     ctxt->sax->processingInstruction(ctxt->userData,
5302                                                      target, NULL);
5303                 if (ctxt->instate != XML_PARSER_EOF)
5304                     ctxt->instate = state;
5305                 return;
5306             }
5307             buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
5308             if (buf == NULL) {
5309                 xmlErrMemory(ctxt, NULL);
5310                 ctxt->instate = state;
5311                 return;
5312             }
5313             cur = CUR;
5314             if (!IS_BLANK(cur)) {
5315                 xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
5316                           "ParsePI: PI %s space expected\n", target);
5317             }
5318             SKIP_BLANKS;
5319             cur = CUR_CHAR(l);
5320             while (IS_CHAR(cur) && /* checked */
5321                    ((cur != '?') || (NXT(1) != '>'))) {
5322                 if (len + 5 >= size) {
5323                     xmlChar *tmp;
5324                     size_t new_size = size * 2;
5325                     tmp = (xmlChar *) xmlRealloc(buf, new_size);
5326                     if (tmp == NULL) {
5327                         xmlErrMemory(ctxt, NULL);
5328                         xmlFree(buf);
5329                         ctxt->instate = state;
5330                         return;
5331                     }
5332                     buf = tmp;
5333                     size = new_size;
5334                 }
5335                 count++;
5336                 if (count > 50) {
5337                     GROW;
5338                     if (ctxt->instate == XML_PARSER_EOF) {
5339                         xmlFree(buf);
5340                         return;
5341                     }
5342                     count = 0;
5343                     if ((len > XML_MAX_TEXT_LENGTH) &&
5344                         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
5345                         xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5346                                           "PI %s too big found", target);
5347                         xmlFree(buf);
5348                         ctxt->instate = state;
5349                         return;
5350                     }
5351                 }
5352                 COPY_BUF(l,buf,len,cur);
5353                 NEXTL(l);
5354                 cur = CUR_CHAR(l);
5355                 if (cur == 0) {
5356                     SHRINK;
5357                     GROW;
5358                     cur = CUR_CHAR(l);
5359                 }
5360             }
5361             if ((len > XML_MAX_TEXT_LENGTH) &&
5362                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
5363                 xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5364                                   "PI %s too big found", target);
5365                 xmlFree(buf);
5366                 ctxt->instate = state;
5367                 return;
5368             }
5369             buf[len] = 0;
5370             if (cur != '?') {
5371                 xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5372                       "ParsePI: PI %s never end ...\n", target);
5373             } else {
5374                 if (input != ctxt->input) {
5375                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5376             "PI declaration doesn't start and stop in the same entity\n");
5377                 }
5378                 SKIP(2);
5379
5380 #ifdef LIBXML_CATALOG_ENABLED
5381                 if (((state == XML_PARSER_MISC) ||
5382                      (state == XML_PARSER_START)) &&
5383                     (xmlStrEqual(target, XML_CATALOG_PI))) {
5384                     xmlCatalogAllow allow = xmlCatalogGetDefaults();
5385                     if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
5386                         (allow == XML_CATA_ALLOW_ALL))
5387                         xmlParseCatalogPI(ctxt, buf);
5388                 }
5389 #endif
5390
5391
5392                 /*
5393                  * SAX: PI detected.
5394                  */
5395                 if ((ctxt->sax) && (!ctxt->disableSAX) &&
5396                     (ctxt->sax->processingInstruction != NULL))
5397                     ctxt->sax->processingInstruction(ctxt->userData,
5398                                                      target, buf);
5399             }
5400             xmlFree(buf);
5401         } else {
5402             xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
5403         }
5404         if (ctxt->instate != XML_PARSER_EOF)
5405             ctxt->instate = state;
5406     }
5407 }
5408
5409 /**
5410  * xmlParseNotationDecl:
5411  * @ctxt:  an XML parser context
5412  *
5413  * parse a notation declaration
5414  *
5415  * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
5416  *
5417  * Hence there is actually 3 choices:
5418  *     'PUBLIC' S PubidLiteral
5419  *     'PUBLIC' S PubidLiteral S SystemLiteral
5420  * and 'SYSTEM' S SystemLiteral
5421  *
5422  * See the NOTE on xmlParseExternalID().
5423  */
5424
5425 void
5426 xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
5427     const xmlChar *name;
5428     xmlChar *Pubid;
5429     xmlChar *Systemid;
5430
5431     if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5432         xmlParserInputPtr input = ctxt->input;
5433         SHRINK;
5434         SKIP(10);
5435         if (!IS_BLANK_CH(CUR)) {
5436             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5437                            "Space required after '<!NOTATION'\n");
5438             return;
5439         }
5440         SKIP_BLANKS;
5441
5442         name = xmlParseName(ctxt);
5443         if (name == NULL) {
5444             xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5445             return;
5446         }
5447         if (!IS_BLANK_CH(CUR)) {
5448             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5449                      "Space required after the NOTATION name'\n");
5450             return;
5451         }
5452         if (xmlStrchr(name, ':') != NULL) {
5453             xmlNsErr(ctxt, XML_NS_ERR_COLON,
5454                      "colons are forbidden from notation names '%s'\n",
5455                      name, NULL, NULL);
5456         }
5457         SKIP_BLANKS;
5458
5459         /*
5460          * Parse the IDs.
5461          */
5462         Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
5463         SKIP_BLANKS;
5464
5465         if (RAW == '>') {
5466             if (input != ctxt->input) {
5467                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5468         "Notation declaration doesn't start and stop in the same entity\n");
5469             }
5470             NEXT;
5471             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5472                 (ctxt->sax->notationDecl != NULL))
5473                 ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
5474         } else {
5475             xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5476         }
5477         if (Systemid != NULL) xmlFree(Systemid);
5478         if (Pubid != NULL) xmlFree(Pubid);
5479     }
5480 }
5481
5482 /**
5483  * xmlParseEntityDecl:
5484  * @ctxt:  an XML parser context
5485  *
5486  * parse <!ENTITY declarations
5487  *
5488  * [70] EntityDecl ::= GEDecl | PEDecl
5489  *
5490  * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
5491  *
5492  * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
5493  *
5494  * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
5495  *
5496  * [74] PEDef ::= EntityValue | ExternalID
5497  *
5498  * [76] NDataDecl ::= S 'NDATA' S Name
5499  *
5500  * [ VC: Notation Declared ]
5501  * The Name must match the declared name of a notation.
5502  */
5503
5504 void
5505 xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
5506     const xmlChar *name = NULL;
5507     xmlChar *value = NULL;
5508     xmlChar *URI = NULL, *literal = NULL;
5509     const xmlChar *ndata = NULL;
5510     int isParameter = 0;
5511     xmlChar *orig = NULL;
5512     int skipped;
5513
5514     /* GROW; done in the caller */
5515     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
5516         xmlParserInputPtr input = ctxt->input;
5517         SHRINK;
5518         SKIP(8);
5519         skipped = SKIP_BLANKS;
5520         if (skipped == 0) {
5521             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5522                            "Space required after '<!ENTITY'\n");
5523         }
5524
5525         if (RAW == '%') {
5526             NEXT;
5527             skipped = SKIP_BLANKS;
5528             if (skipped == 0) {
5529                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5530                                "Space required after '%%'\n");
5531             }
5532             isParameter = 1;
5533         }
5534
5535         name = xmlParseName(ctxt);
5536         if (name == NULL) {
5537             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5538                            "xmlParseEntityDecl: no name\n");
5539             return;
5540         }
5541         if (xmlStrchr(name, ':') != NULL) {
5542             xmlNsErr(ctxt, XML_NS_ERR_COLON,
5543                      "colons are forbidden from entities names '%s'\n",
5544                      name, NULL, NULL);
5545         }
5546         skipped = SKIP_BLANKS;
5547         if (skipped == 0) {
5548             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5549                            "Space required after the entity name\n");
5550         }
5551
5552         ctxt->instate = XML_PARSER_ENTITY_DECL;
5553         /*
5554          * handle the various case of definitions...
5555          */
5556         if (isParameter) {
5557             if ((RAW == '"') || (RAW == '\'')) {
5558                 value = xmlParseEntityValue(ctxt, &orig);
5559                 if (value) {
5560                     if ((ctxt->sax != NULL) &&
5561                         (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5562                         ctxt->sax->entityDecl(ctxt->userData, name,
5563                                     XML_INTERNAL_PARAMETER_ENTITY,
5564                                     NULL, NULL, value);
5565                 }
5566             } else {
5567                 URI = xmlParseExternalID(ctxt, &literal, 1);
5568                 if ((URI == NULL) && (literal == NULL)) {
5569                     xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5570                 }
5571                 if (URI) {
5572                     xmlURIPtr uri;
5573
5574                     uri = xmlParseURI((const char *) URI);
5575                     if (uri == NULL) {
5576                         xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5577                                      "Invalid URI: %s\n", URI);
5578                         /*
5579                          * This really ought to be a well formedness error
5580                          * but the XML Core WG decided otherwise c.f. issue
5581                          * E26 of the XML erratas.
5582                          */
5583                     } else {
5584                         if (uri->fragment != NULL) {
5585                             /*
5586                              * Okay this is foolish to block those but not
5587                              * invalid URIs.
5588                              */
5589                             xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5590                         } else {
5591                             if ((ctxt->sax != NULL) &&
5592                                 (!ctxt->disableSAX) &&
5593                                 (ctxt->sax->entityDecl != NULL))
5594                                 ctxt->sax->entityDecl(ctxt->userData, name,
5595                                             XML_EXTERNAL_PARAMETER_ENTITY,
5596                                             literal, URI, NULL);
5597                         }
5598                         xmlFreeURI(uri);
5599                     }
5600                 }
5601             }
5602         } else {
5603             if ((RAW == '"') || (RAW == '\'')) {
5604                 value = xmlParseEntityValue(ctxt, &orig);
5605                 if ((ctxt->sax != NULL) &&
5606                     (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5607                     ctxt->sax->entityDecl(ctxt->userData, name,
5608                                 XML_INTERNAL_GENERAL_ENTITY,
5609                                 NULL, NULL, value);
5610                 /*
5611                  * For expat compatibility in SAX mode.
5612                  */
5613                 if ((ctxt->myDoc == NULL) ||
5614                     (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
5615                     if (ctxt->myDoc == NULL) {
5616                         ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5617                         if (ctxt->myDoc == NULL) {
5618                             xmlErrMemory(ctxt, "New Doc failed");
5619                             return;
5620                         }
5621                         ctxt->myDoc->properties = XML_DOC_INTERNAL;
5622                     }
5623                     if (ctxt->myDoc->intSubset == NULL)
5624                         ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5625                                             BAD_CAST "fake", NULL, NULL);
5626
5627                     xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
5628                                       NULL, NULL, value);
5629                 }
5630             } else {
5631                 URI = xmlParseExternalID(ctxt, &literal, 1);
5632                 if ((URI == NULL) && (literal == NULL)) {
5633                     xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5634                 }
5635                 if (URI) {
5636                     xmlURIPtr uri;
5637
5638                     uri = xmlParseURI((const char *)URI);
5639                     if (uri == NULL) {
5640                         xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5641                                      "Invalid URI: %s\n", URI);
5642                         /*
5643                          * This really ought to be a well formedness error
5644                          * but the XML Core WG decided otherwise c.f. issue
5645                          * E26 of the XML erratas.
5646                          */
5647                     } else {
5648                         if (uri->fragment != NULL) {
5649                             /*
5650                              * Okay this is foolish to block those but not
5651                              * invalid URIs.
5652                              */
5653                             xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5654                         }
5655                         xmlFreeURI(uri);
5656                     }
5657                 }
5658                 if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
5659                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5660                                    "Space required before 'NDATA'\n");
5661                 }
5662                 SKIP_BLANKS;
5663                 if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
5664                     SKIP(5);
5665                     if (!IS_BLANK_CH(CUR)) {
5666                         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5667                                        "Space required after 'NDATA'\n");
5668                     }
5669                     SKIP_BLANKS;
5670                     ndata = xmlParseName(ctxt);
5671                     if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5672                         (ctxt->sax->unparsedEntityDecl != NULL))
5673                         ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
5674                                     literal, URI, ndata);
5675                 } else {
5676                     if ((ctxt->sax != NULL) &&
5677                         (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5678                         ctxt->sax->entityDecl(ctxt->userData, name,
5679                                     XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5680                                     literal, URI, NULL);
5681                     /*
5682                      * For expat compatibility in SAX mode.
5683                      * assuming the entity repalcement was asked for
5684                      */
5685                     if ((ctxt->replaceEntities != 0) &&
5686                         ((ctxt->myDoc == NULL) ||
5687                         (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
5688                         if (ctxt->myDoc == NULL) {
5689                             ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5690                             if (ctxt->myDoc == NULL) {
5691                                 xmlErrMemory(ctxt, "New Doc failed");
5692                                 return;
5693                             }
5694                             ctxt->myDoc->properties = XML_DOC_INTERNAL;
5695                         }
5696
5697                         if (ctxt->myDoc->intSubset == NULL)
5698                             ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5699                                                 BAD_CAST "fake", NULL, NULL);
5700                         xmlSAX2EntityDecl(ctxt, name,
5701                                           XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5702                                           literal, URI, NULL);
5703                     }
5704                 }
5705             }
5706         }
5707         if (ctxt->instate == XML_PARSER_EOF)
5708             return;
5709         SKIP_BLANKS;
5710         if (RAW != '>') {
5711             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
5712                     "xmlParseEntityDecl: entity %s not terminated\n", name);
5713             xmlHaltParser(ctxt);
5714         } else {
5715             if (input != ctxt->input) {
5716                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5717         "Entity declaration doesn't start and stop in the same entity\n");
5718             }
5719             NEXT;
5720         }
5721         if (orig != NULL) {
5722             /*
5723              * Ugly mechanism to save the raw entity value.
5724              */
5725             xmlEntityPtr cur = NULL;
5726
5727             if (isParameter) {
5728                 if ((ctxt->sax != NULL) &&
5729                     (ctxt->sax->getParameterEntity != NULL))
5730                     cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
5731             } else {
5732                 if ((ctxt->sax != NULL) &&
5733                     (ctxt->sax->getEntity != NULL))
5734                     cur = ctxt->sax->getEntity(ctxt->userData, name);
5735                 if ((cur == NULL) && (ctxt->userData==ctxt)) {
5736                     cur = xmlSAX2GetEntity(ctxt, name);
5737                 }
5738             }
5739             if (cur != NULL) {
5740                 if (cur->orig != NULL)
5741                     xmlFree(orig);
5742                 else
5743                     cur->orig = orig;
5744             } else
5745                 xmlFree(orig);
5746         }
5747         if (value != NULL) xmlFree(value);
5748         if (URI != NULL) xmlFree(URI);
5749         if (literal != NULL) xmlFree(literal);
5750     }
5751 }
5752
5753 /**
5754  * xmlParseDefaultDecl:
5755  * @ctxt:  an XML parser context
5756  * @value:  Receive a possible fixed default value for the attribute
5757  *
5758  * Parse an attribute default declaration
5759  *
5760  * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
5761  *
5762  * [ VC: Required Attribute ]
5763  * if the default declaration is the keyword #REQUIRED, then the
5764  * attribute must be specified for all elements of the type in the
5765  * attribute-list declaration.
5766  *
5767  * [ VC: Attribute Default Legal ]
5768  * The declared default value must meet the lexical constraints of
5769  * the declared attribute type c.f. xmlValidateAttributeDecl()
5770  *
5771  * [ VC: Fixed Attribute Default ]
5772  * if an attribute has a default value declared with the #FIXED
5773  * keyword, instances of that attribute must match the default value.
5774  *
5775  * [ WFC: No < in Attribute Values ]
5776  * handled in xmlParseAttValue()
5777  *
5778  * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
5779  *          or XML_ATTRIBUTE_FIXED.
5780  */
5781
5782 int
5783 xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
5784     int val;
5785     xmlChar *ret;
5786
5787     *value = NULL;
5788     if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
5789         SKIP(9);
5790         return(XML_ATTRIBUTE_REQUIRED);
5791     }
5792     if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
5793         SKIP(8);
5794         return(XML_ATTRIBUTE_IMPLIED);
5795     }
5796     val = XML_ATTRIBUTE_NONE;
5797     if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
5798         SKIP(6);
5799         val = XML_ATTRIBUTE_FIXED;
5800         if (!IS_BLANK_CH(CUR)) {
5801             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5802                            "Space required after '#FIXED'\n");
5803         }
5804         SKIP_BLANKS;
5805     }
5806     ret = xmlParseAttValue(ctxt);
5807     ctxt->instate = XML_PARSER_DTD;
5808     if (ret == NULL) {
5809         xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
5810                        "Attribute default value declaration error\n");
5811     } else
5812         *value = ret;
5813     return(val);
5814 }
5815
5816 /**
5817  * xmlParseNotationType:
5818  * @ctxt:  an XML parser context
5819  *
5820  * parse an Notation attribute type.
5821  *
5822  * Note: the leading 'NOTATION' S part has already being parsed...
5823  *
5824  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5825  *
5826  * [ VC: Notation Attributes ]
5827  * Values of this type must match one of the notation names included
5828  * in the declaration; all notation names in the declaration must be declared.
5829  *
5830  * Returns: the notation attribute tree built while parsing
5831  */
5832
5833 xmlEnumerationPtr
5834 xmlParseNotationType(xmlParserCtxtPtr ctxt) {
5835     const xmlChar *name;
5836     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5837
5838     if (RAW != '(') {
5839         xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5840         return(NULL);
5841     }
5842     SHRINK;
5843     do {
5844         NEXT;
5845         SKIP_BLANKS;
5846         name = xmlParseName(ctxt);
5847         if (name == NULL) {
5848             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5849                            "Name expected in NOTATION declaration\n");
5850             xmlFreeEnumeration(ret);
5851             return(NULL);
5852         }
5853         tmp = ret;
5854         while (tmp != NULL) {
5855             if (xmlStrEqual(name, tmp->name)) {
5856                 xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5857           "standalone: attribute notation value token %s duplicated\n",
5858                                  name, NULL);
5859                 if (!xmlDictOwns(ctxt->dict, name))
5860                     xmlFree((xmlChar *) name);
5861                 break;
5862             }
5863             tmp = tmp->next;
5864         }
5865         if (tmp == NULL) {
5866             cur = xmlCreateEnumeration(name);
5867             if (cur == NULL) {
5868                 xmlFreeEnumeration(ret);
5869                 return(NULL);
5870             }
5871             if (last == NULL) ret = last = cur;
5872             else {
5873                 last->next = cur;
5874                 last = cur;
5875             }
5876         }
5877         SKIP_BLANKS;
5878     } while (RAW == '|');
5879     if (RAW != ')') {
5880         xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5881         xmlFreeEnumeration(ret);
5882         return(NULL);
5883     }
5884     NEXT;
5885     return(ret);
5886 }
5887
5888 /**
5889  * xmlParseEnumerationType:
5890  * @ctxt:  an XML parser context
5891  *
5892  * parse an Enumeration attribute type.
5893  *
5894  * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
5895  *
5896  * [ VC: Enumeration ]
5897  * Values of this type must match one of the Nmtoken tokens in
5898  * the declaration
5899  *
5900  * Returns: the enumeration attribute tree built while parsing
5901  */
5902
5903 xmlEnumerationPtr
5904 xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
5905     xmlChar *name;
5906     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5907
5908     if (RAW != '(') {
5909         xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
5910         return(NULL);
5911     }
5912     SHRINK;
5913     do {
5914         NEXT;
5915         SKIP_BLANKS;
5916         name = xmlParseNmtoken(ctxt);
5917         if (name == NULL) {
5918             xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
5919             return(ret);
5920         }
5921         tmp = ret;
5922         while (tmp != NULL) {
5923             if (xmlStrEqual(name, tmp->name)) {
5924                 xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5925           "standalone: attribute enumeration value token %s duplicated\n",
5926                                  name, NULL);
5927                 if (!xmlDictOwns(ctxt->dict, name))
5928                     xmlFree(name);
5929                 break;
5930             }
5931             tmp = tmp->next;
5932         }
5933         if (tmp == NULL) {
5934             cur = xmlCreateEnumeration(name);
5935             if (!xmlDictOwns(ctxt->dict, name))
5936                 xmlFree(name);
5937             if (cur == NULL) {
5938                 xmlFreeEnumeration(ret);
5939                 return(NULL);
5940             }
5941             if (last == NULL) ret = last = cur;
5942             else {
5943                 last->next = cur;
5944                 last = cur;
5945             }
5946         }
5947         SKIP_BLANKS;
5948     } while (RAW == '|');
5949     if (RAW != ')') {
5950         xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
5951         return(ret);
5952     }
5953     NEXT;
5954     return(ret);
5955 }
5956
5957 /**
5958  * xmlParseEnumeratedType:
5959  * @ctxt:  an XML parser context
5960  * @tree:  the enumeration tree built while parsing
5961  *
5962  * parse an Enumerated attribute type.
5963  *
5964  * [57] EnumeratedType ::= NotationType | Enumeration
5965  *
5966  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5967  *
5968  *
5969  * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
5970  */
5971
5972 int
5973 xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5974     if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5975         SKIP(8);
5976         if (!IS_BLANK_CH(CUR)) {
5977             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5978                            "Space required after 'NOTATION'\n");
5979             return(0);
5980         }
5981         SKIP_BLANKS;
5982         *tree = xmlParseNotationType(ctxt);
5983         if (*tree == NULL) return(0);
5984         return(XML_ATTRIBUTE_NOTATION);
5985     }
5986     *tree = xmlParseEnumerationType(ctxt);
5987     if (*tree == NULL) return(0);
5988     return(XML_ATTRIBUTE_ENUMERATION);
5989 }
5990
5991 /**
5992  * xmlParseAttributeType:
5993  * @ctxt:  an XML parser context
5994  * @tree:  the enumeration tree built while parsing
5995  *
5996  * parse the Attribute list def for an element
5997  *
5998  * [54] AttType ::= StringType | TokenizedType | EnumeratedType
5999  *
6000  * [55] StringType ::= 'CDATA'
6001  *
6002  * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
6003  *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
6004  *
6005  * Validity constraints for attribute values syntax are checked in
6006  * xmlValidateAttributeValue()
6007  *
6008  * [ VC: ID ]
6009  * Values of type ID must match the Name production. A name must not
6010  * appear more than once in an XML document as a value of this type;
6011  * i.e., ID values must uniquely identify the elements which bear them.
6012  *
6013  * [ VC: One ID per Element Type ]
6014  * No element type may have more than one ID attribute specified.
6015  *
6016  * [ VC: ID Attribute Default ]
6017  * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
6018  *
6019  * [ VC: IDREF ]
6020  * Values of type IDREF must match the Name production, and values
6021  * of type IDREFS must match Names; each IDREF Name must match the value
6022  * of an ID attribute on some element in the XML document; i.e. IDREF
6023  * values must match the value of some ID attribute.
6024  *
6025  * [ VC: Entity Name ]
6026  * Values of type ENTITY must match the Name production, values
6027  * of type ENTITIES must match Names; each Entity Name must match the
6028  * name of an unparsed entity declared in the DTD.
6029  *
6030  * [ VC: Name Token ]
6031  * Values of type NMTOKEN must match the Nmtoken production; values
6032  * of type NMTOKENS must match Nmtokens.
6033  *
6034  * Returns the attribute type
6035  */
6036 int
6037 xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
6038     SHRINK;
6039     if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
6040         SKIP(5);
6041         return(XML_ATTRIBUTE_CDATA);
6042      } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
6043         SKIP(6);
6044         return(XML_ATTRIBUTE_IDREFS);
6045      } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
6046         SKIP(5);
6047         return(XML_ATTRIBUTE_IDREF);
6048      } else if ((RAW == 'I') && (NXT(1) == 'D')) {
6049         SKIP(2);
6050         return(XML_ATTRIBUTE_ID);
6051      } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
6052         SKIP(6);
6053         return(XML_ATTRIBUTE_ENTITY);
6054      } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
6055         SKIP(8);
6056         return(XML_ATTRIBUTE_ENTITIES);
6057      } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
6058         SKIP(8);
6059         return(XML_ATTRIBUTE_NMTOKENS);
6060      } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
6061         SKIP(7);
6062         return(XML_ATTRIBUTE_NMTOKEN);
6063      }
6064      return(xmlParseEnumeratedType(ctxt, tree));
6065 }
6066
6067 /**
6068  * xmlParseAttributeListDecl:
6069  * @ctxt:  an XML parser context
6070  *
6071  * : parse the Attribute list def for an element
6072  *
6073  * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
6074  *
6075  * [53] AttDef ::= S Name S AttType S DefaultDecl
6076  *
6077  */
6078 void
6079 xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
6080     const xmlChar *elemName;
6081     const xmlChar *attrName;
6082     xmlEnumerationPtr tree;
6083
6084     if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
6085         xmlParserInputPtr input = ctxt->input;
6086
6087         SKIP(9);
6088         if (!IS_BLANK_CH(CUR)) {
6089             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6090                                  "Space required after '<!ATTLIST'\n");
6091         }
6092         SKIP_BLANKS;
6093         elemName = xmlParseName(ctxt);
6094         if (elemName == NULL) {
6095             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6096                            "ATTLIST: no name for Element\n");
6097             return;
6098         }
6099         SKIP_BLANKS;
6100         GROW;
6101         while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
6102             const xmlChar *check = CUR_PTR;
6103             int type;
6104             int def;
6105             xmlChar *defaultValue = NULL;
6106
6107             GROW;
6108             tree = NULL;
6109             attrName = xmlParseName(ctxt);
6110             if (attrName == NULL) {
6111                 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6112                                "ATTLIST: no name for Attribute\n");
6113                 break;
6114             }
6115             GROW;
6116             if (!IS_BLANK_CH(CUR)) {
6117                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6118                         "Space required after the attribute name\n");
6119                 break;
6120             }
6121             SKIP_BLANKS;
6122
6123             type = xmlParseAttributeType(ctxt, &tree);
6124             if (type <= 0) {
6125                 break;
6126             }
6127
6128             GROW;
6129             if (!IS_BLANK_CH(CUR)) {
6130                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6131                                "Space required after the attribute type\n");
6132                 if (tree != NULL)
6133                     xmlFreeEnumeration(tree);
6134                 break;
6135             }
6136             SKIP_BLANKS;
6137
6138             def = xmlParseDefaultDecl(ctxt, &defaultValue);
6139             if (def <= 0) {
6140                 if (defaultValue != NULL)
6141                     xmlFree(defaultValue);
6142                 if (tree != NULL)
6143                     xmlFreeEnumeration(tree);
6144                 break;
6145             }
6146             if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
6147                 xmlAttrNormalizeSpace(defaultValue, defaultValue);
6148
6149             GROW;
6150             if (RAW != '>') {
6151                 if (!IS_BLANK_CH(CUR)) {
6152                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6153                         "Space required after the attribute default value\n");
6154                     if (defaultValue != NULL)
6155                         xmlFree(defaultValue);
6156                     if (tree != NULL)
6157                         xmlFreeEnumeration(tree);
6158                     break;
6159                 }
6160                 SKIP_BLANKS;
6161             }
6162             if (check == CUR_PTR) {
6163                 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
6164                             "in xmlParseAttributeListDecl\n");
6165                 if (defaultValue != NULL)
6166                     xmlFree(defaultValue);
6167                 if (tree != NULL)
6168                     xmlFreeEnumeration(tree);
6169                 break;
6170             }
6171             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6172                 (ctxt->sax->attributeDecl != NULL))
6173                 ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
6174                                 type, def, defaultValue, tree);
6175             else if (tree != NULL)
6176                 xmlFreeEnumeration(tree);
6177
6178             if ((ctxt->sax2) && (defaultValue != NULL) &&
6179                 (def != XML_ATTRIBUTE_IMPLIED) &&
6180                 (def != XML_ATTRIBUTE_REQUIRED)) {
6181                 xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
6182             }
6183             if (ctxt->sax2) {
6184                 xmlAddSpecialAttr(ctxt, elemName, attrName, type);
6185             }
6186             if (defaultValue != NULL)
6187                 xmlFree(defaultValue);
6188             GROW;
6189         }
6190         if (RAW == '>') {
6191             if (input != ctxt->input) {
6192                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6193     "Attribute list declaration doesn't start and stop in the same entity\n",
6194                                  NULL, NULL);
6195             }
6196             NEXT;
6197         }
6198     }
6199 }
6200
6201 /**
6202  * xmlParseElementMixedContentDecl:
6203  * @ctxt:  an XML parser context
6204  * @inputchk:  the input used for the current entity, needed for boundary checks
6205  *
6206  * parse the declaration for a Mixed Element content
6207  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6208  *
6209  * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
6210  *                '(' S? '#PCDATA' S? ')'
6211  *
6212  * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
6213  *
6214  * [ VC: No Duplicate Types ]
6215  * The same name must not appear more than once in a single
6216  * mixed-content declaration.
6217  *
6218  * returns: the list of the xmlElementContentPtr describing the element choices
6219  */
6220 xmlElementContentPtr
6221 xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6222     xmlElementContentPtr ret = NULL, cur = NULL, n;
6223     const xmlChar *elem = NULL;
6224
6225     GROW;
6226     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6227         SKIP(7);
6228         SKIP_BLANKS;
6229         SHRINK;
6230         if (RAW == ')') {
6231             if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
6232                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6233 "Element content declaration doesn't start and stop in the same entity\n",
6234                                  NULL, NULL);
6235             }
6236             NEXT;
6237             ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6238             if (ret == NULL)
6239                 return(NULL);
6240             if (RAW == '*') {
6241                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6242                 NEXT;
6243             }
6244             return(ret);
6245         }
6246         if ((RAW == '(') || (RAW == '|')) {
6247             ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6248             if (ret == NULL) return(NULL);
6249         }
6250         while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
6251             NEXT;
6252             if (elem == NULL) {
6253                 ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6254                 if (ret == NULL) return(NULL);
6255                 ret->c1 = cur;
6256                 if (cur != NULL)
6257                     cur->parent = ret;
6258                 cur = ret;
6259             } else {
6260                 n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6261                 if (n == NULL) return(NULL);
6262                 n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6263                 if (n->c1 != NULL)
6264                     n->c1->parent = n;
6265                 cur->c2 = n;
6266                 if (n != NULL)
6267                     n->parent = cur;
6268                 cur = n;
6269             }
6270             SKIP_BLANKS;
6271             elem = xmlParseName(ctxt);
6272             if (elem == NULL) {
6273                 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6274                         "xmlParseElementMixedContentDecl : Name expected\n");
6275                 xmlFreeDocElementContent(ctxt->myDoc, cur);
6276                 return(NULL);
6277             }
6278             SKIP_BLANKS;
6279             GROW;
6280         }
6281         if ((RAW == ')') && (NXT(1) == '*')) {
6282             if (elem != NULL) {
6283                 cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
6284                                                XML_ELEMENT_CONTENT_ELEMENT);
6285                 if (cur->c2 != NULL)
6286                     cur->c2->parent = cur;
6287             }
6288             if (ret != NULL)
6289                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6290             if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
6291                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6292 "Element content declaration doesn't start and stop in the same entity\n",
6293                                  NULL, NULL);
6294             }
6295             SKIP(2);
6296         } else {
6297             xmlFreeDocElementContent(ctxt->myDoc, ret);
6298             xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
6299             return(NULL);
6300         }
6301
6302     } else {
6303         xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
6304     }
6305     return(ret);
6306 }
6307
6308 /**
6309  * xmlParseElementChildrenContentDeclPriv:
6310  * @ctxt:  an XML parser context
6311  * @inputchk:  the input used for the current entity, needed for boundary checks
6312  * @depth: the level of recursion
6313  *
6314  * parse the declaration for a Mixed Element content
6315  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6316  *
6317  *
6318  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6319  *
6320  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6321  *
6322  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6323  *
6324  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6325  *
6326  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6327  * TODO Parameter-entity replacement text must be properly nested
6328  *      with parenthesized groups. That is to say, if either of the
6329  *      opening or closing parentheses in a choice, seq, or Mixed
6330  *      construct is contained in the replacement text for a parameter
6331  *      entity, both must be contained in the same replacement text. For
6332  *      interoperability, if a parameter-entity reference appears in a
6333  *      choice, seq, or Mixed construct, its replacement text should not
6334  *      be empty, and neither the first nor last non-blank character of
6335  *      the replacement text should be a connector (| or ,).
6336  *
6337  * Returns the tree of xmlElementContentPtr describing the element
6338  *          hierarchy.
6339  */
6340 static xmlElementContentPtr
6341 xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
6342                                        int depth) {
6343     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
6344     const xmlChar *elem;
6345     xmlChar type = 0;
6346
6347     if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
6348         (depth >  2048)) {
6349         xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
6350 "xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
6351                           depth);
6352         return(NULL);
6353     }
6354     SKIP_BLANKS;
6355     GROW;
6356     if (RAW == '(') {
6357         int inputid = ctxt->input->id;
6358
6359         /* Recurse on first child */
6360         NEXT;
6361         SKIP_BLANKS;
6362         cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6363                                                            depth + 1);
6364         SKIP_BLANKS;
6365         GROW;
6366     } else {
6367         elem = xmlParseName(ctxt);
6368         if (elem == NULL) {
6369             xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6370             return(NULL);
6371         }
6372         cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6373         if (cur == NULL) {
6374             xmlErrMemory(ctxt, NULL);
6375             return(NULL);
6376         }
6377         GROW;
6378         if (RAW == '?') {
6379             cur->ocur = XML_ELEMENT_CONTENT_OPT;
6380             NEXT;
6381         } else if (RAW == '*') {
6382             cur->ocur = XML_ELEMENT_CONTENT_MULT;
6383             NEXT;
6384         } else if (RAW == '+') {
6385             cur->ocur = XML_ELEMENT_CONTENT_PLUS;
6386             NEXT;
6387         } else {
6388             cur->ocur = XML_ELEMENT_CONTENT_ONCE;
6389         }
6390         GROW;
6391     }
6392     SKIP_BLANKS;
6393     SHRINK;
6394     while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
6395         /*
6396          * Each loop we parse one separator and one element.
6397          */
6398         if (RAW == ',') {
6399             if (type == 0) type = CUR;
6400
6401             /*
6402              * Detect "Name | Name , Name" error
6403              */
6404             else if (type != CUR) {
6405                 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6406                     "xmlParseElementChildrenContentDecl : '%c' expected\n",
6407                                   type);
6408                 if ((last != NULL) && (last != ret))
6409                     xmlFreeDocElementContent(ctxt->myDoc, last);
6410                 if (ret != NULL)
6411                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6412                 return(NULL);
6413             }
6414             NEXT;
6415
6416             op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
6417             if (op == NULL) {
6418                 if ((last != NULL) && (last != ret))
6419                     xmlFreeDocElementContent(ctxt->myDoc, last);
6420                 xmlFreeDocElementContent(ctxt->myDoc, ret);
6421                 return(NULL);
6422             }
6423             if (last == NULL) {
6424                 op->c1 = ret;
6425                 if (ret != NULL)
6426                     ret->parent = op;
6427                 ret = cur = op;
6428             } else {
6429                 cur->c2 = op;
6430                 if (op != NULL)
6431                     op->parent = cur;
6432                 op->c1 = last;
6433                 if (last != NULL)
6434                     last->parent = op;
6435                 cur =op;
6436                 last = NULL;
6437             }
6438         } else if (RAW == '|') {
6439             if (type == 0) type = CUR;
6440
6441             /*
6442              * Detect "Name , Name | Name" error
6443              */
6444             else if (type != CUR) {
6445                 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6446                     "xmlParseElementChildrenContentDecl : '%c' expected\n",
6447                                   type);
6448                 if ((last != NULL) && (last != ret))
6449                     xmlFreeDocElementContent(ctxt->myDoc, last);
6450                 if (ret != NULL)
6451                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6452                 return(NULL);
6453             }
6454             NEXT;
6455
6456             op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6457             if (op == NULL) {
6458                 if ((last != NULL) && (last != ret))
6459                     xmlFreeDocElementContent(ctxt->myDoc, last);
6460                 if (ret != NULL)
6461                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6462                 return(NULL);
6463             }
6464             if (last == NULL) {
6465                 op->c1 = ret;
6466                 if (ret != NULL)
6467                     ret->parent = op;
6468                 ret = cur = op;
6469             } else {
6470                 cur->c2 = op;
6471                 if (op != NULL)
6472                     op->parent = cur;
6473                 op->c1 = last;
6474                 if (last != NULL)
6475                     last->parent = op;
6476                 cur =op;
6477                 last = NULL;
6478             }
6479         } else {
6480             xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
6481             if ((last != NULL) && (last != ret))
6482                 xmlFreeDocElementContent(ctxt->myDoc, last);
6483             if (ret != NULL)
6484                 xmlFreeDocElementContent(ctxt->myDoc, ret);
6485             return(NULL);
6486         }
6487         GROW;
6488         SKIP_BLANKS;
6489         GROW;
6490         if (RAW == '(') {
6491             int inputid = ctxt->input->id;
6492             /* Recurse on second child */
6493             NEXT;
6494             SKIP_BLANKS;
6495             last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6496                                                           depth + 1);
6497             SKIP_BLANKS;
6498         } else {
6499             elem = xmlParseName(ctxt);
6500             if (elem == NULL) {
6501                 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6502                 if (ret != NULL)
6503                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6504                 return(NULL);
6505             }
6506             last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6507             if (last == NULL) {
6508                 if (ret != NULL)
6509                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6510                 return(NULL);
6511             }
6512             if (RAW == '?') {
6513                 last->ocur = XML_ELEMENT_CONTENT_OPT;
6514                 NEXT;
6515             } else if (RAW == '*') {
6516                 last->ocur = XML_ELEMENT_CONTENT_MULT;
6517                 NEXT;
6518             } else if (RAW == '+') {
6519                 last->ocur = XML_ELEMENT_CONTENT_PLUS;
6520                 NEXT;
6521             } else {
6522                 last->ocur = XML_ELEMENT_CONTENT_ONCE;
6523             }
6524         }
6525         SKIP_BLANKS;
6526         GROW;
6527     }
6528     if ((cur != NULL) && (last != NULL)) {
6529         cur->c2 = last;
6530         if (last != NULL)
6531             last->parent = cur;
6532     }
6533     if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
6534         xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6535 "Element content declaration doesn't start and stop in the same entity\n",
6536                          NULL, NULL);
6537     }
6538     NEXT;
6539     if (RAW == '?') {
6540         if (ret != NULL) {
6541             if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
6542                 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6543                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6544             else
6545                 ret->ocur = XML_ELEMENT_CONTENT_OPT;
6546         }
6547         NEXT;
6548     } else if (RAW == '*') {
6549         if (ret != NULL) {
6550             ret->ocur = XML_ELEMENT_CONTENT_MULT;
6551             cur = ret;
6552             /*
6553              * Some normalization:
6554              * (a | b* | c?)* == (a | b | c)*
6555              */
6556             while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6557                 if ((cur->c1 != NULL) &&
6558                     ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6559                      (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
6560                     cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6561                 if ((cur->c2 != NULL) &&
6562                     ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6563                      (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
6564                     cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6565                 cur = cur->c2;
6566             }
6567         }
6568         NEXT;
6569     } else if (RAW == '+') {
6570         if (ret != NULL) {
6571             int found = 0;
6572
6573             if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
6574                 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6575                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6576             else
6577                 ret->ocur = XML_ELEMENT_CONTENT_PLUS;
6578             /*
6579              * Some normalization:
6580              * (a | b*)+ == (a | b)*
6581              * (a | b?)+ == (a | b)*
6582              */
6583             while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6584                 if ((cur->c1 != NULL) &&
6585                     ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6586                      (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
6587                     cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6588                     found = 1;
6589                 }
6590                 if ((cur->c2 != NULL) &&
6591                     ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6592                      (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
6593                     cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6594                     found = 1;
6595                 }
6596                 cur = cur->c2;
6597             }
6598             if (found)
6599                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6600         }
6601         NEXT;
6602     }
6603     return(ret);
6604 }
6605
6606 /**
6607  * xmlParseElementChildrenContentDecl:
6608  * @ctxt:  an XML parser context
6609  * @inputchk:  the input used for the current entity, needed for boundary checks
6610  *
6611  * parse the declaration for a Mixed Element content
6612  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6613  *
6614  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6615  *
6616  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6617  *
6618  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6619  *
6620  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6621  *
6622  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6623  * TODO Parameter-entity replacement text must be properly nested
6624  *      with parenthesized groups. That is to say, if either of the
6625  *      opening or closing parentheses in a choice, seq, or Mixed
6626  *      construct is contained in the replacement text for a parameter
6627  *      entity, both must be contained in the same replacement text. For
6628  *      interoperability, if a parameter-entity reference appears in a
6629  *      choice, seq, or Mixed construct, its replacement text should not
6630  *      be empty, and neither the first nor last non-blank character of
6631  *      the replacement text should be a connector (| or ,).
6632  *
6633  * Returns the tree of xmlElementContentPtr describing the element
6634  *          hierarchy.
6635  */
6636 xmlElementContentPtr
6637 xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6638     /* stub left for API/ABI compat */
6639     return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
6640 }
6641
6642 /**
6643  * xmlParseElementContentDecl:
6644  * @ctxt:  an XML parser context
6645  * @name:  the name of the element being defined.
6646  * @result:  the Element Content pointer will be stored here if any
6647  *
6648  * parse the declaration for an Element content either Mixed or Children,
6649  * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
6650  *
6651  * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
6652  *
6653  * returns: the type of element content XML_ELEMENT_TYPE_xxx
6654  */
6655
6656 int
6657 xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
6658                            xmlElementContentPtr *result) {
6659
6660     xmlElementContentPtr tree = NULL;
6661     int inputid = ctxt->input->id;
6662     int res;
6663
6664     *result = NULL;
6665
6666     if (RAW != '(') {
6667         xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6668                 "xmlParseElementContentDecl : %s '(' expected\n", name);
6669         return(-1);
6670     }
6671     NEXT;
6672     GROW;
6673     if (ctxt->instate == XML_PARSER_EOF)
6674         return(-1);
6675     SKIP_BLANKS;
6676     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6677         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
6678         res = XML_ELEMENT_TYPE_MIXED;
6679     } else {
6680         tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
6681         res = XML_ELEMENT_TYPE_ELEMENT;
6682     }
6683     SKIP_BLANKS;
6684     *result = tree;
6685     return(res);
6686 }
6687
6688 /**
6689  * xmlParseElementDecl:
6690  * @ctxt:  an XML parser context
6691  *
6692  * parse an Element declaration.
6693  *
6694  * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
6695  *
6696  * [ VC: Unique Element Type Declaration ]
6697  * No element type may be declared more than once
6698  *
6699  * Returns the type of the element, or -1 in case of error
6700  */
6701 int
6702 xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
6703     const xmlChar *name;
6704     int ret = -1;
6705     xmlElementContentPtr content  = NULL;
6706
6707     /* GROW; done in the caller */
6708     if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
6709         xmlParserInputPtr input = ctxt->input;
6710
6711         SKIP(9);
6712         if (!IS_BLANK_CH(CUR)) {
6713             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6714                            "Space required after 'ELEMENT'\n");
6715             return(-1);
6716         }
6717         SKIP_BLANKS;
6718         name = xmlParseName(ctxt);
6719         if (name == NULL) {
6720             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6721                            "xmlParseElementDecl: no name for Element\n");
6722             return(-1);
6723         }
6724         while ((RAW == 0) && (ctxt->inputNr > 1))
6725             xmlPopInput(ctxt);
6726         if (!IS_BLANK_CH(CUR)) {
6727             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6728                            "Space required after the element name\n");
6729         }
6730         SKIP_BLANKS;
6731         if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
6732             SKIP(5);
6733             /*
6734              * Element must always be empty.
6735              */
6736             ret = XML_ELEMENT_TYPE_EMPTY;
6737         } else if ((RAW == 'A') && (NXT(1) == 'N') &&
6738                    (NXT(2) == 'Y')) {
6739             SKIP(3);
6740             /*
6741              * Element is a generic container.
6742              */
6743             ret = XML_ELEMENT_TYPE_ANY;
6744         } else if (RAW == '(') {
6745             ret = xmlParseElementContentDecl(ctxt, name, &content);
6746         } else {
6747             /*
6748              * [ WFC: PEs in Internal Subset ] error handling.
6749              */
6750             if ((RAW == '%') && (ctxt->external == 0) &&
6751                 (ctxt->inputNr == 1)) {
6752                 xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
6753           "PEReference: forbidden within markup decl in internal subset\n");
6754             } else {
6755                 xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6756                       "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
6757             }
6758             return(-1);
6759         }
6760
6761         SKIP_BLANKS;
6762         /*
6763          * Pop-up of finished entities.
6764          */
6765         while ((RAW == 0) && (ctxt->inputNr > 1))
6766             xmlPopInput(ctxt);
6767         SKIP_BLANKS;
6768
6769         if (RAW != '>') {
6770             xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
6771             if (content != NULL) {
6772                 xmlFreeDocElementContent(ctxt->myDoc, content);
6773             }
6774         } else {
6775             if (input != ctxt->input) {
6776                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6777     "Element declaration doesn't start and stop in the same entity\n");
6778             }
6779
6780             NEXT;
6781             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6782                 (ctxt->sax->elementDecl != NULL)) {
6783                 if (content != NULL)
6784                     content->parent = NULL;
6785                 ctxt->sax->elementDecl(ctxt->userData, name, ret,
6786                                        content);
6787                 if ((content != NULL) && (content->parent == NULL)) {
6788                     /*
6789                      * this is a trick: if xmlAddElementDecl is called,
6790                      * instead of copying the full tree it is plugged directly
6791                      * if called from the parser. Avoid duplicating the
6792                      * interfaces or change the API/ABI
6793                      */
6794                     xmlFreeDocElementContent(ctxt->myDoc, content);
6795                 }
6796             } else if (content != NULL) {
6797                 xmlFreeDocElementContent(ctxt->myDoc, content);
6798             }
6799         }
6800     }
6801     return(ret);
6802 }
6803
6804 /**
6805  * xmlParseConditionalSections
6806  * @ctxt:  an XML parser context
6807  *
6808  * [61] conditionalSect ::= includeSect | ignoreSect
6809  * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
6810  * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
6811  * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
6812  * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
6813  */
6814
6815 static void
6816 xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
6817     int id = ctxt->input->id;
6818
6819     SKIP(3);
6820     SKIP_BLANKS;
6821     if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
6822         SKIP(7);
6823         SKIP_BLANKS;
6824         if (RAW != '[') {
6825             xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6826             xmlHaltParser(ctxt);
6827             return;
6828         } else {
6829             if (ctxt->input->id != id) {
6830                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6831             "All markup of the conditional section is not in the same entity\n",
6832                                      NULL, NULL);
6833             }
6834             NEXT;
6835         }
6836         if (xmlParserDebugEntities) {
6837             if ((ctxt->input != NULL) && (ctxt->input->filename))
6838                 xmlGenericError(xmlGenericErrorContext,
6839                         "%s(%d): ", ctxt->input->filename,
6840                         ctxt->input->line);
6841             xmlGenericError(xmlGenericErrorContext,
6842                     "Entering INCLUDE Conditional Section\n");
6843         }
6844
6845         while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
6846                 (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
6847             const xmlChar *check = CUR_PTR;
6848             unsigned int cons = ctxt->input->consumed;
6849
6850             if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6851                 xmlParseConditionalSections(ctxt);
6852             } else if (IS_BLANK_CH(CUR)) {
6853                 NEXT;
6854             } else if (RAW == '%') {
6855                 xmlParsePEReference(ctxt);
6856             } else
6857                 xmlParseMarkupDecl(ctxt);
6858
6859             /*
6860              * Pop-up of finished entities.
6861              */
6862             while ((RAW == 0) && (ctxt->inputNr > 1))
6863                 xmlPopInput(ctxt);
6864
6865             if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
6866                 xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6867                 xmlHaltParser(ctxt);
6868                 break;
6869             }
6870         }
6871         if (xmlParserDebugEntities) {
6872             if ((ctxt->input != NULL) && (ctxt->input->filename))
6873                 xmlGenericError(xmlGenericErrorContext,
6874                         "%s(%d): ", ctxt->input->filename,
6875                         ctxt->input->line);
6876             xmlGenericError(xmlGenericErrorContext,
6877                     "Leaving INCLUDE Conditional Section\n");
6878         }
6879
6880     } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
6881         int state;
6882         xmlParserInputState instate;
6883         int depth = 0;
6884
6885         SKIP(6);
6886         SKIP_BLANKS;
6887         if (RAW != '[') {
6888             xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6889             xmlHaltParser(ctxt);
6890             return;
6891         } else {
6892             if (ctxt->input->id != id) {
6893                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6894             "All markup of the conditional section is not in the same entity\n",
6895                                      NULL, NULL);
6896             }
6897             NEXT;
6898         }
6899         if (xmlParserDebugEntities) {
6900             if ((ctxt->input != NULL) && (ctxt->input->filename))
6901                 xmlGenericError(xmlGenericErrorContext,
6902                         "%s(%d): ", ctxt->input->filename,
6903                         ctxt->input->line);
6904             xmlGenericError(xmlGenericErrorContext,
6905                     "Entering IGNORE Conditional Section\n");
6906         }
6907
6908         /*
6909          * Parse up to the end of the conditional section
6910          * But disable SAX event generating DTD building in the meantime
6911          */
6912         state = ctxt->disableSAX;
6913         instate = ctxt->instate;
6914         if (ctxt->recovery == 0) ctxt->disableSAX = 1;
6915         ctxt->instate = XML_PARSER_IGNORE;
6916
6917         while (((depth >= 0) && (RAW != 0)) &&
6918                (ctxt->instate != XML_PARSER_EOF)) {
6919           if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6920             depth++;
6921             SKIP(3);
6922             continue;
6923           }
6924           if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
6925             if (--depth >= 0) SKIP(3);
6926             continue;
6927           }
6928           NEXT;
6929           continue;
6930         }
6931
6932         ctxt->disableSAX = state;
6933         ctxt->instate = instate;
6934
6935         if (xmlParserDebugEntities) {
6936             if ((ctxt->input != NULL) && (ctxt->input->filename))
6937                 xmlGenericError(xmlGenericErrorContext,
6938                         "%s(%d): ", ctxt->input->filename,
6939                         ctxt->input->line);
6940             xmlGenericError(xmlGenericErrorContext,
6941                     "Leaving IGNORE Conditional Section\n");
6942         }
6943
6944     } else {
6945         xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
6946         xmlHaltParser(ctxt);
6947         return;
6948     }
6949
6950     if (RAW == 0)
6951         SHRINK;
6952
6953     if (RAW == 0) {
6954         xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
6955     } else {
6956         if (ctxt->input->id != id) {
6957             xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6958         "All markup of the conditional section is not in the same entity\n",
6959                                  NULL, NULL);
6960         }
6961         if ((ctxt-> instate != XML_PARSER_EOF) &&
6962             ((ctxt->input->cur + 3) <= ctxt->input->end))
6963             SKIP(3);
6964     }
6965 }
6966
6967 /**
6968  * xmlParseMarkupDecl:
6969  * @ctxt:  an XML parser context
6970  *
6971  * parse Markup declarations
6972  *
6973  * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
6974  *                     NotationDecl | PI | Comment
6975  *
6976  * [ VC: Proper Declaration/PE Nesting ]
6977  * Parameter-entity replacement text must be properly nested with
6978  * markup declarations. That is to say, if either the first character
6979  * or the last character of a markup declaration (markupdecl above) is
6980  * contained in the replacement text for a parameter-entity reference,
6981  * both must be contained in the same replacement text.
6982  *
6983  * [ WFC: PEs in Internal Subset ]
6984  * In the internal DTD subset, parameter-entity references can occur
6985  * only where markup declarations can occur, not within markup declarations.
6986  * (This does not apply to references that occur in external parameter
6987  * entities or to the external subset.)
6988  */
6989 void
6990 xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
6991     GROW;
6992     if (CUR == '<') {
6993         if (NXT(1) == '!') {
6994             switch (NXT(2)) {
6995                 case 'E':
6996                     if (NXT(3) == 'L')
6997                         xmlParseElementDecl(ctxt);
6998                     else if (NXT(3) == 'N')
6999                         xmlParseEntityDecl(ctxt);
7000                     break;
7001                 case 'A':
7002                     xmlParseAttributeListDecl(ctxt);
7003                     break;
7004                 case 'N':
7005                     xmlParseNotationDecl(ctxt);
7006                     break;
7007                 case '-':
7008                     xmlParseComment(ctxt);
7009                     break;
7010                 default:
7011                     /* there is an error but it will be detected later */
7012                     break;
7013             }
7014         } else if (NXT(1) == '?') {
7015             xmlParsePI(ctxt);
7016         }
7017     }
7018
7019     /*
7020      * detect requirement to exit there and act accordingly
7021      * and avoid having instate overriden later on
7022      */
7023     if (ctxt->instate == XML_PARSER_EOF)
7024         return;
7025
7026     /*
7027      * This is only for internal subset. On external entities,
7028      * the replacement is done before parsing stage
7029      */
7030     if ((ctxt->external == 0) && (ctxt->inputNr == 1))
7031         xmlParsePEReference(ctxt);
7032
7033     /*
7034      * Conditional sections are allowed from entities included
7035      * by PE References in the internal subset.
7036      */
7037     if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
7038         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
7039             xmlParseConditionalSections(ctxt);
7040         }
7041     }
7042
7043     ctxt->instate = XML_PARSER_DTD;
7044 }
7045
7046 /**
7047  * xmlParseTextDecl:
7048  * @ctxt:  an XML parser context
7049  *
7050  * parse an XML declaration header for external entities
7051  *
7052  * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
7053  */
7054
7055 void
7056 xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
7057     xmlChar *version;
7058     const xmlChar *encoding;
7059
7060     /*
7061      * We know that '<?xml' is here.
7062      */
7063     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
7064         SKIP(5);
7065     } else {
7066         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
7067         return;
7068     }
7069
7070     if (!IS_BLANK_CH(CUR)) {
7071         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
7072                        "Space needed after '<?xml'\n");
7073     }
7074     SKIP_BLANKS;
7075
7076     /*
7077      * We may have the VersionInfo here.
7078      */
7079     version = xmlParseVersionInfo(ctxt);
7080     if (version == NULL)
7081         version = xmlCharStrdup(XML_DEFAULT_VERSION);
7082     else {
7083         if (!IS_BLANK_CH(CUR)) {
7084             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
7085                            "Space needed here\n");
7086         }
7087     }
7088     ctxt->input->version = version;
7089
7090     /*
7091      * We must have the encoding declaration
7092      */
7093     encoding = xmlParseEncodingDecl(ctxt);
7094     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
7095         /*
7096          * The XML REC instructs us to stop parsing right here
7097          */
7098         return;
7099     }
7100     if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
7101         xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
7102                        "Missing encoding in text declaration\n");
7103     }
7104
7105     SKIP_BLANKS;
7106     if ((RAW == '?') && (NXT(1) == '>')) {
7107         SKIP(2);
7108     } else if (RAW == '>') {
7109         /* Deprecated old WD ... */
7110         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
7111         NEXT;
7112     } else {
7113         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
7114         MOVETO_ENDTAG(CUR_PTR);
7115         NEXT;
7116     }
7117 }
7118
7119 /**
7120  * xmlParseExternalSubset:
7121  * @ctxt:  an XML parser context
7122  * @ExternalID: the external identifier
7123  * @SystemID: the system identifier (or URL)
7124  *
7125  * parse Markup declarations from an external subset
7126  *
7127  * [30] extSubset ::= textDecl? extSubsetDecl
7128  *
7129  * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
7130  */
7131 void
7132 xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
7133                        const xmlChar *SystemID) {
7134     xmlDetectSAX2(ctxt);
7135     GROW;
7136
7137     if ((ctxt->encoding == NULL) &&
7138         (ctxt->input->end - ctxt->input->cur >= 4)) {
7139         xmlChar start[4];
7140         xmlCharEncoding enc;
7141
7142         start[0] = RAW;
7143         start[1] = NXT(1);
7144         start[2] = NXT(2);
7145         start[3] = NXT(3);
7146         enc = xmlDetectCharEncoding(start, 4);
7147         if (enc != XML_CHAR_ENCODING_NONE)
7148             xmlSwitchEncoding(ctxt, enc);
7149     }
7150
7151     if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
7152         xmlParseTextDecl(ctxt);
7153         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
7154             /*
7155              * The XML REC instructs us to stop parsing right here
7156              */
7157             xmlHaltParser(ctxt);
7158             return;
7159         }
7160     }
7161     if (ctxt->myDoc == NULL) {
7162         ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
7163         if (ctxt->myDoc == NULL) {
7164             xmlErrMemory(ctxt, "New Doc failed");
7165             return;
7166         }
7167         ctxt->myDoc->properties = XML_DOC_INTERNAL;
7168     }
7169     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
7170         xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
7171
7172     ctxt->instate = XML_PARSER_DTD;
7173     ctxt->external = 1;
7174     while (((RAW == '<') && (NXT(1) == '?')) ||
7175            ((RAW == '<') && (NXT(1) == '!')) ||
7176            (RAW == '%') || IS_BLANK_CH(CUR)) {
7177         const xmlChar *check = CUR_PTR;
7178         unsigned int cons = ctxt->input->consumed;
7179
7180         GROW;
7181         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
7182             xmlParseConditionalSections(ctxt);
7183         } else if (IS_BLANK_CH(CUR)) {
7184             NEXT;
7185         } else if (RAW == '%') {
7186             xmlParsePEReference(ctxt);
7187         } else
7188             xmlParseMarkupDecl(ctxt);
7189
7190         /*
7191          * Pop-up of finished entities.
7192          */
7193         while ((RAW == 0) && (ctxt->inputNr > 1))
7194             xmlPopInput(ctxt);
7195
7196         if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
7197             xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7198             break;
7199         }
7200     }
7201
7202     if (RAW != 0) {
7203         xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7204     }
7205
7206 }
7207
7208 /**
7209  * xmlParseReference:
7210  * @ctxt:  an XML parser context
7211  *
7212  * parse and handle entity references in content, depending on the SAX
7213  * interface, this may end-up in a call to character() if this is a
7214  * CharRef, a predefined entity, if there is no reference() callback.
7215  * or if the parser was asked to switch to that mode.
7216  *
7217  * [67] Reference ::= EntityRef | CharRef
7218  */
7219 void
7220 xmlParseReference(xmlParserCtxtPtr ctxt) {
7221     xmlEntityPtr ent;
7222     xmlChar *val;
7223     int was_checked;
7224     xmlNodePtr list = NULL;
7225     xmlParserErrors ret = XML_ERR_OK;
7226
7227
7228     if (RAW != '&')
7229         return;
7230
7231     /*
7232      * Simple case of a CharRef
7233      */
7234     if (NXT(1) == '#') {
7235         int i = 0;
7236         xmlChar out[10];
7237         int hex = NXT(2);
7238         int value = xmlParseCharRef(ctxt);
7239
7240         if (value == 0)
7241             return;
7242         if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
7243             /*
7244              * So we are using non-UTF-8 buffers
7245              * Check that the char fit on 8bits, if not
7246              * generate a CharRef.
7247              */
7248             if (value <= 0xFF) {
7249                 out[0] = value;
7250                 out[1] = 0;
7251                 if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7252                     (!ctxt->disableSAX))
7253                     ctxt->sax->characters(ctxt->userData, out, 1);
7254             } else {
7255                 if ((hex == 'x') || (hex == 'X'))
7256                     snprintf((char *)out, sizeof(out), "#x%X", value);
7257                 else
7258                     snprintf((char *)out, sizeof(out), "#%d", value);
7259                 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7260                     (!ctxt->disableSAX))
7261                     ctxt->sax->reference(ctxt->userData, out);
7262             }
7263         } else {
7264             /*
7265              * Just encode the value in UTF-8
7266              */
7267             COPY_BUF(0 ,out, i, value);
7268             out[i] = 0;
7269             if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7270                 (!ctxt->disableSAX))
7271                 ctxt->sax->characters(ctxt->userData, out, i);
7272         }
7273         return;
7274     }
7275
7276     /*
7277      * We are seeing an entity reference
7278      */
7279     ent = xmlParseEntityRef(ctxt);
7280     if (ent == NULL) return;
7281     if (!ctxt->wellFormed)
7282         return;
7283     was_checked = ent->checked;
7284
7285     /* special case of predefined entities */
7286     if ((ent->name == NULL) ||
7287         (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
7288         val = ent->content;
7289         if (val == NULL) return;
7290         /*
7291          * inline the entity.
7292          */
7293         if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7294             (!ctxt->disableSAX))
7295             ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
7296         return;
7297     }
7298
7299     /*
7300      * The first reference to the entity trigger a parsing phase
7301      * where the ent->children is filled with the result from
7302      * the parsing.
7303      * Note: external parsed entities will not be loaded, it is not
7304      * required for a non-validating parser, unless the parsing option
7305      * of validating, or substituting entities were given. Doing so is
7306      * far more secure as the parser will only process data coming from
7307      * the document entity by default.
7308      */
7309     if (((ent->checked == 0) ||
7310          ((ent->children == NULL) && (ctxt->options & XML_PARSE_NOENT))) &&
7311         ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
7312          (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
7313         unsigned long oldnbent = ctxt->nbentities;
7314
7315         /*
7316          * This is a bit hackish but this seems the best
7317          * way to make sure both SAX and DOM entity support
7318          * behaves okay.
7319          */
7320         void *user_data;
7321         if (ctxt->userData == ctxt)
7322             user_data = NULL;
7323         else
7324             user_data = ctxt->userData;
7325
7326         /*
7327          * Check that this entity is well formed
7328          * 4.3.2: An internal general parsed entity is well-formed
7329          * if its replacement text matches the production labeled
7330          * content.
7331          */
7332         if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7333             ctxt->depth++;
7334             ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
7335                                                       user_data, &list);
7336             ctxt->depth--;
7337
7338         } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7339             ctxt->depth++;
7340             ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
7341                                            user_data, ctxt->depth, ent->URI,
7342                                            ent->ExternalID, &list);
7343             ctxt->depth--;
7344         } else {
7345             ret = XML_ERR_ENTITY_PE_INTERNAL;
7346             xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7347                          "invalid entity type found\n", NULL);
7348         }
7349
7350         /*
7351          * Store the number of entities needing parsing for this entity
7352          * content and do checkings
7353          */
7354         ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
7355         if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
7356             ent->checked |= 1;
7357         if (ret == XML_ERR_ENTITY_LOOP) {
7358             xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7359             xmlFreeNodeList(list);
7360             return;
7361         }
7362         if (xmlParserEntityCheck(ctxt, 0, ent, 0)) {
7363             xmlFreeNodeList(list);
7364             return;
7365         }
7366
7367         if ((ret == XML_ERR_OK) && (list != NULL)) {
7368             if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
7369              (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
7370                 (ent->children == NULL)) {
7371                 ent->children = list;
7372                 if (ctxt->replaceEntities) {
7373                     /*
7374                      * Prune it directly in the generated document
7375                      * except for single text nodes.
7376                      */
7377                     if (((list->type == XML_TEXT_NODE) &&
7378                          (list->next == NULL)) ||
7379                         (ctxt->parseMode == XML_PARSE_READER)) {
7380                         list->parent = (xmlNodePtr) ent;
7381                         list = NULL;
7382                         ent->owner = 1;
7383                     } else {
7384                         ent->owner = 0;
7385                         while (list != NULL) {
7386                             list->parent = (xmlNodePtr) ctxt->node;
7387                             list->doc = ctxt->myDoc;
7388                             if (list->next == NULL)
7389                                 ent->last = list;
7390                             list = list->next;
7391                         }
7392                         list = ent->children;
7393 #ifdef LIBXML_LEGACY_ENABLED
7394                         if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7395                           xmlAddEntityReference(ent, list, NULL);
7396 #endif /* LIBXML_LEGACY_ENABLED */
7397                     }
7398                 } else {
7399                     ent->owner = 1;
7400                     while (list != NULL) {
7401                         list->parent = (xmlNodePtr) ent;
7402                         xmlSetTreeDoc(list, ent->doc);
7403                         if (list->next == NULL)
7404                             ent->last = list;
7405                         list = list->next;
7406                     }
7407                 }
7408             } else {
7409                 xmlFreeNodeList(list);
7410                 list = NULL;
7411             }
7412         } else if ((ret != XML_ERR_OK) &&
7413                    (ret != XML_WAR_UNDECLARED_ENTITY)) {
7414             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7415                      "Entity '%s' failed to parse\n", ent->name);
7416             xmlParserEntityCheck(ctxt, 0, ent, 0);
7417         } else if (list != NULL) {
7418             xmlFreeNodeList(list);
7419             list = NULL;
7420         }
7421         if (ent->checked == 0)
7422             ent->checked = 2;
7423     } else if (ent->checked != 1) {
7424         ctxt->nbentities += ent->checked / 2;
7425     }
7426
7427     /*
7428      * Now that the entity content has been gathered
7429      * provide it to the application, this can take different forms based
7430      * on the parsing modes.
7431      */
7432     if (ent->children == NULL) {
7433         /*
7434          * Probably running in SAX mode and the callbacks don't
7435          * build the entity content. So unless we already went
7436          * though parsing for first checking go though the entity
7437          * content to generate callbacks associated to the entity
7438          */
7439         if (was_checked != 0) {
7440             void *user_data;
7441             /*
7442              * This is a bit hackish but this seems the best
7443              * way to make sure both SAX and DOM entity support
7444              * behaves okay.
7445              */
7446             if (ctxt->userData == ctxt)
7447                 user_data = NULL;
7448             else
7449                 user_data = ctxt->userData;
7450
7451             if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7452                 ctxt->depth++;
7453                 ret = xmlParseBalancedChunkMemoryInternal(ctxt,
7454                                    ent->content, user_data, NULL);
7455                 ctxt->depth--;
7456             } else if (ent->etype ==
7457                        XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7458                 ctxt->depth++;
7459                 ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
7460                            ctxt->sax, user_data, ctxt->depth,
7461                            ent->URI, ent->ExternalID, NULL);
7462                 ctxt->depth--;
7463             } else {
7464                 ret = XML_ERR_ENTITY_PE_INTERNAL;
7465                 xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7466                              "invalid entity type found\n", NULL);
7467             }
7468             if (ret == XML_ERR_ENTITY_LOOP) {
7469                 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7470                 return;
7471             }
7472         }
7473         if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7474             (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7475             /*
7476              * Entity reference callback comes second, it's somewhat
7477              * superfluous but a compatibility to historical behaviour
7478              */
7479             ctxt->sax->reference(ctxt->userData, ent->name);
7480         }
7481         return;
7482     }
7483
7484     /*
7485      * If we didn't get any children for the entity being built
7486      */
7487     if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7488         (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7489         /*
7490          * Create a node.
7491          */
7492         ctxt->sax->reference(ctxt->userData, ent->name);
7493         return;
7494     }
7495
7496     if ((ctxt->replaceEntities) || (ent->children == NULL))  {
7497         /*
7498          * There is a problem on the handling of _private for entities
7499          * (bug 155816): Should we copy the content of the field from
7500          * the entity (possibly overwriting some value set by the user
7501          * when a copy is created), should we leave it alone, or should
7502          * we try to take care of different situations?  The problem
7503          * is exacerbated by the usage of this field by the xmlReader.
7504          * To fix this bug, we look at _private on the created node
7505          * and, if it's NULL, we copy in whatever was in the entity.
7506          * If it's not NULL we leave it alone.  This is somewhat of a
7507          * hack - maybe we should have further tests to determine
7508          * what to do.
7509          */
7510         if ((ctxt->node != NULL) && (ent->children != NULL)) {
7511             /*
7512              * Seems we are generating the DOM content, do
7513              * a simple tree copy for all references except the first
7514              * In the first occurrence list contains the replacement.
7515              */
7516             if (((list == NULL) && (ent->owner == 0)) ||
7517                 (ctxt->parseMode == XML_PARSE_READER)) {
7518                 xmlNodePtr nw = NULL, cur, firstChild = NULL;
7519
7520                 /*
7521                  * We are copying here, make sure there is no abuse
7522                  */
7523                 ctxt->sizeentcopy += ent->length + 5;
7524                 if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
7525                     return;
7526
7527                 /*
7528                  * when operating on a reader, the entities definitions
7529                  * are always owning the entities subtree.
7530                 if (ctxt->parseMode == XML_PARSE_READER)
7531                     ent->owner = 1;
7532                  */
7533
7534                 cur = ent->children;
7535                 while (cur != NULL) {
7536                     nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7537                     if (nw != NULL) {
7538                         if (nw->_private == NULL)
7539                             nw->_private = cur->_private;
7540                         if (firstChild == NULL){
7541                             firstChild = nw;
7542                         }
7543                         nw = xmlAddChild(ctxt->node, nw);
7544                     }
7545                     if (cur == ent->last) {
7546                         /*
7547                          * needed to detect some strange empty
7548                          * node cases in the reader tests
7549                          */
7550                         if ((ctxt->parseMode == XML_PARSE_READER) &&
7551                             (nw != NULL) &&
7552                             (nw->type == XML_ELEMENT_NODE) &&
7553                             (nw->children == NULL))
7554                             nw->extra = 1;
7555
7556                         break;
7557                     }
7558                     cur = cur->next;
7559                 }
7560 #ifdef LIBXML_LEGACY_ENABLED
7561                 if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7562                   xmlAddEntityReference(ent, firstChild, nw);
7563 #endif /* LIBXML_LEGACY_ENABLED */
7564             } else if ((list == NULL) || (ctxt->inputNr > 0)) {
7565                 xmlNodePtr nw = NULL, cur, next, last,
7566                            firstChild = NULL;
7567
7568                 /*
7569                  * We are copying here, make sure there is no abuse
7570                  */
7571                 ctxt->sizeentcopy += ent->length + 5;
7572                 if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
7573                     return;
7574
7575                 /*
7576                  * Copy the entity child list and make it the new
7577                  * entity child list. The goal is to make sure any
7578                  * ID or REF referenced will be the one from the
7579                  * document content and not the entity copy.
7580                  */
7581                 cur = ent->children;
7582                 ent->children = NULL;
7583                 last = ent->last;
7584                 ent->last = NULL;
7585                 while (cur != NULL) {
7586                     next = cur->next;
7587                     cur->next = NULL;
7588                     cur->parent = NULL;
7589                     nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7590                     if (nw != NULL) {
7591                         if (nw->_private == NULL)
7592                             nw->_private = cur->_private;
7593                         if (firstChild == NULL){
7594                             firstChild = cur;
7595                         }
7596                         xmlAddChild((xmlNodePtr) ent, nw);
7597                         xmlAddChild(ctxt->node, cur);
7598                     }
7599                     if (cur == last)
7600                         break;
7601                     cur = next;
7602                 }
7603                 if (ent->owner == 0)
7604                     ent->owner = 1;
7605 #ifdef LIBXML_LEGACY_ENABLED
7606                 if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7607                   xmlAddEntityReference(ent, firstChild, nw);
7608 #endif /* LIBXML_LEGACY_ENABLED */
7609             } else {
7610                 const xmlChar *nbktext;
7611
7612                 /*
7613                  * the name change is to avoid coalescing of the
7614                  * node with a possible previous text one which
7615                  * would make ent->children a dangling pointer
7616                  */
7617                 nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
7618                                         -1);
7619                 if (ent->children->type == XML_TEXT_NODE)
7620                     ent->children->name = nbktext;
7621                 if ((ent->last != ent->children) &&
7622                     (ent->last->type == XML_TEXT_NODE))
7623                     ent->last->name = nbktext;
7624                 xmlAddChildList(ctxt->node, ent->children);
7625             }
7626
7627             /*
7628              * This is to avoid a nasty side effect, see
7629              * characters() in SAX.c
7630              */
7631             ctxt->nodemem = 0;
7632             ctxt->nodelen = 0;
7633             return;
7634         }
7635     }
7636 }
7637
7638 /**
7639  * xmlParseEntityRef:
7640  * @ctxt:  an XML parser context
7641  *
7642  * parse ENTITY references declarations
7643  *
7644  * [68] EntityRef ::= '&' Name ';'
7645  *
7646  * [ WFC: Entity Declared ]
7647  * In a document without any DTD, a document with only an internal DTD
7648  * subset which contains no parameter entity references, or a document
7649  * with "standalone='yes'", the Name given in the entity reference
7650  * must match that in an entity declaration, except that well-formed
7651  * documents need not declare any of the following entities: amp, lt,
7652  * gt, apos, quot.  The declaration of a parameter entity must precede
7653  * any reference to it.  Similarly, the declaration of a general entity
7654  * must precede any reference to it which appears in a default value in an
7655  * attribute-list declaration. Note that if entities are declared in the
7656  * external subset or in external parameter entities, a non-validating
7657  * processor is not obligated to read and process their declarations;
7658  * for such documents, the rule that an entity must be declared is a
7659  * well-formedness constraint only if standalone='yes'.
7660  *
7661  * [ WFC: Parsed Entity ]
7662  * An entity reference must not contain the name of an unparsed entity
7663  *
7664  * Returns the xmlEntityPtr if found, or NULL otherwise.
7665  */
7666 xmlEntityPtr
7667 xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
7668     const xmlChar *name;
7669     xmlEntityPtr ent = NULL;
7670
7671     GROW;
7672     if (ctxt->instate == XML_PARSER_EOF)
7673         return(NULL);
7674
7675     if (RAW != '&')
7676         return(NULL);
7677     NEXT;
7678     name = xmlParseName(ctxt);
7679     if (name == NULL) {
7680         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7681                        "xmlParseEntityRef: no name\n");
7682         return(NULL);
7683     }
7684     if (RAW != ';') {
7685         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7686         return(NULL);
7687     }
7688     NEXT;
7689
7690     /*
7691      * Predefined entities override any extra definition
7692      */
7693     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7694         ent = xmlGetPredefinedEntity(name);
7695         if (ent != NULL)
7696             return(ent);
7697     }
7698
7699     /*
7700      * Increase the number of entity references parsed
7701      */
7702     ctxt->nbentities++;
7703
7704     /*
7705      * Ask first SAX for entity resolution, otherwise try the
7706      * entities which may have stored in the parser context.
7707      */
7708     if (ctxt->sax != NULL) {
7709         if (ctxt->sax->getEntity != NULL)
7710             ent = ctxt->sax->getEntity(ctxt->userData, name);
7711         if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7712             (ctxt->options & XML_PARSE_OLDSAX))
7713             ent = xmlGetPredefinedEntity(name);
7714         if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7715             (ctxt->userData==ctxt)) {
7716             ent = xmlSAX2GetEntity(ctxt, name);
7717         }
7718     }
7719     if (ctxt->instate == XML_PARSER_EOF)
7720         return(NULL);
7721     /*
7722      * [ WFC: Entity Declared ]
7723      * In a document without any DTD, a document with only an
7724      * internal DTD subset which contains no parameter entity
7725      * references, or a document with "standalone='yes'", the
7726      * Name given in the entity reference must match that in an
7727      * entity declaration, except that well-formed documents
7728      * need not declare any of the following entities: amp, lt,
7729      * gt, apos, quot.
7730      * The declaration of a parameter entity must precede any
7731      * reference to it.
7732      * Similarly, the declaration of a general entity must
7733      * precede any reference to it which appears in a default
7734      * value in an attribute-list declaration. Note that if
7735      * entities are declared in the external subset or in
7736      * external parameter entities, a non-validating processor
7737      * is not obligated to read and process their declarations;
7738      * for such documents, the rule that an entity must be
7739      * declared is a well-formedness constraint only if
7740      * standalone='yes'.
7741      */
7742     if (ent == NULL) {
7743         if ((ctxt->standalone == 1) ||
7744             ((ctxt->hasExternalSubset == 0) &&
7745              (ctxt->hasPErefs == 0))) {
7746             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7747                      "Entity '%s' not defined\n", name);
7748         } else {
7749             xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7750                      "Entity '%s' not defined\n", name);
7751             if ((ctxt->inSubset == 0) &&
7752                 (ctxt->sax != NULL) &&
7753                 (ctxt->sax->reference != NULL)) {
7754                 ctxt->sax->reference(ctxt->userData, name);
7755             }
7756         }
7757         xmlParserEntityCheck(ctxt, 0, ent, 0);
7758         ctxt->valid = 0;
7759     }
7760
7761     /*
7762      * [ WFC: Parsed Entity ]
7763      * An entity reference must not contain the name of an
7764      * unparsed entity
7765      */
7766     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7767         xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7768                  "Entity reference to unparsed entity %s\n", name);
7769     }
7770
7771     /*
7772      * [ WFC: No External Entity References ]
7773      * Attribute values cannot contain direct or indirect
7774      * entity references to external entities.
7775      */
7776     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7777              (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7778         xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7779              "Attribute references external entity '%s'\n", name);
7780     }
7781     /*
7782      * [ WFC: No < in Attribute Values ]
7783      * The replacement text of any entity referred to directly or
7784      * indirectly in an attribute value (other than "&lt;") must
7785      * not contain a <.
7786      */
7787     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7788              (ent != NULL) && 
7789              (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
7790         if (((ent->checked & 1) || (ent->checked == 0)) &&
7791              (ent->content != NULL) && (xmlStrchr(ent->content, '<'))) {
7792             xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7793         "'<' in entity '%s' is not allowed in attributes values\n", name);
7794         }
7795     }
7796
7797     /*
7798      * Internal check, no parameter entities here ...
7799      */
7800     else {
7801         switch (ent->etype) {
7802             case XML_INTERNAL_PARAMETER_ENTITY:
7803             case XML_EXTERNAL_PARAMETER_ENTITY:
7804             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7805              "Attempt to reference the parameter entity '%s'\n",
7806                               name);
7807             break;
7808             default:
7809             break;
7810         }
7811     }
7812
7813     /*
7814      * [ WFC: No Recursion ]
7815      * A parsed entity must not contain a recursive reference
7816      * to itself, either directly or indirectly.
7817      * Done somewhere else
7818      */
7819     return(ent);
7820 }
7821
7822 /**
7823  * xmlParseStringEntityRef:
7824  * @ctxt:  an XML parser context
7825  * @str:  a pointer to an index in the string
7826  *
7827  * parse ENTITY references declarations, but this version parses it from
7828  * a string value.
7829  *
7830  * [68] EntityRef ::= '&' Name ';'
7831  *
7832  * [ WFC: Entity Declared ]
7833  * In a document without any DTD, a document with only an internal DTD
7834  * subset which contains no parameter entity references, or a document
7835  * with "standalone='yes'", the Name given in the entity reference
7836  * must match that in an entity declaration, except that well-formed
7837  * documents need not declare any of the following entities: amp, lt,
7838  * gt, apos, quot.  The declaration of a parameter entity must precede
7839  * any reference to it.  Similarly, the declaration of a general entity
7840  * must precede any reference to it which appears in a default value in an
7841  * attribute-list declaration. Note that if entities are declared in the
7842  * external subset or in external parameter entities, a non-validating
7843  * processor is not obligated to read and process their declarations;
7844  * for such documents, the rule that an entity must be declared is a
7845  * well-formedness constraint only if standalone='yes'.
7846  *
7847  * [ WFC: Parsed Entity ]
7848  * An entity reference must not contain the name of an unparsed entity
7849  *
7850  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
7851  * is updated to the current location in the string.
7852  */
7853 static xmlEntityPtr
7854 xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
7855     xmlChar *name;
7856     const xmlChar *ptr;
7857     xmlChar cur;
7858     xmlEntityPtr ent = NULL;
7859
7860     if ((str == NULL) || (*str == NULL))
7861         return(NULL);
7862     ptr = *str;
7863     cur = *ptr;
7864     if (cur != '&')
7865         return(NULL);
7866
7867     ptr++;
7868     name = xmlParseStringName(ctxt, &ptr);
7869     if (name == NULL) {
7870         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7871                        "xmlParseStringEntityRef: no name\n");
7872         *str = ptr;
7873         return(NULL);
7874     }
7875     if (*ptr != ';') {
7876         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7877         xmlFree(name);
7878         *str = ptr;
7879         return(NULL);
7880     }
7881     ptr++;
7882
7883
7884     /*
7885      * Predefined entities override any extra definition
7886      */
7887     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7888         ent = xmlGetPredefinedEntity(name);
7889         if (ent != NULL) {
7890             xmlFree(name);
7891             *str = ptr;
7892             return(ent);
7893         }
7894     }
7895
7896     /*
7897      * Increate the number of entity references parsed
7898      */
7899     ctxt->nbentities++;
7900
7901     /*
7902      * Ask first SAX for entity resolution, otherwise try the
7903      * entities which may have stored in the parser context.
7904      */
7905     if (ctxt->sax != NULL) {
7906         if (ctxt->sax->getEntity != NULL)
7907             ent = ctxt->sax->getEntity(ctxt->userData, name);
7908         if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
7909             ent = xmlGetPredefinedEntity(name);
7910         if ((ent == NULL) && (ctxt->userData==ctxt)) {
7911             ent = xmlSAX2GetEntity(ctxt, name);
7912         }
7913     }
7914     if (ctxt->instate == XML_PARSER_EOF) {
7915         xmlFree(name);
7916         return(NULL);
7917     }
7918
7919     /*
7920      * [ WFC: Entity Declared ]
7921      * In a document without any DTD, a document with only an
7922      * internal DTD subset which contains no parameter entity
7923      * references, or a document with "standalone='yes'", the
7924      * Name given in the entity reference must match that in an
7925      * entity declaration, except that well-formed documents
7926      * need not declare any of the following entities: amp, lt,
7927      * gt, apos, quot.
7928      * The declaration of a parameter entity must precede any
7929      * reference to it.
7930      * Similarly, the declaration of a general entity must
7931      * precede any reference to it which appears in a default
7932      * value in an attribute-list declaration. Note that if
7933      * entities are declared in the external subset or in
7934      * external parameter entities, a non-validating processor
7935      * is not obligated to read and process their declarations;
7936      * for such documents, the rule that an entity must be
7937      * declared is a well-formedness constraint only if
7938      * standalone='yes'.
7939      */
7940     if (ent == NULL) {
7941         if ((ctxt->standalone == 1) ||
7942             ((ctxt->hasExternalSubset == 0) &&
7943              (ctxt->hasPErefs == 0))) {
7944             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7945                      "Entity '%s' not defined\n", name);
7946         } else {
7947             xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7948                           "Entity '%s' not defined\n",
7949                           name);
7950         }
7951         xmlParserEntityCheck(ctxt, 0, ent, 0);
7952         /* TODO ? check regressions ctxt->valid = 0; */
7953     }
7954
7955     /*
7956      * [ WFC: Parsed Entity ]
7957      * An entity reference must not contain the name of an
7958      * unparsed entity
7959      */
7960     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7961         xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7962                  "Entity reference to unparsed entity %s\n", name);
7963     }
7964
7965     /*
7966      * [ WFC: No External Entity References ]
7967      * Attribute values cannot contain direct or indirect
7968      * entity references to external entities.
7969      */
7970     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7971              (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7972         xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7973          "Attribute references external entity '%s'\n", name);
7974     }
7975     /*
7976      * [ WFC: No < in Attribute Values ]
7977      * The replacement text of any entity referred to directly or
7978      * indirectly in an attribute value (other than "&lt;") must
7979      * not contain a <.
7980      */
7981     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7982              (ent != NULL) && (ent->content != NULL) &&
7983              (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
7984              (xmlStrchr(ent->content, '<'))) {
7985         xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7986      "'<' in entity '%s' is not allowed in attributes values\n",
7987                           name);
7988     }
7989
7990     /*
7991      * Internal check, no parameter entities here ...
7992      */
7993     else {
7994         switch (ent->etype) {
7995             case XML_INTERNAL_PARAMETER_ENTITY:
7996             case XML_EXTERNAL_PARAMETER_ENTITY:
7997                 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7998              "Attempt to reference the parameter entity '%s'\n",
7999                                   name);
8000             break;
8001             default:
8002             break;
8003         }
8004     }
8005
8006     /*
8007      * [ WFC: No Recursion ]
8008      * A parsed entity must not contain a recursive reference
8009      * to itself, either directly or indirectly.
8010      * Done somewhere else
8011      */
8012
8013     xmlFree(name);
8014     *str = ptr;
8015     return(ent);
8016 }
8017
8018 /**
8019  * xmlParsePEReference:
8020  * @ctxt:  an XML parser context
8021  *
8022  * parse PEReference declarations
8023  * The entity content is handled directly by pushing it's content as
8024  * a new input stream.
8025  *
8026  * [69] PEReference ::= '%' Name ';'
8027  *
8028  * [ WFC: No Recursion ]
8029  * A parsed entity must not contain a recursive
8030  * reference to itself, either directly or indirectly.
8031  *
8032  * [ WFC: Entity Declared ]
8033  * In a document without any DTD, a document with only an internal DTD
8034  * subset which contains no parameter entity references, or a document
8035  * with "standalone='yes'", ...  ... The declaration of a parameter
8036  * entity must precede any reference to it...
8037  *
8038  * [ VC: Entity Declared ]
8039  * In a document with an external subset or external parameter entities
8040  * with "standalone='no'", ...  ... The declaration of a parameter entity
8041  * must precede any reference to it...
8042  *
8043  * [ WFC: In DTD ]
8044  * Parameter-entity references may only appear in the DTD.
8045  * NOTE: misleading but this is handled.
8046  */
8047 void
8048 xmlParsePEReference(xmlParserCtxtPtr ctxt)
8049 {
8050     const xmlChar *name;
8051     xmlEntityPtr entity = NULL;
8052     xmlParserInputPtr input;
8053
8054     if (RAW != '%')
8055         return;
8056     NEXT;
8057     name = xmlParseName(ctxt);
8058     if (name == NULL) {
8059         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8060                        "xmlParsePEReference: no name\n");
8061         return;
8062     }
8063     if (RAW != ';') {
8064         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
8065         return;
8066     }
8067
8068     NEXT;
8069
8070     /*
8071      * Increate the number of entity references parsed
8072      */
8073     ctxt->nbentities++;
8074
8075     /*
8076      * Request the entity from SAX
8077      */
8078     if ((ctxt->sax != NULL) &&
8079         (ctxt->sax->getParameterEntity != NULL))
8080         entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
8081     if (ctxt->instate == XML_PARSER_EOF)
8082         return;
8083     if (entity == NULL) {
8084         /*
8085          * [ WFC: Entity Declared ]
8086          * In a document without any DTD, a document with only an
8087          * internal DTD subset which contains no parameter entity
8088          * references, or a document with "standalone='yes'", ...
8089          * ... The declaration of a parameter entity must precede
8090          * any reference to it...
8091          */
8092         if ((ctxt->standalone == 1) ||
8093             ((ctxt->hasExternalSubset == 0) &&
8094              (ctxt->hasPErefs == 0))) {
8095             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
8096                               "PEReference: %%%s; not found\n",
8097                               name);
8098         } else {
8099             /*
8100              * [ VC: Entity Declared ]
8101              * In a document with an external subset or external
8102              * parameter entities with "standalone='no'", ...
8103              * ... The declaration of a parameter entity must
8104              * precede any reference to it...
8105              */
8106             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8107                           "PEReference: %%%s; not found\n",
8108                           name, NULL);
8109             ctxt->valid = 0;
8110         }
8111         xmlParserEntityCheck(ctxt, 0, NULL, 0);
8112     } else {
8113         /*
8114          * Internal checking in case the entity quest barfed
8115          */
8116         if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
8117             (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
8118             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8119                   "Internal: %%%s; is not a parameter entity\n",
8120                           name, NULL);
8121         } else if (ctxt->input->free != deallocblankswrapper) {
8122             input = xmlNewBlanksWrapperInputStream(ctxt, entity);
8123             if (xmlPushInput(ctxt, input) < 0)
8124                 return;
8125         } else {
8126             /*
8127              * TODO !!!
8128              * handle the extra spaces added before and after
8129              * c.f. http://www.w3.org/TR/REC-xml#as-PE
8130              */
8131             input = xmlNewEntityInputStream(ctxt, entity);
8132             if (xmlPushInput(ctxt, input) < 0)
8133                 return;
8134             if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
8135                 (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
8136                 (IS_BLANK_CH(NXT(5)))) {
8137                 xmlParseTextDecl(ctxt);
8138                 if (ctxt->errNo ==
8139                     XML_ERR_UNSUPPORTED_ENCODING) {
8140                     /*
8141                      * The XML REC instructs us to stop parsing
8142                      * right here
8143                      */
8144                     xmlHaltParser(ctxt);
8145                     return;
8146                 }
8147             }
8148         }
8149     }
8150     ctxt->hasPErefs = 1;
8151 }
8152
8153 /**
8154  * xmlLoadEntityContent:
8155  * @ctxt:  an XML parser context
8156  * @entity: an unloaded system entity
8157  *
8158  * Load the original content of the given system entity from the
8159  * ExternalID/SystemID given. This is to be used for Included in Literal
8160  * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
8161  *
8162  * Returns 0 in case of success and -1 in case of failure
8163  */
8164 static int
8165 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
8166     xmlParserInputPtr input;
8167     xmlBufferPtr buf;
8168     int l, c;
8169     int count = 0;
8170
8171     if ((ctxt == NULL) || (entity == NULL) ||
8172         ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
8173          (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
8174         (entity->content != NULL)) {
8175         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8176                     "xmlLoadEntityContent parameter error");
8177         return(-1);
8178     }
8179
8180     if (xmlParserDebugEntities)
8181         xmlGenericError(xmlGenericErrorContext,
8182                 "Reading %s entity content input\n", entity->name);
8183
8184     buf = xmlBufferCreate();
8185     if (buf == NULL) {
8186         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8187                     "xmlLoadEntityContent parameter error");
8188         return(-1);
8189     }
8190
8191     input = xmlNewEntityInputStream(ctxt, entity);
8192     if (input == NULL) {
8193         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8194                     "xmlLoadEntityContent input error");
8195         xmlBufferFree(buf);
8196         return(-1);
8197     }
8198
8199     /*
8200      * Push the entity as the current input, read char by char
8201      * saving to the buffer until the end of the entity or an error
8202      */
8203     if (xmlPushInput(ctxt, input) < 0) {
8204         xmlBufferFree(buf);
8205         return(-1);
8206     }
8207
8208     GROW;
8209     c = CUR_CHAR(l);
8210     while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
8211            (IS_CHAR(c))) {
8212         xmlBufferAdd(buf, ctxt->input->cur, l);
8213         if (count++ > XML_PARSER_CHUNK_SIZE) {
8214             count = 0;
8215             GROW;
8216             if (ctxt->instate == XML_PARSER_EOF) {
8217                 xmlBufferFree(buf);
8218                 return(-1);
8219             }
8220         }
8221         NEXTL(l);
8222         c = CUR_CHAR(l);
8223         if (c == 0) {
8224             count = 0;
8225             GROW;
8226             if (ctxt->instate == XML_PARSER_EOF) {
8227                 xmlBufferFree(buf);
8228                 return(-1);
8229             }
8230             c = CUR_CHAR(l);
8231         }
8232     }
8233
8234     if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
8235         xmlPopInput(ctxt);
8236     } else if (!IS_CHAR(c)) {
8237         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
8238                           "xmlLoadEntityContent: invalid char value %d\n",
8239                           c);
8240         xmlBufferFree(buf);
8241         return(-1);
8242     }
8243     entity->content = buf->content;
8244     buf->content = NULL;
8245     xmlBufferFree(buf);
8246
8247     return(0);
8248 }
8249
8250 /**
8251  * xmlParseStringPEReference:
8252  * @ctxt:  an XML parser context
8253  * @str:  a pointer to an index in the string
8254  *
8255  * parse PEReference declarations
8256  *
8257  * [69] PEReference ::= '%' Name ';'
8258  *
8259  * [ WFC: No Recursion ]
8260  * A parsed entity must not contain a recursive
8261  * reference to itself, either directly or indirectly.
8262  *
8263  * [ WFC: Entity Declared ]
8264  * In a document without any DTD, a document with only an internal DTD
8265  * subset which contains no parameter entity references, or a document
8266  * with "standalone='yes'", ...  ... The declaration of a parameter
8267  * entity must precede any reference to it...
8268  *
8269  * [ VC: Entity Declared ]
8270  * In a document with an external subset or external parameter entities
8271  * with "standalone='no'", ...  ... The declaration of a parameter entity
8272  * must precede any reference to it...
8273  *
8274  * [ WFC: In DTD ]
8275  * Parameter-entity references may only appear in the DTD.
8276  * NOTE: misleading but this is handled.
8277  *
8278  * Returns the string of the entity content.
8279  *         str is updated to the current value of the index
8280  */
8281 static xmlEntityPtr
8282 xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
8283     const xmlChar *ptr;
8284     xmlChar cur;
8285     xmlChar *name;
8286     xmlEntityPtr entity = NULL;
8287
8288     if ((str == NULL) || (*str == NULL)) return(NULL);
8289     ptr = *str;
8290     cur = *ptr;
8291     if (cur != '%')
8292         return(NULL);
8293     ptr++;
8294     name = xmlParseStringName(ctxt, &ptr);
8295     if (name == NULL) {
8296         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8297                        "xmlParseStringPEReference: no name\n");
8298         *str = ptr;
8299         return(NULL);
8300     }
8301     cur = *ptr;
8302     if (cur != ';') {
8303         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
8304         xmlFree(name);
8305         *str = ptr;
8306         return(NULL);
8307     }
8308     ptr++;
8309
8310     /*
8311      * Increate the number of entity references parsed
8312      */
8313     ctxt->nbentities++;
8314
8315     /*
8316      * Request the entity from SAX
8317      */
8318     if ((ctxt->sax != NULL) &&
8319         (ctxt->sax->getParameterEntity != NULL))
8320         entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
8321     if (ctxt->instate == XML_PARSER_EOF) {
8322         xmlFree(name);
8323         return(NULL);
8324     }
8325     if (entity == NULL) {
8326         /*
8327          * [ WFC: Entity Declared ]
8328          * In a document without any DTD, a document with only an
8329          * internal DTD subset which contains no parameter entity
8330          * references, or a document with "standalone='yes'", ...
8331          * ... The declaration of a parameter entity must precede
8332          * any reference to it...
8333          */
8334         if ((ctxt->standalone == 1) ||
8335             ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
8336             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
8337                  "PEReference: %%%s; not found\n", name);
8338         } else {
8339             /*
8340              * [ VC: Entity Declared ]
8341              * In a document with an external subset or external
8342              * parameter entities with "standalone='no'", ...
8343              * ... The declaration of a parameter entity must
8344              * precede any reference to it...
8345              */
8346             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8347                           "PEReference: %%%s; not found\n",
8348                           name, NULL);
8349             ctxt->valid = 0;
8350         }
8351         xmlParserEntityCheck(ctxt, 0, NULL, 0);
8352     } else {
8353         /*
8354          * Internal checking in case the entity quest barfed
8355          */
8356         if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
8357             (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
8358             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8359                           "%%%s; is not a parameter entity\n",
8360                           name, NULL);
8361         }
8362     }
8363     ctxt->hasPErefs = 1;
8364     xmlFree(name);
8365     *str = ptr;
8366     return(entity);
8367 }
8368
8369 /**
8370  * xmlParseDocTypeDecl:
8371  * @ctxt:  an XML parser context
8372  *
8373  * parse a DOCTYPE declaration
8374  *
8375  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
8376  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8377  *
8378  * [ VC: Root Element Type ]
8379  * The Name in the document type declaration must match the element
8380  * type of the root element.
8381  */
8382
8383 void
8384 xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
8385     const xmlChar *name = NULL;
8386     xmlChar *ExternalID = NULL;
8387     xmlChar *URI = NULL;
8388
8389     /*
8390      * We know that '<!DOCTYPE' has been detected.
8391      */
8392     SKIP(9);
8393
8394     SKIP_BLANKS;
8395
8396     /*
8397      * Parse the DOCTYPE name.
8398      */
8399     name = xmlParseName(ctxt);
8400     if (name == NULL) {
8401         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8402                        "xmlParseDocTypeDecl : no DOCTYPE name !\n");
8403     }
8404     ctxt->intSubName = name;
8405
8406     SKIP_BLANKS;
8407
8408     /*
8409      * Check for SystemID and ExternalID
8410      */
8411     URI = xmlParseExternalID(ctxt, &ExternalID, 1);
8412
8413     if ((URI != NULL) || (ExternalID != NULL)) {
8414         ctxt->hasExternalSubset = 1;
8415     }
8416     ctxt->extSubURI = URI;
8417     ctxt->extSubSystem = ExternalID;
8418
8419     SKIP_BLANKS;
8420
8421     /*
8422      * Create and update the internal subset.
8423      */
8424     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
8425         (!ctxt->disableSAX))
8426         ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
8427     if (ctxt->instate == XML_PARSER_EOF)
8428         return;
8429
8430     /*
8431      * Is there any internal subset declarations ?
8432      * they are handled separately in xmlParseInternalSubset()
8433      */
8434     if (RAW == '[')
8435         return;
8436
8437     /*
8438      * We should be at the end of the DOCTYPE declaration.
8439      */
8440     if (RAW != '>') {
8441         xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8442     }
8443     NEXT;
8444 }
8445
8446 /**
8447  * xmlParseInternalSubset:
8448  * @ctxt:  an XML parser context
8449  *
8450  * parse the internal subset declaration
8451  *
8452  * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8453  */
8454
8455 static void
8456 xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
8457     /*
8458      * Is there any DTD definition ?
8459      */
8460     if (RAW == '[') {
8461         ctxt->instate = XML_PARSER_DTD;
8462         NEXT;
8463         /*
8464          * Parse the succession of Markup declarations and
8465          * PEReferences.
8466          * Subsequence (markupdecl | PEReference | S)*
8467          */
8468         while ((RAW != ']') && (ctxt->instate != XML_PARSER_EOF)) {
8469             const xmlChar *check = CUR_PTR;
8470             unsigned int cons = ctxt->input->consumed;
8471
8472             SKIP_BLANKS;
8473             xmlParseMarkupDecl(ctxt);
8474             xmlParsePEReference(ctxt);
8475
8476             /*
8477              * Pop-up of finished entities.
8478              */
8479             while ((RAW == 0) && (ctxt->inputNr > 1))
8480                 xmlPopInput(ctxt);
8481
8482             if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
8483                 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8484              "xmlParseInternalSubset: error detected in Markup declaration\n");
8485                 break;
8486             }
8487         }
8488         if (RAW == ']') {
8489             NEXT;
8490             SKIP_BLANKS;
8491         }
8492     }
8493
8494     /*
8495      * We should be at the end of the DOCTYPE declaration.
8496      */
8497     if (RAW != '>') {
8498         xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8499         return;
8500     }
8501     NEXT;
8502 }
8503
8504 #ifdef LIBXML_SAX1_ENABLED
8505 /**
8506  * xmlParseAttribute:
8507  * @ctxt:  an XML parser context
8508  * @value:  a xmlChar ** used to store the value of the attribute
8509  *
8510  * parse an attribute
8511  *
8512  * [41] Attribute ::= Name Eq AttValue
8513  *
8514  * [ WFC: No External Entity References ]
8515  * Attribute values cannot contain direct or indirect entity references
8516  * to external entities.
8517  *
8518  * [ WFC: No < in Attribute Values ]
8519  * The replacement text of any entity referred to directly or indirectly in
8520  * an attribute value (other than "&lt;") must not contain a <.
8521  *
8522  * [ VC: Attribute Value Type ]
8523  * The attribute must have been declared; the value must be of the type
8524  * declared for it.
8525  *
8526  * [25] Eq ::= S? '=' S?
8527  *
8528  * With namespace:
8529  *
8530  * [NS 11] Attribute ::= QName Eq AttValue
8531  *
8532  * Also the case QName == xmlns:??? is handled independently as a namespace
8533  * definition.
8534  *
8535  * Returns the attribute name, and the value in *value.
8536  */
8537
8538 const xmlChar *
8539 xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
8540     const xmlChar *name;
8541     xmlChar *val;
8542
8543     *value = NULL;
8544     GROW;
8545     name = xmlParseName(ctxt);
8546     if (name == NULL) {
8547         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8548                        "error parsing attribute name\n");
8549         return(NULL);
8550     }
8551
8552     /*
8553      * read the value
8554      */
8555     SKIP_BLANKS;
8556     if (RAW == '=') {
8557         NEXT;
8558         SKIP_BLANKS;
8559         val = xmlParseAttValue(ctxt);
8560         ctxt->instate = XML_PARSER_CONTENT;
8561     } else {
8562         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8563                "Specification mandate value for attribute %s\n", name);
8564         return(NULL);
8565     }
8566
8567     /*
8568      * Check that xml:lang conforms to the specification
8569      * No more registered as an error, just generate a warning now
8570      * since this was deprecated in XML second edition
8571      */
8572     if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
8573         if (!xmlCheckLanguageID(val)) {
8574             xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
8575                           "Malformed value for xml:lang : %s\n",
8576                           val, NULL);
8577         }
8578     }
8579
8580     /*
8581      * Check that xml:space conforms to the specification
8582      */
8583     if (xmlStrEqual(name, BAD_CAST "xml:space")) {
8584         if (xmlStrEqual(val, BAD_CAST "default"))
8585             *(ctxt->space) = 0;
8586         else if (xmlStrEqual(val, BAD_CAST "preserve"))
8587             *(ctxt->space) = 1;
8588         else {
8589                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
8590 "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
8591                                  val, NULL);
8592         }
8593     }
8594
8595     *value = val;
8596     return(name);
8597 }
8598
8599 /**
8600  * xmlParseStartTag:
8601  * @ctxt:  an XML parser context
8602  *
8603  * parse a start of tag either for rule element or
8604  * EmptyElement. In both case we don't parse the tag closing chars.
8605  *
8606  * [40] STag ::= '<' Name (S Attribute)* S? '>'
8607  *
8608  * [ WFC: Unique Att Spec ]
8609  * No attribute name may appear more than once in the same start-tag or
8610  * empty-element tag.
8611  *
8612  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
8613  *
8614  * [ WFC: Unique Att Spec ]
8615  * No attribute name may appear more than once in the same start-tag or
8616  * empty-element tag.
8617  *
8618  * With namespace:
8619  *
8620  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
8621  *
8622  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
8623  *
8624  * Returns the element name parsed
8625  */
8626
8627 const xmlChar *
8628 xmlParseStartTag(xmlParserCtxtPtr ctxt) {
8629     const xmlChar *name;
8630     const xmlChar *attname;
8631     xmlChar *attvalue;
8632     const xmlChar **atts = ctxt->atts;
8633     int nbatts = 0;
8634     int maxatts = ctxt->maxatts;
8635     int i;
8636
8637     if (RAW != '<') return(NULL);
8638     NEXT1;
8639
8640     name = xmlParseName(ctxt);
8641     if (name == NULL) {
8642         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8643              "xmlParseStartTag: invalid element name\n");
8644         return(NULL);
8645     }
8646
8647     /*
8648      * Now parse the attributes, it ends up with the ending
8649      *
8650      * (S Attribute)* S?
8651      */
8652     SKIP_BLANKS;
8653     GROW;
8654
8655     while (((RAW != '>') &&
8656            ((RAW != '/') || (NXT(1) != '>')) &&
8657            (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
8658         const xmlChar *q = CUR_PTR;
8659         unsigned int cons = ctxt->input->consumed;
8660
8661         attname = xmlParseAttribute(ctxt, &attvalue);
8662         if ((attname != NULL) && (attvalue != NULL)) {
8663             /*
8664              * [ WFC: Unique Att Spec ]
8665              * No attribute name may appear more than once in the same
8666              * start-tag or empty-element tag.
8667              */
8668             for (i = 0; i < nbatts;i += 2) {
8669                 if (xmlStrEqual(atts[i], attname)) {
8670                     xmlErrAttributeDup(ctxt, NULL, attname);
8671                     xmlFree(attvalue);
8672                     goto failed;
8673                 }
8674             }
8675             /*
8676              * Add the pair to atts
8677              */
8678             if (atts == NULL) {
8679                 maxatts = 22; /* allow for 10 attrs by default */
8680                 atts = (const xmlChar **)
8681                        xmlMalloc(maxatts * sizeof(xmlChar *));
8682                 if (atts == NULL) {
8683                     xmlErrMemory(ctxt, NULL);
8684                     if (attvalue != NULL)
8685                         xmlFree(attvalue);
8686                     goto failed;
8687                 }
8688                 ctxt->atts = atts;
8689                 ctxt->maxatts = maxatts;
8690             } else if (nbatts + 4 > maxatts) {
8691                 const xmlChar **n;
8692
8693                 maxatts *= 2;
8694                 n = (const xmlChar **) xmlRealloc((void *) atts,
8695                                              maxatts * sizeof(const xmlChar *));
8696                 if (n == NULL) {
8697                     xmlErrMemory(ctxt, NULL);
8698                     if (attvalue != NULL)
8699                         xmlFree(attvalue);
8700                     goto failed;
8701                 }
8702                 atts = n;
8703                 ctxt->atts = atts;
8704                 ctxt->maxatts = maxatts;
8705             }
8706             atts[nbatts++] = attname;
8707             atts[nbatts++] = attvalue;
8708             atts[nbatts] = NULL;
8709             atts[nbatts + 1] = NULL;
8710         } else {
8711             if (attvalue != NULL)
8712                 xmlFree(attvalue);
8713         }
8714
8715 failed:
8716
8717         GROW
8718         if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
8719             break;
8720         if (!IS_BLANK_CH(RAW)) {
8721             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
8722                            "attributes construct error\n");
8723         }
8724         SKIP_BLANKS;
8725         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
8726             (attname == NULL) && (attvalue == NULL)) {
8727             xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
8728                            "xmlParseStartTag: problem parsing attributes\n");
8729             break;
8730         }
8731         SHRINK;
8732         GROW;
8733     }
8734
8735     /*
8736      * SAX: Start of Element !
8737      */
8738     if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
8739         (!ctxt->disableSAX)) {
8740         if (nbatts > 0)
8741             ctxt->sax->startElement(ctxt->userData, name, atts);
8742         else
8743             ctxt->sax->startElement(ctxt->userData, name, NULL);
8744     }
8745
8746     if (atts != NULL) {
8747         /* Free only the content strings */
8748         for (i = 1;i < nbatts;i+=2)
8749             if (atts[i] != NULL)
8750                xmlFree((xmlChar *) atts[i]);
8751     }
8752     return(name);
8753 }
8754
8755 /**
8756  * xmlParseEndTag1:
8757  * @ctxt:  an XML parser context
8758  * @line:  line of the start tag
8759  * @nsNr:  number of namespaces on the start tag
8760  *
8761  * parse an end of tag
8762  *
8763  * [42] ETag ::= '</' Name S? '>'
8764  *
8765  * With namespace
8766  *
8767  * [NS 9] ETag ::= '</' QName S? '>'
8768  */
8769
8770 static void
8771 xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
8772     const xmlChar *name;
8773
8774     GROW;
8775     if ((RAW != '<') || (NXT(1) != '/')) {
8776         xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
8777                        "xmlParseEndTag: '</' not found\n");
8778         return;
8779     }
8780     SKIP(2);
8781
8782     name = xmlParseNameAndCompare(ctxt,ctxt->name);
8783
8784     /*
8785      * We should definitely be at the ending "S? '>'" part
8786      */
8787     GROW;
8788     SKIP_BLANKS;
8789     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
8790         xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
8791     } else
8792         NEXT1;
8793
8794     /*
8795      * [ WFC: Element Type Match ]
8796      * The Name in an element's end-tag must match the element type in the
8797      * start-tag.
8798      *
8799      */
8800     if (name != (xmlChar*)1) {
8801         if (name == NULL) name = BAD_CAST "unparseable";
8802         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
8803                      "Opening and ending tag mismatch: %s line %d and %s\n",
8804                                 ctxt->name, line, name);
8805     }
8806
8807     /*
8808      * SAX: End of Tag
8809      */
8810     if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
8811         (!ctxt->disableSAX))
8812         ctxt->sax->endElement(ctxt->userData, ctxt->name);
8813
8814     namePop(ctxt);
8815     spacePop(ctxt);
8816     return;
8817 }
8818
8819 /**
8820  * xmlParseEndTag:
8821  * @ctxt:  an XML parser context
8822  *
8823  * parse an end of tag
8824  *
8825  * [42] ETag ::= '</' Name S? '>'
8826  *
8827  * With namespace
8828  *
8829  * [NS 9] ETag ::= '</' QName S? '>'
8830  */
8831
8832 void
8833 xmlParseEndTag(xmlParserCtxtPtr ctxt) {
8834     xmlParseEndTag1(ctxt, 0);
8835 }
8836 #endif /* LIBXML_SAX1_ENABLED */
8837
8838 /************************************************************************
8839  *                                                                      *
8840  *                    SAX 2 specific operations                         *
8841  *                                                                      *
8842  ************************************************************************/
8843
8844 /*
8845  * xmlGetNamespace:
8846  * @ctxt:  an XML parser context
8847  * @prefix:  the prefix to lookup
8848  *
8849  * Lookup the namespace name for the @prefix (which ca be NULL)
8850  * The prefix must come from the @ctxt->dict dictionary
8851  *
8852  * Returns the namespace name or NULL if not bound
8853  */
8854 static const xmlChar *
8855 xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
8856     int i;
8857
8858     if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
8859     for (i = ctxt->nsNr - 2;i >= 0;i-=2)
8860         if (ctxt->nsTab[i] == prefix) {
8861             if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
8862                 return(NULL);
8863             return(ctxt->nsTab[i + 1]);
8864         }
8865     return(NULL);
8866 }
8867
8868 /**
8869  * xmlParseQName:
8870  * @ctxt:  an XML parser context
8871  * @prefix:  pointer to store the prefix part
8872  *
8873  * parse an XML Namespace QName
8874  *
8875  * [6]  QName  ::= (Prefix ':')? LocalPart
8876  * [7]  Prefix  ::= NCName
8877  * [8]  LocalPart  ::= NCName
8878  *
8879  * Returns the Name parsed or NULL
8880  */
8881
8882 static const xmlChar *
8883 xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
8884     const xmlChar *l, *p;
8885
8886     GROW;
8887
8888     l = xmlParseNCName(ctxt);
8889     if (l == NULL) {
8890         if (CUR == ':') {
8891             l = xmlParseName(ctxt);
8892             if (l != NULL) {
8893                 xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8894                          "Failed to parse QName '%s'\n", l, NULL, NULL);
8895                 *prefix = NULL;
8896                 return(l);
8897             }
8898         }
8899         return(NULL);
8900     }
8901     if (CUR == ':') {
8902         NEXT;
8903         p = l;
8904         l = xmlParseNCName(ctxt);
8905         if (l == NULL) {
8906             xmlChar *tmp;
8907
8908             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8909                      "Failed to parse QName '%s:'\n", p, NULL, NULL);
8910             l = xmlParseNmtoken(ctxt);
8911             if (l == NULL)
8912                 tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
8913             else {
8914                 tmp = xmlBuildQName(l, p, NULL, 0);
8915                 xmlFree((char *)l);
8916             }
8917             p = xmlDictLookup(ctxt->dict, tmp, -1);
8918             if (tmp != NULL) xmlFree(tmp);
8919             *prefix = NULL;
8920             return(p);
8921         }
8922         if (CUR == ':') {
8923             xmlChar *tmp;
8924
8925             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8926                      "Failed to parse QName '%s:%s:'\n", p, l, NULL);
8927             NEXT;
8928             tmp = (xmlChar *) xmlParseName(ctxt);
8929             if (tmp != NULL) {
8930                 tmp = xmlBuildQName(tmp, l, NULL, 0);
8931                 l = xmlDictLookup(ctxt->dict, tmp, -1);
8932                 if (tmp != NULL) xmlFree(tmp);
8933                 *prefix = p;
8934                 return(l);
8935             }
8936             tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
8937             l = xmlDictLookup(ctxt->dict, tmp, -1);
8938             if (tmp != NULL) xmlFree(tmp);
8939             *prefix = p;
8940             return(l);
8941         }
8942         *prefix = p;
8943     } else
8944         *prefix = NULL;
8945     return(l);
8946 }
8947
8948 /**
8949  * xmlParseQNameAndCompare:
8950  * @ctxt:  an XML parser context
8951  * @name:  the localname
8952  * @prefix:  the prefix, if any.
8953  *
8954  * parse an XML name and compares for match
8955  * (specialized for endtag parsing)
8956  *
8957  * Returns NULL for an illegal name, (xmlChar*) 1 for success
8958  * and the name for mismatch
8959  */
8960
8961 static const xmlChar *
8962 xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
8963                         xmlChar const *prefix) {
8964     const xmlChar *cmp;
8965     const xmlChar *in;
8966     const xmlChar *ret;
8967     const xmlChar *prefix2;
8968
8969     if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
8970
8971     GROW;
8972     in = ctxt->input->cur;
8973
8974     cmp = prefix;
8975     while (*in != 0 && *in == *cmp) {
8976         ++in;
8977         ++cmp;
8978     }
8979     if ((*cmp == 0) && (*in == ':')) {
8980         in++;
8981         cmp = name;
8982         while (*in != 0 && *in == *cmp) {
8983             ++in;
8984             ++cmp;
8985         }
8986         if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
8987             /* success */
8988             ctxt->input->cur = in;
8989             return((const xmlChar*) 1);
8990         }
8991     }
8992     /*
8993      * all strings coms from the dictionary, equality can be done directly
8994      */
8995     ret = xmlParseQName (ctxt, &prefix2);
8996     if ((ret == name) && (prefix == prefix2))
8997         return((const xmlChar*) 1);
8998     return ret;
8999 }
9000
9001 /**
9002  * xmlParseAttValueInternal:
9003  * @ctxt:  an XML parser context
9004  * @len:  attribute len result
9005  * @alloc:  whether the attribute was reallocated as a new string
9006  * @normalize:  if 1 then further non-CDATA normalization must be done
9007  *
9008  * parse a value for an attribute.
9009  * NOTE: if no normalization is needed, the routine will return pointers
9010  *       directly from the data buffer.
9011  *
9012  * 3.3.3 Attribute-Value Normalization:
9013  * Before the value of an attribute is passed to the application or
9014  * checked for validity, the XML processor must normalize it as follows:
9015  * - a character reference is processed by appending the referenced
9016  *   character to the attribute value
9017  * - an entity reference is processed by recursively processing the
9018  *   replacement text of the entity
9019  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
9020  *   appending #x20 to the normalized value, except that only a single
9021  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
9022  *   parsed entity or the literal entity value of an internal parsed entity
9023  * - other characters are processed by appending them to the normalized value
9024  * If the declared value is not CDATA, then the XML processor must further
9025  * process the normalized attribute value by discarding any leading and
9026  * trailing space (#x20) characters, and by replacing sequences of space
9027  * (#x20) characters by a single space (#x20) character.
9028  * All attributes for which no declaration has been read should be treated
9029  * by a non-validating parser as if declared CDATA.
9030  *
9031  * Returns the AttValue parsed or NULL. The value has to be freed by the
9032  *     caller if it was copied, this can be detected by val[*len] == 0.
9033  */
9034
9035 static xmlChar *
9036 xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
9037                          int normalize)
9038 {
9039     xmlChar limit = 0;
9040     const xmlChar *in = NULL, *start, *end, *last;
9041     xmlChar *ret = NULL;
9042     int line, col;
9043
9044     GROW;
9045     in = (xmlChar *) CUR_PTR;
9046     line = ctxt->input->line;
9047     col = ctxt->input->col;
9048     if (*in != '"' && *in != '\'') {
9049         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
9050         return (NULL);
9051     }
9052     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
9053
9054     /*
9055      * try to handle in this routine the most common case where no
9056      * allocation of a new string is required and where content is
9057      * pure ASCII.
9058      */
9059     limit = *in++;
9060     col++;
9061     end = ctxt->input->end;
9062     start = in;
9063     if (in >= end) {
9064         const xmlChar *oldbase = ctxt->input->base;
9065         GROW;
9066         if (oldbase != ctxt->input->base) {
9067             long delta = ctxt->input->base - oldbase;
9068             start = start + delta;
9069             in = in + delta;
9070         }
9071         end = ctxt->input->end;
9072     }
9073     if (normalize) {
9074         /*
9075          * Skip any leading spaces
9076          */
9077         while ((in < end) && (*in != limit) &&
9078                ((*in == 0x20) || (*in == 0x9) ||
9079                 (*in == 0xA) || (*in == 0xD))) {
9080             if (*in == 0xA) {
9081                 line++; col = 1;
9082             } else {
9083                 col++;
9084             }
9085             in++;
9086             start = in;
9087             if (in >= end) {
9088                 const xmlChar *oldbase = ctxt->input->base;
9089                 GROW;
9090                 if (ctxt->instate == XML_PARSER_EOF)
9091                     return(NULL);
9092                 if (oldbase != ctxt->input->base) {
9093                     long delta = ctxt->input->base - oldbase;
9094                     start = start + delta;
9095                     in = in + delta;
9096                 }
9097                 end = ctxt->input->end;
9098                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9099                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9100                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9101                                    "AttValue length too long\n");
9102                     return(NULL);
9103                 }
9104             }
9105         }
9106         while ((in < end) && (*in != limit) && (*in >= 0x20) &&
9107                (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
9108             col++;
9109             if ((*in++ == 0x20) && (*in == 0x20)) break;
9110             if (in >= end) {
9111                 const xmlChar *oldbase = ctxt->input->base;
9112                 GROW;
9113                 if (ctxt->instate == XML_PARSER_EOF)
9114                     return(NULL);
9115                 if (oldbase != ctxt->input->base) {
9116                     long delta = ctxt->input->base - oldbase;
9117                     start = start + delta;
9118                     in = in + delta;
9119                 }
9120                 end = ctxt->input->end;
9121                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9122                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9123                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9124                                    "AttValue length too long\n");
9125                     return(NULL);
9126                 }
9127             }
9128         }
9129         last = in;
9130         /*
9131          * skip the trailing blanks
9132          */
9133         while ((last[-1] == 0x20) && (last > start)) last--;
9134         while ((in < end) && (*in != limit) &&
9135                ((*in == 0x20) || (*in == 0x9) ||
9136                 (*in == 0xA) || (*in == 0xD))) {
9137             if (*in == 0xA) {
9138                 line++, col = 1;
9139             } else {
9140                 col++;
9141             }
9142             in++;
9143             if (in >= end) {
9144                 const xmlChar *oldbase = ctxt->input->base;
9145                 GROW;
9146                 if (ctxt->instate == XML_PARSER_EOF)
9147                     return(NULL);
9148                 if (oldbase != ctxt->input->base) {
9149                     long delta = ctxt->input->base - oldbase;
9150                     start = start + delta;
9151                     in = in + delta;
9152                     last = last + delta;
9153                 }
9154                 end = ctxt->input->end;
9155                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9156                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9157                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9158                                    "AttValue length too long\n");
9159                     return(NULL);
9160                 }
9161             }
9162         }
9163         if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9164             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9165             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9166                            "AttValue length too long\n");
9167             return(NULL);
9168         }
9169         if (*in != limit) goto need_complex;
9170     } else {
9171         while ((in < end) && (*in != limit) && (*in >= 0x20) &&
9172                (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
9173             in++;
9174             col++;
9175             if (in >= end) {
9176                 const xmlChar *oldbase = ctxt->input->base;
9177                 GROW;
9178                 if (ctxt->instate == XML_PARSER_EOF)
9179                     return(NULL);
9180                 if (oldbase != ctxt->input->base) {
9181                     long delta = ctxt->input->base - oldbase;
9182                     start = start + delta;
9183                     in = in + delta;
9184                 }
9185                 end = ctxt->input->end;
9186                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9187                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9188                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9189                                    "AttValue length too long\n");
9190                     return(NULL);
9191                 }
9192             }
9193         }
9194         last = in;
9195         if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9196             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9197             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9198                            "AttValue length too long\n");
9199             return(NULL);
9200         }
9201         if (*in != limit) goto need_complex;
9202     }
9203     in++;
9204     col++;
9205     if (len != NULL) {
9206         *len = last - start;
9207         ret = (xmlChar *) start;
9208     } else {
9209         if (alloc) *alloc = 1;
9210         ret = xmlStrndup(start, last - start);
9211     }
9212     CUR_PTR = in;
9213     ctxt->input->line = line;
9214     ctxt->input->col = col;
9215     if (alloc) *alloc = 0;
9216     return ret;
9217 need_complex:
9218     if (alloc) *alloc = 1;
9219     return xmlParseAttValueComplex(ctxt, len, normalize);
9220 }
9221
9222 /**
9223  * xmlParseAttribute2:
9224  * @ctxt:  an XML parser context
9225  * @pref:  the element prefix
9226  * @elem:  the element name
9227  * @prefix:  a xmlChar ** used to store the value of the attribute prefix
9228  * @value:  a xmlChar ** used to store the value of the attribute
9229  * @len:  an int * to save the length of the attribute
9230  * @alloc:  an int * to indicate if the attribute was allocated
9231  *
9232  * parse an attribute in the new SAX2 framework.
9233  *
9234  * Returns the attribute name, and the value in *value, .
9235  */
9236
9237 static const xmlChar *
9238 xmlParseAttribute2(xmlParserCtxtPtr ctxt,
9239                    const xmlChar * pref, const xmlChar * elem,
9240                    const xmlChar ** prefix, xmlChar ** value,
9241                    int *len, int *alloc)
9242 {
9243     const xmlChar *name;
9244     xmlChar *val, *internal_val = NULL;
9245     int normalize = 0;
9246
9247     *value = NULL;
9248     GROW;
9249     name = xmlParseQName(ctxt, prefix);
9250     if (name == NULL) {
9251         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9252                        "error parsing attribute name\n");
9253         return (NULL);
9254     }
9255
9256     /*
9257      * get the type if needed
9258      */
9259     if (ctxt->attsSpecial != NULL) {
9260         int type;
9261
9262         type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
9263                                             pref, elem, *prefix, name);
9264         if (type != 0)
9265             normalize = 1;
9266     }
9267
9268     /*
9269      * read the value
9270      */
9271     SKIP_BLANKS;
9272     if (RAW == '=') {
9273         NEXT;
9274         SKIP_BLANKS;
9275         val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
9276         if (normalize) {
9277             /*
9278              * Sometimes a second normalisation pass for spaces is needed
9279              * but that only happens if charrefs or entities refernces
9280              * have been used in the attribute value, i.e. the attribute
9281              * value have been extracted in an allocated string already.
9282              */
9283             if (*alloc) {
9284                 const xmlChar *val2;
9285
9286                 val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
9287                 if ((val2 != NULL) && (val2 != val)) {
9288                     xmlFree(val);
9289                     val = (xmlChar *) val2;
9290                 }
9291             }
9292         }
9293         ctxt->instate = XML_PARSER_CONTENT;
9294     } else {
9295         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
9296                           "Specification mandate value for attribute %s\n",
9297                           name);
9298         return (NULL);
9299     }
9300
9301     if (*prefix == ctxt->str_xml) {
9302         /*
9303          * Check that xml:lang conforms to the specification
9304          * No more registered as an error, just generate a warning now
9305          * since this was deprecated in XML second edition
9306          */
9307         if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
9308             internal_val = xmlStrndup(val, *len);
9309             if (!xmlCheckLanguageID(internal_val)) {
9310                 xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
9311                               "Malformed value for xml:lang : %s\n",
9312                               internal_val, NULL);
9313             }
9314         }
9315
9316         /*
9317          * Check that xml:space conforms to the specification
9318          */
9319         if (xmlStrEqual(name, BAD_CAST "space")) {
9320             internal_val = xmlStrndup(val, *len);
9321             if (xmlStrEqual(internal_val, BAD_CAST "default"))
9322                 *(ctxt->space) = 0;
9323             else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
9324                 *(ctxt->space) = 1;
9325             else {
9326                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
9327                               "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
9328                               internal_val, NULL);
9329             }
9330         }
9331         if (internal_val) {
9332             xmlFree(internal_val);
9333         }
9334     }
9335
9336     *value = val;
9337     return (name);
9338 }
9339 /**
9340  * xmlParseStartTag2:
9341  * @ctxt:  an XML parser context
9342  *
9343  * parse a start of tag either for rule element or
9344  * EmptyElement. In both case we don't parse the tag closing chars.
9345  * This routine is called when running SAX2 parsing
9346  *
9347  * [40] STag ::= '<' Name (S Attribute)* S? '>'
9348  *
9349  * [ WFC: Unique Att Spec ]
9350  * No attribute name may appear more than once in the same start-tag or
9351  * empty-element tag.
9352  *
9353  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
9354  *
9355  * [ WFC: Unique Att Spec ]
9356  * No attribute name may appear more than once in the same start-tag or
9357  * empty-element tag.
9358  *
9359  * With namespace:
9360  *
9361  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
9362  *
9363  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
9364  *
9365  * Returns the element name parsed
9366  */
9367
9368 static const xmlChar *
9369 xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
9370                   const xmlChar **URI, int *tlen) {
9371     const xmlChar *localname;
9372     const xmlChar *prefix;
9373     const xmlChar *attname;
9374     const xmlChar *aprefix;
9375     const xmlChar *nsname;
9376     xmlChar *attvalue;
9377     const xmlChar **atts = ctxt->atts;
9378     int maxatts = ctxt->maxatts;
9379     int nratts, nbatts, nbdef;
9380     int i, j, nbNs, attval, oldline, oldcol, inputNr;
9381     const xmlChar *base;
9382     unsigned long cur;
9383     int nsNr = ctxt->nsNr;
9384
9385     if (RAW != '<') return(NULL);
9386     NEXT1;
9387
9388     /*
9389      * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
9390      *       point since the attribute values may be stored as pointers to
9391      *       the buffer and calling SHRINK would destroy them !
9392      *       The Shrinking is only possible once the full set of attribute
9393      *       callbacks have been done.
9394      */
9395 reparse:
9396     SHRINK;
9397     base = ctxt->input->base;
9398     cur = ctxt->input->cur - ctxt->input->base;
9399     inputNr = ctxt->inputNr;
9400     oldline = ctxt->input->line;
9401     oldcol = ctxt->input->col;
9402     nbatts = 0;
9403     nratts = 0;
9404     nbdef = 0;
9405     nbNs = 0;
9406     attval = 0;
9407     /* Forget any namespaces added during an earlier parse of this element. */
9408     ctxt->nsNr = nsNr;
9409
9410     localname = xmlParseQName(ctxt, &prefix);
9411     if (localname == NULL) {
9412         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9413                        "StartTag: invalid element name\n");
9414         return(NULL);
9415     }
9416     *tlen = ctxt->input->cur - ctxt->input->base - cur;
9417
9418     /*
9419      * Now parse the attributes, it ends up with the ending
9420      *
9421      * (S Attribute)* S?
9422      */
9423     SKIP_BLANKS;
9424     GROW;
9425     if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
9426         goto base_changed;
9427
9428     while (((RAW != '>') &&
9429            ((RAW != '/') || (NXT(1) != '>')) &&
9430            (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
9431         const xmlChar *q = CUR_PTR;
9432         unsigned int cons = ctxt->input->consumed;
9433         int len = -1, alloc = 0;
9434
9435         attname = xmlParseAttribute2(ctxt, prefix, localname,
9436                                      &aprefix, &attvalue, &len, &alloc);
9437         if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) {
9438             if ((attvalue != NULL) && (alloc != 0))
9439                 xmlFree(attvalue);
9440             attvalue = NULL;
9441             goto base_changed;
9442         }
9443         if ((attname != NULL) && (attvalue != NULL)) {
9444             if (len < 0) len = xmlStrlen(attvalue);
9445             if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9446                 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9447                 xmlURIPtr uri;
9448
9449                 if (URL == NULL) {
9450                     xmlErrMemory(ctxt, "dictionary allocation failure");
9451                     if ((attvalue != NULL) && (alloc != 0))
9452                         xmlFree(attvalue);
9453                     return(NULL);
9454                 }
9455                 if (*URL != 0) {
9456                     uri = xmlParseURI((const char *) URL);
9457                     if (uri == NULL) {
9458                         xmlNsErr(ctxt, XML_WAR_NS_URI,
9459                                  "xmlns: '%s' is not a valid URI\n",
9460                                            URL, NULL, NULL);
9461                     } else {
9462                         if (uri->scheme == NULL) {
9463                             xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9464                                       "xmlns: URI %s is not absolute\n",
9465                                       URL, NULL, NULL);
9466                         }
9467                         xmlFreeURI(uri);
9468                     }
9469                     if (URL == ctxt->str_xml_ns) {
9470                         if (attname != ctxt->str_xml) {
9471                             xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9472                          "xml namespace URI cannot be the default namespace\n",
9473                                      NULL, NULL, NULL);
9474                         }
9475                         goto skip_default_ns;
9476                     }
9477                     if ((len == 29) &&
9478                         (xmlStrEqual(URL,
9479                                  BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9480                         xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9481                              "reuse of the xmlns namespace name is forbidden\n",
9482                                  NULL, NULL, NULL);
9483                         goto skip_default_ns;
9484                     }
9485                 }
9486                 /*
9487                  * check that it's not a defined namespace
9488                  */
9489                 for (j = 1;j <= nbNs;j++)
9490                     if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9491                         break;
9492                 if (j <= nbNs)
9493                     xmlErrAttributeDup(ctxt, NULL, attname);
9494                 else
9495                     if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
9496 skip_default_ns:
9497                 if ((attvalue != NULL) && (alloc != 0)) {
9498                     xmlFree(attvalue);
9499                     attvalue = NULL;
9500                 }
9501                 if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
9502                     break;
9503                 if (!IS_BLANK_CH(RAW)) {
9504                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9505                                    "attributes construct error\n");
9506                     break;
9507                 }
9508                 SKIP_BLANKS;
9509                 if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
9510                     goto base_changed;
9511                 continue;
9512             }
9513             if (aprefix == ctxt->str_xmlns) {
9514                 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9515                 xmlURIPtr uri;
9516
9517                 if (attname == ctxt->str_xml) {
9518                     if (URL != ctxt->str_xml_ns) {
9519                         xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9520                                  "xml namespace prefix mapped to wrong URI\n",
9521                                  NULL, NULL, NULL);
9522                     }
9523                     /*
9524                      * Do not keep a namespace definition node
9525                      */
9526                     goto skip_ns;
9527                 }
9528                 if (URL == ctxt->str_xml_ns) {
9529                     if (attname != ctxt->str_xml) {
9530                         xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9531                                  "xml namespace URI mapped to wrong prefix\n",
9532                                  NULL, NULL, NULL);
9533                     }
9534                     goto skip_ns;
9535                 }
9536                 if (attname == ctxt->str_xmlns) {
9537                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9538                              "redefinition of the xmlns prefix is forbidden\n",
9539                              NULL, NULL, NULL);
9540                     goto skip_ns;
9541                 }
9542                 if ((len == 29) &&
9543                     (xmlStrEqual(URL,
9544                                  BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9545                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9546                              "reuse of the xmlns namespace name is forbidden\n",
9547                              NULL, NULL, NULL);
9548                     goto skip_ns;
9549                 }
9550                 if ((URL == NULL) || (URL[0] == 0)) {
9551                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9552                              "xmlns:%s: Empty XML namespace is not allowed\n",
9553                                   attname, NULL, NULL);
9554                     goto skip_ns;
9555                 } else {
9556                     uri = xmlParseURI((const char *) URL);
9557                     if (uri == NULL) {
9558                         xmlNsErr(ctxt, XML_WAR_NS_URI,
9559                              "xmlns:%s: '%s' is not a valid URI\n",
9560                                            attname, URL, NULL);
9561                     } else {
9562                         if ((ctxt->pedantic) && (uri->scheme == NULL)) {
9563                             xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9564                                       "xmlns:%s: URI %s is not absolute\n",
9565                                       attname, URL, NULL);
9566                         }
9567                         xmlFreeURI(uri);
9568                     }
9569                 }
9570
9571                 /*
9572                  * check that it's not a defined namespace
9573                  */
9574                 for (j = 1;j <= nbNs;j++)
9575                     if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9576                         break;
9577                 if (j <= nbNs)
9578                     xmlErrAttributeDup(ctxt, aprefix, attname);
9579                 else
9580                     if (nsPush(ctxt, attname, URL) > 0) nbNs++;
9581 skip_ns:
9582                 if ((attvalue != NULL) && (alloc != 0)) {
9583                     xmlFree(attvalue);
9584                     attvalue = NULL;
9585                 }
9586                 if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
9587                     break;
9588                 if (!IS_BLANK_CH(RAW)) {
9589                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9590                                    "attributes construct error\n");
9591                     break;
9592                 }
9593                 SKIP_BLANKS;
9594                 if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
9595                     goto base_changed;
9596                 continue;
9597             }
9598
9599             /*
9600              * Add the pair to atts
9601              */
9602             if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9603                 if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9604                     if (attvalue[len] == 0)
9605                         xmlFree(attvalue);
9606                     goto failed;
9607                 }
9608                 maxatts = ctxt->maxatts;
9609                 atts = ctxt->atts;
9610             }
9611             ctxt->attallocs[nratts++] = alloc;
9612             atts[nbatts++] = attname;
9613             atts[nbatts++] = aprefix;
9614             atts[nbatts++] = NULL; /* the URI will be fetched later */
9615             atts[nbatts++] = attvalue;
9616             attvalue += len;
9617             atts[nbatts++] = attvalue;
9618             /*
9619              * tag if some deallocation is needed
9620              */
9621             if (alloc != 0) attval = 1;
9622         } else {
9623             if ((attvalue != NULL) && (attvalue[len] == 0))
9624                 xmlFree(attvalue);
9625         }
9626
9627 failed:
9628
9629         GROW
9630         if (ctxt->instate == XML_PARSER_EOF)
9631             break;
9632         if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
9633             goto base_changed;
9634         if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
9635             break;
9636         if (!IS_BLANK_CH(RAW)) {
9637             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9638                            "attributes construct error\n");
9639             break;
9640         }
9641         SKIP_BLANKS;
9642         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
9643             (attname == NULL) && (attvalue == NULL)) {
9644             xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9645                  "xmlParseStartTag: problem parsing attributes\n");
9646             break;
9647         }
9648         GROW;
9649         if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
9650             goto base_changed;
9651     }
9652
9653     /*
9654      * The attributes defaulting
9655      */
9656     if (ctxt->attsDefault != NULL) {
9657         xmlDefAttrsPtr defaults;
9658
9659         defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
9660         if (defaults != NULL) {
9661             for (i = 0;i < defaults->nbAttrs;i++) {
9662                 attname = defaults->values[5 * i];
9663                 aprefix = defaults->values[5 * i + 1];
9664
9665                 /*
9666                  * special work for namespaces defaulted defs
9667                  */
9668                 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9669                     /*
9670                      * check that it's not a defined namespace
9671                      */
9672                     for (j = 1;j <= nbNs;j++)
9673                         if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9674                             break;
9675                     if (j <= nbNs) continue;
9676
9677                     nsname = xmlGetNamespace(ctxt, NULL);
9678                     if (nsname != defaults->values[5 * i + 2]) {
9679                         if (nsPush(ctxt, NULL,
9680                                    defaults->values[5 * i + 2]) > 0)
9681                             nbNs++;
9682                     }
9683                 } else if (aprefix == ctxt->str_xmlns) {
9684                     /*
9685                      * check that it's not a defined namespace
9686                      */
9687                     for (j = 1;j <= nbNs;j++)
9688                         if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9689                             break;
9690                     if (j <= nbNs) continue;
9691
9692                     nsname = xmlGetNamespace(ctxt, attname);
9693                     if (nsname != defaults->values[2]) {
9694                         if (nsPush(ctxt, attname,
9695                                    defaults->values[5 * i + 2]) > 0)
9696                             nbNs++;
9697                     }
9698                 } else {
9699                     /*
9700                      * check that it's not a defined attribute
9701                      */
9702                     for (j = 0;j < nbatts;j+=5) {
9703                         if ((attname == atts[j]) && (aprefix == atts[j+1]))
9704                             break;
9705                     }
9706                     if (j < nbatts) continue;
9707
9708                     if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9709                         if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9710                             return(NULL);
9711                         }
9712                         maxatts = ctxt->maxatts;
9713                         atts = ctxt->atts;
9714                     }
9715                     atts[nbatts++] = attname;
9716                     atts[nbatts++] = aprefix;
9717                     if (aprefix == NULL)
9718                         atts[nbatts++] = NULL;
9719                     else
9720                         atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
9721                     atts[nbatts++] = defaults->values[5 * i + 2];
9722                     atts[nbatts++] = defaults->values[5 * i + 3];
9723                     if ((ctxt->standalone == 1) &&
9724                         (defaults->values[5 * i + 4] != NULL)) {
9725                         xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
9726           "standalone: attribute %s on %s defaulted from external subset\n",
9727                                          attname, localname);
9728                     }
9729                     nbdef++;
9730                 }
9731             }
9732         }
9733     }
9734
9735     /*
9736      * The attributes checkings
9737      */
9738     for (i = 0; i < nbatts;i += 5) {
9739         /*
9740         * The default namespace does not apply to attribute names.
9741         */
9742         if (atts[i + 1] != NULL) {
9743             nsname = xmlGetNamespace(ctxt, atts[i + 1]);
9744             if (nsname == NULL) {
9745                 xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9746                     "Namespace prefix %s for %s on %s is not defined\n",
9747                     atts[i + 1], atts[i], localname);
9748             }
9749             atts[i + 2] = nsname;
9750         } else
9751             nsname = NULL;
9752         /*
9753          * [ WFC: Unique Att Spec ]
9754          * No attribute name may appear more than once in the same
9755          * start-tag or empty-element tag.
9756          * As extended by the Namespace in XML REC.
9757          */
9758         for (j = 0; j < i;j += 5) {
9759             if (atts[i] == atts[j]) {
9760                 if (atts[i+1] == atts[j+1]) {
9761                     xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
9762                     break;
9763                 }
9764                 if ((nsname != NULL) && (atts[j + 2] == nsname)) {
9765                     xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
9766                              "Namespaced Attribute %s in '%s' redefined\n",
9767                              atts[i], nsname, NULL);
9768                     break;
9769                 }
9770             }
9771         }
9772     }
9773
9774     nsname = xmlGetNamespace(ctxt, prefix);
9775     if ((prefix != NULL) && (nsname == NULL)) {
9776         xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9777                  "Namespace prefix %s on %s is not defined\n",
9778                  prefix, localname, NULL);
9779     }
9780     *pref = prefix;
9781     *URI = nsname;
9782
9783     /*
9784      * SAX: Start of Element !
9785      */
9786     if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
9787         (!ctxt->disableSAX)) {
9788         if (nbNs > 0)
9789             ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9790                           nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
9791                           nbatts / 5, nbdef, atts);
9792         else
9793             ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9794                           nsname, 0, NULL, nbatts / 5, nbdef, atts);
9795     }
9796
9797     /*
9798      * Free up attribute allocated strings if needed
9799      */
9800     if (attval != 0) {
9801         for (i = 3,j = 0; j < nratts;i += 5,j++)
9802             if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9803                 xmlFree((xmlChar *) atts[i]);
9804     }
9805
9806     return(localname);
9807
9808 base_changed:
9809     /*
9810      * the attribute strings are valid iif the base didn't changed
9811      */
9812     if (attval != 0) {
9813         for (i = 3,j = 0; j < nratts;i += 5,j++)
9814             if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9815                 xmlFree((xmlChar *) atts[i]);
9816     }
9817
9818     /*
9819      * We can't switch from one entity to another in the middle
9820      * of a start tag
9821      */
9822     if (inputNr != ctxt->inputNr) {
9823         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
9824                     "Start tag doesn't start and stop in the same entity\n");
9825         return(NULL);
9826     }
9827
9828     ctxt->input->cur = ctxt->input->base + cur;
9829     ctxt->input->line = oldline;
9830     ctxt->input->col = oldcol;
9831     if (ctxt->wellFormed == 1) {
9832         goto reparse;
9833     }
9834     return(NULL);
9835 }
9836
9837 /**
9838  * xmlParseEndTag2:
9839  * @ctxt:  an XML parser context
9840  * @line:  line of the start tag
9841  * @nsNr:  number of namespaces on the start tag
9842  *
9843  * parse an end of tag
9844  *
9845  * [42] ETag ::= '</' Name S? '>'
9846  *
9847  * With namespace
9848  *
9849  * [NS 9] ETag ::= '</' QName S? '>'
9850  */
9851
9852 static void
9853 xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
9854                 const xmlChar *URI, int line, int nsNr, int tlen) {
9855     const xmlChar *name;
9856     size_t curLength;
9857
9858     GROW;
9859     if ((RAW != '<') || (NXT(1) != '/')) {
9860         xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
9861         return;
9862     }
9863     SKIP(2);
9864
9865     curLength = ctxt->input->end - ctxt->input->cur;
9866     if ((tlen > 0) && (curLength >= (size_t)tlen) &&
9867         (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
9868         if ((curLength >= (size_t)(tlen + 1)) &&
9869             (ctxt->input->cur[tlen] == '>')) {
9870             ctxt->input->cur += tlen + 1;
9871             ctxt->input->col += tlen + 1;
9872             goto done;
9873         }
9874         ctxt->input->cur += tlen;
9875         ctxt->input->col += tlen;
9876         name = (xmlChar*)1;
9877     } else {
9878         if (prefix == NULL)
9879             name = xmlParseNameAndCompare(ctxt, ctxt->name);
9880         else
9881             name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
9882     }
9883
9884     /*
9885      * We should definitely be at the ending "S? '>'" part
9886      */
9887     GROW;
9888     if (ctxt->instate == XML_PARSER_EOF)
9889         return;
9890     SKIP_BLANKS;
9891     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
9892         xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
9893     } else
9894         NEXT1;
9895
9896     /*
9897      * [ WFC: Element Type Match ]
9898      * The Name in an element's end-tag must match the element type in the
9899      * start-tag.
9900      *
9901      */
9902     if (name != (xmlChar*)1) {
9903         if (name == NULL) name = BAD_CAST "unparseable";
9904         if ((line == 0) && (ctxt->node != NULL))
9905             line = ctxt->node->line;
9906         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
9907                      "Opening and ending tag mismatch: %s line %d and %s\n",
9908                                 ctxt->name, line, name);
9909     }
9910
9911     /*
9912      * SAX: End of Tag
9913      */
9914 done:
9915     if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9916         (!ctxt->disableSAX))
9917         ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
9918
9919     spacePop(ctxt);
9920     if (nsNr != 0)
9921         nsPop(ctxt, nsNr);
9922     return;
9923 }
9924
9925 /**
9926  * xmlParseCDSect:
9927  * @ctxt:  an XML parser context
9928  *
9929  * Parse escaped pure raw content.
9930  *
9931  * [18] CDSect ::= CDStart CData CDEnd
9932  *
9933  * [19] CDStart ::= '<![CDATA['
9934  *
9935  * [20] Data ::= (Char* - (Char* ']]>' Char*))
9936  *
9937  * [21] CDEnd ::= ']]>'
9938  */
9939 void
9940 xmlParseCDSect(xmlParserCtxtPtr ctxt) {
9941     xmlChar *buf = NULL;
9942     int len = 0;
9943     int size = XML_PARSER_BUFFER_SIZE;
9944     int r, rl;
9945     int s, sl;
9946     int cur, l;
9947     int count = 0;
9948
9949     /* Check 2.6.0 was NXT(0) not RAW */
9950     if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9951         SKIP(9);
9952     } else
9953         return;
9954
9955     ctxt->instate = XML_PARSER_CDATA_SECTION;
9956     r = CUR_CHAR(rl);
9957     if (!IS_CHAR(r)) {
9958         xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9959         ctxt->instate = XML_PARSER_CONTENT;
9960         return;
9961     }
9962     NEXTL(rl);
9963     s = CUR_CHAR(sl);
9964     if (!IS_CHAR(s)) {
9965         xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9966         ctxt->instate = XML_PARSER_CONTENT;
9967         return;
9968     }
9969     NEXTL(sl);
9970     cur = CUR_CHAR(l);
9971     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
9972     if (buf == NULL) {
9973         xmlErrMemory(ctxt, NULL);
9974         return;
9975     }
9976     while (IS_CHAR(cur) &&
9977            ((r != ']') || (s != ']') || (cur != '>'))) {
9978         if (len + 5 >= size) {
9979             xmlChar *tmp;
9980
9981             if ((size > XML_MAX_TEXT_LENGTH) &&
9982                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9983                 xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9984                              "CData section too big found", NULL);
9985                 xmlFree (buf);
9986                 return;
9987             }
9988             tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
9989             if (tmp == NULL) {
9990                 xmlFree(buf);
9991                 xmlErrMemory(ctxt, NULL);
9992                 return;
9993             }
9994             buf = tmp;
9995             size *= 2;
9996         }
9997         COPY_BUF(rl,buf,len,r);
9998         r = s;
9999         rl = sl;
10000         s = cur;
10001         sl = l;
10002         count++;
10003         if (count > 50) {
10004             GROW;
10005             if (ctxt->instate == XML_PARSER_EOF) {
10006                 xmlFree(buf);
10007                 return;
10008             }
10009             count = 0;
10010         }
10011         NEXTL(l);
10012         cur = CUR_CHAR(l);
10013     }
10014     buf[len] = 0;
10015     ctxt->instate = XML_PARSER_CONTENT;
10016     if (cur != '>') {
10017         xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
10018                              "CData section not finished\n%.50s\n", buf);
10019         xmlFree(buf);
10020         return;
10021     }
10022     NEXTL(l);
10023
10024     /*
10025      * OK the buffer is to be consumed as cdata.
10026      */
10027     if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
10028         if (ctxt->sax->cdataBlock != NULL)
10029             ctxt->sax->cdataBlock(ctxt->userData, buf, len);
10030         else if (ctxt->sax->characters != NULL)
10031             ctxt->sax->characters(ctxt->userData, buf, len);
10032     }
10033     xmlFree(buf);
10034 }
10035
10036 /**
10037  * xmlParseContent:
10038  * @ctxt:  an XML parser context
10039  *
10040  * Parse a content:
10041  *
10042  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
10043  */
10044
10045 void
10046 xmlParseContent(xmlParserCtxtPtr ctxt) {
10047     GROW;
10048     while ((RAW != 0) &&
10049            ((RAW != '<') || (NXT(1) != '/')) &&
10050            (ctxt->instate != XML_PARSER_EOF)) {
10051         const xmlChar *test = CUR_PTR;
10052         unsigned int cons = ctxt->input->consumed;
10053         const xmlChar *cur = ctxt->input->cur;
10054
10055         /*
10056          * First case : a Processing Instruction.
10057          */
10058         if ((*cur == '<') && (cur[1] == '?')) {
10059             xmlParsePI(ctxt);
10060         }
10061
10062         /*
10063          * Second case : a CDSection
10064          */
10065         /* 2.6.0 test was *cur not RAW */
10066         else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
10067             xmlParseCDSect(ctxt);
10068         }
10069
10070         /*
10071          * Third case :  a comment
10072          */
10073         else if ((*cur == '<') && (NXT(1) == '!') &&
10074                  (NXT(2) == '-') && (NXT(3) == '-')) {
10075             xmlParseComment(ctxt);
10076             ctxt->instate = XML_PARSER_CONTENT;
10077         }
10078
10079         /*
10080          * Fourth case :  a sub-element.
10081          */
10082         else if (*cur == '<') {
10083             xmlParseElement(ctxt);
10084         }
10085
10086         /*
10087          * Fifth case : a reference. If if has not been resolved,
10088          *    parsing returns it's Name, create the node
10089          */
10090
10091         else if (*cur == '&') {
10092             xmlParseReference(ctxt);
10093         }
10094
10095         /*
10096          * Last case, text. Note that References are handled directly.
10097          */
10098         else {
10099             xmlParseCharData(ctxt, 0);
10100         }
10101
10102         GROW;
10103         /*
10104          * Pop-up of finished entities.
10105          */
10106         while ((RAW == 0) && (ctxt->inputNr > 1))
10107             xmlPopInput(ctxt);
10108         SHRINK;
10109
10110         if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
10111             xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
10112                         "detected an error in element content\n");
10113             xmlHaltParser(ctxt);
10114             break;
10115         }
10116     }
10117 }
10118
10119 /**
10120  * xmlParseElement:
10121  * @ctxt:  an XML parser context
10122  *
10123  * parse an XML element, this is highly recursive
10124  *
10125  * [39] element ::= EmptyElemTag | STag content ETag
10126  *
10127  * [ WFC: Element Type Match ]
10128  * The Name in an element's end-tag must match the element type in the
10129  * start-tag.
10130  *
10131  */
10132
10133 void
10134 xmlParseElement(xmlParserCtxtPtr ctxt) {
10135     const xmlChar *name;
10136     const xmlChar *prefix = NULL;
10137     const xmlChar *URI = NULL;
10138     xmlParserNodeInfo node_info;
10139     int line, tlen = 0;
10140     xmlNodePtr ret;
10141     int nsNr = ctxt->nsNr;
10142
10143     if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
10144         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
10145         xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
10146                  "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
10147                           xmlParserMaxDepth);
10148         xmlHaltParser(ctxt);
10149         return;
10150     }
10151
10152     /* Capture start position */
10153     if (ctxt->record_info) {
10154         node_info.begin_pos = ctxt->input->consumed +
10155                           (CUR_PTR - ctxt->input->base);
10156         node_info.begin_line = ctxt->input->line;
10157     }
10158
10159     if (ctxt->spaceNr == 0)
10160         spacePush(ctxt, -1);
10161     else if (*ctxt->space == -2)
10162         spacePush(ctxt, -1);
10163     else
10164         spacePush(ctxt, *ctxt->space);
10165
10166     line = ctxt->input->line;
10167 #ifdef LIBXML_SAX1_ENABLED
10168     if (ctxt->sax2)
10169 #endif /* LIBXML_SAX1_ENABLED */
10170         name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
10171 #ifdef LIBXML_SAX1_ENABLED
10172     else
10173         name = xmlParseStartTag(ctxt);
10174 #endif /* LIBXML_SAX1_ENABLED */
10175     if (ctxt->instate == XML_PARSER_EOF)
10176         return;
10177     if (name == NULL) {
10178         spacePop(ctxt);
10179         return;
10180     }
10181     namePush(ctxt, name);
10182     ret = ctxt->node;
10183
10184 #ifdef LIBXML_VALID_ENABLED
10185     /*
10186      * [ VC: Root Element Type ]
10187      * The Name in the document type declaration must match the element
10188      * type of the root element.
10189      */
10190     if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
10191         ctxt->node && (ctxt->node == ctxt->myDoc->children))
10192         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
10193 #endif /* LIBXML_VALID_ENABLED */
10194
10195     /*
10196      * Check for an Empty Element.
10197      */
10198     if ((RAW == '/') && (NXT(1) == '>')) {
10199         SKIP(2);
10200         if (ctxt->sax2) {
10201             if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
10202                 (!ctxt->disableSAX))
10203                 ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
10204 #ifdef LIBXML_SAX1_ENABLED
10205         } else {
10206             if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
10207                 (!ctxt->disableSAX))
10208                 ctxt->sax->endElement(ctxt->userData, name);
10209 #endif /* LIBXML_SAX1_ENABLED */
10210         }
10211         namePop(ctxt);
10212         spacePop(ctxt);
10213         if (nsNr != ctxt->nsNr)
10214             nsPop(ctxt, ctxt->nsNr - nsNr);
10215         if ( ret != NULL && ctxt->record_info ) {
10216            node_info.end_pos = ctxt->input->consumed +
10217                               (CUR_PTR - ctxt->input->base);
10218            node_info.end_line = ctxt->input->line;
10219            node_info.node = ret;
10220            xmlParserAddNodeInfo(ctxt, &node_info);
10221         }
10222         return;
10223     }
10224     if (RAW == '>') {
10225         NEXT1;
10226     } else {
10227         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
10228                      "Couldn't find end of Start Tag %s line %d\n",
10229                                 name, line, NULL);
10230
10231         /*
10232          * end of parsing of this node.
10233          */
10234         nodePop(ctxt);
10235         namePop(ctxt);
10236         spacePop(ctxt);
10237         if (nsNr != ctxt->nsNr)
10238             nsPop(ctxt, ctxt->nsNr - nsNr);
10239
10240         /*
10241          * Capture end position and add node
10242          */
10243         if ( ret != NULL && ctxt->record_info ) {
10244            node_info.end_pos = ctxt->input->consumed +
10245                               (CUR_PTR - ctxt->input->base);
10246            node_info.end_line = ctxt->input->line;
10247            node_info.node = ret;
10248            xmlParserAddNodeInfo(ctxt, &node_info);
10249         }
10250         return;
10251     }
10252
10253     /*
10254      * Parse the content of the element:
10255      */
10256     xmlParseContent(ctxt);
10257     if (ctxt->instate == XML_PARSER_EOF)
10258         return;
10259     if (!IS_BYTE_CHAR(RAW)) {
10260         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
10261          "Premature end of data in tag %s line %d\n",
10262                                 name, line, NULL);
10263
10264         /*
10265          * end of parsing of this node.
10266          */
10267         nodePop(ctxt);
10268         namePop(ctxt);
10269         spacePop(ctxt);
10270         if (nsNr != ctxt->nsNr)
10271             nsPop(ctxt, ctxt->nsNr - nsNr);
10272         return;
10273     }
10274
10275     /*
10276      * parse the end of tag: '</' should be here.
10277      */
10278     if (ctxt->sax2) {
10279         xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
10280         namePop(ctxt);
10281     }
10282 #ifdef LIBXML_SAX1_ENABLED
10283       else
10284         xmlParseEndTag1(ctxt, line);
10285 #endif /* LIBXML_SAX1_ENABLED */
10286
10287     /*
10288      * Capture end position and add node
10289      */
10290     if ( ret != NULL && ctxt->record_info ) {
10291        node_info.end_pos = ctxt->input->consumed +
10292                           (CUR_PTR - ctxt->input->base);
10293        node_info.end_line = ctxt->input->line;
10294        node_info.node = ret;
10295        xmlParserAddNodeInfo(ctxt, &node_info);
10296     }
10297 }
10298
10299 /**
10300  * xmlParseVersionNum:
10301  * @ctxt:  an XML parser context
10302  *
10303  * parse the XML version value.
10304  *
10305  * [26] VersionNum ::= '1.' [0-9]+
10306  *
10307  * In practice allow [0-9].[0-9]+ at that level
10308  *
10309  * Returns the string giving the XML version number, or NULL
10310  */
10311 xmlChar *
10312 xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
10313     xmlChar *buf = NULL;
10314     int len = 0;
10315     int size = 10;
10316     xmlChar cur;
10317
10318     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
10319     if (buf == NULL) {
10320         xmlErrMemory(ctxt, NULL);
10321         return(NULL);
10322     }
10323     cur = CUR;
10324     if (!((cur >= '0') && (cur <= '9'))) {
10325         xmlFree(buf);
10326         return(NULL);
10327     }
10328     buf[len++] = cur;
10329     NEXT;
10330     cur=CUR;
10331     if (cur != '.') {
10332         xmlFree(buf);
10333         return(NULL);
10334     }
10335     buf[len++] = cur;
10336     NEXT;
10337     cur=CUR;
10338     while ((cur >= '0') && (cur <= '9')) {
10339         if (len + 1 >= size) {
10340             xmlChar *tmp;
10341
10342             size *= 2;
10343             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
10344             if (tmp == NULL) {
10345                 xmlFree(buf);
10346                 xmlErrMemory(ctxt, NULL);
10347                 return(NULL);
10348             }
10349             buf = tmp;
10350         }
10351         buf[len++] = cur;
10352         NEXT;
10353         cur=CUR;
10354     }
10355     buf[len] = 0;
10356     return(buf);
10357 }
10358
10359 /**
10360  * xmlParseVersionInfo:
10361  * @ctxt:  an XML parser context
10362  *
10363  * parse the XML version.
10364  *
10365  * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
10366  *
10367  * [25] Eq ::= S? '=' S?
10368  *
10369  * Returns the version string, e.g. "1.0"
10370  */
10371
10372 xmlChar *
10373 xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
10374     xmlChar *version = NULL;
10375
10376     if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
10377         SKIP(7);
10378         SKIP_BLANKS;
10379         if (RAW != '=') {
10380             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10381             return(NULL);
10382         }
10383         NEXT;
10384         SKIP_BLANKS;
10385         if (RAW == '"') {
10386             NEXT;
10387             version = xmlParseVersionNum(ctxt);
10388             if (RAW != '"') {
10389                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10390             } else
10391                 NEXT;
10392         } else if (RAW == '\''){
10393             NEXT;
10394             version = xmlParseVersionNum(ctxt);
10395             if (RAW != '\'') {
10396                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10397             } else
10398                 NEXT;
10399         } else {
10400             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10401         }
10402     }
10403     return(version);
10404 }
10405
10406 /**
10407  * xmlParseEncName:
10408  * @ctxt:  an XML parser context
10409  *
10410  * parse the XML encoding name
10411  *
10412  * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
10413  *
10414  * Returns the encoding name value or NULL
10415  */
10416 xmlChar *
10417 xmlParseEncName(xmlParserCtxtPtr ctxt) {
10418     xmlChar *buf = NULL;
10419     int len = 0;
10420     int size = 10;
10421     xmlChar cur;
10422
10423     cur = CUR;
10424     if (((cur >= 'a') && (cur <= 'z')) ||
10425         ((cur >= 'A') && (cur <= 'Z'))) {
10426         buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
10427         if (buf == NULL) {
10428             xmlErrMemory(ctxt, NULL);
10429             return(NULL);
10430         }
10431
10432         buf[len++] = cur;
10433         NEXT;
10434         cur = CUR;
10435         while (((cur >= 'a') && (cur <= 'z')) ||
10436                ((cur >= 'A') && (cur <= 'Z')) ||
10437                ((cur >= '0') && (cur <= '9')) ||
10438                (cur == '.') || (cur == '_') ||
10439                (cur == '-')) {
10440             if (len + 1 >= size) {
10441                 xmlChar *tmp;
10442
10443                 size *= 2;
10444                 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
10445                 if (tmp == NULL) {
10446                     xmlErrMemory(ctxt, NULL);
10447                     xmlFree(buf);
10448                     return(NULL);
10449                 }
10450                 buf = tmp;
10451             }
10452             buf[len++] = cur;
10453             NEXT;
10454             cur = CUR;
10455             if (cur == 0) {
10456                 SHRINK;
10457                 GROW;
10458                 cur = CUR;
10459             }
10460         }
10461         buf[len] = 0;
10462     } else {
10463         xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
10464     }
10465     return(buf);
10466 }
10467
10468 /**
10469  * xmlParseEncodingDecl:
10470  * @ctxt:  an XML parser context
10471  *
10472  * parse the XML encoding declaration
10473  *
10474  * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
10475  *
10476  * this setups the conversion filters.
10477  *
10478  * Returns the encoding value or NULL
10479  */
10480
10481 const xmlChar *
10482 xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
10483     xmlChar *encoding = NULL;
10484
10485     SKIP_BLANKS;
10486     if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
10487         SKIP(8);
10488         SKIP_BLANKS;
10489         if (RAW != '=') {
10490             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10491             return(NULL);
10492         }
10493         NEXT;
10494         SKIP_BLANKS;
10495         if (RAW == '"') {
10496             NEXT;
10497             encoding = xmlParseEncName(ctxt);
10498             if (RAW != '"') {
10499                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10500                 xmlFree((xmlChar *) encoding);
10501                 return(NULL);
10502             } else
10503                 NEXT;
10504         } else if (RAW == '\''){
10505             NEXT;
10506             encoding = xmlParseEncName(ctxt);
10507             if (RAW != '\'') {
10508                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10509                 xmlFree((xmlChar *) encoding);
10510                 return(NULL);
10511             } else
10512                 NEXT;
10513         } else {
10514             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10515         }
10516
10517         /*
10518          * Non standard parsing, allowing the user to ignore encoding
10519          */
10520         if (ctxt->options & XML_PARSE_IGNORE_ENC) {
10521             xmlFree((xmlChar *) encoding);
10522             return(NULL);
10523         }
10524
10525         /*
10526          * UTF-16 encoding stwich has already taken place at this stage,
10527          * more over the little-endian/big-endian selection is already done
10528          */
10529         if ((encoding != NULL) &&
10530             ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
10531              (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
10532             /*
10533              * If no encoding was passed to the parser, that we are
10534              * using UTF-16 and no decoder is present i.e. the
10535              * document is apparently UTF-8 compatible, then raise an
10536              * encoding mismatch fatal error
10537              */
10538             if ((ctxt->encoding == NULL) &&
10539                 (ctxt->input->buf != NULL) &&
10540                 (ctxt->input->buf->encoder == NULL)) {
10541                 xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
10542                   "Document labelled UTF-16 but has UTF-8 content\n");
10543             }
10544             if (ctxt->encoding != NULL)
10545                 xmlFree((xmlChar *) ctxt->encoding);
10546             ctxt->encoding = encoding;
10547         }
10548         /*
10549          * UTF-8 encoding is handled natively
10550          */
10551         else if ((encoding != NULL) &&
10552             ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
10553              (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
10554             if (ctxt->encoding != NULL)
10555                 xmlFree((xmlChar *) ctxt->encoding);
10556             ctxt->encoding = encoding;
10557         }
10558         else if (encoding != NULL) {
10559             xmlCharEncodingHandlerPtr handler;
10560
10561             if (ctxt->input->encoding != NULL)
10562                 xmlFree((xmlChar *) ctxt->input->encoding);
10563             ctxt->input->encoding = encoding;
10564
10565             handler = xmlFindCharEncodingHandler((const char *) encoding);
10566             if (handler != NULL) {
10567                 if (xmlSwitchToEncoding(ctxt, handler) < 0) {
10568                     /* failed to convert */
10569                     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
10570                     return(NULL);
10571                 }
10572             } else {
10573                 xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
10574                         "Unsupported encoding %s\n", encoding);
10575                 return(NULL);
10576             }
10577         }
10578     }
10579     return(encoding);
10580 }
10581
10582 /**
10583  * xmlParseSDDecl:
10584  * @ctxt:  an XML parser context
10585  *
10586  * parse the XML standalone declaration
10587  *
10588  * [32] SDDecl ::= S 'standalone' Eq
10589  *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
10590  *
10591  * [ VC: Standalone Document Declaration ]
10592  * TODO The standalone document declaration must have the value "no"
10593  * if any external markup declarations contain declarations of:
10594  *  - attributes with default values, if elements to which these
10595  *    attributes apply appear in the document without specifications
10596  *    of values for these attributes, or
10597  *  - entities (other than amp, lt, gt, apos, quot), if references
10598  *    to those entities appear in the document, or
10599  *  - attributes with values subject to normalization, where the
10600  *    attribute appears in the document with a value which will change
10601  *    as a result of normalization, or
10602  *  - element types with element content, if white space occurs directly
10603  *    within any instance of those types.
10604  *
10605  * Returns:
10606  *   1 if standalone="yes"
10607  *   0 if standalone="no"
10608  *  -2 if standalone attribute is missing or invalid
10609  *        (A standalone value of -2 means that the XML declaration was found,
10610  *         but no value was specified for the standalone attribute).
10611  */
10612
10613 int
10614 xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
10615     int standalone = -2;
10616
10617     SKIP_BLANKS;
10618     if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
10619         SKIP(10);
10620         SKIP_BLANKS;
10621         if (RAW != '=') {
10622             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10623             return(standalone);
10624         }
10625         NEXT;
10626         SKIP_BLANKS;
10627         if (RAW == '\''){
10628             NEXT;
10629             if ((RAW == 'n') && (NXT(1) == 'o')) {
10630                 standalone = 0;
10631                 SKIP(2);
10632             } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10633                        (NXT(2) == 's')) {
10634                 standalone = 1;
10635                 SKIP(3);
10636             } else {
10637                 xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10638             }
10639             if (RAW != '\'') {
10640                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10641             } else
10642                 NEXT;
10643         } else if (RAW == '"'){
10644             NEXT;
10645             if ((RAW == 'n') && (NXT(1) == 'o')) {
10646                 standalone = 0;
10647                 SKIP(2);
10648             } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10649                        (NXT(2) == 's')) {
10650                 standalone = 1;
10651                 SKIP(3);
10652             } else {
10653                 xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10654             }
10655             if (RAW != '"') {
10656                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10657             } else
10658                 NEXT;
10659         } else {
10660             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10661         }
10662     }
10663     return(standalone);
10664 }
10665
10666 /**
10667  * xmlParseXMLDecl:
10668  * @ctxt:  an XML parser context
10669  *
10670  * parse an XML declaration header
10671  *
10672  * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
10673  */
10674
10675 void
10676 xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
10677     xmlChar *version;
10678
10679     /*
10680      * This value for standalone indicates that the document has an
10681      * XML declaration but it does not have a standalone attribute.
10682      * It will be overwritten later if a standalone attribute is found.
10683      */
10684     ctxt->input->standalone = -2;
10685
10686     /*
10687      * We know that '<?xml' is here.
10688      */
10689     SKIP(5);
10690
10691     if (!IS_BLANK_CH(RAW)) {
10692         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
10693                        "Blank needed after '<?xml'\n");
10694     }
10695     SKIP_BLANKS;
10696
10697     /*
10698      * We must have the VersionInfo here.
10699      */
10700     version = xmlParseVersionInfo(ctxt);
10701     if (version == NULL) {
10702         xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
10703     } else {
10704         if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
10705             /*
10706              * Changed here for XML-1.0 5th edition
10707              */
10708             if (ctxt->options & XML_PARSE_OLD10) {
10709                 xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10710                                   "Unsupported version '%s'\n",
10711                                   version);
10712             } else {
10713                 if ((version[0] == '1') && ((version[1] == '.'))) {
10714                     xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
10715                                   "Unsupported version '%s'\n",
10716                                   version, NULL);
10717                 } else {
10718                     xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10719                                       "Unsupported version '%s'\n",
10720                                       version);
10721                 }
10722             }
10723         }
10724         if (ctxt->version != NULL)
10725             xmlFree((void *) ctxt->version);
10726         ctxt->version = version;
10727     }
10728
10729     /*
10730      * We may have the encoding declaration
10731      */
10732     if (!IS_BLANK_CH(RAW)) {
10733         if ((RAW == '?') && (NXT(1) == '>')) {
10734             SKIP(2);
10735             return;
10736         }
10737         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10738     }
10739     xmlParseEncodingDecl(ctxt);
10740     if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
10741          (ctxt->instate == XML_PARSER_EOF)) {
10742         /*
10743          * The XML REC instructs us to stop parsing right here
10744          */
10745         return;
10746     }
10747
10748     /*
10749      * We may have the standalone status.
10750      */
10751     if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
10752         if ((RAW == '?') && (NXT(1) == '>')) {
10753             SKIP(2);
10754             return;
10755         }
10756         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10757     }
10758
10759     /*
10760      * We can grow the input buffer freely at that point
10761      */
10762     GROW;
10763
10764     SKIP_BLANKS;
10765     ctxt->input->standalone = xmlParseSDDecl(ctxt);
10766
10767     SKIP_BLANKS;
10768     if ((RAW == '?') && (NXT(1) == '>')) {
10769         SKIP(2);
10770     } else if (RAW == '>') {
10771         /* Deprecated old WD ... */
10772         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10773         NEXT;
10774     } else {
10775         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10776         MOVETO_ENDTAG(CUR_PTR);
10777         NEXT;
10778     }
10779 }
10780
10781 /**
10782  * xmlParseMisc:
10783  * @ctxt:  an XML parser context
10784  *
10785  * parse an XML Misc* optional field.
10786  *
10787  * [27] Misc ::= Comment | PI |  S
10788  */
10789
10790 void
10791 xmlParseMisc(xmlParserCtxtPtr ctxt) {
10792     while ((ctxt->instate != XML_PARSER_EOF) &&
10793            (((RAW == '<') && (NXT(1) == '?')) ||
10794             (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
10795             IS_BLANK_CH(CUR))) {
10796         if ((RAW == '<') && (NXT(1) == '?')) {
10797             xmlParsePI(ctxt);
10798         } else if (IS_BLANK_CH(CUR)) {
10799             NEXT;
10800         } else
10801             xmlParseComment(ctxt);
10802     }
10803 }
10804
10805 /**
10806  * xmlParseDocument:
10807  * @ctxt:  an XML parser context
10808  *
10809  * parse an XML document (and build a tree if using the standard SAX
10810  * interface).
10811  *
10812  * [1] document ::= prolog element Misc*
10813  *
10814  * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
10815  *
10816  * Returns 0, -1 in case of error. the parser context is augmented
10817  *                as a result of the parsing.
10818  */
10819
10820 int
10821 xmlParseDocument(xmlParserCtxtPtr ctxt) {
10822     xmlChar start[4];
10823     xmlCharEncoding enc;
10824
10825     xmlInitParser();
10826
10827     if ((ctxt == NULL) || (ctxt->input == NULL))
10828         return(-1);
10829
10830     GROW;
10831
10832     /*
10833      * SAX: detecting the level.
10834      */
10835     xmlDetectSAX2(ctxt);
10836
10837     /*
10838      * SAX: beginning of the document processing.
10839      */
10840     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10841         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10842     if (ctxt->instate == XML_PARSER_EOF)
10843         return(-1);
10844
10845     if ((ctxt->encoding == NULL) &&
10846         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
10847         /*
10848          * Get the 4 first bytes and decode the charset
10849          * if enc != XML_CHAR_ENCODING_NONE
10850          * plug some encoding conversion routines.
10851          */
10852         start[0] = RAW;
10853         start[1] = NXT(1);
10854         start[2] = NXT(2);
10855         start[3] = NXT(3);
10856         enc = xmlDetectCharEncoding(&start[0], 4);
10857         if (enc != XML_CHAR_ENCODING_NONE) {
10858             xmlSwitchEncoding(ctxt, enc);
10859         }
10860     }
10861
10862
10863     if (CUR == 0) {
10864         xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10865         return(-1);
10866     }
10867
10868     /*
10869      * Check for the XMLDecl in the Prolog.
10870      * do not GROW here to avoid the detected encoder to decode more
10871      * than just the first line, unless the amount of data is really
10872      * too small to hold "<?xml version="1.0" encoding="foo"
10873      */
10874     if ((ctxt->input->end - ctxt->input->cur) < 35) {
10875        GROW;
10876     }
10877     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10878
10879         /*
10880          * Note that we will switch encoding on the fly.
10881          */
10882         xmlParseXMLDecl(ctxt);
10883         if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
10884             (ctxt->instate == XML_PARSER_EOF)) {
10885             /*
10886              * The XML REC instructs us to stop parsing right here
10887              */
10888             return(-1);
10889         }
10890         ctxt->standalone = ctxt->input->standalone;
10891         SKIP_BLANKS;
10892     } else {
10893         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10894     }
10895     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10896         ctxt->sax->startDocument(ctxt->userData);
10897     if (ctxt->instate == XML_PARSER_EOF)
10898         return(-1);
10899     if ((ctxt->myDoc != NULL) && (ctxt->input != NULL) &&
10900         (ctxt->input->buf != NULL) && (ctxt->input->buf->compressed >= 0)) {
10901         ctxt->myDoc->compression = ctxt->input->buf->compressed;
10902     }
10903
10904     /*
10905      * The Misc part of the Prolog
10906      */
10907     GROW;
10908     xmlParseMisc(ctxt);
10909
10910     /*
10911      * Then possibly doc type declaration(s) and more Misc
10912      * (doctypedecl Misc*)?
10913      */
10914     GROW;
10915     if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
10916
10917         ctxt->inSubset = 1;
10918         xmlParseDocTypeDecl(ctxt);
10919         if (RAW == '[') {
10920             ctxt->instate = XML_PARSER_DTD;
10921             xmlParseInternalSubset(ctxt);
10922             if (ctxt->instate == XML_PARSER_EOF)
10923                 return(-1);
10924         }
10925
10926         /*
10927          * Create and update the external subset.
10928          */
10929         ctxt->inSubset = 2;
10930         if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
10931             (!ctxt->disableSAX))
10932             ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
10933                                       ctxt->extSubSystem, ctxt->extSubURI);
10934         if (ctxt->instate == XML_PARSER_EOF)
10935             return(-1);
10936         ctxt->inSubset = 0;
10937
10938         xmlCleanSpecialAttr(ctxt);
10939
10940         ctxt->instate = XML_PARSER_PROLOG;
10941         xmlParseMisc(ctxt);
10942     }
10943
10944     /*
10945      * Time to start parsing the tree itself
10946      */
10947     GROW;
10948     if (RAW != '<') {
10949         xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
10950                        "Start tag expected, '<' not found\n");
10951     } else {
10952         ctxt->instate = XML_PARSER_CONTENT;
10953         xmlParseElement(ctxt);
10954         ctxt->instate = XML_PARSER_EPILOG;
10955
10956
10957         /*
10958          * The Misc part at the end
10959          */
10960         xmlParseMisc(ctxt);
10961
10962         if (RAW != 0) {
10963             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10964         }
10965         ctxt->instate = XML_PARSER_EOF;
10966     }
10967
10968     /*
10969      * SAX: end of the document processing.
10970      */
10971     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10972         ctxt->sax->endDocument(ctxt->userData);
10973
10974     /*
10975      * Remove locally kept entity definitions if the tree was not built
10976      */
10977     if ((ctxt->myDoc != NULL) &&
10978         (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
10979         xmlFreeDoc(ctxt->myDoc);
10980         ctxt->myDoc = NULL;
10981     }
10982
10983     if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
10984         ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
10985         if (ctxt->valid)
10986             ctxt->myDoc->properties |= XML_DOC_DTDVALID;
10987         if (ctxt->nsWellFormed)
10988             ctxt->myDoc->properties |= XML_DOC_NSVALID;
10989         if (ctxt->options & XML_PARSE_OLD10)
10990             ctxt->myDoc->properties |= XML_DOC_OLD10;
10991     }
10992     if (! ctxt->wellFormed) {
10993         ctxt->valid = 0;
10994         return(-1);
10995     }
10996     return(0);
10997 }
10998
10999 /**
11000  * xmlParseExtParsedEnt:
11001  * @ctxt:  an XML parser context
11002  *
11003  * parse a general parsed entity
11004  * An external general parsed entity is well-formed if it matches the
11005  * production labeled extParsedEnt.
11006  *
11007  * [78] extParsedEnt ::= TextDecl? content
11008  *
11009  * Returns 0, -1 in case of error. the parser context is augmented
11010  *                as a result of the parsing.
11011  */
11012
11013 int
11014 xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
11015     xmlChar start[4];
11016     xmlCharEncoding enc;
11017
11018     if ((ctxt == NULL) || (ctxt->input == NULL))
11019         return(-1);
11020
11021     xmlDefaultSAXHandlerInit();
11022
11023     xmlDetectSAX2(ctxt);
11024
11025     GROW;
11026
11027     /*
11028      * SAX: beginning of the document processing.
11029      */
11030     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11031         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
11032
11033     /*
11034      * Get the 4 first bytes and decode the charset
11035      * if enc != XML_CHAR_ENCODING_NONE
11036      * plug some encoding conversion routines.
11037      */
11038     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
11039         start[0] = RAW;
11040         start[1] = NXT(1);
11041         start[2] = NXT(2);
11042         start[3] = NXT(3);
11043         enc = xmlDetectCharEncoding(start, 4);
11044         if (enc != XML_CHAR_ENCODING_NONE) {
11045             xmlSwitchEncoding(ctxt, enc);
11046         }
11047     }
11048
11049
11050     if (CUR == 0) {
11051         xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11052     }
11053
11054     /*
11055      * Check for the XMLDecl in the Prolog.
11056      */
11057     GROW;
11058     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
11059
11060         /*
11061          * Note that we will switch encoding on the fly.
11062          */
11063         xmlParseXMLDecl(ctxt);
11064         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
11065             /*
11066              * The XML REC instructs us to stop parsing right here
11067              */
11068             return(-1);
11069         }
11070         SKIP_BLANKS;
11071     } else {
11072         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11073     }
11074     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
11075         ctxt->sax->startDocument(ctxt->userData);
11076     if (ctxt->instate == XML_PARSER_EOF)
11077         return(-1);
11078
11079     /*
11080      * Doing validity checking on chunk doesn't make sense
11081      */
11082     ctxt->instate = XML_PARSER_CONTENT;
11083     ctxt->validate = 0;
11084     ctxt->loadsubset = 0;
11085     ctxt->depth = 0;
11086
11087     xmlParseContent(ctxt);
11088     if (ctxt->instate == XML_PARSER_EOF)
11089         return(-1);
11090
11091     if ((RAW == '<') && (NXT(1) == '/')) {
11092         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11093     } else if (RAW != 0) {
11094         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
11095     }
11096
11097     /*
11098      * SAX: end of the document processing.
11099      */
11100     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11101         ctxt->sax->endDocument(ctxt->userData);
11102
11103     if (! ctxt->wellFormed) return(-1);
11104     return(0);
11105 }
11106
11107 #ifdef LIBXML_PUSH_ENABLED
11108 /************************************************************************
11109  *                                                                      *
11110  *              Progressive parsing interfaces                          *
11111  *                                                                      *
11112  ************************************************************************/
11113
11114 /**
11115  * xmlParseLookupSequence:
11116  * @ctxt:  an XML parser context
11117  * @first:  the first char to lookup
11118  * @next:  the next char to lookup or zero
11119  * @third:  the next char to lookup or zero
11120  *
11121  * Try to find if a sequence (first, next, third) or  just (first next) or
11122  * (first) is available in the input stream.
11123  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
11124  * to avoid rescanning sequences of bytes, it DOES change the state of the
11125  * parser, do not use liberally.
11126  *
11127  * Returns the index to the current parsing point if the full sequence
11128  *      is available, -1 otherwise.
11129  */
11130 static int
11131 xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
11132                        xmlChar next, xmlChar third) {
11133     int base, len;
11134     xmlParserInputPtr in;
11135     const xmlChar *buf;
11136
11137     in = ctxt->input;
11138     if (in == NULL) return(-1);
11139     base = in->cur - in->base;
11140     if (base < 0) return(-1);
11141     if (ctxt->checkIndex > base)
11142         base = ctxt->checkIndex;
11143     if (in->buf == NULL) {
11144         buf = in->base;
11145         len = in->length;
11146     } else {
11147         buf = xmlBufContent(in->buf->buffer);
11148         len = xmlBufUse(in->buf->buffer);
11149     }
11150     /* take into account the sequence length */
11151     if (third) len -= 2;
11152     else if (next) len --;
11153     for (;base < len;base++) {
11154         if (buf[base] == first) {
11155             if (third != 0) {
11156                 if ((buf[base + 1] != next) ||
11157                     (buf[base + 2] != third)) continue;
11158             } else if (next != 0) {
11159                 if (buf[base + 1] != next) continue;
11160             }
11161             ctxt->checkIndex = 0;
11162 #ifdef DEBUG_PUSH
11163             if (next == 0)
11164                 xmlGenericError(xmlGenericErrorContext,
11165                         "PP: lookup '%c' found at %d\n",
11166                         first, base);
11167             else if (third == 0)
11168                 xmlGenericError(xmlGenericErrorContext,
11169                         "PP: lookup '%c%c' found at %d\n",
11170                         first, next, base);
11171             else
11172                 xmlGenericError(xmlGenericErrorContext,
11173                         "PP: lookup '%c%c%c' found at %d\n",
11174                         first, next, third, base);
11175 #endif
11176             return(base - (in->cur - in->base));
11177         }
11178     }
11179     ctxt->checkIndex = base;
11180 #ifdef DEBUG_PUSH
11181     if (next == 0)
11182         xmlGenericError(xmlGenericErrorContext,
11183                 "PP: lookup '%c' failed\n", first);
11184     else if (third == 0)
11185         xmlGenericError(xmlGenericErrorContext,
11186                 "PP: lookup '%c%c' failed\n", first, next);
11187     else
11188         xmlGenericError(xmlGenericErrorContext,
11189                 "PP: lookup '%c%c%c' failed\n", first, next, third);
11190 #endif
11191     return(-1);
11192 }
11193
11194 /**
11195  * xmlParseGetLasts:
11196  * @ctxt:  an XML parser context
11197  * @lastlt:  pointer to store the last '<' from the input
11198  * @lastgt:  pointer to store the last '>' from the input
11199  *
11200  * Lookup the last < and > in the current chunk
11201  */
11202 static void
11203 xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
11204                  const xmlChar **lastgt) {
11205     const xmlChar *tmp;
11206
11207     if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
11208         xmlGenericError(xmlGenericErrorContext,
11209                     "Internal error: xmlParseGetLasts\n");
11210         return;
11211     }
11212     if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
11213         tmp = ctxt->input->end;
11214         tmp--;
11215         while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
11216         if (tmp < ctxt->input->base) {
11217             *lastlt = NULL;
11218             *lastgt = NULL;
11219         } else {
11220             *lastlt = tmp;
11221             tmp++;
11222             while ((tmp < ctxt->input->end) && (*tmp != '>')) {
11223                 if (*tmp == '\'') {
11224                     tmp++;
11225                     while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
11226                     if (tmp < ctxt->input->end) tmp++;
11227                 } else if (*tmp == '"') {
11228                     tmp++;
11229                     while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
11230                     if (tmp < ctxt->input->end) tmp++;
11231                 } else
11232                     tmp++;
11233             }
11234             if (tmp < ctxt->input->end)
11235                 *lastgt = tmp;
11236             else {
11237                 tmp = *lastlt;
11238                 tmp--;
11239                 while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
11240                 if (tmp >= ctxt->input->base)
11241                     *lastgt = tmp;
11242                 else
11243                     *lastgt = NULL;
11244             }
11245         }
11246     } else {
11247         *lastlt = NULL;
11248         *lastgt = NULL;
11249     }
11250 }
11251 /**
11252  * xmlCheckCdataPush:
11253  * @cur: pointer to the block of characters
11254  * @len: length of the block in bytes
11255  * @complete: 1 if complete CDATA block is passed in, 0 if partial block
11256  *
11257  * Check that the block of characters is okay as SCdata content [20]
11258  *
11259  * Returns the number of bytes to pass if okay, a negative index where an
11260  *         UTF-8 error occured otherwise
11261  */
11262 static int
11263 xmlCheckCdataPush(const xmlChar *utf, int len, int complete) {
11264     int ix;
11265     unsigned char c;
11266     int codepoint;
11267
11268     if ((utf == NULL) || (len <= 0))
11269         return(0);
11270
11271     for (ix = 0; ix < len;) {      /* string is 0-terminated */
11272         c = utf[ix];
11273         if ((c & 0x80) == 0x00) {       /* 1-byte code, starts with 10 */
11274             if (c >= 0x20)
11275                 ix++;
11276             else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
11277                 ix++;
11278             else
11279                 return(-ix);
11280         } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
11281             if (ix + 2 > len) return(complete ? -ix : ix);
11282             if ((utf[ix+1] & 0xc0 ) != 0x80)
11283                 return(-ix);
11284             codepoint = (utf[ix] & 0x1f) << 6;
11285             codepoint |= utf[ix+1] & 0x3f;
11286             if (!xmlIsCharQ(codepoint))
11287                 return(-ix);
11288             ix += 2;
11289         } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
11290             if (ix + 3 > len) return(complete ? -ix : ix);
11291             if (((utf[ix+1] & 0xc0) != 0x80) ||
11292                 ((utf[ix+2] & 0xc0) != 0x80))
11293                     return(-ix);
11294             codepoint = (utf[ix] & 0xf) << 12;
11295             codepoint |= (utf[ix+1] & 0x3f) << 6;
11296             codepoint |= utf[ix+2] & 0x3f;
11297             if (!xmlIsCharQ(codepoint))
11298                 return(-ix);
11299             ix += 3;
11300         } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
11301             if (ix + 4 > len) return(complete ? -ix : ix);
11302             if (((utf[ix+1] & 0xc0) != 0x80) ||
11303                 ((utf[ix+2] & 0xc0) != 0x80) ||
11304                 ((utf[ix+3] & 0xc0) != 0x80))
11305                     return(-ix);
11306             codepoint = (utf[ix] & 0x7) << 18;
11307             codepoint |= (utf[ix+1] & 0x3f) << 12;
11308             codepoint |= (utf[ix+2] & 0x3f) << 6;
11309             codepoint |= utf[ix+3] & 0x3f;
11310             if (!xmlIsCharQ(codepoint))
11311                 return(-ix);
11312             ix += 4;
11313         } else                          /* unknown encoding */
11314             return(-ix);
11315       }
11316       return(ix);
11317 }
11318
11319 /**
11320  * xmlParseTryOrFinish:
11321  * @ctxt:  an XML parser context
11322  * @terminate:  last chunk indicator
11323  *
11324  * Try to progress on parsing
11325  *
11326  * Returns zero if no parsing was possible
11327  */
11328 static int
11329 xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
11330     int ret = 0;
11331     int avail, tlen;
11332     xmlChar cur, next;
11333     const xmlChar *lastlt, *lastgt;
11334
11335     if (ctxt->input == NULL)
11336         return(0);
11337
11338 #ifdef DEBUG_PUSH
11339     switch (ctxt->instate) {
11340         case XML_PARSER_EOF:
11341             xmlGenericError(xmlGenericErrorContext,
11342                     "PP: try EOF\n"); break;
11343         case XML_PARSER_START:
11344             xmlGenericError(xmlGenericErrorContext,
11345                     "PP: try START\n"); break;
11346         case XML_PARSER_MISC:
11347             xmlGenericError(xmlGenericErrorContext,
11348                     "PP: try MISC\n");break;
11349         case XML_PARSER_COMMENT:
11350             xmlGenericError(xmlGenericErrorContext,
11351                     "PP: try COMMENT\n");break;
11352         case XML_PARSER_PROLOG:
11353             xmlGenericError(xmlGenericErrorContext,
11354                     "PP: try PROLOG\n");break;
11355         case XML_PARSER_START_TAG:
11356             xmlGenericError(xmlGenericErrorContext,
11357                     "PP: try START_TAG\n");break;
11358         case XML_PARSER_CONTENT:
11359             xmlGenericError(xmlGenericErrorContext,
11360                     "PP: try CONTENT\n");break;
11361         case XML_PARSER_CDATA_SECTION:
11362             xmlGenericError(xmlGenericErrorContext,
11363                     "PP: try CDATA_SECTION\n");break;
11364         case XML_PARSER_END_TAG:
11365             xmlGenericError(xmlGenericErrorContext,
11366                     "PP: try END_TAG\n");break;
11367         case XML_PARSER_ENTITY_DECL:
11368             xmlGenericError(xmlGenericErrorContext,
11369                     "PP: try ENTITY_DECL\n");break;
11370         case XML_PARSER_ENTITY_VALUE:
11371             xmlGenericError(xmlGenericErrorContext,
11372                     "PP: try ENTITY_VALUE\n");break;
11373         case XML_PARSER_ATTRIBUTE_VALUE:
11374             xmlGenericError(xmlGenericErrorContext,
11375                     "PP: try ATTRIBUTE_VALUE\n");break;
11376         case XML_PARSER_DTD:
11377             xmlGenericError(xmlGenericErrorContext,
11378                     "PP: try DTD\n");break;
11379         case XML_PARSER_EPILOG:
11380             xmlGenericError(xmlGenericErrorContext,
11381                     "PP: try EPILOG\n");break;
11382         case XML_PARSER_PI:
11383             xmlGenericError(xmlGenericErrorContext,
11384                     "PP: try PI\n");break;
11385         case XML_PARSER_IGNORE:
11386             xmlGenericError(xmlGenericErrorContext,
11387                     "PP: try IGNORE\n");break;
11388     }
11389 #endif
11390
11391     if ((ctxt->input != NULL) &&
11392         (ctxt->input->cur - ctxt->input->base > 4096)) {
11393         xmlSHRINK(ctxt);
11394         ctxt->checkIndex = 0;
11395     }
11396     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11397
11398     while (ctxt->instate != XML_PARSER_EOF) {
11399         if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11400             return(0);
11401
11402
11403         /*
11404          * Pop-up of finished entities.
11405          */
11406         while ((RAW == 0) && (ctxt->inputNr > 1))
11407             xmlPopInput(ctxt);
11408
11409         if (ctxt->input == NULL) break;
11410         if (ctxt->input->buf == NULL)
11411             avail = ctxt->input->length -
11412                     (ctxt->input->cur - ctxt->input->base);
11413         else {
11414             /*
11415              * If we are operating on converted input, try to flush
11416              * remainng chars to avoid them stalling in the non-converted
11417              * buffer. But do not do this in document start where
11418              * encoding="..." may not have been read and we work on a
11419              * guessed encoding.
11420              */
11421             if ((ctxt->instate != XML_PARSER_START) &&
11422                 (ctxt->input->buf->raw != NULL) &&
11423                 (xmlBufIsEmpty(ctxt->input->buf->raw) == 0)) {
11424                 size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
11425                                                  ctxt->input);
11426                 size_t current = ctxt->input->cur - ctxt->input->base;
11427
11428                 xmlParserInputBufferPush(ctxt->input->buf, 0, "");
11429                 xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
11430                                       base, current);
11431             }
11432             avail = xmlBufUse(ctxt->input->buf->buffer) -
11433                     (ctxt->input->cur - ctxt->input->base);
11434         }
11435         if (avail < 1)
11436             goto done;
11437         switch (ctxt->instate) {
11438             case XML_PARSER_EOF:
11439                 /*
11440                  * Document parsing is done !
11441                  */
11442                 goto done;
11443             case XML_PARSER_START:
11444                 if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
11445                     xmlChar start[4];
11446                     xmlCharEncoding enc;
11447
11448                     /*
11449                      * Very first chars read from the document flow.
11450                      */
11451                     if (avail < 4)
11452                         goto done;
11453
11454                     /*
11455                      * Get the 4 first bytes and decode the charset
11456                      * if enc != XML_CHAR_ENCODING_NONE
11457                      * plug some encoding conversion routines,
11458                      * else xmlSwitchEncoding will set to (default)
11459                      * UTF8.
11460                      */
11461                     start[0] = RAW;
11462                     start[1] = NXT(1);
11463                     start[2] = NXT(2);
11464                     start[3] = NXT(3);
11465                     enc = xmlDetectCharEncoding(start, 4);
11466                     xmlSwitchEncoding(ctxt, enc);
11467                     break;
11468                 }
11469
11470                 if (avail < 2)
11471                     goto done;
11472                 cur = ctxt->input->cur[0];
11473                 next = ctxt->input->cur[1];
11474                 if (cur == 0) {
11475                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11476                         ctxt->sax->setDocumentLocator(ctxt->userData,
11477                                                       &xmlDefaultSAXLocator);
11478                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11479                     xmlHaltParser(ctxt);
11480 #ifdef DEBUG_PUSH
11481                     xmlGenericError(xmlGenericErrorContext,
11482                             "PP: entering EOF\n");
11483 #endif
11484                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11485                         ctxt->sax->endDocument(ctxt->userData);
11486                     goto done;
11487                 }
11488                 if ((cur == '<') && (next == '?')) {
11489                     /* PI or XML decl */
11490                     if (avail < 5) return(ret);
11491                     if ((!terminate) &&
11492                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11493                         return(ret);
11494                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11495                         ctxt->sax->setDocumentLocator(ctxt->userData,
11496                                                       &xmlDefaultSAXLocator);
11497                     if ((ctxt->input->cur[2] == 'x') &&
11498                         (ctxt->input->cur[3] == 'm') &&
11499                         (ctxt->input->cur[4] == 'l') &&
11500                         (IS_BLANK_CH(ctxt->input->cur[5]))) {
11501                         ret += 5;
11502 #ifdef DEBUG_PUSH
11503                         xmlGenericError(xmlGenericErrorContext,
11504                                 "PP: Parsing XML Decl\n");
11505 #endif
11506                         xmlParseXMLDecl(ctxt);
11507                         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
11508                             /*
11509                              * The XML REC instructs us to stop parsing right
11510                              * here
11511                              */
11512                             xmlHaltParser(ctxt);
11513                             return(0);
11514                         }
11515                         ctxt->standalone = ctxt->input->standalone;
11516                         if ((ctxt->encoding == NULL) &&
11517                             (ctxt->input->encoding != NULL))
11518                             ctxt->encoding = xmlStrdup(ctxt->input->encoding);
11519                         if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11520                             (!ctxt->disableSAX))
11521                             ctxt->sax->startDocument(ctxt->userData);
11522                         ctxt->instate = XML_PARSER_MISC;
11523 #ifdef DEBUG_PUSH
11524                         xmlGenericError(xmlGenericErrorContext,
11525                                 "PP: entering MISC\n");
11526 #endif
11527                     } else {
11528                         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11529                         if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11530                             (!ctxt->disableSAX))
11531                             ctxt->sax->startDocument(ctxt->userData);
11532                         ctxt->instate = XML_PARSER_MISC;
11533 #ifdef DEBUG_PUSH
11534                         xmlGenericError(xmlGenericErrorContext,
11535                                 "PP: entering MISC\n");
11536 #endif
11537                     }
11538                 } else {
11539                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11540                         ctxt->sax->setDocumentLocator(ctxt->userData,
11541                                                       &xmlDefaultSAXLocator);
11542                     ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11543                     if (ctxt->version == NULL) {
11544                         xmlErrMemory(ctxt, NULL);
11545                         break;
11546                     }
11547                     if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11548                         (!ctxt->disableSAX))
11549                         ctxt->sax->startDocument(ctxt->userData);
11550                     ctxt->instate = XML_PARSER_MISC;
11551 #ifdef DEBUG_PUSH
11552                     xmlGenericError(xmlGenericErrorContext,
11553                             "PP: entering MISC\n");
11554 #endif
11555                 }
11556                 break;
11557             case XML_PARSER_START_TAG: {
11558                 const xmlChar *name;
11559                 const xmlChar *prefix = NULL;
11560                 const xmlChar *URI = NULL;
11561                 int nsNr = ctxt->nsNr;
11562
11563                 if ((avail < 2) && (ctxt->inputNr == 1))
11564                     goto done;
11565                 cur = ctxt->input->cur[0];
11566                 if (cur != '<') {
11567                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11568                     xmlHaltParser(ctxt);
11569                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11570                         ctxt->sax->endDocument(ctxt->userData);
11571                     goto done;
11572                 }
11573                 if (!terminate) {
11574                     if (ctxt->progressive) {
11575                         /* > can be found unescaped in attribute values */
11576                         if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11577                             goto done;
11578                     } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11579                         goto done;
11580                     }
11581                 }
11582                 if (ctxt->spaceNr == 0)
11583                     spacePush(ctxt, -1);
11584                 else if (*ctxt->space == -2)
11585                     spacePush(ctxt, -1);
11586                 else
11587                     spacePush(ctxt, *ctxt->space);
11588 #ifdef LIBXML_SAX1_ENABLED
11589                 if (ctxt->sax2)
11590 #endif /* LIBXML_SAX1_ENABLED */
11591                     name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
11592 #ifdef LIBXML_SAX1_ENABLED
11593                 else
11594                     name = xmlParseStartTag(ctxt);
11595 #endif /* LIBXML_SAX1_ENABLED */
11596                 if (ctxt->instate == XML_PARSER_EOF)
11597                     goto done;
11598                 if (name == NULL) {
11599                     spacePop(ctxt);
11600                     xmlHaltParser(ctxt);
11601                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11602                         ctxt->sax->endDocument(ctxt->userData);
11603                     goto done;
11604                 }
11605 #ifdef LIBXML_VALID_ENABLED
11606                 /*
11607                  * [ VC: Root Element Type ]
11608                  * The Name in the document type declaration must match
11609                  * the element type of the root element.
11610                  */
11611                 if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
11612                     ctxt->node && (ctxt->node == ctxt->myDoc->children))
11613                     ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
11614 #endif /* LIBXML_VALID_ENABLED */
11615
11616                 /*
11617                  * Check for an Empty Element.
11618                  */
11619                 if ((RAW == '/') && (NXT(1) == '>')) {
11620                     SKIP(2);
11621
11622                     if (ctxt->sax2) {
11623                         if ((ctxt->sax != NULL) &&
11624                             (ctxt->sax->endElementNs != NULL) &&
11625                             (!ctxt->disableSAX))
11626                             ctxt->sax->endElementNs(ctxt->userData, name,
11627                                                     prefix, URI);
11628                         if (ctxt->nsNr - nsNr > 0)
11629                             nsPop(ctxt, ctxt->nsNr - nsNr);
11630 #ifdef LIBXML_SAX1_ENABLED
11631                     } else {
11632                         if ((ctxt->sax != NULL) &&
11633                             (ctxt->sax->endElement != NULL) &&
11634                             (!ctxt->disableSAX))
11635                             ctxt->sax->endElement(ctxt->userData, name);
11636 #endif /* LIBXML_SAX1_ENABLED */
11637                     }
11638                     if (ctxt->instate == XML_PARSER_EOF)
11639                         goto done;
11640                     spacePop(ctxt);
11641                     if (ctxt->nameNr == 0) {
11642                         ctxt->instate = XML_PARSER_EPILOG;
11643                     } else {
11644                         ctxt->instate = XML_PARSER_CONTENT;
11645                     }
11646                     ctxt->progressive = 1;
11647                     break;
11648                 }
11649                 if (RAW == '>') {
11650                     NEXT;
11651                 } else {
11652                     xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
11653                                          "Couldn't find end of Start Tag %s\n",
11654                                          name);
11655                     nodePop(ctxt);
11656                     spacePop(ctxt);
11657                 }
11658                 if (ctxt->sax2)
11659                     nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
11660 #ifdef LIBXML_SAX1_ENABLED
11661                 else
11662                     namePush(ctxt, name);
11663 #endif /* LIBXML_SAX1_ENABLED */
11664
11665                 ctxt->instate = XML_PARSER_CONTENT;
11666                 ctxt->progressive = 1;
11667                 break;
11668             }
11669             case XML_PARSER_CONTENT: {
11670                 const xmlChar *test;
11671                 unsigned int cons;
11672                 if ((avail < 2) && (ctxt->inputNr == 1))
11673                     goto done;
11674                 cur = ctxt->input->cur[0];
11675                 next = ctxt->input->cur[1];
11676
11677                 test = CUR_PTR;
11678                 cons = ctxt->input->consumed;
11679                 if ((cur == '<') && (next == '/')) {
11680                     ctxt->instate = XML_PARSER_END_TAG;
11681                     break;
11682                 } else if ((cur == '<') && (next == '?')) {
11683                     if ((!terminate) &&
11684                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11685                         ctxt->progressive = XML_PARSER_PI;
11686                         goto done;
11687                     }
11688                     xmlParsePI(ctxt);
11689                     ctxt->instate = XML_PARSER_CONTENT;
11690                     ctxt->progressive = 1;
11691                 } else if ((cur == '<') && (next != '!')) {
11692                     ctxt->instate = XML_PARSER_START_TAG;
11693                     break;
11694                 } else if ((cur == '<') && (next == '!') &&
11695                            (ctxt->input->cur[2] == '-') &&
11696                            (ctxt->input->cur[3] == '-')) {
11697                     int term;
11698
11699                     if (avail < 4)
11700                         goto done;
11701                     ctxt->input->cur += 4;
11702                     term = xmlParseLookupSequence(ctxt, '-', '-', '>');
11703                     ctxt->input->cur -= 4;
11704                     if ((!terminate) && (term < 0)) {
11705                         ctxt->progressive = XML_PARSER_COMMENT;
11706                         goto done;
11707                     }
11708                     xmlParseComment(ctxt);
11709                     ctxt->instate = XML_PARSER_CONTENT;
11710                     ctxt->progressive = 1;
11711                 } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
11712                     (ctxt->input->cur[2] == '[') &&
11713                     (ctxt->input->cur[3] == 'C') &&
11714                     (ctxt->input->cur[4] == 'D') &&
11715                     (ctxt->input->cur[5] == 'A') &&
11716                     (ctxt->input->cur[6] == 'T') &&
11717                     (ctxt->input->cur[7] == 'A') &&
11718                     (ctxt->input->cur[8] == '[')) {
11719                     SKIP(9);
11720                     ctxt->instate = XML_PARSER_CDATA_SECTION;
11721                     break;
11722                 } else if ((cur == '<') && (next == '!') &&
11723                            (avail < 9)) {
11724                     goto done;
11725                 } else if (cur == '&') {
11726                     if ((!terminate) &&
11727                         (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
11728                         goto done;
11729                     xmlParseReference(ctxt);
11730                 } else {
11731                     /* TODO Avoid the extra copy, handle directly !!! */
11732                     /*
11733                      * Goal of the following test is:
11734                      *  - minimize calls to the SAX 'character' callback
11735                      *    when they are mergeable
11736                      *  - handle an problem for isBlank when we only parse
11737                      *    a sequence of blank chars and the next one is
11738                      *    not available to check against '<' presence.
11739                      *  - tries to homogenize the differences in SAX
11740                      *    callbacks between the push and pull versions
11741                      *    of the parser.
11742                      */
11743                     if ((ctxt->inputNr == 1) &&
11744                         (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
11745                         if (!terminate) {
11746                             if (ctxt->progressive) {
11747                                 if ((lastlt == NULL) ||
11748                                     (ctxt->input->cur > lastlt))
11749                                     goto done;
11750                             } else if (xmlParseLookupSequence(ctxt,
11751                                                               '<', 0, 0) < 0) {
11752                                 goto done;
11753                             }
11754                         }
11755                     }
11756                     ctxt->checkIndex = 0;
11757                     xmlParseCharData(ctxt, 0);
11758                 }
11759                 /*
11760                  * Pop-up of finished entities.
11761                  */
11762                 while ((RAW == 0) && (ctxt->inputNr > 1))
11763                     xmlPopInput(ctxt);
11764                 if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
11765                     xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
11766                                 "detected an error in element content\n");
11767                     xmlHaltParser(ctxt);
11768                     break;
11769                 }
11770                 break;
11771             }
11772             case XML_PARSER_END_TAG:
11773                 if (avail < 2)
11774                     goto done;
11775                 if (!terminate) {
11776                     if (ctxt->progressive) {
11777                         /* > can be found unescaped in attribute values */
11778                         if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11779                             goto done;
11780                     } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11781                         goto done;
11782                     }
11783                 }
11784                 if (ctxt->sax2) {
11785                     xmlParseEndTag2(ctxt,
11786                            (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
11787                            (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
11788                        (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
11789                     nameNsPop(ctxt);
11790                 }
11791 #ifdef LIBXML_SAX1_ENABLED
11792                   else
11793                     xmlParseEndTag1(ctxt, 0);
11794 #endif /* LIBXML_SAX1_ENABLED */
11795                 if (ctxt->instate == XML_PARSER_EOF) {
11796                     /* Nothing */
11797                 } else if (ctxt->nameNr == 0) {
11798                     ctxt->instate = XML_PARSER_EPILOG;
11799                 } else {
11800                     ctxt->instate = XML_PARSER_CONTENT;
11801                 }
11802                 break;
11803             case XML_PARSER_CDATA_SECTION: {
11804                 /*
11805                  * The Push mode need to have the SAX callback for
11806                  * cdataBlock merge back contiguous callbacks.
11807                  */
11808                 int base;
11809
11810                 base = xmlParseLookupSequence(ctxt, ']', ']', '>');
11811                 if (base < 0) {
11812                     if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
11813                         int tmp;
11814
11815                         tmp = xmlCheckCdataPush(ctxt->input->cur,
11816                                                 XML_PARSER_BIG_BUFFER_SIZE, 0);
11817                         if (tmp < 0) {
11818                             tmp = -tmp;
11819                             ctxt->input->cur += tmp;
11820                             goto encoding_error;
11821                         }
11822                         if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
11823                             if (ctxt->sax->cdataBlock != NULL)
11824                                 ctxt->sax->cdataBlock(ctxt->userData,
11825                                                       ctxt->input->cur, tmp);
11826                             else if (ctxt->sax->characters != NULL)
11827                                 ctxt->sax->characters(ctxt->userData,
11828                                                       ctxt->input->cur, tmp);
11829                         }
11830                         if (ctxt->instate == XML_PARSER_EOF)
11831                             goto done;
11832                         SKIPL(tmp);
11833                         ctxt->checkIndex = 0;
11834                     }
11835                     goto done;
11836                 } else {
11837                     int tmp;
11838
11839                     tmp = xmlCheckCdataPush(ctxt->input->cur, base, 1);
11840                     if ((tmp < 0) || (tmp != base)) {
11841                         tmp = -tmp;
11842                         ctxt->input->cur += tmp;
11843                         goto encoding_error;
11844                     }
11845                     if ((ctxt->sax != NULL) && (base == 0) &&
11846                         (ctxt->sax->cdataBlock != NULL) &&
11847                         (!ctxt->disableSAX)) {
11848                         /*
11849                          * Special case to provide identical behaviour
11850                          * between pull and push parsers on enpty CDATA
11851                          * sections
11852                          */
11853                          if ((ctxt->input->cur - ctxt->input->base >= 9) &&
11854                              (!strncmp((const char *)&ctxt->input->cur[-9],
11855                                        "<![CDATA[", 9)))
11856                              ctxt->sax->cdataBlock(ctxt->userData,
11857                                                    BAD_CAST "", 0);
11858                     } else if ((ctxt->sax != NULL) && (base > 0) &&
11859                         (!ctxt->disableSAX)) {
11860                         if (ctxt->sax->cdataBlock != NULL)
11861                             ctxt->sax->cdataBlock(ctxt->userData,
11862                                                   ctxt->input->cur, base);
11863                         else if (ctxt->sax->characters != NULL)
11864                             ctxt->sax->characters(ctxt->userData,
11865                                                   ctxt->input->cur, base);
11866                     }
11867                     if (ctxt->instate == XML_PARSER_EOF)
11868                         goto done;
11869                     SKIPL(base + 3);
11870                     ctxt->checkIndex = 0;
11871                     ctxt->instate = XML_PARSER_CONTENT;
11872 #ifdef DEBUG_PUSH
11873                     xmlGenericError(xmlGenericErrorContext,
11874                             "PP: entering CONTENT\n");
11875 #endif
11876                 }
11877                 break;
11878             }
11879             case XML_PARSER_MISC:
11880                 SKIP_BLANKS;
11881                 if (ctxt->input->buf == NULL)
11882                     avail = ctxt->input->length -
11883                             (ctxt->input->cur - ctxt->input->base);
11884                 else
11885                     avail = xmlBufUse(ctxt->input->buf->buffer) -
11886                             (ctxt->input->cur - ctxt->input->base);
11887                 if (avail < 2)
11888                     goto done;
11889                 cur = ctxt->input->cur[0];
11890                 next = ctxt->input->cur[1];
11891                 if ((cur == '<') && (next == '?')) {
11892                     if ((!terminate) &&
11893                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11894                         ctxt->progressive = XML_PARSER_PI;
11895                         goto done;
11896                     }
11897 #ifdef DEBUG_PUSH
11898                     xmlGenericError(xmlGenericErrorContext,
11899                             "PP: Parsing PI\n");
11900 #endif
11901                     xmlParsePI(ctxt);
11902                     if (ctxt->instate == XML_PARSER_EOF)
11903                         goto done;
11904                     ctxt->instate = XML_PARSER_MISC;
11905                     ctxt->progressive = 1;
11906                     ctxt->checkIndex = 0;
11907                 } else if ((cur == '<') && (next == '!') &&
11908                     (ctxt->input->cur[2] == '-') &&
11909                     (ctxt->input->cur[3] == '-')) {
11910                     if ((!terminate) &&
11911                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11912                         ctxt->progressive = XML_PARSER_COMMENT;
11913                         goto done;
11914                     }
11915 #ifdef DEBUG_PUSH
11916                     xmlGenericError(xmlGenericErrorContext,
11917                             "PP: Parsing Comment\n");
11918 #endif
11919                     xmlParseComment(ctxt);
11920                     if (ctxt->instate == XML_PARSER_EOF)
11921                         goto done;
11922                     ctxt->instate = XML_PARSER_MISC;
11923                     ctxt->progressive = 1;
11924                     ctxt->checkIndex = 0;
11925                 } else if ((cur == '<') && (next == '!') &&
11926                     (ctxt->input->cur[2] == 'D') &&
11927                     (ctxt->input->cur[3] == 'O') &&
11928                     (ctxt->input->cur[4] == 'C') &&
11929                     (ctxt->input->cur[5] == 'T') &&
11930                     (ctxt->input->cur[6] == 'Y') &&
11931                     (ctxt->input->cur[7] == 'P') &&
11932                     (ctxt->input->cur[8] == 'E')) {
11933                     if ((!terminate) &&
11934                         (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0)) {
11935                         ctxt->progressive = XML_PARSER_DTD;
11936                         goto done;
11937                     }
11938 #ifdef DEBUG_PUSH
11939                     xmlGenericError(xmlGenericErrorContext,
11940                             "PP: Parsing internal subset\n");
11941 #endif
11942                     ctxt->inSubset = 1;
11943                     ctxt->progressive = 0;
11944                     ctxt->checkIndex = 0;
11945                     xmlParseDocTypeDecl(ctxt);
11946                     if (ctxt->instate == XML_PARSER_EOF)
11947                         goto done;
11948                     if (RAW == '[') {
11949                         ctxt->instate = XML_PARSER_DTD;
11950 #ifdef DEBUG_PUSH
11951                         xmlGenericError(xmlGenericErrorContext,
11952                                 "PP: entering DTD\n");
11953 #endif
11954                     } else {
11955                         /*
11956                          * Create and update the external subset.
11957                          */
11958                         ctxt->inSubset = 2;
11959                         if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11960                             (ctxt->sax->externalSubset != NULL))
11961                             ctxt->sax->externalSubset(ctxt->userData,
11962                                     ctxt->intSubName, ctxt->extSubSystem,
11963                                     ctxt->extSubURI);
11964                         ctxt->inSubset = 0;
11965                         xmlCleanSpecialAttr(ctxt);
11966                         ctxt->instate = XML_PARSER_PROLOG;
11967 #ifdef DEBUG_PUSH
11968                         xmlGenericError(xmlGenericErrorContext,
11969                                 "PP: entering PROLOG\n");
11970 #endif
11971                     }
11972                 } else if ((cur == '<') && (next == '!') &&
11973                            (avail < 9)) {
11974                     goto done;
11975                 } else {
11976                     ctxt->instate = XML_PARSER_START_TAG;
11977                     ctxt->progressive = XML_PARSER_START_TAG;
11978                     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11979 #ifdef DEBUG_PUSH
11980                     xmlGenericError(xmlGenericErrorContext,
11981                             "PP: entering START_TAG\n");
11982 #endif
11983                 }
11984                 break;
11985             case XML_PARSER_PROLOG:
11986                 SKIP_BLANKS;
11987                 if (ctxt->input->buf == NULL)
11988                     avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11989                 else
11990                     avail = xmlBufUse(ctxt->input->buf->buffer) -
11991                             (ctxt->input->cur - ctxt->input->base);
11992                 if (avail < 2)
11993                     goto done;
11994                 cur = ctxt->input->cur[0];
11995                 next = ctxt->input->cur[1];
11996                 if ((cur == '<') && (next == '?')) {
11997                     if ((!terminate) &&
11998                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11999                         ctxt->progressive = XML_PARSER_PI;
12000                         goto done;
12001                     }
12002 #ifdef DEBUG_PUSH
12003                     xmlGenericError(xmlGenericErrorContext,
12004                             "PP: Parsing PI\n");
12005 #endif
12006                     xmlParsePI(ctxt);
12007                     if (ctxt->instate == XML_PARSER_EOF)
12008                         goto done;
12009                     ctxt->instate = XML_PARSER_PROLOG;
12010                     ctxt->progressive = 1;
12011                 } else if ((cur == '<') && (next == '!') &&
12012                     (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
12013                     if ((!terminate) &&
12014                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
12015                         ctxt->progressive = XML_PARSER_COMMENT;
12016                         goto done;
12017                     }
12018 #ifdef DEBUG_PUSH
12019                     xmlGenericError(xmlGenericErrorContext,
12020                             "PP: Parsing Comment\n");
12021 #endif
12022                     xmlParseComment(ctxt);
12023                     if (ctxt->instate == XML_PARSER_EOF)
12024                         goto done;
12025                     ctxt->instate = XML_PARSER_PROLOG;
12026                     ctxt->progressive = 1;
12027                 } else if ((cur == '<') && (next == '!') &&
12028                            (avail < 4)) {
12029                     goto done;
12030                 } else {
12031                     ctxt->instate = XML_PARSER_START_TAG;
12032                     if (ctxt->progressive == 0)
12033                         ctxt->progressive = XML_PARSER_START_TAG;
12034                     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
12035 #ifdef DEBUG_PUSH
12036                     xmlGenericError(xmlGenericErrorContext,
12037                             "PP: entering START_TAG\n");
12038 #endif
12039                 }
12040                 break;
12041             case XML_PARSER_EPILOG:
12042                 SKIP_BLANKS;
12043                 if (ctxt->input->buf == NULL)
12044                     avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
12045                 else
12046                     avail = xmlBufUse(ctxt->input->buf->buffer) -
12047                             (ctxt->input->cur - ctxt->input->base);
12048                 if (avail < 2)
12049                     goto done;
12050                 cur = ctxt->input->cur[0];
12051                 next = ctxt->input->cur[1];
12052                 if ((cur == '<') && (next == '?')) {
12053                     if ((!terminate) &&
12054                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
12055                         ctxt->progressive = XML_PARSER_PI;
12056                         goto done;
12057                     }
12058 #ifdef DEBUG_PUSH
12059                     xmlGenericError(xmlGenericErrorContext,
12060                             "PP: Parsing PI\n");
12061 #endif
12062                     xmlParsePI(ctxt);
12063                     if (ctxt->instate == XML_PARSER_EOF)
12064                         goto done;
12065                     ctxt->instate = XML_PARSER_EPILOG;
12066                     ctxt->progressive = 1;
12067                 } else if ((cur == '<') && (next == '!') &&
12068                     (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
12069                     if ((!terminate) &&
12070                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
12071                         ctxt->progressive = XML_PARSER_COMMENT;
12072                         goto done;
12073                     }
12074 #ifdef DEBUG_PUSH
12075                     xmlGenericError(xmlGenericErrorContext,
12076                             "PP: Parsing Comment\n");
12077 #endif
12078                     xmlParseComment(ctxt);
12079                     if (ctxt->instate == XML_PARSER_EOF)
12080                         goto done;
12081                     ctxt->instate = XML_PARSER_EPILOG;
12082                     ctxt->progressive = 1;
12083                 } else if ((cur == '<') && (next == '!') &&
12084                            (avail < 4)) {
12085                     goto done;
12086                 } else {
12087                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12088                     xmlHaltParser(ctxt);
12089 #ifdef DEBUG_PUSH
12090                     xmlGenericError(xmlGenericErrorContext,
12091                             "PP: entering EOF\n");
12092 #endif
12093                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
12094                         ctxt->sax->endDocument(ctxt->userData);
12095                     goto done;
12096                 }
12097                 break;
12098             case XML_PARSER_DTD: {
12099                 /*
12100                  * Sorry but progressive parsing of the internal subset
12101                  * is not expected to be supported. We first check that
12102                  * the full content of the internal subset is available and
12103                  * the parsing is launched only at that point.
12104                  * Internal subset ends up with "']' S? '>'" in an unescaped
12105                  * section and not in a ']]>' sequence which are conditional
12106                  * sections (whoever argued to keep that crap in XML deserve
12107                  * a place in hell !).
12108                  */
12109                 int base, i;
12110                 xmlChar *buf;
12111                 xmlChar quote = 0;
12112                 size_t use;
12113
12114                 base = ctxt->input->cur - ctxt->input->base;
12115                 if (base < 0) return(0);
12116                 if (ctxt->checkIndex > base)
12117                     base = ctxt->checkIndex;
12118                 buf = xmlBufContent(ctxt->input->buf->buffer);
12119                 use = xmlBufUse(ctxt->input->buf->buffer);
12120                 for (;(unsigned int) base < use; base++) {
12121                     if (quote != 0) {
12122                         if (buf[base] == quote)
12123                             quote = 0;
12124                         continue;
12125                     }
12126                     if ((quote == 0) && (buf[base] == '<')) {
12127                         int found  = 0;
12128                         /* special handling of comments */
12129                         if (((unsigned int) base + 4 < use) &&
12130                             (buf[base + 1] == '!') &&
12131                             (buf[base + 2] == '-') &&
12132                             (buf[base + 3] == '-')) {
12133                             for (;(unsigned int) base + 3 < use; base++) {
12134                                 if ((buf[base] == '-') &&
12135                                     (buf[base + 1] == '-') &&
12136                                     (buf[base + 2] == '>')) {
12137                                     found = 1;
12138                                     base += 2;
12139                                     break;
12140                                 }
12141                             }
12142                             if (!found) {
12143 #if 0
12144                                 fprintf(stderr, "unfinished comment\n");
12145 #endif
12146                                 break; /* for */
12147                             }
12148                             continue;
12149                         }
12150                     }
12151                     if (buf[base] == '"') {
12152                         quote = '"';
12153                         continue;
12154                     }
12155                     if (buf[base] == '\'') {
12156                         quote = '\'';
12157                         continue;
12158                     }
12159                     if (buf[base] == ']') {
12160 #if 0
12161                         fprintf(stderr, "%c%c%c%c: ", buf[base],
12162                                 buf[base + 1], buf[base + 2], buf[base + 3]);
12163 #endif
12164                         if ((unsigned int) base +1 >= use)
12165                             break;
12166                         if (buf[base + 1] == ']') {
12167                             /* conditional crap, skip both ']' ! */
12168                             base++;
12169                             continue;
12170                         }
12171                         for (i = 1; (unsigned int) base + i < use; i++) {
12172                             if (buf[base + i] == '>') {
12173 #if 0
12174                                 fprintf(stderr, "found\n");
12175 #endif
12176                                 goto found_end_int_subset;
12177                             }
12178                             if (!IS_BLANK_CH(buf[base + i])) {
12179 #if 0
12180                                 fprintf(stderr, "not found\n");
12181 #endif
12182                                 goto not_end_of_int_subset;
12183                             }
12184                         }
12185 #if 0
12186                         fprintf(stderr, "end of stream\n");
12187 #endif
12188                         break;
12189
12190                     }
12191 not_end_of_int_subset:
12192                     continue; /* for */
12193                 }
12194                 /*
12195                  * We didn't found the end of the Internal subset
12196                  */
12197                 if (quote == 0)
12198                     ctxt->checkIndex = base;
12199                 else
12200                     ctxt->checkIndex = 0;
12201 #ifdef DEBUG_PUSH
12202                 if (next == 0)
12203                     xmlGenericError(xmlGenericErrorContext,
12204                             "PP: lookup of int subset end filed\n");
12205 #endif
12206                 goto done;
12207
12208 found_end_int_subset:
12209                 ctxt->checkIndex = 0;
12210                 xmlParseInternalSubset(ctxt);
12211                 if (ctxt->instate == XML_PARSER_EOF)
12212                     goto done;
12213                 ctxt->inSubset = 2;
12214                 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
12215                     (ctxt->sax->externalSubset != NULL))
12216                     ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
12217                             ctxt->extSubSystem, ctxt->extSubURI);
12218                 ctxt->inSubset = 0;
12219                 xmlCleanSpecialAttr(ctxt);
12220                 if (ctxt->instate == XML_PARSER_EOF)
12221                     goto done;
12222                 ctxt->instate = XML_PARSER_PROLOG;
12223                 ctxt->checkIndex = 0;
12224 #ifdef DEBUG_PUSH
12225                 xmlGenericError(xmlGenericErrorContext,
12226                         "PP: entering PROLOG\n");
12227 #endif
12228                 break;
12229             }
12230             case XML_PARSER_COMMENT:
12231                 xmlGenericError(xmlGenericErrorContext,
12232                         "PP: internal error, state == COMMENT\n");
12233                 ctxt->instate = XML_PARSER_CONTENT;
12234 #ifdef DEBUG_PUSH
12235                 xmlGenericError(xmlGenericErrorContext,
12236                         "PP: entering CONTENT\n");
12237 #endif
12238                 break;
12239             case XML_PARSER_IGNORE:
12240                 xmlGenericError(xmlGenericErrorContext,
12241                         "PP: internal error, state == IGNORE");
12242                 ctxt->instate = XML_PARSER_DTD;
12243 #ifdef DEBUG_PUSH
12244                 xmlGenericError(xmlGenericErrorContext,
12245                         "PP: entering DTD\n");
12246 #endif
12247                 break;
12248             case XML_PARSER_PI:
12249                 xmlGenericError(xmlGenericErrorContext,
12250                         "PP: internal error, state == PI\n");
12251                 ctxt->instate = XML_PARSER_CONTENT;
12252 #ifdef DEBUG_PUSH
12253                 xmlGenericError(xmlGenericErrorContext,
12254                         "PP: entering CONTENT\n");
12255 #endif
12256                 break;
12257             case XML_PARSER_ENTITY_DECL:
12258                 xmlGenericError(xmlGenericErrorContext,
12259                         "PP: internal error, state == ENTITY_DECL\n");
12260                 ctxt->instate = XML_PARSER_DTD;
12261 #ifdef DEBUG_PUSH
12262                 xmlGenericError(xmlGenericErrorContext,
12263                         "PP: entering DTD\n");
12264 #endif
12265                 break;
12266             case XML_PARSER_ENTITY_VALUE:
12267                 xmlGenericError(xmlGenericErrorContext,
12268                         "PP: internal error, state == ENTITY_VALUE\n");
12269                 ctxt->instate = XML_PARSER_CONTENT;
12270 #ifdef DEBUG_PUSH
12271                 xmlGenericError(xmlGenericErrorContext,
12272                         "PP: entering DTD\n");
12273 #endif
12274                 break;
12275             case XML_PARSER_ATTRIBUTE_VALUE:
12276                 xmlGenericError(xmlGenericErrorContext,
12277                         "PP: internal error, state == ATTRIBUTE_VALUE\n");
12278                 ctxt->instate = XML_PARSER_START_TAG;
12279 #ifdef DEBUG_PUSH
12280                 xmlGenericError(xmlGenericErrorContext,
12281                         "PP: entering START_TAG\n");
12282 #endif
12283                 break;
12284             case XML_PARSER_SYSTEM_LITERAL:
12285                 xmlGenericError(xmlGenericErrorContext,
12286                         "PP: internal error, state == SYSTEM_LITERAL\n");
12287                 ctxt->instate = XML_PARSER_START_TAG;
12288 #ifdef DEBUG_PUSH
12289                 xmlGenericError(xmlGenericErrorContext,
12290                         "PP: entering START_TAG\n");
12291 #endif
12292                 break;
12293             case XML_PARSER_PUBLIC_LITERAL:
12294                 xmlGenericError(xmlGenericErrorContext,
12295                         "PP: internal error, state == PUBLIC_LITERAL\n");
12296                 ctxt->instate = XML_PARSER_START_TAG;
12297 #ifdef DEBUG_PUSH
12298                 xmlGenericError(xmlGenericErrorContext,
12299                         "PP: entering START_TAG\n");
12300 #endif
12301                 break;
12302         }
12303     }
12304 done:
12305 #ifdef DEBUG_PUSH
12306     xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
12307 #endif
12308     return(ret);
12309 encoding_error:
12310     {
12311         char buffer[150];
12312
12313         snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
12314                         ctxt->input->cur[0], ctxt->input->cur[1],
12315                         ctxt->input->cur[2], ctxt->input->cur[3]);
12316         __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
12317                      "Input is not proper UTF-8, indicate encoding !\n%s",
12318                      BAD_CAST buffer, NULL);
12319     }
12320     return(0);
12321 }
12322
12323 /**
12324  * xmlParseCheckTransition:
12325  * @ctxt:  an XML parser context
12326  * @chunk:  a char array
12327  * @size:  the size in byte of the chunk
12328  *
12329  * Check depending on the current parser state if the chunk given must be
12330  * processed immediately or one need more data to advance on parsing.
12331  *
12332  * Returns -1 in case of error, 0 if the push is not needed and 1 if needed
12333  */
12334 static int
12335 xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
12336     if ((ctxt == NULL) || (chunk == NULL) || (size < 0))
12337         return(-1);
12338     if (ctxt->instate == XML_PARSER_START_TAG) {
12339         if (memchr(chunk, '>', size) != NULL)
12340             return(1);
12341         return(0);
12342     }
12343     if (ctxt->progressive == XML_PARSER_COMMENT) {
12344         if (memchr(chunk, '>', size) != NULL)
12345             return(1);
12346         return(0);
12347     }
12348     if (ctxt->instate == XML_PARSER_CDATA_SECTION) {
12349         if (memchr(chunk, '>', size) != NULL)
12350             return(1);
12351         return(0);
12352     }
12353     if (ctxt->progressive == XML_PARSER_PI) {
12354         if (memchr(chunk, '>', size) != NULL)
12355             return(1);
12356         return(0);
12357     }
12358     if (ctxt->instate == XML_PARSER_END_TAG) {
12359         if (memchr(chunk, '>', size) != NULL)
12360             return(1);
12361         return(0);
12362     }
12363     if ((ctxt->progressive == XML_PARSER_DTD) ||
12364         (ctxt->instate == XML_PARSER_DTD)) {
12365         if (memchr(chunk, '>', size) != NULL)
12366             return(1);
12367         return(0);
12368     }
12369     return(1);
12370 }
12371
12372 /**
12373  * xmlParseChunk:
12374  * @ctxt:  an XML parser context
12375  * @chunk:  an char array
12376  * @size:  the size in byte of the chunk
12377  * @terminate:  last chunk indicator
12378  *
12379  * Parse a Chunk of memory
12380  *
12381  * Returns zero if no error, the xmlParserErrors otherwise.
12382  */
12383 int
12384 xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
12385               int terminate) {
12386     int end_in_lf = 0;
12387     int remain = 0;
12388     size_t old_avail = 0;
12389     size_t avail = 0;
12390
12391     if (ctxt == NULL)
12392         return(XML_ERR_INTERNAL_ERROR);
12393     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12394         return(ctxt->errNo);
12395     if (ctxt->instate == XML_PARSER_EOF)
12396         return(-1);
12397     if (ctxt->instate == XML_PARSER_START)
12398         xmlDetectSAX2(ctxt);
12399     if ((size > 0) && (chunk != NULL) && (!terminate) &&
12400         (chunk[size - 1] == '\r')) {
12401         end_in_lf = 1;
12402         size--;
12403     }
12404
12405 xmldecl_done:
12406
12407     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
12408         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
12409         size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12410         size_t cur = ctxt->input->cur - ctxt->input->base;
12411         int res;
12412
12413         old_avail = xmlBufUse(ctxt->input->buf->buffer);
12414         /*
12415          * Specific handling if we autodetected an encoding, we should not
12416          * push more than the first line ... which depend on the encoding
12417          * And only push the rest once the final encoding was detected
12418          */
12419         if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
12420             (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
12421             unsigned int len = 45;
12422
12423             if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12424                                BAD_CAST "UTF-16")) ||
12425                 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12426                                BAD_CAST "UTF16")))
12427                 len = 90;
12428             else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12429                                     BAD_CAST "UCS-4")) ||
12430                      (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12431                                     BAD_CAST "UCS4")))
12432                 len = 180;
12433
12434             if (ctxt->input->buf->rawconsumed < len)
12435                 len -= ctxt->input->buf->rawconsumed;
12436
12437             /*
12438              * Change size for reading the initial declaration only
12439              * if size is greater than len. Otherwise, memmove in xmlBufferAdd
12440              * will blindly copy extra bytes from memory.
12441              */
12442             if ((unsigned int) size > len) {
12443                 remain = size - len;
12444                 size = len;
12445             } else {
12446                 remain = 0;
12447             }
12448         }
12449         res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12450         if (res < 0) {
12451             ctxt->errNo = XML_PARSER_EOF;
12452             xmlHaltParser(ctxt);
12453             return (XML_PARSER_EOF);
12454         }
12455         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12456 #ifdef DEBUG_PUSH
12457         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12458 #endif
12459
12460     } else if (ctxt->instate != XML_PARSER_EOF) {
12461         if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
12462             xmlParserInputBufferPtr in = ctxt->input->buf;
12463             if ((in->encoder != NULL) && (in->buffer != NULL) &&
12464                     (in->raw != NULL)) {
12465                 int nbchars;
12466                 size_t base = xmlBufGetInputBase(in->buffer, ctxt->input);
12467                 size_t current = ctxt->input->cur - ctxt->input->base;
12468
12469                 nbchars = xmlCharEncInput(in, terminate);
12470                 if (nbchars < 0) {
12471                     /* TODO 2.6.0 */
12472                     xmlGenericError(xmlGenericErrorContext,
12473                                     "xmlParseChunk: encoder error\n");
12474                     return(XML_ERR_INVALID_ENCODING);
12475                 }
12476                 xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
12477             }
12478         }
12479     }
12480     if (remain != 0) {
12481         xmlParseTryOrFinish(ctxt, 0);
12482     } else {
12483         if ((ctxt->input != NULL) && (ctxt->input->buf != NULL))
12484             avail = xmlBufUse(ctxt->input->buf->buffer);
12485         /*
12486          * Depending on the current state it may not be such
12487          * a good idea to try parsing if there is nothing in the chunk
12488          * which would be worth doing a parser state transition and we
12489          * need to wait for more data
12490          */
12491         if ((terminate) || (avail > XML_MAX_TEXT_LENGTH) ||
12492             (old_avail == 0) || (avail == 0) ||
12493             (xmlParseCheckTransition(ctxt,
12494                        (const char *)&ctxt->input->base[old_avail],
12495                                      avail - old_avail)))
12496             xmlParseTryOrFinish(ctxt, terminate);
12497     }
12498     if (ctxt->instate == XML_PARSER_EOF)
12499         return(ctxt->errNo);
12500
12501     if ((ctxt->input != NULL) &&
12502          (((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
12503          ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
12504         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
12505         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
12506         xmlHaltParser(ctxt);
12507     }
12508     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12509         return(ctxt->errNo);
12510
12511     if (remain != 0) {
12512         chunk += size;
12513         size = remain;
12514         remain = 0;
12515         goto xmldecl_done;
12516     }
12517     if ((end_in_lf == 1) && (ctxt->input != NULL) &&
12518         (ctxt->input->buf != NULL)) {
12519         size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
12520                                          ctxt->input);
12521         size_t current = ctxt->input->cur - ctxt->input->base;
12522
12523         xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
12524
12525         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
12526                               base, current);
12527     }
12528     if (terminate) {
12529         /*
12530          * Check for termination
12531          */
12532         int cur_avail = 0;
12533
12534         if (ctxt->input != NULL) {
12535             if (ctxt->input->buf == NULL)
12536                 cur_avail = ctxt->input->length -
12537                             (ctxt->input->cur - ctxt->input->base);
12538             else
12539                 cur_avail = xmlBufUse(ctxt->input->buf->buffer) -
12540                                       (ctxt->input->cur - ctxt->input->base);
12541         }
12542
12543         if ((ctxt->instate != XML_PARSER_EOF) &&
12544             (ctxt->instate != XML_PARSER_EPILOG)) {
12545             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12546         }
12547         if ((ctxt->instate == XML_PARSER_EPILOG) && (cur_avail > 0)) {
12548             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12549         }
12550         if (ctxt->instate != XML_PARSER_EOF) {
12551             if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
12552                 ctxt->sax->endDocument(ctxt->userData);
12553         }
12554         ctxt->instate = XML_PARSER_EOF;
12555     }
12556     if (ctxt->wellFormed == 0)
12557         return((xmlParserErrors) ctxt->errNo);
12558     else
12559         return(0);
12560 }
12561
12562 /************************************************************************
12563  *                                                                      *
12564  *              I/O front end functions to the parser                   *
12565  *                                                                      *
12566  ************************************************************************/
12567
12568 /**
12569  * xmlCreatePushParserCtxt:
12570  * @sax:  a SAX handler
12571  * @user_data:  The user data returned on SAX callbacks
12572  * @chunk:  a pointer to an array of chars
12573  * @size:  number of chars in the array
12574  * @filename:  an optional file name or URI
12575  *
12576  * Create a parser context for using the XML parser in push mode.
12577  * If @buffer and @size are non-NULL, the data is used to detect
12578  * the encoding.  The remaining characters will be parsed so they
12579  * don't need to be fed in again through xmlParseChunk.
12580  * To allow content encoding detection, @size should be >= 4
12581  * The value of @filename is used for fetching external entities
12582  * and error/warning reports.
12583  *
12584  * Returns the new parser context or NULL
12585  */
12586
12587 xmlParserCtxtPtr
12588 xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12589                         const char *chunk, int size, const char *filename) {
12590     xmlParserCtxtPtr ctxt;
12591     xmlParserInputPtr inputStream;
12592     xmlParserInputBufferPtr buf;
12593     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
12594
12595     /*
12596      * plug some encoding conversion routines
12597      */
12598     if ((chunk != NULL) && (size >= 4))
12599         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
12600
12601     buf = xmlAllocParserInputBuffer(enc);
12602     if (buf == NULL) return(NULL);
12603
12604     ctxt = xmlNewParserCtxt();
12605     if (ctxt == NULL) {
12606         xmlErrMemory(NULL, "creating parser: out of memory\n");
12607         xmlFreeParserInputBuffer(buf);
12608         return(NULL);
12609     }
12610     ctxt->dictNames = 1;
12611     ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
12612     if (ctxt->pushTab == NULL) {
12613         xmlErrMemory(ctxt, NULL);
12614         xmlFreeParserInputBuffer(buf);
12615         xmlFreeParserCtxt(ctxt);
12616         return(NULL);
12617     }
12618     if (sax != NULL) {
12619 #ifdef LIBXML_SAX1_ENABLED
12620         if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12621 #endif /* LIBXML_SAX1_ENABLED */
12622             xmlFree(ctxt->sax);
12623         ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12624         if (ctxt->sax == NULL) {
12625             xmlErrMemory(ctxt, NULL);
12626             xmlFreeParserInputBuffer(buf);
12627             xmlFreeParserCtxt(ctxt);
12628             return(NULL);
12629         }
12630         memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12631         if (sax->initialized == XML_SAX2_MAGIC)
12632             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12633         else
12634             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12635         if (user_data != NULL)
12636             ctxt->userData = user_data;
12637     }
12638     if (filename == NULL) {
12639         ctxt->directory = NULL;
12640     } else {
12641         ctxt->directory = xmlParserGetDirectory(filename);
12642     }
12643
12644     inputStream = xmlNewInputStream(ctxt);
12645     if (inputStream == NULL) {
12646         xmlFreeParserCtxt(ctxt);
12647         xmlFreeParserInputBuffer(buf);
12648         return(NULL);
12649     }
12650
12651     if (filename == NULL)
12652         inputStream->filename = NULL;
12653     else {
12654         inputStream->filename = (char *)
12655             xmlCanonicPath((const xmlChar *) filename);
12656         if (inputStream->filename == NULL) {
12657             xmlFreeParserCtxt(ctxt);
12658             xmlFreeParserInputBuffer(buf);
12659             return(NULL);
12660         }
12661     }
12662     inputStream->buf = buf;
12663     xmlBufResetInput(inputStream->buf->buffer, inputStream);
12664     inputPush(ctxt, inputStream);
12665
12666     /*
12667      * If the caller didn't provide an initial 'chunk' for determining
12668      * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
12669      * that it can be automatically determined later
12670      */
12671     if ((size == 0) || (chunk == NULL)) {
12672         ctxt->charset = XML_CHAR_ENCODING_NONE;
12673     } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
12674         size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12675         size_t cur = ctxt->input->cur - ctxt->input->base;
12676
12677         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12678
12679         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12680 #ifdef DEBUG_PUSH
12681         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12682 #endif
12683     }
12684
12685     if (enc != XML_CHAR_ENCODING_NONE) {
12686         xmlSwitchEncoding(ctxt, enc);
12687     }
12688
12689     return(ctxt);
12690 }
12691 #endif /* LIBXML_PUSH_ENABLED */
12692
12693 /**
12694  * xmlHaltParser:
12695  * @ctxt:  an XML parser context
12696  *
12697  * Blocks further parser processing don't override error
12698  * for internal use
12699  */
12700 static void
12701 xmlHaltParser(xmlParserCtxtPtr ctxt) {
12702     if (ctxt == NULL)
12703         return;
12704     ctxt->instate = XML_PARSER_EOF;
12705     ctxt->disableSAX = 1;
12706     if (ctxt->input != NULL) {
12707         /*
12708          * in case there was a specific allocation deallocate before
12709          * overriding base
12710          */
12711         if (ctxt->input->free != NULL) {
12712             ctxt->input->free((xmlChar *) ctxt->input->base);
12713             ctxt->input->free = NULL;
12714         }
12715         ctxt->input->cur = BAD_CAST"";
12716         ctxt->input->base = ctxt->input->cur;
12717     }
12718 }
12719
12720 /**
12721  * xmlStopParser:
12722  * @ctxt:  an XML parser context
12723  *
12724  * Blocks further parser processing
12725  */
12726 void
12727 xmlStopParser(xmlParserCtxtPtr ctxt) {
12728     if (ctxt == NULL)
12729         return;
12730     xmlHaltParser(ctxt);
12731     ctxt->errNo = XML_ERR_USER_STOP;
12732 }
12733
12734 /**
12735  * xmlCreateIOParserCtxt:
12736  * @sax:  a SAX handler
12737  * @user_data:  The user data returned on SAX callbacks
12738  * @ioread:  an I/O read function
12739  * @ioclose:  an I/O close function
12740  * @ioctx:  an I/O handler
12741  * @enc:  the charset encoding if known
12742  *
12743  * Create a parser context for using the XML parser with an existing
12744  * I/O stream
12745  *
12746  * Returns the new parser context or NULL
12747  */
12748 xmlParserCtxtPtr
12749 xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12750         xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
12751         void *ioctx, xmlCharEncoding enc) {
12752     xmlParserCtxtPtr ctxt;
12753     xmlParserInputPtr inputStream;
12754     xmlParserInputBufferPtr buf;
12755
12756     if (ioread == NULL) return(NULL);
12757
12758     buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
12759     if (buf == NULL) {
12760         if (ioclose != NULL)
12761             ioclose(ioctx);
12762         return (NULL);
12763     }
12764
12765     ctxt = xmlNewParserCtxt();
12766     if (ctxt == NULL) {
12767         xmlFreeParserInputBuffer(buf);
12768         return(NULL);
12769     }
12770     if (sax != NULL) {
12771 #ifdef LIBXML_SAX1_ENABLED
12772         if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12773 #endif /* LIBXML_SAX1_ENABLED */
12774             xmlFree(ctxt->sax);
12775         ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12776         if (ctxt->sax == NULL) {
12777             xmlErrMemory(ctxt, NULL);
12778             xmlFreeParserCtxt(ctxt);
12779             return(NULL);
12780         }
12781         memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12782         if (sax->initialized == XML_SAX2_MAGIC)
12783             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12784         else
12785             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12786         if (user_data != NULL)
12787             ctxt->userData = user_data;
12788     }
12789
12790     inputStream = xmlNewIOInputStream(ctxt, buf, enc);
12791     if (inputStream == NULL) {
12792         xmlFreeParserCtxt(ctxt);
12793         return(NULL);
12794     }
12795     inputPush(ctxt, inputStream);
12796
12797     return(ctxt);
12798 }
12799
12800 #ifdef LIBXML_VALID_ENABLED
12801 /************************************************************************
12802  *                                                                      *
12803  *              Front ends when parsing a DTD                           *
12804  *                                                                      *
12805  ************************************************************************/
12806
12807 /**
12808  * xmlIOParseDTD:
12809  * @sax:  the SAX handler block or NULL
12810  * @input:  an Input Buffer
12811  * @enc:  the charset encoding if known
12812  *
12813  * Load and parse a DTD
12814  *
12815  * Returns the resulting xmlDtdPtr or NULL in case of error.
12816  * @input will be freed by the function in any case.
12817  */
12818
12819 xmlDtdPtr
12820 xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
12821               xmlCharEncoding enc) {
12822     xmlDtdPtr ret = NULL;
12823     xmlParserCtxtPtr ctxt;
12824     xmlParserInputPtr pinput = NULL;
12825     xmlChar start[4];
12826
12827     if (input == NULL)
12828         return(NULL);
12829
12830     ctxt = xmlNewParserCtxt();
12831     if (ctxt == NULL) {
12832         xmlFreeParserInputBuffer(input);
12833         return(NULL);
12834     }
12835
12836     /* We are loading a DTD */
12837     ctxt->options |= XML_PARSE_DTDLOAD;
12838
12839     /*
12840      * Set-up the SAX context
12841      */
12842     if (sax != NULL) {
12843         if (ctxt->sax != NULL)
12844             xmlFree(ctxt->sax);
12845         ctxt->sax = sax;
12846         ctxt->userData = ctxt;
12847     }
12848     xmlDetectSAX2(ctxt);
12849
12850     /*
12851      * generate a parser input from the I/O handler
12852      */
12853
12854     pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
12855     if (pinput == NULL) {
12856         if (sax != NULL) ctxt->sax = NULL;
12857         xmlFreeParserInputBuffer(input);
12858         xmlFreeParserCtxt(ctxt);
12859         return(NULL);
12860     }
12861
12862     /*
12863      * plug some encoding conversion routines here.
12864      */
12865     if (xmlPushInput(ctxt, pinput) < 0) {
12866         if (sax != NULL) ctxt->sax = NULL;
12867         xmlFreeParserCtxt(ctxt);
12868         return(NULL);
12869     }
12870     if (enc != XML_CHAR_ENCODING_NONE) {
12871         xmlSwitchEncoding(ctxt, enc);
12872     }
12873
12874     pinput->filename = NULL;
12875     pinput->line = 1;
12876     pinput->col = 1;
12877     pinput->base = ctxt->input->cur;
12878     pinput->cur = ctxt->input->cur;
12879     pinput->free = NULL;
12880
12881     /*
12882      * let's parse that entity knowing it's an external subset.
12883      */
12884     ctxt->inSubset = 2;
12885     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12886     if (ctxt->myDoc == NULL) {
12887         xmlErrMemory(ctxt, "New Doc failed");
12888         return(NULL);
12889     }
12890     ctxt->myDoc->properties = XML_DOC_INTERNAL;
12891     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12892                                        BAD_CAST "none", BAD_CAST "none");
12893
12894     if ((enc == XML_CHAR_ENCODING_NONE) &&
12895         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
12896         /*
12897          * Get the 4 first bytes and decode the charset
12898          * if enc != XML_CHAR_ENCODING_NONE
12899          * plug some encoding conversion routines.
12900          */
12901         start[0] = RAW;
12902         start[1] = NXT(1);
12903         start[2] = NXT(2);
12904         start[3] = NXT(3);
12905         enc = xmlDetectCharEncoding(start, 4);
12906         if (enc != XML_CHAR_ENCODING_NONE) {
12907             xmlSwitchEncoding(ctxt, enc);
12908         }
12909     }
12910
12911     xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
12912
12913     if (ctxt->myDoc != NULL) {
12914         if (ctxt->wellFormed) {
12915             ret = ctxt->myDoc->extSubset;
12916             ctxt->myDoc->extSubset = NULL;
12917             if (ret != NULL) {
12918                 xmlNodePtr tmp;
12919
12920                 ret->doc = NULL;
12921                 tmp = ret->children;
12922                 while (tmp != NULL) {
12923                     tmp->doc = NULL;
12924                     tmp = tmp->next;
12925                 }
12926             }
12927         } else {
12928             ret = NULL;
12929         }
12930         xmlFreeDoc(ctxt->myDoc);
12931         ctxt->myDoc = NULL;
12932     }
12933     if (sax != NULL) ctxt->sax = NULL;
12934     xmlFreeParserCtxt(ctxt);
12935
12936     return(ret);
12937 }
12938
12939 /**
12940  * xmlSAXParseDTD:
12941  * @sax:  the SAX handler block
12942  * @ExternalID:  a NAME* containing the External ID of the DTD
12943  * @SystemID:  a NAME* containing the URL to the DTD
12944  *
12945  * Load and parse an external subset.
12946  *
12947  * Returns the resulting xmlDtdPtr or NULL in case of error.
12948  */
12949
12950 xmlDtdPtr
12951 xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
12952                           const xmlChar *SystemID) {
12953     xmlDtdPtr ret = NULL;
12954     xmlParserCtxtPtr ctxt;
12955     xmlParserInputPtr input = NULL;
12956     xmlCharEncoding enc;
12957     xmlChar* systemIdCanonic;
12958
12959     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
12960
12961     ctxt = xmlNewParserCtxt();
12962     if (ctxt == NULL) {
12963         return(NULL);
12964     }
12965
12966     /* We are loading a DTD */
12967     ctxt->options |= XML_PARSE_DTDLOAD;
12968
12969     /*
12970      * Set-up the SAX context
12971      */
12972     if (sax != NULL) {
12973         if (ctxt->sax != NULL)
12974             xmlFree(ctxt->sax);
12975         ctxt->sax = sax;
12976         ctxt->userData = ctxt;
12977     }
12978
12979     /*
12980      * Canonicalise the system ID
12981      */
12982     systemIdCanonic = xmlCanonicPath(SystemID);
12983     if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
12984         xmlFreeParserCtxt(ctxt);
12985         return(NULL);
12986     }
12987
12988     /*
12989      * Ask the Entity resolver to load the damn thing
12990      */
12991
12992     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
12993         input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
12994                                          systemIdCanonic);
12995     if (input == NULL) {
12996         if (sax != NULL) ctxt->sax = NULL;
12997         xmlFreeParserCtxt(ctxt);
12998         if (systemIdCanonic != NULL)
12999             xmlFree(systemIdCanonic);
13000         return(NULL);
13001     }
13002
13003     /*
13004      * plug some encoding conversion routines here.
13005      */
13006     if (xmlPushInput(ctxt, input) < 0) {
13007         if (sax != NULL) ctxt->sax = NULL;
13008         xmlFreeParserCtxt(ctxt);
13009         if (systemIdCanonic != NULL)
13010             xmlFree(systemIdCanonic);
13011         return(NULL);
13012     }
13013     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
13014         enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
13015         xmlSwitchEncoding(ctxt, enc);
13016     }
13017
13018     if (input->filename == NULL)
13019         input->filename = (char *) systemIdCanonic;
13020     else
13021         xmlFree(systemIdCanonic);
13022     input->line = 1;
13023     input->col = 1;
13024     input->base = ctxt->input->cur;
13025     input->cur = ctxt->input->cur;
13026     input->free = NULL;
13027
13028     /*
13029      * let's parse that entity knowing it's an external subset.
13030      */
13031     ctxt->inSubset = 2;
13032     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
13033     if (ctxt->myDoc == NULL) {
13034         xmlErrMemory(ctxt, "New Doc failed");
13035         if (sax != NULL) ctxt->sax = NULL;
13036         xmlFreeParserCtxt(ctxt);
13037         return(NULL);
13038     }
13039     ctxt->myDoc->properties = XML_DOC_INTERNAL;
13040     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
13041                                        ExternalID, SystemID);
13042     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
13043
13044     if (ctxt->myDoc != NULL) {
13045         if (ctxt->wellFormed) {
13046             ret = ctxt->myDoc->extSubset;
13047             ctxt->myDoc->extSubset = NULL;
13048             if (ret != NULL) {
13049                 xmlNodePtr tmp;
13050
13051                 ret->doc = NULL;
13052                 tmp = ret->children;
13053                 while (tmp != NULL) {
13054                     tmp->doc = NULL;
13055                     tmp = tmp->next;
13056                 }
13057             }
13058         } else {
13059             ret = NULL;
13060         }
13061         xmlFreeDoc(ctxt->myDoc);
13062         ctxt->myDoc = NULL;
13063     }
13064     if (sax != NULL) ctxt->sax = NULL;
13065     xmlFreeParserCtxt(ctxt);
13066
13067     return(ret);
13068 }
13069
13070
13071 /**
13072  * xmlParseDTD:
13073  * @ExternalID:  a NAME* containing the External ID of the DTD
13074  * @SystemID:  a NAME* containing the URL to the DTD
13075  *
13076  * Load and parse an external subset.
13077  *
13078  * Returns the resulting xmlDtdPtr or NULL in case of error.
13079  */
13080
13081 xmlDtdPtr
13082 xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
13083     return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
13084 }
13085 #endif /* LIBXML_VALID_ENABLED */
13086
13087 /************************************************************************
13088  *                                                                      *
13089  *              Front ends when parsing an Entity                       *
13090  *                                                                      *
13091  ************************************************************************/
13092
13093 /**
13094  * xmlParseCtxtExternalEntity:
13095  * @ctx:  the existing parsing context
13096  * @URL:  the URL for the entity to load
13097  * @ID:  the System ID for the entity to load
13098  * @lst:  the return value for the set of parsed nodes
13099  *
13100  * Parse an external general entity within an existing parsing context
13101  * An external general parsed entity is well-formed if it matches the
13102  * production labeled extParsedEnt.
13103  *
13104  * [78] extParsedEnt ::= TextDecl? content
13105  *
13106  * Returns 0 if the entity is well formed, -1 in case of args problem and
13107  *    the parser error code otherwise
13108  */
13109
13110 int
13111 xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
13112                        const xmlChar *ID, xmlNodePtr *lst) {
13113     xmlParserCtxtPtr ctxt;
13114     xmlDocPtr newDoc;
13115     xmlNodePtr newRoot;
13116     xmlSAXHandlerPtr oldsax = NULL;
13117     int ret = 0;
13118     xmlChar start[4];
13119     xmlCharEncoding enc;
13120
13121     if (ctx == NULL) return(-1);
13122
13123     if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
13124         (ctx->depth > 1024)) {
13125         return(XML_ERR_ENTITY_LOOP);
13126     }
13127
13128     if (lst != NULL)
13129         *lst = NULL;
13130     if ((URL == NULL) && (ID == NULL))
13131         return(-1);
13132     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
13133         return(-1);
13134
13135     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
13136     if (ctxt == NULL) {
13137         return(-1);
13138     }
13139
13140     oldsax = ctxt->sax;
13141     ctxt->sax = ctx->sax;
13142     xmlDetectSAX2(ctxt);
13143     newDoc = xmlNewDoc(BAD_CAST "1.0");
13144     if (newDoc == NULL) {
13145         xmlFreeParserCtxt(ctxt);
13146         return(-1);
13147     }
13148     newDoc->properties = XML_DOC_INTERNAL;
13149     if (ctx->myDoc->dict) {
13150         newDoc->dict = ctx->myDoc->dict;
13151         xmlDictReference(newDoc->dict);
13152     }
13153     if (ctx->myDoc != NULL) {
13154         newDoc->intSubset = ctx->myDoc->intSubset;
13155         newDoc->extSubset = ctx->myDoc->extSubset;
13156     }
13157     if (ctx->myDoc->URL != NULL) {
13158         newDoc->URL = xmlStrdup(ctx->myDoc->URL);
13159     }
13160     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13161     if (newRoot == NULL) {
13162         ctxt->sax = oldsax;
13163         xmlFreeParserCtxt(ctxt);
13164         newDoc->intSubset = NULL;
13165         newDoc->extSubset = NULL;
13166         xmlFreeDoc(newDoc);
13167         return(-1);
13168     }
13169     xmlAddChild((xmlNodePtr) newDoc, newRoot);
13170     nodePush(ctxt, newDoc->children);
13171     if (ctx->myDoc == NULL) {
13172         ctxt->myDoc = newDoc;
13173     } else {
13174         ctxt->myDoc = ctx->myDoc;
13175         newDoc->children->doc = ctx->myDoc;
13176     }
13177
13178     /*
13179      * Get the 4 first bytes and decode the charset
13180      * if enc != XML_CHAR_ENCODING_NONE
13181      * plug some encoding conversion routines.
13182      */
13183     GROW
13184     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
13185         start[0] = RAW;
13186         start[1] = NXT(1);
13187         start[2] = NXT(2);
13188         start[3] = NXT(3);
13189         enc = xmlDetectCharEncoding(start, 4);
13190         if (enc != XML_CHAR_ENCODING_NONE) {
13191             xmlSwitchEncoding(ctxt, enc);
13192         }
13193     }
13194
13195     /*
13196      * Parse a possible text declaration first
13197      */
13198     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
13199         xmlParseTextDecl(ctxt);
13200         /*
13201          * An XML-1.0 document can't reference an entity not XML-1.0
13202          */
13203         if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
13204             (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
13205             xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
13206                            "Version mismatch between document and entity\n");
13207         }
13208     }
13209
13210     /*
13211      * If the user provided its own SAX callbacks then reuse the
13212      * useData callback field, otherwise the expected setup in a
13213      * DOM builder is to have userData == ctxt
13214      */
13215     if (ctx->userData == ctx)
13216         ctxt->userData = ctxt;
13217     else
13218         ctxt->userData = ctx->userData;
13219
13220     /*
13221      * Doing validity checking on chunk doesn't make sense
13222      */
13223     ctxt->instate = XML_PARSER_CONTENT;
13224     ctxt->validate = ctx->validate;
13225     ctxt->valid = ctx->valid;
13226     ctxt->loadsubset = ctx->loadsubset;
13227     ctxt->depth = ctx->depth + 1;
13228     ctxt->replaceEntities = ctx->replaceEntities;
13229     if (ctxt->validate) {
13230         ctxt->vctxt.error = ctx->vctxt.error;
13231         ctxt->vctxt.warning = ctx->vctxt.warning;
13232     } else {
13233         ctxt->vctxt.error = NULL;
13234         ctxt->vctxt.warning = NULL;
13235     }
13236     ctxt->vctxt.nodeTab = NULL;
13237     ctxt->vctxt.nodeNr = 0;
13238     ctxt->vctxt.nodeMax = 0;
13239     ctxt->vctxt.node = NULL;
13240     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
13241     ctxt->dict = ctx->dict;
13242     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13243     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13244     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13245     ctxt->dictNames = ctx->dictNames;
13246     ctxt->attsDefault = ctx->attsDefault;
13247     ctxt->attsSpecial = ctx->attsSpecial;
13248     ctxt->linenumbers = ctx->linenumbers;
13249
13250     xmlParseContent(ctxt);
13251
13252     ctx->validate = ctxt->validate;
13253     ctx->valid = ctxt->valid;
13254     if ((RAW == '<') && (NXT(1) == '/')) {
13255         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13256     } else if (RAW != 0) {
13257         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13258     }
13259     if (ctxt->node != newDoc->children) {
13260         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13261     }
13262
13263     if (!ctxt->wellFormed) {
13264         if (ctxt->errNo == 0)
13265             ret = 1;
13266         else
13267             ret = ctxt->errNo;
13268     } else {
13269         if (lst != NULL) {
13270             xmlNodePtr cur;
13271
13272             /*
13273              * Return the newly created nodeset after unlinking it from
13274              * they pseudo parent.
13275              */
13276             cur = newDoc->children->children;
13277             *lst = cur;
13278             while (cur != NULL) {
13279                 cur->parent = NULL;
13280                 cur = cur->next;
13281             }
13282             newDoc->children->children = NULL;
13283         }
13284         ret = 0;
13285     }
13286     ctxt->sax = oldsax;
13287     ctxt->dict = NULL;
13288     ctxt->attsDefault = NULL;
13289     ctxt->attsSpecial = NULL;
13290     xmlFreeParserCtxt(ctxt);
13291     newDoc->intSubset = NULL;
13292     newDoc->extSubset = NULL;
13293     xmlFreeDoc(newDoc);
13294
13295     return(ret);
13296 }
13297
13298 /**
13299  * xmlParseExternalEntityPrivate:
13300  * @doc:  the document the chunk pertains to
13301  * @oldctxt:  the previous parser context if available
13302  * @sax:  the SAX handler bloc (possibly NULL)
13303  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13304  * @depth:  Used for loop detection, use 0
13305  * @URL:  the URL for the entity to load
13306  * @ID:  the System ID for the entity to load
13307  * @list:  the return value for the set of parsed nodes
13308  *
13309  * Private version of xmlParseExternalEntity()
13310  *
13311  * Returns 0 if the entity is well formed, -1 in case of args problem and
13312  *    the parser error code otherwise
13313  */
13314
13315 static xmlParserErrors
13316 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
13317                       xmlSAXHandlerPtr sax,
13318                       void *user_data, int depth, const xmlChar *URL,
13319                       const xmlChar *ID, xmlNodePtr *list) {
13320     xmlParserCtxtPtr ctxt;
13321     xmlDocPtr newDoc;
13322     xmlNodePtr newRoot;
13323     xmlSAXHandlerPtr oldsax = NULL;
13324     xmlParserErrors ret = XML_ERR_OK;
13325     xmlChar start[4];
13326     xmlCharEncoding enc;
13327
13328     if (((depth > 40) &&
13329         ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
13330         (depth > 1024)) {
13331         return(XML_ERR_ENTITY_LOOP);
13332     }
13333
13334     if (list != NULL)
13335         *list = NULL;
13336     if ((URL == NULL) && (ID == NULL))
13337         return(XML_ERR_INTERNAL_ERROR);
13338     if (doc == NULL)
13339         return(XML_ERR_INTERNAL_ERROR);
13340
13341
13342     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
13343     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
13344     ctxt->userData = ctxt;
13345     if (oldctxt != NULL) {
13346         ctxt->_private = oldctxt->_private;
13347         ctxt->loadsubset = oldctxt->loadsubset;
13348         ctxt->validate = oldctxt->validate;
13349         ctxt->external = oldctxt->external;
13350         ctxt->record_info = oldctxt->record_info;
13351         ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
13352         ctxt->node_seq.length = oldctxt->node_seq.length;
13353         ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
13354     } else {
13355         /*
13356          * Doing validity checking on chunk without context
13357          * doesn't make sense
13358          */
13359         ctxt->_private = NULL;
13360         ctxt->validate = 0;
13361         ctxt->external = 2;
13362         ctxt->loadsubset = 0;
13363     }
13364     if (sax != NULL) {
13365         oldsax = ctxt->sax;
13366         ctxt->sax = sax;
13367         if (user_data != NULL)
13368             ctxt->userData = user_data;
13369     }
13370     xmlDetectSAX2(ctxt);
13371     newDoc = xmlNewDoc(BAD_CAST "1.0");
13372     if (newDoc == NULL) {
13373         ctxt->node_seq.maximum = 0;
13374         ctxt->node_seq.length = 0;
13375         ctxt->node_seq.buffer = NULL;
13376         xmlFreeParserCtxt(ctxt);
13377         return(XML_ERR_INTERNAL_ERROR);
13378     }
13379     newDoc->properties = XML_DOC_INTERNAL;
13380     newDoc->intSubset = doc->intSubset;
13381     newDoc->extSubset = doc->extSubset;
13382     newDoc->dict = doc->dict;
13383     xmlDictReference(newDoc->dict);
13384
13385     if (doc->URL != NULL) {
13386         newDoc->URL = xmlStrdup(doc->URL);
13387     }
13388     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13389     if (newRoot == NULL) {
13390         if (sax != NULL)
13391             ctxt->sax = oldsax;
13392         ctxt->node_seq.maximum = 0;
13393         ctxt->node_seq.length = 0;
13394         ctxt->node_seq.buffer = NULL;
13395         xmlFreeParserCtxt(ctxt);
13396         newDoc->intSubset = NULL;
13397         newDoc->extSubset = NULL;
13398         xmlFreeDoc(newDoc);
13399         return(XML_ERR_INTERNAL_ERROR);
13400     }
13401     xmlAddChild((xmlNodePtr) newDoc, newRoot);
13402     nodePush(ctxt, newDoc->children);
13403     ctxt->myDoc = doc;
13404     newRoot->doc = doc;
13405
13406     /*
13407      * Get the 4 first bytes and decode the charset
13408      * if enc != XML_CHAR_ENCODING_NONE
13409      * plug some encoding conversion routines.
13410      */
13411     GROW;
13412     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
13413         start[0] = RAW;
13414         start[1] = NXT(1);
13415         start[2] = NXT(2);
13416         start[3] = NXT(3);
13417         enc = xmlDetectCharEncoding(start, 4);
13418         if (enc != XML_CHAR_ENCODING_NONE) {
13419             xmlSwitchEncoding(ctxt, enc);
13420         }
13421     }
13422
13423     /*
13424      * Parse a possible text declaration first
13425      */
13426     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
13427         xmlParseTextDecl(ctxt);
13428     }
13429
13430     ctxt->instate = XML_PARSER_CONTENT;
13431     ctxt->depth = depth;
13432
13433     xmlParseContent(ctxt);
13434
13435     if ((RAW == '<') && (NXT(1) == '/')) {
13436         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13437     } else if (RAW != 0) {
13438         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13439     }
13440     if (ctxt->node != newDoc->children) {
13441         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13442     }
13443
13444     if (!ctxt->wellFormed) {
13445         if (ctxt->errNo == 0)
13446             ret = XML_ERR_INTERNAL_ERROR;
13447         else
13448             ret = (xmlParserErrors)ctxt->errNo;
13449     } else {
13450         if (list != NULL) {
13451             xmlNodePtr cur;
13452
13453             /*
13454              * Return the newly created nodeset after unlinking it from
13455              * they pseudo parent.
13456              */
13457             cur = newDoc->children->children;
13458             *list = cur;
13459             while (cur != NULL) {
13460                 cur->parent = NULL;
13461                 cur = cur->next;
13462             }
13463             newDoc->children->children = NULL;
13464         }
13465         ret = XML_ERR_OK;
13466     }
13467
13468     /*
13469      * Record in the parent context the number of entities replacement
13470      * done when parsing that reference.
13471      */
13472     if (oldctxt != NULL)
13473         oldctxt->nbentities += ctxt->nbentities;
13474
13475     /*
13476      * Also record the size of the entity parsed
13477      */
13478     if (ctxt->input != NULL && oldctxt != NULL) {
13479         oldctxt->sizeentities += ctxt->input->consumed;
13480         oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
13481     }
13482     /*
13483      * And record the last error if any
13484      */
13485     if (ctxt->lastError.code != XML_ERR_OK)
13486         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13487
13488     if (sax != NULL)
13489         ctxt->sax = oldsax;
13490     if (oldctxt != NULL) {
13491         oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
13492         oldctxt->node_seq.length = ctxt->node_seq.length;
13493         oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
13494     }
13495     ctxt->node_seq.maximum = 0;
13496     ctxt->node_seq.length = 0;
13497     ctxt->node_seq.buffer = NULL;
13498     xmlFreeParserCtxt(ctxt);
13499     newDoc->intSubset = NULL;
13500     newDoc->extSubset = NULL;
13501     xmlFreeDoc(newDoc);
13502
13503     return(ret);
13504 }
13505
13506 #ifdef LIBXML_SAX1_ENABLED
13507 /**
13508  * xmlParseExternalEntity:
13509  * @doc:  the document the chunk pertains to
13510  * @sax:  the SAX handler bloc (possibly NULL)
13511  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13512  * @depth:  Used for loop detection, use 0
13513  * @URL:  the URL for the entity to load
13514  * @ID:  the System ID for the entity to load
13515  * @lst:  the return value for the set of parsed nodes
13516  *
13517  * Parse an external general entity
13518  * An external general parsed entity is well-formed if it matches the
13519  * production labeled extParsedEnt.
13520  *
13521  * [78] extParsedEnt ::= TextDecl? content
13522  *
13523  * Returns 0 if the entity is well formed, -1 in case of args problem and
13524  *    the parser error code otherwise
13525  */
13526
13527 int
13528 xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
13529           int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
13530     return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
13531                                        ID, lst));
13532 }
13533
13534 /**
13535  * xmlParseBalancedChunkMemory:
13536  * @doc:  the document the chunk pertains to
13537  * @sax:  the SAX handler bloc (possibly NULL)
13538  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13539  * @depth:  Used for loop detection, use 0
13540  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13541  * @lst:  the return value for the set of parsed nodes
13542  *
13543  * Parse a well-balanced chunk of an XML document
13544  * called by the parser
13545  * The allowed sequence for the Well Balanced Chunk is the one defined by
13546  * the content production in the XML grammar:
13547  *
13548  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13549  *
13550  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13551  *    the parser error code otherwise
13552  */
13553
13554 int
13555 xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13556      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
13557     return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
13558                                                 depth, string, lst, 0 );
13559 }
13560 #endif /* LIBXML_SAX1_ENABLED */
13561
13562 /**
13563  * xmlParseBalancedChunkMemoryInternal:
13564  * @oldctxt:  the existing parsing context
13565  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13566  * @user_data:  the user data field for the parser context
13567  * @lst:  the return value for the set of parsed nodes
13568  *
13569  *
13570  * Parse a well-balanced chunk of an XML document
13571  * called by the parser
13572  * The allowed sequence for the Well Balanced Chunk is the one defined by
13573  * the content production in the XML grammar:
13574  *
13575  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13576  *
13577  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13578  * error code otherwise
13579  *
13580  * In case recover is set to 1, the nodelist will not be empty even if
13581  * the parsed chunk is not well balanced.
13582  */
13583 static xmlParserErrors
13584 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
13585         const xmlChar *string, void *user_data, xmlNodePtr *lst) {
13586     xmlParserCtxtPtr ctxt;
13587     xmlDocPtr newDoc = NULL;
13588     xmlNodePtr newRoot;
13589     xmlSAXHandlerPtr oldsax = NULL;
13590     xmlNodePtr content = NULL;
13591     xmlNodePtr last = NULL;
13592     int size;
13593     xmlParserErrors ret = XML_ERR_OK;
13594 #ifdef SAX2
13595     int i;
13596 #endif
13597
13598     if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
13599         (oldctxt->depth >  1024)) {
13600         return(XML_ERR_ENTITY_LOOP);
13601     }
13602
13603
13604     if (lst != NULL)
13605         *lst = NULL;
13606     if (string == NULL)
13607         return(XML_ERR_INTERNAL_ERROR);
13608
13609     size = xmlStrlen(string);
13610
13611     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13612     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
13613     if (user_data != NULL)
13614         ctxt->userData = user_data;
13615     else
13616         ctxt->userData = ctxt;
13617     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
13618     ctxt->dict = oldctxt->dict;
13619     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13620     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13621     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13622
13623 #ifdef SAX2
13624     /* propagate namespaces down the entity */
13625     for (i = 0;i < oldctxt->nsNr;i += 2) {
13626         nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
13627     }
13628 #endif
13629
13630     oldsax = ctxt->sax;
13631     ctxt->sax = oldctxt->sax;
13632     xmlDetectSAX2(ctxt);
13633     ctxt->replaceEntities = oldctxt->replaceEntities;
13634     ctxt->options = oldctxt->options;
13635
13636     ctxt->_private = oldctxt->_private;
13637     if (oldctxt->myDoc == NULL) {
13638         newDoc = xmlNewDoc(BAD_CAST "1.0");
13639         if (newDoc == NULL) {
13640             ctxt->sax = oldsax;
13641             ctxt->dict = NULL;
13642             xmlFreeParserCtxt(ctxt);
13643             return(XML_ERR_INTERNAL_ERROR);
13644         }
13645         newDoc->properties = XML_DOC_INTERNAL;
13646         newDoc->dict = ctxt->dict;
13647         xmlDictReference(newDoc->dict);
13648         ctxt->myDoc = newDoc;
13649     } else {
13650         ctxt->myDoc = oldctxt->myDoc;
13651         content = ctxt->myDoc->children;
13652         last = ctxt->myDoc->last;
13653     }
13654     newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
13655     if (newRoot == NULL) {
13656         ctxt->sax = oldsax;
13657         ctxt->dict = NULL;
13658         xmlFreeParserCtxt(ctxt);
13659         if (newDoc != NULL) {
13660             xmlFreeDoc(newDoc);
13661         }
13662         return(XML_ERR_INTERNAL_ERROR);
13663     }
13664     ctxt->myDoc->children = NULL;
13665     ctxt->myDoc->last = NULL;
13666     xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
13667     nodePush(ctxt, ctxt->myDoc->children);
13668     ctxt->instate = XML_PARSER_CONTENT;
13669     ctxt->depth = oldctxt->depth + 1;
13670
13671     ctxt->validate = 0;
13672     ctxt->loadsubset = oldctxt->loadsubset;
13673     if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
13674         /*
13675          * ID/IDREF registration will be done in xmlValidateElement below
13676          */
13677         ctxt->loadsubset |= XML_SKIP_IDS;
13678     }
13679     ctxt->dictNames = oldctxt->dictNames;
13680     ctxt->attsDefault = oldctxt->attsDefault;
13681     ctxt->attsSpecial = oldctxt->attsSpecial;
13682
13683     xmlParseContent(ctxt);
13684     if ((RAW == '<') && (NXT(1) == '/')) {
13685         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13686     } else if (RAW != 0) {
13687         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13688     }
13689     if (ctxt->node != ctxt->myDoc->children) {
13690         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13691     }
13692
13693     if (!ctxt->wellFormed) {
13694         if (ctxt->errNo == 0)
13695             ret = XML_ERR_INTERNAL_ERROR;
13696         else
13697             ret = (xmlParserErrors)ctxt->errNo;
13698     } else {
13699       ret = XML_ERR_OK;
13700     }
13701
13702     if ((lst != NULL) && (ret == XML_ERR_OK)) {
13703         xmlNodePtr cur;
13704
13705         /*
13706          * Return the newly created nodeset after unlinking it from
13707          * they pseudo parent.
13708          */
13709         cur = ctxt->myDoc->children->children;
13710         *lst = cur;
13711         while (cur != NULL) {
13712 #ifdef LIBXML_VALID_ENABLED
13713             if ((oldctxt->validate) && (oldctxt->wellFormed) &&
13714                 (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
13715                 (cur->type == XML_ELEMENT_NODE)) {
13716                 oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
13717                         oldctxt->myDoc, cur);
13718             }
13719 #endif /* LIBXML_VALID_ENABLED */
13720             cur->parent = NULL;
13721             cur = cur->next;
13722         }
13723         ctxt->myDoc->children->children = NULL;
13724     }
13725     if (ctxt->myDoc != NULL) {
13726         xmlFreeNode(ctxt->myDoc->children);
13727         ctxt->myDoc->children = content;
13728         ctxt->myDoc->last = last;
13729     }
13730
13731     /*
13732      * Record in the parent context the number of entities replacement
13733      * done when parsing that reference.
13734      */
13735     if (oldctxt != NULL)
13736         oldctxt->nbentities += ctxt->nbentities;
13737
13738     /*
13739      * Also record the last error if any
13740      */
13741     if (ctxt->lastError.code != XML_ERR_OK)
13742         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13743
13744     ctxt->sax = oldsax;
13745     ctxt->dict = NULL;
13746     ctxt->attsDefault = NULL;
13747     ctxt->attsSpecial = NULL;
13748     xmlFreeParserCtxt(ctxt);
13749     if (newDoc != NULL) {
13750         xmlFreeDoc(newDoc);
13751     }
13752
13753     return(ret);
13754 }
13755
13756 /**
13757  * xmlParseInNodeContext:
13758  * @node:  the context node
13759  * @data:  the input string
13760  * @datalen:  the input string length in bytes
13761  * @options:  a combination of xmlParserOption
13762  * @lst:  the return value for the set of parsed nodes
13763  *
13764  * Parse a well-balanced chunk of an XML document
13765  * within the context (DTD, namespaces, etc ...) of the given node.
13766  *
13767  * The allowed sequence for the data is a Well Balanced Chunk defined by
13768  * the content production in the XML grammar:
13769  *
13770  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13771  *
13772  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13773  * error code otherwise
13774  */
13775 xmlParserErrors
13776 xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
13777                       int options, xmlNodePtr *lst) {
13778 #ifdef SAX2
13779     xmlParserCtxtPtr ctxt;
13780     xmlDocPtr doc = NULL;
13781     xmlNodePtr fake, cur;
13782     int nsnr = 0;
13783
13784     xmlParserErrors ret = XML_ERR_OK;
13785
13786     /*
13787      * check all input parameters, grab the document
13788      */
13789     if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
13790         return(XML_ERR_INTERNAL_ERROR);
13791     switch (node->type) {
13792         case XML_ELEMENT_NODE:
13793         case XML_ATTRIBUTE_NODE:
13794         case XML_TEXT_NODE:
13795         case XML_CDATA_SECTION_NODE:
13796         case XML_ENTITY_REF_NODE:
13797         case XML_PI_NODE:
13798         case XML_COMMENT_NODE:
13799         case XML_DOCUMENT_NODE:
13800         case XML_HTML_DOCUMENT_NODE:
13801             break;
13802         default:
13803             return(XML_ERR_INTERNAL_ERROR);
13804
13805     }
13806     while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
13807            (node->type != XML_DOCUMENT_NODE) &&
13808            (node->type != XML_HTML_DOCUMENT_NODE))
13809         node = node->parent;
13810     if (node == NULL)
13811         return(XML_ERR_INTERNAL_ERROR);
13812     if (node->type == XML_ELEMENT_NODE)
13813         doc = node->doc;
13814     else
13815         doc = (xmlDocPtr) node;
13816     if (doc == NULL)
13817         return(XML_ERR_INTERNAL_ERROR);
13818
13819     /*
13820      * allocate a context and set-up everything not related to the
13821      * node position in the tree
13822      */
13823     if (doc->type == XML_DOCUMENT_NODE)
13824         ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
13825 #ifdef LIBXML_HTML_ENABLED
13826     else if (doc->type == XML_HTML_DOCUMENT_NODE) {
13827         ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
13828         /*
13829          * When parsing in context, it makes no sense to add implied
13830          * elements like html/body/etc...
13831          */
13832         options |= HTML_PARSE_NOIMPLIED;
13833     }
13834 #endif
13835     else
13836         return(XML_ERR_INTERNAL_ERROR);
13837
13838     if (ctxt == NULL)
13839         return(XML_ERR_NO_MEMORY);
13840
13841     /*
13842      * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
13843      * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
13844      * we must wait until the last moment to free the original one.
13845      */
13846     if (doc->dict != NULL) {
13847         if (ctxt->dict != NULL)
13848             xmlDictFree(ctxt->dict);
13849         ctxt->dict = doc->dict;
13850     } else
13851         options |= XML_PARSE_NODICT;
13852
13853     if (doc->encoding != NULL) {
13854         xmlCharEncodingHandlerPtr hdlr;
13855
13856         if (ctxt->encoding != NULL)
13857             xmlFree((xmlChar *) ctxt->encoding);
13858         ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
13859
13860         hdlr = xmlFindCharEncodingHandler((const char *) doc->encoding);
13861         if (hdlr != NULL) {
13862             xmlSwitchToEncoding(ctxt, hdlr);
13863         } else {
13864             return(XML_ERR_UNSUPPORTED_ENCODING);
13865         }
13866     }
13867
13868     xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13869     xmlDetectSAX2(ctxt);
13870     ctxt->myDoc = doc;
13871     /* parsing in context, i.e. as within existing content */
13872     ctxt->instate = XML_PARSER_CONTENT;
13873
13874     fake = xmlNewComment(NULL);
13875     if (fake == NULL) {
13876         xmlFreeParserCtxt(ctxt);
13877         return(XML_ERR_NO_MEMORY);
13878     }
13879     xmlAddChild(node, fake);
13880
13881     if (node->type == XML_ELEMENT_NODE) {
13882         nodePush(ctxt, node);
13883         /*
13884          * initialize the SAX2 namespaces stack
13885          */
13886         cur = node;
13887         while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
13888             xmlNsPtr ns = cur->nsDef;
13889             const xmlChar *iprefix, *ihref;
13890
13891             while (ns != NULL) {
13892                 if (ctxt->dict) {
13893                     iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
13894                     ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
13895                 } else {
13896                     iprefix = ns->prefix;
13897                     ihref = ns->href;
13898                 }
13899
13900                 if (xmlGetNamespace(ctxt, iprefix) == NULL) {
13901                     nsPush(ctxt, iprefix, ihref);
13902                     nsnr++;
13903                 }
13904                 ns = ns->next;
13905             }
13906             cur = cur->parent;
13907         }
13908     }
13909
13910     if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
13911         /*
13912          * ID/IDREF registration will be done in xmlValidateElement below
13913          */
13914         ctxt->loadsubset |= XML_SKIP_IDS;
13915     }
13916
13917 #ifdef LIBXML_HTML_ENABLED
13918     if (doc->type == XML_HTML_DOCUMENT_NODE)
13919         __htmlParseContent(ctxt);
13920     else
13921 #endif
13922         xmlParseContent(ctxt);
13923
13924     nsPop(ctxt, nsnr);
13925     if ((RAW == '<') && (NXT(1) == '/')) {
13926         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13927     } else if (RAW != 0) {
13928         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13929     }
13930     if ((ctxt->node != NULL) && (ctxt->node != node)) {
13931         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13932         ctxt->wellFormed = 0;
13933     }
13934
13935     if (!ctxt->wellFormed) {
13936         if (ctxt->errNo == 0)
13937             ret = XML_ERR_INTERNAL_ERROR;
13938         else
13939             ret = (xmlParserErrors)ctxt->errNo;
13940     } else {
13941         ret = XML_ERR_OK;
13942     }
13943
13944     /*
13945      * Return the newly created nodeset after unlinking it from
13946      * the pseudo sibling.
13947      */
13948
13949     cur = fake->next;
13950     fake->next = NULL;
13951     node->last = fake;
13952
13953     if (cur != NULL) {
13954         cur->prev = NULL;
13955     }
13956
13957     *lst = cur;
13958
13959     while (cur != NULL) {
13960         cur->parent = NULL;
13961         cur = cur->next;
13962     }
13963
13964     xmlUnlinkNode(fake);
13965     xmlFreeNode(fake);
13966
13967
13968     if (ret != XML_ERR_OK) {
13969         xmlFreeNodeList(*lst);
13970         *lst = NULL;
13971     }
13972
13973     if (doc->dict != NULL)
13974         ctxt->dict = NULL;
13975     xmlFreeParserCtxt(ctxt);
13976
13977     return(ret);
13978 #else /* !SAX2 */
13979     return(XML_ERR_INTERNAL_ERROR);
13980 #endif
13981 }
13982
13983 #ifdef LIBXML_SAX1_ENABLED
13984 /**
13985  * xmlParseBalancedChunkMemoryRecover:
13986  * @doc:  the document the chunk pertains to
13987  * @sax:  the SAX handler bloc (possibly NULL)
13988  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13989  * @depth:  Used for loop detection, use 0
13990  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13991  * @lst:  the return value for the set of parsed nodes
13992  * @recover: return nodes even if the data is broken (use 0)
13993  *
13994  *
13995  * Parse a well-balanced chunk of an XML document
13996  * called by the parser
13997  * The allowed sequence for the Well Balanced Chunk is the one defined by
13998  * the content production in the XML grammar:
13999  *
14000  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
14001  *
14002  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
14003  *    the parser error code otherwise
14004  *
14005  * In case recover is set to 1, the nodelist will not be empty even if
14006  * the parsed chunk is not well balanced, assuming the parsing succeeded to
14007  * some extent.
14008  */
14009 int
14010 xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
14011      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
14012      int recover) {
14013     xmlParserCtxtPtr ctxt;
14014     xmlDocPtr newDoc;
14015     xmlSAXHandlerPtr oldsax = NULL;
14016     xmlNodePtr content, newRoot;
14017     int size;
14018     int ret = 0;
14019
14020     if (depth > 40) {
14021         return(XML_ERR_ENTITY_LOOP);
14022     }
14023
14024
14025     if (lst != NULL)
14026         *lst = NULL;
14027     if (string == NULL)
14028         return(-1);
14029
14030     size = xmlStrlen(string);
14031
14032     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
14033     if (ctxt == NULL) return(-1);
14034     ctxt->userData = ctxt;
14035     if (sax != NULL) {
14036         oldsax = ctxt->sax;
14037         ctxt->sax = sax;
14038         if (user_data != NULL)
14039             ctxt->userData = user_data;
14040     }
14041     newDoc = xmlNewDoc(BAD_CAST "1.0");
14042     if (newDoc == NULL) {
14043         xmlFreeParserCtxt(ctxt);
14044         return(-1);
14045     }
14046     newDoc->properties = XML_DOC_INTERNAL;
14047     if ((doc != NULL) && (doc->dict != NULL)) {
14048         xmlDictFree(ctxt->dict);
14049         ctxt->dict = doc->dict;
14050         xmlDictReference(ctxt->dict);
14051         ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
14052         ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
14053         ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
14054         ctxt->dictNames = 1;
14055     } else {
14056         xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
14057     }
14058     if (doc != NULL) {
14059         newDoc->intSubset = doc->intSubset;
14060         newDoc->extSubset = doc->extSubset;
14061     }
14062     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
14063     if (newRoot == NULL) {
14064         if (sax != NULL)
14065             ctxt->sax = oldsax;
14066         xmlFreeParserCtxt(ctxt);
14067         newDoc->intSubset = NULL;
14068         newDoc->extSubset = NULL;
14069         xmlFreeDoc(newDoc);
14070         return(-1);
14071     }
14072     xmlAddChild((xmlNodePtr) newDoc, newRoot);
14073     nodePush(ctxt, newRoot);
14074     if (doc == NULL) {
14075         ctxt->myDoc = newDoc;
14076     } else {
14077         ctxt->myDoc = newDoc;
14078         newDoc->children->doc = doc;
14079         /* Ensure that doc has XML spec namespace */
14080         xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
14081         newDoc->oldNs = doc->oldNs;
14082     }
14083     ctxt->instate = XML_PARSER_CONTENT;
14084     ctxt->depth = depth;
14085
14086     /*
14087      * Doing validity checking on chunk doesn't make sense
14088      */
14089     ctxt->validate = 0;
14090     ctxt->loadsubset = 0;
14091     xmlDetectSAX2(ctxt);
14092
14093     if ( doc != NULL ){
14094         content = doc->children;
14095         doc->children = NULL;
14096         xmlParseContent(ctxt);
14097         doc->children = content;
14098     }
14099     else {
14100         xmlParseContent(ctxt);
14101     }
14102     if ((RAW == '<') && (NXT(1) == '/')) {
14103         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
14104     } else if (RAW != 0) {
14105         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
14106     }
14107     if (ctxt->node != newDoc->children) {
14108         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
14109     }
14110
14111     if (!ctxt->wellFormed) {
14112         if (ctxt->errNo == 0)
14113             ret = 1;
14114         else
14115             ret = ctxt->errNo;
14116     } else {
14117       ret = 0;
14118     }
14119
14120     if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
14121         xmlNodePtr cur;
14122
14123         /*
14124          * Return the newly created nodeset after unlinking it from
14125          * they pseudo parent.
14126          */
14127         cur = newDoc->children->children;
14128         *lst = cur;
14129         while (cur != NULL) {
14130             xmlSetTreeDoc(cur, doc);
14131             cur->parent = NULL;
14132             cur = cur->next;
14133         }
14134         newDoc->children->children = NULL;
14135     }
14136
14137     if (sax != NULL)
14138         ctxt->sax = oldsax;
14139     xmlFreeParserCtxt(ctxt);
14140     newDoc->intSubset = NULL;
14141     newDoc->extSubset = NULL;
14142     newDoc->oldNs = NULL;
14143     xmlFreeDoc(newDoc);
14144
14145     return(ret);
14146 }
14147
14148 /**
14149  * xmlSAXParseEntity:
14150  * @sax:  the SAX handler block
14151  * @filename:  the filename
14152  *
14153  * parse an XML external entity out of context and build a tree.
14154  * It use the given SAX function block to handle the parsing callback.
14155  * If sax is NULL, fallback to the default DOM tree building routines.
14156  *
14157  * [78] extParsedEnt ::= TextDecl? content
14158  *
14159  * This correspond to a "Well Balanced" chunk
14160  *
14161  * Returns the resulting document tree
14162  */
14163
14164 xmlDocPtr
14165 xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
14166     xmlDocPtr ret;
14167     xmlParserCtxtPtr ctxt;
14168
14169     ctxt = xmlCreateFileParserCtxt(filename);
14170     if (ctxt == NULL) {
14171         return(NULL);
14172     }
14173     if (sax != NULL) {
14174         if (ctxt->sax != NULL)
14175             xmlFree(ctxt->sax);
14176         ctxt->sax = sax;
14177         ctxt->userData = NULL;
14178     }
14179
14180     xmlParseExtParsedEnt(ctxt);
14181
14182     if (ctxt->wellFormed)
14183         ret = ctxt->myDoc;
14184     else {
14185         ret = NULL;
14186         xmlFreeDoc(ctxt->myDoc);
14187         ctxt->myDoc = NULL;
14188     }
14189     if (sax != NULL)
14190         ctxt->sax = NULL;
14191     xmlFreeParserCtxt(ctxt);
14192
14193     return(ret);
14194 }
14195
14196 /**
14197  * xmlParseEntity:
14198  * @filename:  the filename
14199  *
14200  * parse an XML external entity out of context and build a tree.
14201  *
14202  * [78] extParsedEnt ::= TextDecl? content
14203  *
14204  * This correspond to a "Well Balanced" chunk
14205  *
14206  * Returns the resulting document tree
14207  */
14208
14209 xmlDocPtr
14210 xmlParseEntity(const char *filename) {
14211     return(xmlSAXParseEntity(NULL, filename));
14212 }
14213 #endif /* LIBXML_SAX1_ENABLED */
14214
14215 /**
14216  * xmlCreateEntityParserCtxtInternal:
14217  * @URL:  the entity URL
14218  * @ID:  the entity PUBLIC ID
14219  * @base:  a possible base for the target URI
14220  * @pctx:  parser context used to set options on new context
14221  *
14222  * Create a parser context for an external entity
14223  * Automatic support for ZLIB/Compress compressed document is provided
14224  * by default if found at compile-time.
14225  *
14226  * Returns the new parser context or NULL
14227  */
14228 static xmlParserCtxtPtr
14229 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
14230                           const xmlChar *base, xmlParserCtxtPtr pctx) {
14231     xmlParserCtxtPtr ctxt;
14232     xmlParserInputPtr inputStream;
14233     char *directory = NULL;
14234     xmlChar *uri;
14235
14236     ctxt = xmlNewParserCtxt();
14237     if (ctxt == NULL) {
14238         return(NULL);
14239     }
14240
14241     if (pctx != NULL) {
14242         ctxt->options = pctx->options;
14243         ctxt->_private = pctx->_private;
14244     }
14245
14246     uri = xmlBuildURI(URL, base);
14247
14248     if (uri == NULL) {
14249         inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
14250         if (inputStream == NULL) {
14251             xmlFreeParserCtxt(ctxt);
14252             return(NULL);
14253         }
14254
14255         inputPush(ctxt, inputStream);
14256
14257         if ((ctxt->directory == NULL) && (directory == NULL))
14258             directory = xmlParserGetDirectory((char *)URL);
14259         if ((ctxt->directory == NULL) && (directory != NULL))
14260             ctxt->directory = directory;
14261     } else {
14262         inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
14263         if (inputStream == NULL) {
14264             xmlFree(uri);
14265             xmlFreeParserCtxt(ctxt);
14266             return(NULL);
14267         }
14268
14269         inputPush(ctxt, inputStream);
14270
14271         if ((ctxt->directory == NULL) && (directory == NULL))
14272             directory = xmlParserGetDirectory((char *)uri);
14273         if ((ctxt->directory == NULL) && (directory != NULL))
14274             ctxt->directory = directory;
14275         xmlFree(uri);
14276     }
14277     return(ctxt);
14278 }
14279
14280 /**
14281  * xmlCreateEntityParserCtxt:
14282  * @URL:  the entity URL
14283  * @ID:  the entity PUBLIC ID
14284  * @base:  a possible base for the target URI
14285  *
14286  * Create a parser context for an external entity
14287  * Automatic support for ZLIB/Compress compressed document is provided
14288  * by default if found at compile-time.
14289  *
14290  * Returns the new parser context or NULL
14291  */
14292 xmlParserCtxtPtr
14293 xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
14294                           const xmlChar *base) {
14295     return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
14296
14297 }
14298
14299 /************************************************************************
14300  *                                                                      *
14301  *              Front ends when parsing from a file                     *
14302  *                                                                      *
14303  ************************************************************************/
14304
14305 /**
14306  * xmlCreateURLParserCtxt:
14307  * @filename:  the filename or URL
14308  * @options:  a combination of xmlParserOption
14309  *
14310  * Create a parser context for a file or URL content.
14311  * Automatic support for ZLIB/Compress compressed document is provided
14312  * by default if found at compile-time and for file accesses
14313  *
14314  * Returns the new parser context or NULL
14315  */
14316 xmlParserCtxtPtr
14317 xmlCreateURLParserCtxt(const char *filename, int options)
14318 {
14319     xmlParserCtxtPtr ctxt;
14320     xmlParserInputPtr inputStream;
14321     char *directory = NULL;
14322
14323     ctxt = xmlNewParserCtxt();
14324     if (ctxt == NULL) {
14325         xmlErrMemory(NULL, "cannot allocate parser context");
14326         return(NULL);
14327     }
14328
14329     if (options)
14330         xmlCtxtUseOptionsInternal(ctxt, options, NULL);
14331     ctxt->linenumbers = 1;
14332
14333     inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
14334     if (inputStream == NULL) {
14335         xmlFreeParserCtxt(ctxt);
14336         return(NULL);
14337     }
14338
14339     inputPush(ctxt, inputStream);
14340     if ((ctxt->directory == NULL) && (directory == NULL))
14341         directory = xmlParserGetDirectory(filename);
14342     if ((ctxt->directory == NULL) && (directory != NULL))
14343         ctxt->directory = directory;
14344
14345     return(ctxt);
14346 }
14347
14348 /**
14349  * xmlCreateFileParserCtxt:
14350  * @filename:  the filename
14351  *
14352  * Create a parser context for a file content.
14353  * Automatic support for ZLIB/Compress compressed document is provided
14354  * by default if found at compile-time.
14355  *
14356  * Returns the new parser context or NULL
14357  */
14358 xmlParserCtxtPtr
14359 xmlCreateFileParserCtxt(const char *filename)
14360 {
14361     return(xmlCreateURLParserCtxt(filename, 0));
14362 }
14363
14364 #ifdef LIBXML_SAX1_ENABLED
14365 /**
14366  * xmlSAXParseFileWithData:
14367  * @sax:  the SAX handler block
14368  * @filename:  the filename
14369  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14370  *             documents
14371  * @data:  the userdata
14372  *
14373  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14374  * compressed document is provided by default if found at compile-time.
14375  * It use the given SAX function block to handle the parsing callback.
14376  * If sax is NULL, fallback to the default DOM tree building routines.
14377  *
14378  * User data (void *) is stored within the parser context in the
14379  * context's _private member, so it is available nearly everywhere in libxml
14380  *
14381  * Returns the resulting document tree
14382  */
14383
14384 xmlDocPtr
14385 xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
14386                         int recovery, void *data) {
14387     xmlDocPtr ret;
14388     xmlParserCtxtPtr ctxt;
14389
14390     xmlInitParser();
14391
14392     ctxt = xmlCreateFileParserCtxt(filename);
14393     if (ctxt == NULL) {
14394         return(NULL);
14395     }
14396     if (sax != NULL) {
14397         if (ctxt->sax != NULL)
14398             xmlFree(ctxt->sax);
14399         ctxt->sax = sax;
14400     }
14401     xmlDetectSAX2(ctxt);
14402     if (data!=NULL) {
14403         ctxt->_private = data;
14404     }
14405
14406     if (ctxt->directory == NULL)
14407         ctxt->directory = xmlParserGetDirectory(filename);
14408
14409     ctxt->recovery = recovery;
14410
14411     xmlParseDocument(ctxt);
14412
14413     if ((ctxt->wellFormed) || recovery) {
14414         ret = ctxt->myDoc;
14415         if (ret != NULL) {
14416             if (ctxt->input->buf->compressed > 0)
14417                 ret->compression = 9;
14418             else
14419                 ret->compression = ctxt->input->buf->compressed;
14420         }
14421     }
14422     else {
14423        ret = NULL;
14424        xmlFreeDoc(ctxt->myDoc);
14425        ctxt->myDoc = NULL;
14426     }
14427     if (sax != NULL)
14428         ctxt->sax = NULL;
14429     xmlFreeParserCtxt(ctxt);
14430
14431     return(ret);
14432 }
14433
14434 /**
14435  * xmlSAXParseFile:
14436  * @sax:  the SAX handler block
14437  * @filename:  the filename
14438  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14439  *             documents
14440  *
14441  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14442  * compressed document is provided by default if found at compile-time.
14443  * It use the given SAX function block to handle the parsing callback.
14444  * If sax is NULL, fallback to the default DOM tree building routines.
14445  *
14446  * Returns the resulting document tree
14447  */
14448
14449 xmlDocPtr
14450 xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
14451                           int recovery) {
14452     return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
14453 }
14454
14455 /**
14456  * xmlRecoverDoc:
14457  * @cur:  a pointer to an array of xmlChar
14458  *
14459  * parse an XML in-memory document and build a tree.
14460  * In the case the document is not Well Formed, a attempt to build a
14461  * tree is tried anyway
14462  *
14463  * Returns the resulting document tree or NULL in case of failure
14464  */
14465
14466 xmlDocPtr
14467 xmlRecoverDoc(const xmlChar *cur) {
14468     return(xmlSAXParseDoc(NULL, cur, 1));
14469 }
14470
14471 /**
14472  * xmlParseFile:
14473  * @filename:  the filename
14474  *
14475  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14476  * compressed document is provided by default if found at compile-time.
14477  *
14478  * Returns the resulting document tree if the file was wellformed,
14479  * NULL otherwise.
14480  */
14481
14482 xmlDocPtr
14483 xmlParseFile(const char *filename) {
14484     return(xmlSAXParseFile(NULL, filename, 0));
14485 }
14486
14487 /**
14488  * xmlRecoverFile:
14489  * @filename:  the filename
14490  *
14491  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14492  * compressed document is provided by default if found at compile-time.
14493  * In the case the document is not Well Formed, it attempts to build
14494  * a tree anyway
14495  *
14496  * Returns the resulting document tree or NULL in case of failure
14497  */
14498
14499 xmlDocPtr
14500 xmlRecoverFile(const char *filename) {
14501     return(xmlSAXParseFile(NULL, filename, 1));
14502 }
14503
14504
14505 /**
14506  * xmlSetupParserForBuffer:
14507  * @ctxt:  an XML parser context
14508  * @buffer:  a xmlChar * buffer
14509  * @filename:  a file name
14510  *
14511  * Setup the parser context to parse a new buffer; Clears any prior
14512  * contents from the parser context. The buffer parameter must not be
14513  * NULL, but the filename parameter can be
14514  */
14515 void
14516 xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
14517                              const char* filename)
14518 {
14519     xmlParserInputPtr input;
14520
14521     if ((ctxt == NULL) || (buffer == NULL))
14522         return;
14523
14524     input = xmlNewInputStream(ctxt);
14525     if (input == NULL) {
14526         xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
14527         xmlClearParserCtxt(ctxt);
14528         return;
14529     }
14530
14531     xmlClearParserCtxt(ctxt);
14532     if (filename != NULL)
14533         input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
14534     input->base = buffer;
14535     input->cur = buffer;
14536     input->end = &buffer[xmlStrlen(buffer)];
14537     inputPush(ctxt, input);
14538 }
14539
14540 /**
14541  * xmlSAXUserParseFile:
14542  * @sax:  a SAX handler
14543  * @user_data:  The user data returned on SAX callbacks
14544  * @filename:  a file name
14545  *
14546  * parse an XML file and call the given SAX handler routines.
14547  * Automatic support for ZLIB/Compress compressed document is provided
14548  *
14549  * Returns 0 in case of success or a error number otherwise
14550  */
14551 int
14552 xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
14553                     const char *filename) {
14554     int ret = 0;
14555     xmlParserCtxtPtr ctxt;
14556
14557     ctxt = xmlCreateFileParserCtxt(filename);
14558     if (ctxt == NULL) return -1;
14559     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14560         xmlFree(ctxt->sax);
14561     ctxt->sax = sax;
14562     xmlDetectSAX2(ctxt);
14563
14564     if (user_data != NULL)
14565         ctxt->userData = user_data;
14566
14567     xmlParseDocument(ctxt);
14568
14569     if (ctxt->wellFormed)
14570         ret = 0;
14571     else {
14572         if (ctxt->errNo != 0)
14573             ret = ctxt->errNo;
14574         else
14575             ret = -1;
14576     }
14577     if (sax != NULL)
14578         ctxt->sax = NULL;
14579     if (ctxt->myDoc != NULL) {
14580         xmlFreeDoc(ctxt->myDoc);
14581         ctxt->myDoc = NULL;
14582     }
14583     xmlFreeParserCtxt(ctxt);
14584
14585     return ret;
14586 }
14587 #endif /* LIBXML_SAX1_ENABLED */
14588
14589 /************************************************************************
14590  *                                                                      *
14591  *              Front ends when parsing from memory                     *
14592  *                                                                      *
14593  ************************************************************************/
14594
14595 /**
14596  * xmlCreateMemoryParserCtxt:
14597  * @buffer:  a pointer to a char array
14598  * @size:  the size of the array
14599  *
14600  * Create a parser context for an XML in-memory document.
14601  *
14602  * Returns the new parser context or NULL
14603  */
14604 xmlParserCtxtPtr
14605 xmlCreateMemoryParserCtxt(const char *buffer, int size) {
14606     xmlParserCtxtPtr ctxt;
14607     xmlParserInputPtr input;
14608     xmlParserInputBufferPtr buf;
14609
14610     if (buffer == NULL)
14611         return(NULL);
14612     if (size <= 0)
14613         return(NULL);
14614
14615     ctxt = xmlNewParserCtxt();
14616     if (ctxt == NULL)
14617         return(NULL);
14618
14619     /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
14620     buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
14621     if (buf == NULL) {
14622         xmlFreeParserCtxt(ctxt);
14623         return(NULL);
14624     }
14625
14626     input = xmlNewInputStream(ctxt);
14627     if (input == NULL) {
14628         xmlFreeParserInputBuffer(buf);
14629         xmlFreeParserCtxt(ctxt);
14630         return(NULL);
14631     }
14632
14633     input->filename = NULL;
14634     input->buf = buf;
14635     xmlBufResetInput(input->buf->buffer, input);
14636
14637     inputPush(ctxt, input);
14638     return(ctxt);
14639 }
14640
14641 #ifdef LIBXML_SAX1_ENABLED
14642 /**
14643  * xmlSAXParseMemoryWithData:
14644  * @sax:  the SAX handler block
14645  * @buffer:  an pointer to a char array
14646  * @size:  the size of the array
14647  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14648  *             documents
14649  * @data:  the userdata
14650  *
14651  * parse an XML in-memory block and use the given SAX function block
14652  * to handle the parsing callback. If sax is NULL, fallback to the default
14653  * DOM tree building routines.
14654  *
14655  * User data (void *) is stored within the parser context in the
14656  * context's _private member, so it is available nearly everywhere in libxml
14657  *
14658  * Returns the resulting document tree
14659  */
14660
14661 xmlDocPtr
14662 xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
14663                   int size, int recovery, void *data) {
14664     xmlDocPtr ret;
14665     xmlParserCtxtPtr ctxt;
14666
14667     xmlInitParser();
14668
14669     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14670     if (ctxt == NULL) return(NULL);
14671     if (sax != NULL) {
14672         if (ctxt->sax != NULL)
14673             xmlFree(ctxt->sax);
14674         ctxt->sax = sax;
14675     }
14676     xmlDetectSAX2(ctxt);
14677     if (data!=NULL) {
14678         ctxt->_private=data;
14679     }
14680
14681     ctxt->recovery = recovery;
14682
14683     xmlParseDocument(ctxt);
14684
14685     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14686     else {
14687        ret = NULL;
14688        xmlFreeDoc(ctxt->myDoc);
14689        ctxt->myDoc = NULL;
14690     }
14691     if (sax != NULL)
14692         ctxt->sax = NULL;
14693     xmlFreeParserCtxt(ctxt);
14694
14695     return(ret);
14696 }
14697
14698 /**
14699  * xmlSAXParseMemory:
14700  * @sax:  the SAX handler block
14701  * @buffer:  an pointer to a char array
14702  * @size:  the size of the array
14703  * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
14704  *             documents
14705  *
14706  * parse an XML in-memory block and use the given SAX function block
14707  * to handle the parsing callback. If sax is NULL, fallback to the default
14708  * DOM tree building routines.
14709  *
14710  * Returns the resulting document tree
14711  */
14712 xmlDocPtr
14713 xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
14714                   int size, int recovery) {
14715     return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
14716 }
14717
14718 /**
14719  * xmlParseMemory:
14720  * @buffer:  an pointer to a char array
14721  * @size:  the size of the array
14722  *
14723  * parse an XML in-memory block and build a tree.
14724  *
14725  * Returns the resulting document tree
14726  */
14727
14728 xmlDocPtr xmlParseMemory(const char *buffer, int size) {
14729    return(xmlSAXParseMemory(NULL, buffer, size, 0));
14730 }
14731
14732 /**
14733  * xmlRecoverMemory:
14734  * @buffer:  an pointer to a char array
14735  * @size:  the size of the array
14736  *
14737  * parse an XML in-memory block and build a tree.
14738  * In the case the document is not Well Formed, an attempt to
14739  * build a tree is tried anyway
14740  *
14741  * Returns the resulting document tree or NULL in case of error
14742  */
14743
14744 xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
14745    return(xmlSAXParseMemory(NULL, buffer, size, 1));
14746 }
14747
14748 /**
14749  * xmlSAXUserParseMemory:
14750  * @sax:  a SAX handler
14751  * @user_data:  The user data returned on SAX callbacks
14752  * @buffer:  an in-memory XML document input
14753  * @size:  the length of the XML document in bytes
14754  *
14755  * A better SAX parsing routine.
14756  * parse an XML in-memory buffer and call the given SAX handler routines.
14757  *
14758  * Returns 0 in case of success or a error number otherwise
14759  */
14760 int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
14761                           const char *buffer, int size) {
14762     int ret = 0;
14763     xmlParserCtxtPtr ctxt;
14764
14765     xmlInitParser();
14766
14767     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14768     if (ctxt == NULL) return -1;
14769     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14770         xmlFree(ctxt->sax);
14771     ctxt->sax = sax;
14772     xmlDetectSAX2(ctxt);
14773
14774     if (user_data != NULL)
14775         ctxt->userData = user_data;
14776
14777     xmlParseDocument(ctxt);
14778
14779     if (ctxt->wellFormed)
14780         ret = 0;
14781     else {
14782         if (ctxt->errNo != 0)
14783             ret = ctxt->errNo;
14784         else
14785             ret = -1;
14786     }
14787     if (sax != NULL)
14788         ctxt->sax = NULL;
14789     if (ctxt->myDoc != NULL) {
14790         xmlFreeDoc(ctxt->myDoc);
14791         ctxt->myDoc = NULL;
14792     }
14793     xmlFreeParserCtxt(ctxt);
14794
14795     return ret;
14796 }
14797 #endif /* LIBXML_SAX1_ENABLED */
14798
14799 /**
14800  * xmlCreateDocParserCtxt:
14801  * @cur:  a pointer to an array of xmlChar
14802  *
14803  * Creates a parser context for an XML in-memory document.
14804  *
14805  * Returns the new parser context or NULL
14806  */
14807 xmlParserCtxtPtr
14808 xmlCreateDocParserCtxt(const xmlChar *cur) {
14809     int len;
14810
14811     if (cur == NULL)
14812         return(NULL);
14813     len = xmlStrlen(cur);
14814     return(xmlCreateMemoryParserCtxt((const char *)cur, len));
14815 }
14816
14817 #ifdef LIBXML_SAX1_ENABLED
14818 /**
14819  * xmlSAXParseDoc:
14820  * @sax:  the SAX handler block
14821  * @cur:  a pointer to an array of xmlChar
14822  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14823  *             documents
14824  *
14825  * parse an XML in-memory document and build a tree.
14826  * It use the given SAX function block to handle the parsing callback.
14827  * If sax is NULL, fallback to the default DOM tree building routines.
14828  *
14829  * Returns the resulting document tree
14830  */
14831
14832 xmlDocPtr
14833 xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
14834     xmlDocPtr ret;
14835     xmlParserCtxtPtr ctxt;
14836     xmlSAXHandlerPtr oldsax = NULL;
14837
14838     if (cur == NULL) return(NULL);
14839
14840
14841     ctxt = xmlCreateDocParserCtxt(cur);
14842     if (ctxt == NULL) return(NULL);
14843     if (sax != NULL) {
14844         oldsax = ctxt->sax;
14845         ctxt->sax = sax;
14846         ctxt->userData = NULL;
14847     }
14848     xmlDetectSAX2(ctxt);
14849
14850     xmlParseDocument(ctxt);
14851     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14852     else {
14853        ret = NULL;
14854        xmlFreeDoc(ctxt->myDoc);
14855        ctxt->myDoc = NULL;
14856     }
14857     if (sax != NULL)
14858         ctxt->sax = oldsax;
14859     xmlFreeParserCtxt(ctxt);
14860
14861     return(ret);
14862 }
14863
14864 /**
14865  * xmlParseDoc:
14866  * @cur:  a pointer to an array of xmlChar
14867  *
14868  * parse an XML in-memory document and build a tree.
14869  *
14870  * Returns the resulting document tree
14871  */
14872
14873 xmlDocPtr
14874 xmlParseDoc(const xmlChar *cur) {
14875     return(xmlSAXParseDoc(NULL, cur, 0));
14876 }
14877 #endif /* LIBXML_SAX1_ENABLED */
14878
14879 #ifdef LIBXML_LEGACY_ENABLED
14880 /************************************************************************
14881  *                                                                      *
14882  *      Specific function to keep track of entities references          *
14883  *      and used by the XSLT debugger                                   *
14884  *                                                                      *
14885  ************************************************************************/
14886
14887 static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
14888
14889 /**
14890  * xmlAddEntityReference:
14891  * @ent : A valid entity
14892  * @firstNode : A valid first node for children of entity
14893  * @lastNode : A valid last node of children entity
14894  *
14895  * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
14896  */
14897 static void
14898 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
14899                       xmlNodePtr lastNode)
14900 {
14901     if (xmlEntityRefFunc != NULL) {
14902         (*xmlEntityRefFunc) (ent, firstNode, lastNode);
14903     }
14904 }
14905
14906
14907 /**
14908  * xmlSetEntityReferenceFunc:
14909  * @func: A valid function
14910  *
14911  * Set the function to call call back when a xml reference has been made
14912  */
14913 void
14914 xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
14915 {
14916     xmlEntityRefFunc = func;
14917 }
14918 #endif /* LIBXML_LEGACY_ENABLED */
14919
14920 /************************************************************************
14921  *                                                                      *
14922  *                              Miscellaneous                           *
14923  *                                                                      *
14924  ************************************************************************/
14925
14926 #ifdef LIBXML_XPATH_ENABLED
14927 #include <libxml/xpath.h>
14928 #endif
14929
14930 extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
14931 static int xmlParserInitialized = 0;
14932
14933 /**
14934  * xmlInitParser:
14935  *
14936  * Initialization function for the XML parser.
14937  * This is not reentrant. Call once before processing in case of
14938  * use in multithreaded programs.
14939  */
14940
14941 void
14942 xmlInitParser(void) {
14943     if (xmlParserInitialized != 0)
14944         return;
14945
14946 #ifdef LIBXML_THREAD_ENABLED
14947     __xmlGlobalInitMutexLock();
14948     if (xmlParserInitialized == 0) {
14949 #endif
14950         xmlInitThreads();
14951         xmlInitGlobals();
14952         if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
14953             (xmlGenericError == NULL))
14954             initGenericErrorDefaultFunc(NULL);
14955         xmlInitMemory();
14956         xmlInitializeDict();
14957         xmlInitCharEncodingHandlers();
14958         xmlDefaultSAXHandlerInit();
14959         xmlRegisterDefaultInputCallbacks();
14960 #ifdef LIBXML_OUTPUT_ENABLED
14961         xmlRegisterDefaultOutputCallbacks();
14962 #endif /* LIBXML_OUTPUT_ENABLED */
14963 #ifdef LIBXML_HTML_ENABLED
14964         htmlInitAutoClose();
14965         htmlDefaultSAXHandlerInit();
14966 #endif
14967 #ifdef LIBXML_XPATH_ENABLED
14968         xmlXPathInit();
14969 #endif
14970         xmlParserInitialized = 1;
14971 #ifdef LIBXML_THREAD_ENABLED
14972     }
14973     __xmlGlobalInitMutexUnlock();
14974 #endif
14975 }
14976
14977 /**
14978  * xmlCleanupParser:
14979  *
14980  * This function name is somewhat misleading. It does not clean up
14981  * parser state, it cleans up memory allocated by the library itself.
14982  * It is a cleanup function for the XML library. It tries to reclaim all
14983  * related global memory allocated for the library processing.
14984  * It doesn't deallocate any document related memory. One should
14985  * call xmlCleanupParser() only when the process has finished using
14986  * the library and all XML/HTML documents built with it.
14987  * See also xmlInitParser() which has the opposite function of preparing
14988  * the library for operations.
14989  *
14990  * WARNING: if your application is multithreaded or has plugin support
14991  *          calling this may crash the application if another thread or
14992  *          a plugin is still using libxml2. It's sometimes very hard to
14993  *          guess if libxml2 is in use in the application, some libraries
14994  *          or plugins may use it without notice. In case of doubt abstain
14995  *          from calling this function or do it just before calling exit()
14996  *          to avoid leak reports from valgrind !
14997  */
14998
14999 void
15000 xmlCleanupParser(void) {
15001     if (!xmlParserInitialized)
15002         return;
15003
15004     xmlCleanupCharEncodingHandlers();
15005 #ifdef LIBXML_CATALOG_ENABLED
15006     xmlCatalogCleanup();
15007 #endif
15008     xmlDictCleanup();
15009     xmlCleanupInputCallbacks();
15010 #ifdef LIBXML_OUTPUT_ENABLED
15011     xmlCleanupOutputCallbacks();
15012 #endif
15013 #ifdef LIBXML_SCHEMAS_ENABLED
15014     xmlSchemaCleanupTypes();
15015     xmlRelaxNGCleanupTypes();
15016 #endif
15017     xmlResetLastError();
15018     xmlCleanupGlobals();
15019     xmlCleanupThreads(); /* must be last if called not from the main thread */
15020     xmlCleanupMemory();
15021     xmlParserInitialized = 0;
15022 }
15023
15024 /************************************************************************
15025  *                                                                      *
15026  *      New set (2.6.0) of simpler and more flexible APIs               *
15027  *                                                                      *
15028  ************************************************************************/
15029
15030 /**
15031  * DICT_FREE:
15032  * @str:  a string
15033  *
15034  * Free a string if it is not owned by the "dict" dictionary in the
15035  * current scope
15036  */
15037 #define DICT_FREE(str)                                          \
15038         if ((str) && ((!dict) ||                                \
15039             (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
15040             xmlFree((char *)(str));
15041
15042 /**
15043  * xmlCtxtReset:
15044  * @ctxt: an XML parser context
15045  *
15046  * Reset a parser context
15047  */
15048 void
15049 xmlCtxtReset(xmlParserCtxtPtr ctxt)
15050 {
15051     xmlParserInputPtr input;
15052     xmlDictPtr dict;
15053
15054     if (ctxt == NULL)
15055         return;
15056
15057     dict = ctxt->dict;
15058
15059     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
15060         xmlFreeInputStream(input);
15061     }
15062     ctxt->inputNr = 0;
15063     ctxt->input = NULL;
15064
15065     ctxt->spaceNr = 0;
15066     if (ctxt->spaceTab != NULL) {
15067         ctxt->spaceTab[0] = -1;
15068         ctxt->space = &ctxt->spaceTab[0];
15069     } else {
15070         ctxt->space = NULL;
15071     }
15072
15073
15074     ctxt->nodeNr = 0;
15075     ctxt->node = NULL;
15076
15077     ctxt->nameNr = 0;
15078     ctxt->name = NULL;
15079
15080     DICT_FREE(ctxt->version);
15081     ctxt->version = NULL;
15082     DICT_FREE(ctxt->encoding);
15083     ctxt->encoding = NULL;
15084     DICT_FREE(ctxt->directory);
15085     ctxt->directory = NULL;
15086     DICT_FREE(ctxt->extSubURI);
15087     ctxt->extSubURI = NULL;
15088     DICT_FREE(ctxt->extSubSystem);
15089     ctxt->extSubSystem = NULL;
15090     if (ctxt->myDoc != NULL)
15091         xmlFreeDoc(ctxt->myDoc);
15092     ctxt->myDoc = NULL;
15093
15094     ctxt->standalone = -1;
15095     ctxt->hasExternalSubset = 0;
15096     ctxt->hasPErefs = 0;
15097     ctxt->html = 0;
15098     ctxt->external = 0;
15099     ctxt->instate = XML_PARSER_START;
15100     ctxt->token = 0;
15101
15102     ctxt->wellFormed = 1;
15103     ctxt->nsWellFormed = 1;
15104     ctxt->disableSAX = 0;
15105     ctxt->valid = 1;
15106 #if 0
15107     ctxt->vctxt.userData = ctxt;
15108     ctxt->vctxt.error = xmlParserValidityError;
15109     ctxt->vctxt.warning = xmlParserValidityWarning;
15110 #endif
15111     ctxt->record_info = 0;
15112     ctxt->nbChars = 0;
15113     ctxt->checkIndex = 0;
15114     ctxt->inSubset = 0;
15115     ctxt->errNo = XML_ERR_OK;
15116     ctxt->depth = 0;
15117     ctxt->charset = XML_CHAR_ENCODING_UTF8;
15118     ctxt->catalogs = NULL;
15119     ctxt->nbentities = 0;
15120     ctxt->sizeentities = 0;
15121     ctxt->sizeentcopy = 0;
15122     xmlInitNodeInfoSeq(&ctxt->node_seq);
15123
15124     if (ctxt->attsDefault != NULL) {
15125         xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
15126         ctxt->attsDefault = NULL;
15127     }
15128     if (ctxt->attsSpecial != NULL) {
15129         xmlHashFree(ctxt->attsSpecial, NULL);
15130         ctxt->attsSpecial = NULL;
15131     }
15132
15133 #ifdef LIBXML_CATALOG_ENABLED
15134     if (ctxt->catalogs != NULL)
15135         xmlCatalogFreeLocal(ctxt->catalogs);
15136 #endif
15137     if (ctxt->lastError.code != XML_ERR_OK)
15138         xmlResetError(&ctxt->lastError);
15139 }
15140
15141 /**
15142  * xmlCtxtResetPush:
15143  * @ctxt: an XML parser context
15144  * @chunk:  a pointer to an array of chars
15145  * @size:  number of chars in the array
15146  * @filename:  an optional file name or URI
15147  * @encoding:  the document encoding, or NULL
15148  *
15149  * Reset a push parser context
15150  *
15151  * Returns 0 in case of success and 1 in case of error
15152  */
15153 int
15154 xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
15155                  int size, const char *filename, const char *encoding)
15156 {
15157     xmlParserInputPtr inputStream;
15158     xmlParserInputBufferPtr buf;
15159     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
15160
15161     if (ctxt == NULL)
15162         return(1);
15163
15164     if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
15165         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
15166
15167     buf = xmlAllocParserInputBuffer(enc);
15168     if (buf == NULL)
15169         return(1);
15170
15171     if (ctxt == NULL) {
15172         xmlFreeParserInputBuffer(buf);
15173         return(1);
15174     }
15175
15176     xmlCtxtReset(ctxt);
15177
15178     if (ctxt->pushTab == NULL) {
15179         ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
15180                                             sizeof(xmlChar *));
15181         if (ctxt->pushTab == NULL) {
15182             xmlErrMemory(ctxt, NULL);
15183             xmlFreeParserInputBuffer(buf);
15184             return(1);
15185         }
15186     }
15187
15188     if (filename == NULL) {
15189         ctxt->directory = NULL;
15190     } else {
15191         ctxt->directory = xmlParserGetDirectory(filename);
15192     }
15193
15194     inputStream = xmlNewInputStream(ctxt);
15195     if (inputStream == NULL) {
15196         xmlFreeParserInputBuffer(buf);
15197         return(1);
15198     }
15199
15200     if (filename == NULL)
15201         inputStream->filename = NULL;
15202     else
15203         inputStream->filename = (char *)
15204             xmlCanonicPath((const xmlChar *) filename);
15205     inputStream->buf = buf;
15206     xmlBufResetInput(buf->buffer, inputStream);
15207
15208     inputPush(ctxt, inputStream);
15209
15210     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
15211         (ctxt->input->buf != NULL)) {
15212         size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
15213         size_t cur = ctxt->input->cur - ctxt->input->base;
15214
15215         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
15216
15217         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
15218 #ifdef DEBUG_PUSH
15219         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
15220 #endif
15221     }
15222
15223     if (encoding != NULL) {
15224         xmlCharEncodingHandlerPtr hdlr;
15225
15226         if (ctxt->encoding != NULL)
15227             xmlFree((xmlChar *) ctxt->encoding);
15228         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
15229
15230         hdlr = xmlFindCharEncodingHandler(encoding);
15231         if (hdlr != NULL) {
15232             xmlSwitchToEncoding(ctxt, hdlr);
15233         } else {
15234             xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
15235                               "Unsupported encoding %s\n", BAD_CAST encoding);
15236         }
15237     } else if (enc != XML_CHAR_ENCODING_NONE) {
15238         xmlSwitchEncoding(ctxt, enc);
15239     }
15240
15241     return(0);
15242 }
15243
15244
15245 /**
15246  * xmlCtxtUseOptionsInternal:
15247  * @ctxt: an XML parser context
15248  * @options:  a combination of xmlParserOption
15249  * @encoding:  the user provided encoding to use
15250  *
15251  * Applies the options to the parser context
15252  *
15253  * Returns 0 in case of success, the set of unknown or unimplemented options
15254  *         in case of error.
15255  */
15256 static int
15257 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
15258 {
15259     if (ctxt == NULL)
15260         return(-1);
15261     if (encoding != NULL) {
15262         if (ctxt->encoding != NULL)
15263             xmlFree((xmlChar *) ctxt->encoding);
15264         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
15265     }
15266     if (options & XML_PARSE_RECOVER) {
15267         ctxt->recovery = 1;
15268         options -= XML_PARSE_RECOVER;
15269         ctxt->options |= XML_PARSE_RECOVER;
15270     } else
15271         ctxt->recovery = 0;
15272     if (options & XML_PARSE_DTDLOAD) {
15273         ctxt->loadsubset = XML_DETECT_IDS;
15274         options -= XML_PARSE_DTDLOAD;
15275         ctxt->options |= XML_PARSE_DTDLOAD;
15276     } else
15277         ctxt->loadsubset = 0;
15278     if (options & XML_PARSE_DTDATTR) {
15279         ctxt->loadsubset |= XML_COMPLETE_ATTRS;
15280         options -= XML_PARSE_DTDATTR;
15281         ctxt->options |= XML_PARSE_DTDATTR;
15282     }
15283     if (options & XML_PARSE_NOENT) {
15284         ctxt->replaceEntities = 1;
15285         /* ctxt->loadsubset |= XML_DETECT_IDS; */
15286         options -= XML_PARSE_NOENT;
15287         ctxt->options |= XML_PARSE_NOENT;
15288     } else
15289         ctxt->replaceEntities = 0;
15290     if (options & XML_PARSE_PEDANTIC) {
15291         ctxt->pedantic = 1;
15292         options -= XML_PARSE_PEDANTIC;
15293         ctxt->options |= XML_PARSE_PEDANTIC;
15294     } else
15295         ctxt->pedantic = 0;
15296     if (options & XML_PARSE_NOBLANKS) {
15297         ctxt->keepBlanks = 0;
15298         ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
15299         options -= XML_PARSE_NOBLANKS;
15300         ctxt->options |= XML_PARSE_NOBLANKS;
15301     } else
15302         ctxt->keepBlanks = 1;
15303     if (options & XML_PARSE_DTDVALID) {
15304         ctxt->validate = 1;
15305         if (options & XML_PARSE_NOWARNING)
15306             ctxt->vctxt.warning = NULL;
15307         if (options & XML_PARSE_NOERROR)
15308             ctxt->vctxt.error = NULL;
15309         options -= XML_PARSE_DTDVALID;
15310         ctxt->options |= XML_PARSE_DTDVALID;
15311     } else
15312         ctxt->validate = 0;
15313     if (options & XML_PARSE_NOWARNING) {
15314         ctxt->sax->warning = NULL;
15315         options -= XML_PARSE_NOWARNING;
15316     }
15317     if (options & XML_PARSE_NOERROR) {
15318         ctxt->sax->error = NULL;
15319         ctxt->sax->fatalError = NULL;
15320         options -= XML_PARSE_NOERROR;
15321     }
15322 #ifdef LIBXML_SAX1_ENABLED
15323     if (options & XML_PARSE_SAX1) {
15324         ctxt->sax->startElement = xmlSAX2StartElement;
15325         ctxt->sax->endElement = xmlSAX2EndElement;
15326         ctxt->sax->startElementNs = NULL;
15327         ctxt->sax->endElementNs = NULL;
15328         ctxt->sax->initialized = 1;
15329         options -= XML_PARSE_SAX1;
15330         ctxt->options |= XML_PARSE_SAX1;
15331     }
15332 #endif /* LIBXML_SAX1_ENABLED */
15333     if (options & XML_PARSE_NODICT) {
15334         ctxt->dictNames = 0;
15335         options -= XML_PARSE_NODICT;
15336         ctxt->options |= XML_PARSE_NODICT;
15337     } else {
15338         ctxt->dictNames = 1;
15339     }
15340     if (options & XML_PARSE_NOCDATA) {
15341         ctxt->sax->cdataBlock = NULL;
15342         options -= XML_PARSE_NOCDATA;
15343         ctxt->options |= XML_PARSE_NOCDATA;
15344     }
15345     if (options & XML_PARSE_NSCLEAN) {
15346         ctxt->options |= XML_PARSE_NSCLEAN;
15347         options -= XML_PARSE_NSCLEAN;
15348     }
15349     if (options & XML_PARSE_NONET) {
15350         ctxt->options |= XML_PARSE_NONET;
15351         options -= XML_PARSE_NONET;
15352     }
15353     if (options & XML_PARSE_COMPACT) {
15354         ctxt->options |= XML_PARSE_COMPACT;
15355         options -= XML_PARSE_COMPACT;
15356     }
15357     if (options & XML_PARSE_OLD10) {
15358         ctxt->options |= XML_PARSE_OLD10;
15359         options -= XML_PARSE_OLD10;
15360     }
15361     if (options & XML_PARSE_NOBASEFIX) {
15362         ctxt->options |= XML_PARSE_NOBASEFIX;
15363         options -= XML_PARSE_NOBASEFIX;
15364     }
15365     if (options & XML_PARSE_HUGE) {
15366         ctxt->options |= XML_PARSE_HUGE;
15367         options -= XML_PARSE_HUGE;
15368         if (ctxt->dict != NULL)
15369             xmlDictSetLimit(ctxt->dict, 0);
15370     }
15371     if (options & XML_PARSE_OLDSAX) {
15372         ctxt->options |= XML_PARSE_OLDSAX;
15373         options -= XML_PARSE_OLDSAX;
15374     }
15375     if (options & XML_PARSE_IGNORE_ENC) {
15376         ctxt->options |= XML_PARSE_IGNORE_ENC;
15377         options -= XML_PARSE_IGNORE_ENC;
15378     }
15379     if (options & XML_PARSE_BIG_LINES) {
15380         ctxt->options |= XML_PARSE_BIG_LINES;
15381         options -= XML_PARSE_BIG_LINES;
15382     }
15383     ctxt->linenumbers = 1;
15384     return (options);
15385 }
15386
15387 /**
15388  * xmlCtxtUseOptions:
15389  * @ctxt: an XML parser context
15390  * @options:  a combination of xmlParserOption
15391  *
15392  * Applies the options to the parser context
15393  *
15394  * Returns 0 in case of success, the set of unknown or unimplemented options
15395  *         in case of error.
15396  */
15397 int
15398 xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
15399 {
15400    return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
15401 }
15402
15403 /**
15404  * xmlDoRead:
15405  * @ctxt:  an XML parser context
15406  * @URL:  the base URL to use for the document
15407  * @encoding:  the document encoding, or NULL
15408  * @options:  a combination of xmlParserOption
15409  * @reuse:  keep the context for reuse
15410  *
15411  * Common front-end for the xmlRead functions
15412  *
15413  * Returns the resulting document tree or NULL
15414  */
15415 static xmlDocPtr
15416 xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
15417           int options, int reuse)
15418 {
15419     xmlDocPtr ret;
15420
15421     xmlCtxtUseOptionsInternal(ctxt, options, encoding);
15422     if (encoding != NULL) {
15423         xmlCharEncodingHandlerPtr hdlr;
15424
15425         hdlr = xmlFindCharEncodingHandler(encoding);
15426         if (hdlr != NULL)
15427             xmlSwitchToEncoding(ctxt, hdlr);
15428     }
15429     if ((URL != NULL) && (ctxt->input != NULL) &&
15430         (ctxt->input->filename == NULL))
15431         ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
15432     xmlParseDocument(ctxt);
15433     if ((ctxt->wellFormed) || ctxt->recovery)
15434         ret = ctxt->myDoc;
15435     else {
15436         ret = NULL;
15437         if (ctxt->myDoc != NULL) {
15438             xmlFreeDoc(ctxt->myDoc);
15439         }
15440     }
15441     ctxt->myDoc = NULL;
15442     if (!reuse) {
15443         xmlFreeParserCtxt(ctxt);
15444     }
15445
15446     return (ret);
15447 }
15448
15449 /**
15450  * xmlReadDoc:
15451  * @cur:  a pointer to a zero terminated string
15452  * @URL:  the base URL to use for the document
15453  * @encoding:  the document encoding, or NULL
15454  * @options:  a combination of xmlParserOption
15455  *
15456  * parse an XML in-memory document and build a tree.
15457  *
15458  * Returns the resulting document tree
15459  */
15460 xmlDocPtr
15461 xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
15462 {
15463     xmlParserCtxtPtr ctxt;
15464
15465     if (cur == NULL)
15466         return (NULL);
15467     xmlInitParser();
15468
15469     ctxt = xmlCreateDocParserCtxt(cur);
15470     if (ctxt == NULL)
15471         return (NULL);
15472     return (xmlDoRead(ctxt, URL, encoding, options, 0));
15473 }
15474
15475 /**
15476  * xmlReadFile:
15477  * @filename:  a file or URL
15478  * @encoding:  the document encoding, or NULL
15479  * @options:  a combination of xmlParserOption
15480  *
15481  * parse an XML file from the filesystem or the network.
15482  *
15483  * Returns the resulting document tree
15484  */
15485 xmlDocPtr
15486 xmlReadFile(const char *filename, const char *encoding, int options)
15487 {
15488     xmlParserCtxtPtr ctxt;
15489
15490     xmlInitParser();
15491     ctxt = xmlCreateURLParserCtxt(filename, options);
15492     if (ctxt == NULL)
15493         return (NULL);
15494     return (xmlDoRead(ctxt, NULL, encoding, options, 0));
15495 }
15496
15497 /**
15498  * xmlReadMemory:
15499  * @buffer:  a pointer to a char array
15500  * @size:  the size of the array
15501  * @URL:  the base URL to use for the document
15502  * @encoding:  the document encoding, or NULL
15503  * @options:  a combination of xmlParserOption
15504  *
15505  * parse an XML in-memory document and build a tree.
15506  *
15507  * Returns the resulting document tree
15508  */
15509 xmlDocPtr
15510 xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
15511 {
15512     xmlParserCtxtPtr ctxt;
15513
15514     xmlInitParser();
15515     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
15516     if (ctxt == NULL)
15517         return (NULL);
15518     return (xmlDoRead(ctxt, URL, encoding, options, 0));
15519 }
15520
15521 /**
15522  * xmlReadFd:
15523  * @fd:  an open file descriptor
15524  * @URL:  the base URL to use for the document
15525  * @encoding:  the document encoding, or NULL
15526  * @options:  a combination of xmlParserOption
15527  *
15528  * parse an XML from a file descriptor and build a tree.
15529  * NOTE that the file descriptor will not be closed when the
15530  *      reader is closed or reset.
15531  *
15532  * Returns the resulting document tree
15533  */
15534 xmlDocPtr
15535 xmlReadFd(int fd, const char *URL, const char *encoding, int options)
15536 {
15537     xmlParserCtxtPtr ctxt;
15538     xmlParserInputBufferPtr input;
15539     xmlParserInputPtr stream;
15540
15541     if (fd < 0)
15542         return (NULL);
15543     xmlInitParser();
15544
15545     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15546     if (input == NULL)
15547         return (NULL);
15548     input->closecallback = NULL;
15549     ctxt = xmlNewParserCtxt();
15550     if (ctxt == NULL) {
15551         xmlFreeParserInputBuffer(input);
15552         return (NULL);
15553     }
15554     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15555     if (stream == NULL) {
15556         xmlFreeParserInputBuffer(input);
15557         xmlFreeParserCtxt(ctxt);
15558         return (NULL);
15559     }
15560     inputPush(ctxt, stream);
15561     return (xmlDoRead(ctxt, URL, encoding, options, 0));
15562 }
15563
15564 /**
15565  * xmlReadIO:
15566  * @ioread:  an I/O read function
15567  * @ioclose:  an I/O close function
15568  * @ioctx:  an I/O handler
15569  * @URL:  the base URL to use for the document
15570  * @encoding:  the document encoding, or NULL
15571  * @options:  a combination of xmlParserOption
15572  *
15573  * parse an XML document from I/O functions and source and build a tree.
15574  *
15575  * Returns the resulting document tree
15576  */
15577 xmlDocPtr
15578 xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
15579           void *ioctx, const char *URL, const char *encoding, int options)
15580 {
15581     xmlParserCtxtPtr ctxt;
15582     xmlParserInputBufferPtr input;
15583     xmlParserInputPtr stream;
15584
15585     if (ioread == NULL)
15586         return (NULL);
15587     xmlInitParser();
15588
15589     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15590                                          XML_CHAR_ENCODING_NONE);
15591     if (input == NULL) {
15592         if (ioclose != NULL)
15593             ioclose(ioctx);
15594         return (NULL);
15595     }
15596     ctxt = xmlNewParserCtxt();
15597     if (ctxt == NULL) {
15598         xmlFreeParserInputBuffer(input);
15599         return (NULL);
15600     }
15601     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15602     if (stream == NULL) {
15603         xmlFreeParserInputBuffer(input);
15604         xmlFreeParserCtxt(ctxt);
15605         return (NULL);
15606     }
15607     inputPush(ctxt, stream);
15608     return (xmlDoRead(ctxt, URL, encoding, options, 0));
15609 }
15610
15611 /**
15612  * xmlCtxtReadDoc:
15613  * @ctxt:  an XML parser context
15614  * @cur:  a pointer to a zero terminated string
15615  * @URL:  the base URL to use for the document
15616  * @encoding:  the document encoding, or NULL
15617  * @options:  a combination of xmlParserOption
15618  *
15619  * parse an XML in-memory document and build a tree.
15620  * This reuses the existing @ctxt parser context
15621  *
15622  * Returns the resulting document tree
15623  */
15624 xmlDocPtr
15625 xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
15626                const char *URL, const char *encoding, int options)
15627 {
15628     xmlParserInputPtr stream;
15629
15630     if (cur == NULL)
15631         return (NULL);
15632     if (ctxt == NULL)
15633         return (NULL);
15634     xmlInitParser();
15635
15636     xmlCtxtReset(ctxt);
15637
15638     stream = xmlNewStringInputStream(ctxt, cur);
15639     if (stream == NULL) {
15640         return (NULL);
15641     }
15642     inputPush(ctxt, stream);
15643     return (xmlDoRead(ctxt, URL, encoding, options, 1));
15644 }
15645
15646 /**
15647  * xmlCtxtReadFile:
15648  * @ctxt:  an XML parser context
15649  * @filename:  a file or URL
15650  * @encoding:  the document encoding, or NULL
15651  * @options:  a combination of xmlParserOption
15652  *
15653  * parse an XML file from the filesystem or the network.
15654  * This reuses the existing @ctxt parser context
15655  *
15656  * Returns the resulting document tree
15657  */
15658 xmlDocPtr
15659 xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
15660                 const char *encoding, int options)
15661 {
15662     xmlParserInputPtr stream;
15663
15664     if (filename == NULL)
15665         return (NULL);
15666     if (ctxt == NULL)
15667         return (NULL);
15668     xmlInitParser();
15669
15670     xmlCtxtReset(ctxt);
15671
15672     stream = xmlLoadExternalEntity(filename, NULL, ctxt);
15673     if (stream == NULL) {
15674         return (NULL);
15675     }
15676     inputPush(ctxt, stream);
15677     return (xmlDoRead(ctxt, NULL, encoding, options, 1));
15678 }
15679
15680 /**
15681  * xmlCtxtReadMemory:
15682  * @ctxt:  an XML parser context
15683  * @buffer:  a pointer to a char array
15684  * @size:  the size of the array
15685  * @URL:  the base URL to use for the document
15686  * @encoding:  the document encoding, or NULL
15687  * @options:  a combination of xmlParserOption
15688  *
15689  * parse an XML in-memory document and build a tree.
15690  * This reuses the existing @ctxt parser context
15691  *
15692  * Returns the resulting document tree
15693  */
15694 xmlDocPtr
15695 xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
15696                   const char *URL, const char *encoding, int options)
15697 {
15698     xmlParserInputBufferPtr input;
15699     xmlParserInputPtr stream;
15700
15701     if (ctxt == NULL)
15702         return (NULL);
15703     if (buffer == NULL)
15704         return (NULL);
15705     xmlInitParser();
15706
15707     xmlCtxtReset(ctxt);
15708
15709     input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
15710     if (input == NULL) {
15711         return(NULL);
15712     }
15713
15714     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15715     if (stream == NULL) {
15716         xmlFreeParserInputBuffer(input);
15717         return(NULL);
15718     }
15719
15720     inputPush(ctxt, stream);
15721     return (xmlDoRead(ctxt, URL, encoding, options, 1));
15722 }
15723
15724 /**
15725  * xmlCtxtReadFd:
15726  * @ctxt:  an XML parser context
15727  * @fd:  an open file descriptor
15728  * @URL:  the base URL to use for the document
15729  * @encoding:  the document encoding, or NULL
15730  * @options:  a combination of xmlParserOption
15731  *
15732  * parse an XML from a file descriptor and build a tree.
15733  * This reuses the existing @ctxt parser context
15734  * NOTE that the file descriptor will not be closed when the
15735  *      reader is closed or reset.
15736  *
15737  * Returns the resulting document tree
15738  */
15739 xmlDocPtr
15740 xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
15741               const char *URL, const char *encoding, int options)
15742 {
15743     xmlParserInputBufferPtr input;
15744     xmlParserInputPtr stream;
15745
15746     if (fd < 0)
15747         return (NULL);
15748     if (ctxt == NULL)
15749         return (NULL);
15750     xmlInitParser();
15751
15752     xmlCtxtReset(ctxt);
15753
15754
15755     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15756     if (input == NULL)
15757         return (NULL);
15758     input->closecallback = NULL;
15759     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15760     if (stream == NULL) {
15761         xmlFreeParserInputBuffer(input);
15762         return (NULL);
15763     }
15764     inputPush(ctxt, stream);
15765     return (xmlDoRead(ctxt, URL, encoding, options, 1));
15766 }
15767
15768 /**
15769  * xmlCtxtReadIO:
15770  * @ctxt:  an XML parser context
15771  * @ioread:  an I/O read function
15772  * @ioclose:  an I/O close function
15773  * @ioctx:  an I/O handler
15774  * @URL:  the base URL to use for the document
15775  * @encoding:  the document encoding, or NULL
15776  * @options:  a combination of xmlParserOption
15777  *
15778  * parse an XML document from I/O functions and source and build a tree.
15779  * This reuses the existing @ctxt parser context
15780  *
15781  * Returns the resulting document tree
15782  */
15783 xmlDocPtr
15784 xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
15785               xmlInputCloseCallback ioclose, void *ioctx,
15786               const char *URL,
15787               const char *encoding, int options)
15788 {
15789     xmlParserInputBufferPtr input;
15790     xmlParserInputPtr stream;
15791
15792     if (ioread == NULL)
15793         return (NULL);
15794     if (ctxt == NULL)
15795         return (NULL);
15796     xmlInitParser();
15797
15798     xmlCtxtReset(ctxt);
15799
15800     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15801                                          XML_CHAR_ENCODING_NONE);
15802     if (input == NULL) {
15803         if (ioclose != NULL)
15804             ioclose(ioctx);
15805         return (NULL);
15806     }
15807     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15808     if (stream == NULL) {
15809         xmlFreeParserInputBuffer(input);
15810         return (NULL);
15811     }
15812     inputPush(ctxt, stream);
15813     return (xmlDoRead(ctxt, URL, encoding, options, 1));
15814 }
15815
15816 #define bottom_parser
15817 #include "elfgcchack.h"