Imported Upstream version 2.9.6_rc1
[platform/upstream/libxml2.git] / SAX2.c
1 /*
2  * SAX2.c : Default SAX2 handler to build a tree.
3  *
4  * See Copyright for the status of this software.
5  *
6  * Daniel Veillard <daniel@veillard.com>
7  */
8
9
10 #define IN_LIBXML
11 #include "libxml.h"
12 #include <stdlib.h>
13 #include <string.h>
14 #include <limits.h>
15 #include <libxml/xmlmemory.h>
16 #include <libxml/tree.h>
17 #include <libxml/parser.h>
18 #include <libxml/parserInternals.h>
19 #include <libxml/valid.h>
20 #include <libxml/entities.h>
21 #include <libxml/xmlerror.h>
22 #include <libxml/debugXML.h>
23 #include <libxml/xmlIO.h>
24 #include <libxml/SAX.h>
25 #include <libxml/uri.h>
26 #include <libxml/valid.h>
27 #include <libxml/HTMLtree.h>
28 #include <libxml/globals.h>
29
30 /* Define SIZE_T_MAX unless defined through <limits.h>. */
31 #ifndef SIZE_T_MAX
32 # define SIZE_T_MAX     ((size_t)-1)
33 #endif /* !SIZE_T_MAX */
34
35 /* #define DEBUG_SAX2 */
36 /* #define DEBUG_SAX2_TREE */
37
38 /**
39  * TODO:
40  *
41  * macro to flag unimplemented blocks
42  * XML_CATALOG_PREFER user env to select between system/public prefered
43  * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
44  *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
45  *> values "system" and "public".  I have made the default be "system" to
46  *> match yours.
47  */
48 #define TODO                                                            \
49     xmlGenericError(xmlGenericErrorContext,                             \
50             "Unimplemented block at %s:%d\n",                           \
51             __FILE__, __LINE__);
52
53 /*
54  * xmlSAX2ErrMemory:
55  * @ctxt:  an XML validation parser context
56  * @msg:   a string to accompany the error message
57  */
58 static void LIBXML_ATTR_FORMAT(2,0)
59 xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
60     xmlStructuredErrorFunc schannel = NULL;
61     const char *str1 = "out of memory\n";
62
63     if (ctxt != NULL) {
64         ctxt->errNo = XML_ERR_NO_MEMORY;
65         if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
66             schannel = ctxt->sax->serror;
67         __xmlRaiseError(schannel,
68                         ctxt->vctxt.error, ctxt->vctxt.userData,
69                         ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
70                         XML_ERR_ERROR, NULL, 0, (const char *) str1,
71                         NULL, NULL, 0, 0,
72                         msg, (const char *) str1, NULL);
73         ctxt->errNo = XML_ERR_NO_MEMORY;
74         ctxt->instate = XML_PARSER_EOF;
75         ctxt->disableSAX = 1;
76     } else {
77         __xmlRaiseError(schannel,
78                         NULL, NULL,
79                         ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
80                         XML_ERR_ERROR, NULL, 0, (const char *) str1,
81                         NULL, NULL, 0, 0,
82                         msg, (const char *) str1, NULL);
83     }
84 }
85
86 /**
87  * xmlValidError:
88  * @ctxt:  an XML validation parser context
89  * @error:  the error number
90  * @msg:  the error message
91  * @str1:  extra data
92  * @str2:  extra data
93  *
94  * Handle a validation error
95  */
96 static void LIBXML_ATTR_FORMAT(3,0)
97 xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
98             const char *msg, const char *str1, const char *str2)
99 {
100     xmlStructuredErrorFunc schannel = NULL;
101
102     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
103         (ctxt->instate == XML_PARSER_EOF))
104         return;
105     if (ctxt != NULL) {
106         ctxt->errNo = error;
107         if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
108             schannel = ctxt->sax->serror;
109         __xmlRaiseError(schannel,
110                         ctxt->vctxt.error, ctxt->vctxt.userData,
111                         ctxt, NULL, XML_FROM_DTD, error,
112                         XML_ERR_ERROR, NULL, 0, (const char *) str1,
113                         (const char *) str2, NULL, 0, 0,
114                         msg, (const char *) str1, (const char *) str2);
115         ctxt->valid = 0;
116     } else {
117         __xmlRaiseError(schannel,
118                         NULL, NULL,
119                         ctxt, NULL, XML_FROM_DTD, error,
120                         XML_ERR_ERROR, NULL, 0, (const char *) str1,
121                         (const char *) str2, NULL, 0, 0,
122                         msg, (const char *) str1, (const char *) str2);
123     }
124 }
125
126 /**
127  * xmlFatalErrMsg:
128  * @ctxt:  an XML parser context
129  * @error:  the error number
130  * @msg:  the error message
131  * @str1:  an error string
132  * @str2:  an error string
133  *
134  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
135  */
136 static void LIBXML_ATTR_FORMAT(3,0)
137 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
138                const char *msg, const xmlChar *str1, const xmlChar *str2)
139 {
140     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
141         (ctxt->instate == XML_PARSER_EOF))
142         return;
143     if (ctxt != NULL)
144         ctxt->errNo = error;
145     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
146                     XML_ERR_FATAL, NULL, 0,
147                     (const char *) str1, (const char *) str2,
148                     NULL, 0, 0, msg, str1, str2);
149     if (ctxt != NULL) {
150         ctxt->wellFormed = 0;
151         ctxt->valid = 0;
152         if (ctxt->recovery == 0)
153             ctxt->disableSAX = 1;
154     }
155 }
156
157 /**
158  * xmlWarnMsg:
159  * @ctxt:  an XML parser context
160  * @error:  the error number
161  * @msg:  the error message
162  * @str1:  an error string
163  * @str2:  an error string
164  *
165  * Handle a parser warning
166  */
167 static void LIBXML_ATTR_FORMAT(3,0)
168 xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
169                const char *msg, const xmlChar *str1)
170 {
171     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
172         (ctxt->instate == XML_PARSER_EOF))
173         return;
174     if (ctxt != NULL)
175         ctxt->errNo = error;
176     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
177                     XML_ERR_WARNING, NULL, 0,
178                     (const char *) str1, NULL,
179                     NULL, 0, 0, msg, str1);
180 }
181
182 /**
183  * xmlNsErrMsg:
184  * @ctxt:  an XML parser context
185  * @error:  the error number
186  * @msg:  the error message
187  * @str1:  an error string
188  * @str2:  an error string
189  *
190  * Handle a namespace error
191  */
192 static void LIBXML_ATTR_FORMAT(3,0)
193 xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
194             const char *msg, const xmlChar *str1, const xmlChar *str2)
195 {
196     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
197         (ctxt->instate == XML_PARSER_EOF))
198         return;
199     if (ctxt != NULL)
200         ctxt->errNo = error;
201     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
202                     XML_ERR_ERROR, NULL, 0,
203                     (const char *) str1, (const char *) str2,
204                     NULL, 0, 0, msg, str1, str2);
205 }
206
207 /**
208  * xmlNsWarnMsg:
209  * @ctxt:  an XML parser context
210  * @error:  the error number
211  * @msg:  the error message
212  * @str1:  an error string
213  *
214  * Handle a namespace warning
215  */
216 static void LIBXML_ATTR_FORMAT(3,0)
217 xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
218              const char *msg, const xmlChar *str1, const xmlChar *str2)
219 {
220     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
221         (ctxt->instate == XML_PARSER_EOF))
222         return;
223     if (ctxt != NULL)
224         ctxt->errNo = error;
225     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
226                     XML_ERR_WARNING, NULL, 0,
227                     (const char *) str1, (const char *) str2,
228                     NULL, 0, 0, msg, str1, str2);
229 }
230
231 /**
232  * xmlSAX2GetPublicId:
233  * @ctx: the user data (XML parser context)
234  *
235  * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
236  *
237  * Returns a xmlChar *
238  */
239 const xmlChar *
240 xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED)
241 {
242     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
243     return(NULL);
244 }
245
246 /**
247  * xmlSAX2GetSystemId:
248  * @ctx: the user data (XML parser context)
249  *
250  * Provides the system ID, basically URL or filename e.g.
251  * http://www.sgmlsource.com/dtds/memo.dtd
252  *
253  * Returns a xmlChar *
254  */
255 const xmlChar *
256 xmlSAX2GetSystemId(void *ctx)
257 {
258     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
259     if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL);
260     return((const xmlChar *) ctxt->input->filename);
261 }
262
263 /**
264  * xmlSAX2GetLineNumber:
265  * @ctx: the user data (XML parser context)
266  *
267  * Provide the line number of the current parsing point.
268  *
269  * Returns an int
270  */
271 int
272 xmlSAX2GetLineNumber(void *ctx)
273 {
274     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
275     if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
276     return(ctxt->input->line);
277 }
278
279 /**
280  * xmlSAX2GetColumnNumber:
281  * @ctx: the user data (XML parser context)
282  *
283  * Provide the column number of the current parsing point.
284  *
285  * Returns an int
286  */
287 int
288 xmlSAX2GetColumnNumber(void *ctx)
289 {
290     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
291     if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
292     return(ctxt->input->col);
293 }
294
295 /**
296  * xmlSAX2IsStandalone:
297  * @ctx: the user data (XML parser context)
298  *
299  * Is this document tagged standalone ?
300  *
301  * Returns 1 if true
302  */
303 int
304 xmlSAX2IsStandalone(void *ctx)
305 {
306     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
307     if ((ctx == NULL) || (ctxt->myDoc == NULL)) return(0);
308     return(ctxt->myDoc->standalone == 1);
309 }
310
311 /**
312  * xmlSAX2HasInternalSubset:
313  * @ctx: the user data (XML parser context)
314  *
315  * Does this document has an internal subset
316  *
317  * Returns 1 if true
318  */
319 int
320 xmlSAX2HasInternalSubset(void *ctx)
321 {
322     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
323     if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
324     return(ctxt->myDoc->intSubset != NULL);
325 }
326
327 /**
328  * xmlSAX2HasExternalSubset:
329  * @ctx: the user data (XML parser context)
330  *
331  * Does this document has an external subset
332  *
333  * Returns 1 if true
334  */
335 int
336 xmlSAX2HasExternalSubset(void *ctx)
337 {
338     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
339     if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
340     return(ctxt->myDoc->extSubset != NULL);
341 }
342
343 /**
344  * xmlSAX2InternalSubset:
345  * @ctx:  the user data (XML parser context)
346  * @name:  the root element name
347  * @ExternalID:  the external ID
348  * @SystemID:  the SYSTEM ID (e.g. filename or URL)
349  *
350  * Callback on internal subset declaration.
351  */
352 void
353 xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
354                const xmlChar *ExternalID, const xmlChar *SystemID)
355 {
356     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
357     xmlDtdPtr dtd;
358     if (ctx == NULL) return;
359 #ifdef DEBUG_SAX
360     xmlGenericError(xmlGenericErrorContext,
361             "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
362             name, ExternalID, SystemID);
363 #endif
364
365     if (ctxt->myDoc == NULL)
366         return;
367     dtd = xmlGetIntSubset(ctxt->myDoc);
368     if (dtd != NULL) {
369         if (ctxt->html)
370             return;
371         xmlUnlinkNode((xmlNodePtr) dtd);
372         xmlFreeDtd(dtd);
373         ctxt->myDoc->intSubset = NULL;
374     }
375     ctxt->myDoc->intSubset =
376         xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
377     if (ctxt->myDoc->intSubset == NULL)
378         xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset");
379 }
380
381 /**
382  * xmlSAX2ExternalSubset:
383  * @ctx: the user data (XML parser context)
384  * @name:  the root element name
385  * @ExternalID:  the external ID
386  * @SystemID:  the SYSTEM ID (e.g. filename or URL)
387  *
388  * Callback on external subset declaration.
389  */
390 void
391 xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
392                const xmlChar *ExternalID, const xmlChar *SystemID)
393 {
394     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
395     if (ctx == NULL) return;
396 #ifdef DEBUG_SAX
397     xmlGenericError(xmlGenericErrorContext,
398             "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
399             name, ExternalID, SystemID);
400 #endif
401     if (((ExternalID != NULL) || (SystemID != NULL)) &&
402         (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
403          (ctxt->wellFormed && ctxt->myDoc))) {
404         /*
405          * Try to fetch and parse the external subset.
406          */
407         xmlParserInputPtr oldinput;
408         int oldinputNr;
409         int oldinputMax;
410         xmlParserInputPtr *oldinputTab;
411         xmlParserInputPtr input = NULL;
412         xmlCharEncoding enc;
413         int oldcharset;
414         const xmlChar *oldencoding;
415
416         /*
417          * Ask the Entity resolver to load the damn thing
418          */
419         if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
420             input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
421                                                 SystemID);
422         if (input == NULL) {
423             return;
424         }
425
426         xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
427
428         /*
429          * make sure we won't destroy the main document context
430          */
431         oldinput = ctxt->input;
432         oldinputNr = ctxt->inputNr;
433         oldinputMax = ctxt->inputMax;
434         oldinputTab = ctxt->inputTab;
435         oldcharset = ctxt->charset;
436         oldencoding = ctxt->encoding;
437         ctxt->encoding = NULL;
438
439         ctxt->inputTab = (xmlParserInputPtr *)
440                          xmlMalloc(5 * sizeof(xmlParserInputPtr));
441         if (ctxt->inputTab == NULL) {
442             xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset");
443             ctxt->input = oldinput;
444             ctxt->inputNr = oldinputNr;
445             ctxt->inputMax = oldinputMax;
446             ctxt->inputTab = oldinputTab;
447             ctxt->charset = oldcharset;
448             ctxt->encoding = oldencoding;
449             return;
450         }
451         ctxt->inputNr = 0;
452         ctxt->inputMax = 5;
453         ctxt->input = NULL;
454         xmlPushInput(ctxt, input);
455
456         /*
457          * On the fly encoding conversion if needed
458          */
459         if (ctxt->input->length >= 4) {
460             enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
461             xmlSwitchEncoding(ctxt, enc);
462         }
463
464         if (input->filename == NULL)
465             input->filename = (char *) xmlCanonicPath(SystemID);
466         input->line = 1;
467         input->col = 1;
468         input->base = ctxt->input->cur;
469         input->cur = ctxt->input->cur;
470         input->free = NULL;
471
472         /*
473          * let's parse that entity knowing it's an external subset.
474          */
475         xmlParseExternalSubset(ctxt, ExternalID, SystemID);
476
477         /*
478          * Free up the external entities
479          */
480
481         while (ctxt->inputNr > 1)
482             xmlPopInput(ctxt);
483         xmlFreeInputStream(ctxt->input);
484         xmlFree(ctxt->inputTab);
485
486         /*
487          * Restore the parsing context of the main entity
488          */
489         ctxt->input = oldinput;
490         ctxt->inputNr = oldinputNr;
491         ctxt->inputMax = oldinputMax;
492         ctxt->inputTab = oldinputTab;
493         ctxt->charset = oldcharset;
494         if ((ctxt->encoding != NULL) &&
495             ((ctxt->dict == NULL) ||
496              (!xmlDictOwns(ctxt->dict, ctxt->encoding))))
497             xmlFree((xmlChar *) ctxt->encoding);
498         ctxt->encoding = oldencoding;
499         /* ctxt->wellFormed = oldwellFormed; */
500     }
501 }
502
503 /**
504  * xmlSAX2ResolveEntity:
505  * @ctx: the user data (XML parser context)
506  * @publicId: The public ID of the entity
507  * @systemId: The system ID of the entity
508  *
509  * The entity loader, to control the loading of external entities,
510  * the application can either:
511  *    - override this xmlSAX2ResolveEntity() callback in the SAX block
512  *    - or better use the xmlSetExternalEntityLoader() function to
513  *      set up it's own entity resolution routine
514  *
515  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
516  */
517 xmlParserInputPtr
518 xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
519 {
520     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
521     xmlParserInputPtr ret;
522     xmlChar *URI;
523     const char *base = NULL;
524
525     if (ctx == NULL) return(NULL);
526     if (ctxt->input != NULL)
527         base = ctxt->input->filename;
528     if (base == NULL)
529         base = ctxt->directory;
530
531     URI = xmlBuildURI(systemId, (const xmlChar *) base);
532
533 #ifdef DEBUG_SAX
534     xmlGenericError(xmlGenericErrorContext,
535             "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId);
536 #endif
537
538     ret = xmlLoadExternalEntity((const char *) URI,
539                                 (const char *) publicId, ctxt);
540     if (URI != NULL)
541         xmlFree(URI);
542     return(ret);
543 }
544
545 /**
546  * xmlSAX2GetEntity:
547  * @ctx: the user data (XML parser context)
548  * @name: The entity name
549  *
550  * Get an entity by name
551  *
552  * Returns the xmlEntityPtr if found.
553  */
554 xmlEntityPtr
555 xmlSAX2GetEntity(void *ctx, const xmlChar *name)
556 {
557     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
558     xmlEntityPtr ret = NULL;
559
560     if (ctx == NULL) return(NULL);
561 #ifdef DEBUG_SAX
562     xmlGenericError(xmlGenericErrorContext,
563             "SAX.xmlSAX2GetEntity(%s)\n", name);
564 #endif
565
566     if (ctxt->inSubset == 0) {
567         ret = xmlGetPredefinedEntity(name);
568         if (ret != NULL)
569             return(ret);
570     }
571     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
572         if (ctxt->inSubset == 2) {
573             ctxt->myDoc->standalone = 0;
574             ret = xmlGetDocEntity(ctxt->myDoc, name);
575             ctxt->myDoc->standalone = 1;
576         } else {
577             ret = xmlGetDocEntity(ctxt->myDoc, name);
578             if (ret == NULL) {
579                 ctxt->myDoc->standalone = 0;
580                 ret = xmlGetDocEntity(ctxt->myDoc, name);
581                 if (ret != NULL) {
582                     xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE,
583          "Entity(%s) document marked standalone but requires external subset\n",
584                                    name, NULL);
585                 }
586                 ctxt->myDoc->standalone = 1;
587             }
588         }
589     } else {
590         ret = xmlGetDocEntity(ctxt->myDoc, name);
591     }
592     if ((ret != NULL) &&
593         ((ctxt->validate) || (ctxt->replaceEntities)) &&
594         (ret->children == NULL) &&
595         (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
596         int val;
597
598         /*
599          * for validation purposes we really need to fetch and
600          * parse the external entity
601          */
602         xmlNodePtr children;
603         unsigned long oldnbent = ctxt->nbentities;
604
605         val = xmlParseCtxtExternalEntity(ctxt, ret->URI,
606                                          ret->ExternalID, &children);
607         if (val == 0) {
608             xmlAddChildList((xmlNodePtr) ret, children);
609         } else {
610             xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
611                            "Failure to process entity %s\n", name, NULL);
612             ctxt->validate = 0;
613             return(NULL);
614         }
615         ret->owner = 1;
616         if (ret->checked == 0) {
617             ret->checked = (ctxt->nbentities - oldnbent + 1) * 2;
618             if ((ret->content != NULL) && (xmlStrchr(ret->content, '<')))
619                 ret->checked |= 1;
620         }
621     }
622     return(ret);
623 }
624
625 /**
626  * xmlSAX2GetParameterEntity:
627  * @ctx: the user data (XML parser context)
628  * @name: The entity name
629  *
630  * Get a parameter entity by name
631  *
632  * Returns the xmlEntityPtr if found.
633  */
634 xmlEntityPtr
635 xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
636 {
637     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
638     xmlEntityPtr ret;
639
640     if (ctx == NULL) return(NULL);
641 #ifdef DEBUG_SAX
642     xmlGenericError(xmlGenericErrorContext,
643             "SAX.xmlSAX2GetParameterEntity(%s)\n", name);
644 #endif
645
646     ret = xmlGetParameterEntity(ctxt->myDoc, name);
647     return(ret);
648 }
649
650
651 /**
652  * xmlSAX2EntityDecl:
653  * @ctx: the user data (XML parser context)
654  * @name:  the entity name
655  * @type:  the entity type
656  * @publicId: The public ID of the entity
657  * @systemId: The system ID of the entity
658  * @content: the entity value (without processing).
659  *
660  * An entity definition has been parsed
661  */
662 void
663 xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
664           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
665 {
666     xmlEntityPtr ent;
667     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
668
669     if (ctx == NULL) return;
670 #ifdef DEBUG_SAX
671     xmlGenericError(xmlGenericErrorContext,
672             "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
673             name, type, publicId, systemId, content);
674 #endif
675     if (ctxt->inSubset == 1) {
676         ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
677                               systemId, content);
678         if ((ent == NULL) && (ctxt->pedantic))
679             xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED,
680              "Entity(%s) already defined in the internal subset\n",
681                        name);
682         if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
683             xmlChar *URI;
684             const char *base = NULL;
685
686             if (ctxt->input != NULL)
687                 base = ctxt->input->filename;
688             if (base == NULL)
689                 base = ctxt->directory;
690
691             URI = xmlBuildURI(systemId, (const xmlChar *) base);
692             ent->URI = URI;
693         }
694     } else if (ctxt->inSubset == 2) {
695         ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
696                               systemId, content);
697         if ((ent == NULL) && (ctxt->pedantic) &&
698             (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
699             ctxt->sax->warning(ctxt->userData,
700              "Entity(%s) already defined in the external subset\n", name);
701         if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
702             xmlChar *URI;
703             const char *base = NULL;
704
705             if (ctxt->input != NULL)
706                 base = ctxt->input->filename;
707             if (base == NULL)
708                 base = ctxt->directory;
709
710             URI = xmlBuildURI(systemId, (const xmlChar *) base);
711             ent->URI = URI;
712         }
713     } else {
714         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
715                        "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
716                        name, NULL);
717     }
718 }
719
720 /**
721  * xmlSAX2AttributeDecl:
722  * @ctx: the user data (XML parser context)
723  * @elem:  the name of the element
724  * @fullname:  the attribute name
725  * @type:  the attribute type
726  * @def:  the type of default value
727  * @defaultValue: the attribute default value
728  * @tree:  the tree of enumerated value set
729  *
730  * An attribute definition has been parsed
731  */
732 void
733 xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
734               int type, int def, const xmlChar *defaultValue,
735               xmlEnumerationPtr tree)
736 {
737     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
738     xmlAttributePtr attr;
739     xmlChar *name = NULL, *prefix = NULL;
740
741     if ((ctxt == NULL) || (ctxt->myDoc == NULL))
742         return;
743
744 #ifdef DEBUG_SAX
745     xmlGenericError(xmlGenericErrorContext,
746             "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
747             elem, fullname, type, def, defaultValue);
748 #endif
749     if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
750         (type != XML_ATTRIBUTE_ID)) {
751         /*
752          * Raise the error but keep the validity flag
753          */
754         int tmp = ctxt->valid;
755         xmlErrValid(ctxt, XML_DTD_XMLID_TYPE,
756               "xml:id : attribute type should be ID\n", NULL, NULL);
757         ctxt->valid = tmp;
758     }
759     /* TODO: optimize name/prefix allocation */
760     name = xmlSplitQName(ctxt, fullname, &prefix);
761     ctxt->vctxt.valid = 1;
762     if (ctxt->inSubset == 1)
763         attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
764                name, prefix, (xmlAttributeType) type,
765                (xmlAttributeDefault) def, defaultValue, tree);
766     else if (ctxt->inSubset == 2)
767         attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
768            name, prefix, (xmlAttributeType) type,
769            (xmlAttributeDefault) def, defaultValue, tree);
770     else {
771         xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
772              "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
773                        name, NULL);
774         xmlFreeEnumeration(tree);
775         return;
776     }
777 #ifdef LIBXML_VALID_ENABLED
778     if (ctxt->vctxt.valid == 0)
779         ctxt->valid = 0;
780     if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
781         (ctxt->myDoc->intSubset != NULL))
782         ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
783                                                 attr);
784 #endif /* LIBXML_VALID_ENABLED */
785     if (prefix != NULL)
786         xmlFree(prefix);
787     if (name != NULL)
788         xmlFree(name);
789 }
790
791 /**
792  * xmlSAX2ElementDecl:
793  * @ctx: the user data (XML parser context)
794  * @name:  the element name
795  * @type:  the element type
796  * @content: the element value tree
797  *
798  * An element definition has been parsed
799  */
800 void
801 xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
802             xmlElementContentPtr content)
803 {
804     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
805     xmlElementPtr elem = NULL;
806
807     if ((ctxt == NULL) || (ctxt->myDoc == NULL))
808         return;
809
810 #ifdef DEBUG_SAX
811     xmlGenericError(xmlGenericErrorContext,
812                     "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type);
813 #endif
814
815     if (ctxt->inSubset == 1)
816         elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
817                                  name, (xmlElementTypeVal) type, content);
818     else if (ctxt->inSubset == 2)
819         elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
820                                  name, (xmlElementTypeVal) type, content);
821     else {
822         xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
823              "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
824                        name, NULL);
825         return;
826     }
827 #ifdef LIBXML_VALID_ENABLED
828     if (elem == NULL)
829         ctxt->valid = 0;
830     if (ctxt->validate && ctxt->wellFormed &&
831         ctxt->myDoc && ctxt->myDoc->intSubset)
832         ctxt->valid &=
833             xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
834 #endif /* LIBXML_VALID_ENABLED */
835 }
836
837 /**
838  * xmlSAX2NotationDecl:
839  * @ctx: the user data (XML parser context)
840  * @name: The name of the notation
841  * @publicId: The public ID of the entity
842  * @systemId: The system ID of the entity
843  *
844  * What to do when a notation declaration has been parsed.
845  */
846 void
847 xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
848              const xmlChar *publicId, const xmlChar *systemId)
849 {
850     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
851     xmlNotationPtr nota = NULL;
852
853     if ((ctxt == NULL) || (ctxt->myDoc == NULL))
854         return;
855
856 #ifdef DEBUG_SAX
857     xmlGenericError(xmlGenericErrorContext,
858             "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId);
859 #endif
860
861     if ((publicId == NULL) && (systemId == NULL)) {
862         xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
863              "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
864                        name, NULL);
865         return;
866     } else if (ctxt->inSubset == 1)
867         nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
868                               publicId, systemId);
869     else if (ctxt->inSubset == 2)
870         nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
871                               publicId, systemId);
872     else {
873         xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
874              "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
875                        name, NULL);
876         return;
877     }
878 #ifdef LIBXML_VALID_ENABLED
879     if (nota == NULL) ctxt->valid = 0;
880     if ((ctxt->validate) && (ctxt->wellFormed) &&
881         (ctxt->myDoc->intSubset != NULL))
882         ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
883                                                nota);
884 #endif /* LIBXML_VALID_ENABLED */
885 }
886
887 /**
888  * xmlSAX2UnparsedEntityDecl:
889  * @ctx: the user data (XML parser context)
890  * @name: The name of the entity
891  * @publicId: The public ID of the entity
892  * @systemId: The system ID of the entity
893  * @notationName: the name of the notation
894  *
895  * What to do when an unparsed entity declaration is parsed
896  */
897 void
898 xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
899                    const xmlChar *publicId, const xmlChar *systemId,
900                    const xmlChar *notationName)
901 {
902     xmlEntityPtr ent;
903     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
904     if (ctx == NULL) return;
905 #ifdef DEBUG_SAX
906     xmlGenericError(xmlGenericErrorContext,
907             "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
908             name, publicId, systemId, notationName);
909 #endif
910     if (ctxt->inSubset == 1) {
911         ent = xmlAddDocEntity(ctxt->myDoc, name,
912                         XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
913                         publicId, systemId, notationName);
914         if ((ent == NULL) && (ctxt->pedantic) &&
915             (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
916             ctxt->sax->warning(ctxt->userData,
917              "Entity(%s) already defined in the internal subset\n", name);
918         if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
919             xmlChar *URI;
920             const char *base = NULL;
921
922             if (ctxt->input != NULL)
923                 base = ctxt->input->filename;
924             if (base == NULL)
925                 base = ctxt->directory;
926
927             URI = xmlBuildURI(systemId, (const xmlChar *) base);
928             ent->URI = URI;
929         }
930     } else if (ctxt->inSubset == 2) {
931         ent = xmlAddDtdEntity(ctxt->myDoc, name,
932                         XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
933                         publicId, systemId, notationName);
934         if ((ent == NULL) && (ctxt->pedantic) &&
935             (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
936             ctxt->sax->warning(ctxt->userData,
937              "Entity(%s) already defined in the external subset\n", name);
938         if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
939             xmlChar *URI;
940             const char *base = NULL;
941
942             if (ctxt->input != NULL)
943                 base = ctxt->input->filename;
944             if (base == NULL)
945                 base = ctxt->directory;
946
947             URI = xmlBuildURI(systemId, (const xmlChar *) base);
948             ent->URI = URI;
949         }
950     } else {
951         xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
952              "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
953                        name, NULL);
954     }
955 }
956
957 /**
958  * xmlSAX2SetDocumentLocator:
959  * @ctx: the user data (XML parser context)
960  * @loc: A SAX Locator
961  *
962  * Receive the document locator at startup, actually xmlDefaultSAXLocator
963  * Everything is available on the context, so this is useless in our case.
964  */
965 void
966 xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
967 {
968     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
969 #ifdef DEBUG_SAX
970     xmlGenericError(xmlGenericErrorContext,
971             "SAX.xmlSAX2SetDocumentLocator()\n");
972 #endif
973 }
974
975 /**
976  * xmlSAX2StartDocument:
977  * @ctx: the user data (XML parser context)
978  *
979  * called when the document start being processed.
980  */
981 void
982 xmlSAX2StartDocument(void *ctx)
983 {
984     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
985     xmlDocPtr doc;
986
987     if (ctx == NULL) return;
988
989 #ifdef DEBUG_SAX
990     xmlGenericError(xmlGenericErrorContext,
991             "SAX.xmlSAX2StartDocument()\n");
992 #endif
993     if (ctxt->html) {
994 #ifdef LIBXML_HTML_ENABLED
995         if (ctxt->myDoc == NULL)
996             ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
997         if (ctxt->myDoc == NULL) {
998             xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
999             return;
1000         }
1001         ctxt->myDoc->properties = XML_DOC_HTML;
1002         ctxt->myDoc->parseFlags = ctxt->options;
1003 #else
1004         xmlGenericError(xmlGenericErrorContext,
1005                 "libxml2 built without HTML support\n");
1006         ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1007         ctxt->instate = XML_PARSER_EOF;
1008         ctxt->disableSAX = 1;
1009         return;
1010 #endif
1011     } else {
1012         doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
1013         if (doc != NULL) {
1014             doc->properties = 0;
1015             if (ctxt->options & XML_PARSE_OLD10)
1016                 doc->properties |= XML_DOC_OLD10;
1017             doc->parseFlags = ctxt->options;
1018             if (ctxt->encoding != NULL)
1019                 doc->encoding = xmlStrdup(ctxt->encoding);
1020             else
1021                 doc->encoding = NULL;
1022             doc->standalone = ctxt->standalone;
1023         } else {
1024             xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
1025             return;
1026         }
1027         if ((ctxt->dictNames) && (doc != NULL)) {
1028             doc->dict = ctxt->dict;
1029             xmlDictReference(doc->dict);
1030         }
1031     }
1032     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
1033         (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
1034         ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename);
1035         if (ctxt->myDoc->URL == NULL)
1036             xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
1037     }
1038 }
1039
1040 /**
1041  * xmlSAX2EndDocument:
1042  * @ctx: the user data (XML parser context)
1043  *
1044  * called when the document end has been detected.
1045  */
1046 void
1047 xmlSAX2EndDocument(void *ctx)
1048 {
1049     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1050 #ifdef DEBUG_SAX
1051     xmlGenericError(xmlGenericErrorContext,
1052             "SAX.xmlSAX2EndDocument()\n");
1053 #endif
1054     if (ctx == NULL) return;
1055 #ifdef LIBXML_VALID_ENABLED
1056     if (ctxt->validate && ctxt->wellFormed &&
1057         ctxt->myDoc && ctxt->myDoc->intSubset)
1058         ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
1059 #endif /* LIBXML_VALID_ENABLED */
1060
1061     /*
1062      * Grab the encoding if it was added on-the-fly
1063      */
1064     if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
1065         (ctxt->myDoc->encoding == NULL)) {
1066         ctxt->myDoc->encoding = ctxt->encoding;
1067         ctxt->encoding = NULL;
1068     }
1069     if ((ctxt->inputTab != NULL) &&
1070         (ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) &&
1071         (ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
1072         (ctxt->myDoc->encoding == NULL)) {
1073         ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
1074     }
1075     if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
1076         (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
1077         ctxt->myDoc->charset = ctxt->charset;
1078     }
1079 }
1080
1081 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
1082 /**
1083  * xmlSAX2AttributeInternal:
1084  * @ctx: the user data (XML parser context)
1085  * @fullname:  The attribute name, including namespace prefix
1086  * @value:  The attribute value
1087  * @prefix: the prefix on the element node
1088  *
1089  * Handle an attribute that has been read by the parser.
1090  * The default handling is to convert the attribute into an
1091  * DOM subtree and past it in a new xmlAttr element added to
1092  * the element.
1093  */
1094 static void
1095 xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
1096              const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED)
1097 {
1098     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1099     xmlAttrPtr ret;
1100     xmlChar *name;
1101     xmlChar *ns;
1102     xmlChar *nval;
1103     xmlNsPtr namespace;
1104
1105     if (ctxt->html) {
1106         name = xmlStrdup(fullname);
1107         ns = NULL;
1108         namespace = NULL;
1109     } else {
1110         /*
1111          * Split the full name into a namespace prefix and the tag name
1112          */
1113         name = xmlSplitQName(ctxt, fullname, &ns);
1114         if ((name != NULL) && (name[0] == 0)) {
1115             if (xmlStrEqual(ns, BAD_CAST "xmlns")) {
1116                 xmlNsErrMsg(ctxt, XML_ERR_NS_DECL_ERROR,
1117                             "invalid namespace declaration '%s'\n",
1118                             fullname, NULL);
1119             } else {
1120                 xmlNsWarnMsg(ctxt, XML_WAR_NS_COLUMN,
1121                              "Avoid attribute ending with ':' like '%s'\n",
1122                              fullname, NULL);
1123             }
1124             if (ns != NULL)
1125                 xmlFree(ns);
1126             ns = NULL;
1127             xmlFree(name);
1128             name = xmlStrdup(fullname);
1129         }
1130     }
1131     if (name == NULL) {
1132         xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1133         if (ns != NULL)
1134             xmlFree(ns);
1135         return;
1136     }
1137
1138 #ifdef LIBXML_HTML_ENABLED
1139     if ((ctxt->html) &&
1140         (value == NULL) && (htmlIsBooleanAttr(fullname))) {
1141             nval = xmlStrdup(fullname);
1142             value = (const xmlChar *) nval;
1143     } else
1144 #endif
1145     {
1146 #ifdef LIBXML_VALID_ENABLED
1147         /*
1148          * Do the last stage of the attribute normalization
1149          * Needed for HTML too:
1150          *   http://www.w3.org/TR/html4/types.html#h-6.2
1151          */
1152         ctxt->vctxt.valid = 1;
1153         nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
1154                                                ctxt->myDoc, ctxt->node,
1155                                                fullname, value);
1156         if (ctxt->vctxt.valid != 1) {
1157             ctxt->valid = 0;
1158         }
1159         if (nval != NULL)
1160             value = nval;
1161 #else
1162         nval = NULL;
1163 #endif /* LIBXML_VALID_ENABLED */
1164     }
1165
1166     /*
1167      * Check whether it's a namespace definition
1168      */
1169     if ((!ctxt->html) && (ns == NULL) &&
1170         (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
1171         (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
1172         xmlNsPtr nsret;
1173         xmlChar *val;
1174
1175         if (!ctxt->replaceEntities) {
1176             ctxt->depth++;
1177             val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1178                                           0,0,0);
1179             ctxt->depth--;
1180             if (val == NULL) {
1181                 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1182                 if (name != NULL)
1183                     xmlFree(name);
1184                 if (nval != NULL)
1185                     xmlFree(nval);
1186                 return;
1187             }
1188         } else {
1189             val = (xmlChar *) value;
1190         }
1191
1192         if (val[0] != 0) {
1193             xmlURIPtr uri;
1194
1195             uri = xmlParseURI((const char *)val);
1196             if (uri == NULL) {
1197                 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1198                     ctxt->sax->warning(ctxt->userData,
1199                          "xmlns: %s not a valid URI\n", val);
1200             } else {
1201                 if (uri->scheme == NULL) {
1202                     if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1203                         ctxt->sax->warning(ctxt->userData,
1204                              "xmlns: URI %s is not absolute\n", val);
1205                 }
1206                 xmlFreeURI(uri);
1207             }
1208         }
1209
1210         /* a default namespace definition */
1211         nsret = xmlNewNs(ctxt->node, val, NULL);
1212
1213 #ifdef LIBXML_VALID_ENABLED
1214         /*
1215          * Validate also for namespace decls, they are attributes from
1216          * an XML-1.0 perspective
1217          */
1218         if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
1219             ctxt->myDoc && ctxt->myDoc->intSubset)
1220             ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1221                                            ctxt->node, prefix, nsret, val);
1222 #endif /* LIBXML_VALID_ENABLED */
1223         if (name != NULL)
1224             xmlFree(name);
1225         if (nval != NULL)
1226             xmlFree(nval);
1227         if (val != value)
1228             xmlFree(val);
1229         return;
1230     }
1231     if ((!ctxt->html) &&
1232         (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
1233         (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
1234         xmlNsPtr nsret;
1235         xmlChar *val;
1236
1237         if (!ctxt->replaceEntities) {
1238             ctxt->depth++;
1239             val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1240                                           0,0,0);
1241             ctxt->depth--;
1242             if (val == NULL) {
1243                 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1244                 xmlFree(ns);
1245                 if (name != NULL)
1246                     xmlFree(name);
1247                 if (nval != NULL)
1248                     xmlFree(nval);
1249                 return;
1250             }
1251         } else {
1252             val = (xmlChar *) value;
1253         }
1254
1255         if (val[0] == 0) {
1256             xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY,
1257                         "Empty namespace name for prefix %s\n", name, NULL);
1258         }
1259         if ((ctxt->pedantic != 0) && (val[0] != 0)) {
1260             xmlURIPtr uri;
1261
1262             uri = xmlParseURI((const char *)val);
1263             if (uri == NULL) {
1264                 xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
1265                          "xmlns:%s: %s not a valid URI\n", name, value);
1266             } else {
1267                 if (uri->scheme == NULL) {
1268                     xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
1269                            "xmlns:%s: URI %s is not absolute\n", name, value);
1270                 }
1271                 xmlFreeURI(uri);
1272             }
1273         }
1274
1275         /* a standard namespace definition */
1276         nsret = xmlNewNs(ctxt->node, val, name);
1277         xmlFree(ns);
1278 #ifdef LIBXML_VALID_ENABLED
1279         /*
1280          * Validate also for namespace decls, they are attributes from
1281          * an XML-1.0 perspective
1282          */
1283         if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
1284             ctxt->myDoc && ctxt->myDoc->intSubset)
1285             ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1286                                            ctxt->node, prefix, nsret, value);
1287 #endif /* LIBXML_VALID_ENABLED */
1288         if (name != NULL)
1289             xmlFree(name);
1290         if (nval != NULL)
1291             xmlFree(nval);
1292         if (val != value)
1293             xmlFree(val);
1294         return;
1295     }
1296
1297     if (ns != NULL) {
1298         namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
1299
1300         if (namespace == NULL) {
1301             xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
1302                     "Namespace prefix %s of attribute %s is not defined\n",
1303                              ns, name);
1304         } else {
1305             xmlAttrPtr prop;
1306
1307             prop = ctxt->node->properties;
1308             while (prop != NULL) {
1309                 if (prop->ns != NULL) {
1310                     if ((xmlStrEqual(name, prop->name)) &&
1311                         ((namespace == prop->ns) ||
1312                          (xmlStrEqual(namespace->href, prop->ns->href)))) {
1313                             xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
1314                                     "Attribute %s in %s redefined\n",
1315                                              name, namespace->href);
1316                         ctxt->wellFormed = 0;
1317                         if (ctxt->recovery == 0) ctxt->disableSAX = 1;
1318                         if (name != NULL)
1319                             xmlFree(name);
1320                         goto error;
1321                     }
1322                 }
1323                 prop = prop->next;
1324             }
1325         }
1326     } else {
1327         namespace = NULL;
1328     }
1329
1330     /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
1331     ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
1332
1333     if (ret != NULL) {
1334         if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
1335             xmlNodePtr tmp;
1336
1337             ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
1338             tmp = ret->children;
1339             while (tmp != NULL) {
1340                 tmp->parent = (xmlNodePtr) ret;
1341                 if (tmp->next == NULL)
1342                     ret->last = tmp;
1343                 tmp = tmp->next;
1344             }
1345         } else if (value != NULL) {
1346             ret->children = xmlNewDocText(ctxt->myDoc, value);
1347             ret->last = ret->children;
1348             if (ret->children != NULL)
1349                 ret->children->parent = (xmlNodePtr) ret;
1350         }
1351     }
1352
1353 #ifdef LIBXML_VALID_ENABLED
1354     if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
1355         ctxt->myDoc && ctxt->myDoc->intSubset) {
1356
1357         /*
1358          * If we don't substitute entities, the validation should be
1359          * done on a value with replaced entities anyway.
1360          */
1361         if (!ctxt->replaceEntities) {
1362             xmlChar *val;
1363
1364             ctxt->depth++;
1365             val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1366                                           0,0,0);
1367             ctxt->depth--;
1368
1369             if (val == NULL)
1370                 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1371                                 ctxt->myDoc, ctxt->node, ret, value);
1372             else {
1373                 xmlChar *nvalnorm;
1374
1375                 /*
1376                  * Do the last stage of the attribute normalization
1377                  * It need to be done twice ... it's an extra burden related
1378                  * to the ability to keep xmlSAX2References in attributes
1379                  */
1380                 nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc,
1381                                             ctxt->node, fullname, val);
1382                 if (nvalnorm != NULL) {
1383                     xmlFree(val);
1384                     val = nvalnorm;
1385                 }
1386
1387                 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1388                                 ctxt->myDoc, ctxt->node, ret, val);
1389                 xmlFree(val);
1390             }
1391         } else {
1392             ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
1393                                                ctxt->node, ret, value);
1394         }
1395     } else
1396 #endif /* LIBXML_VALID_ENABLED */
1397            if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
1398                (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
1399                 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
1400         /*
1401          * when validating, the ID registration is done at the attribute
1402          * validation level. Otherwise we have to do specific handling here.
1403          */
1404         if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
1405             /*
1406              * Add the xml:id value
1407              *
1408              * Open issue: normalization of the value.
1409              */
1410             if (xmlValidateNCName(value, 1) != 0) {
1411                 xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
1412                       "xml:id : attribute value %s is not an NCName\n",
1413                             (const char *) value, NULL);
1414             }
1415             xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
1416         } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
1417             xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
1418         else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
1419             xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
1420     }
1421
1422 error:
1423     if (nval != NULL)
1424         xmlFree(nval);
1425     if (ns != NULL)
1426         xmlFree(ns);
1427 }
1428
1429 /*
1430  * xmlCheckDefaultedAttributes:
1431  *
1432  * Check defaulted attributes from the DTD
1433  */
1434 static void
1435 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
1436         const xmlChar *prefix, const xmlChar **atts) {
1437     xmlElementPtr elemDecl;
1438     const xmlChar *att;
1439     int internal = 1;
1440     int i;
1441
1442     elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
1443     if (elemDecl == NULL) {
1444         elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
1445         internal = 0;
1446     }
1447
1448 process_external_subset:
1449
1450     if (elemDecl != NULL) {
1451         xmlAttributePtr attr = elemDecl->attributes;
1452         /*
1453          * Check against defaulted attributes from the external subset
1454          * if the document is stamped as standalone
1455          */
1456         if ((ctxt->myDoc->standalone == 1) &&
1457             (ctxt->myDoc->extSubset != NULL) &&
1458             (ctxt->validate)) {
1459             while (attr != NULL) {
1460                 if ((attr->defaultValue != NULL) &&
1461                     (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset,
1462                                         attr->elem, attr->name,
1463                                         attr->prefix) == attr) &&
1464                     (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1465                                         attr->elem, attr->name,
1466                                         attr->prefix) == NULL)) {
1467                     xmlChar *fulln;
1468
1469                     if (attr->prefix != NULL) {
1470                         fulln = xmlStrdup(attr->prefix);
1471                         fulln = xmlStrcat(fulln, BAD_CAST ":");
1472                         fulln = xmlStrcat(fulln, attr->name);
1473                     } else {
1474                         fulln = xmlStrdup(attr->name);
1475                     }
1476                     if (fulln == NULL) {
1477                         xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1478                         break;
1479                     }
1480
1481                     /*
1482                      * Check that the attribute is not declared in the
1483                      * serialization
1484                      */
1485                     att = NULL;
1486                     if (atts != NULL) {
1487                         i = 0;
1488                         att = atts[i];
1489                         while (att != NULL) {
1490                             if (xmlStrEqual(att, fulln))
1491                                 break;
1492                             i += 2;
1493                             att = atts[i];
1494                         }
1495                     }
1496                     if (att == NULL) {
1497                         xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED,
1498       "standalone: attribute %s on %s defaulted from external subset\n",
1499                                     (const char *)fulln,
1500                                     (const char *)attr->elem);
1501                     }
1502                     xmlFree(fulln);
1503                 }
1504                 attr = attr->nexth;
1505             }
1506         }
1507
1508         /*
1509          * Actually insert defaulted values when needed
1510          */
1511         attr = elemDecl->attributes;
1512         while (attr != NULL) {
1513             /*
1514              * Make sure that attributes redefinition occuring in the
1515              * internal subset are not overriden by definitions in the
1516              * external subset.
1517              */
1518             if (attr->defaultValue != NULL) {
1519                 /*
1520                  * the element should be instantiated in the tree if:
1521                  *  - this is a namespace prefix
1522                  *  - the user required for completion in the tree
1523                  *    like XSLT
1524                  *  - there isn't already an attribute definition
1525                  *    in the internal subset overriding it.
1526                  */
1527                 if (((attr->prefix != NULL) &&
1528                      (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
1529                     ((attr->prefix == NULL) &&
1530                      (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
1531                     (ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
1532                     xmlAttributePtr tst;
1533
1534                     tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1535                                              attr->elem, attr->name,
1536                                              attr->prefix);
1537                     if ((tst == attr) || (tst == NULL)) {
1538                         xmlChar fn[50];
1539                         xmlChar *fulln;
1540
1541                         fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
1542                         if (fulln == NULL) {
1543                             xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1544                             return;
1545                         }
1546
1547                         /*
1548                          * Check that the attribute is not declared in the
1549                          * serialization
1550                          */
1551                         att = NULL;
1552                         if (atts != NULL) {
1553                             i = 0;
1554                             att = atts[i];
1555                             while (att != NULL) {
1556                                 if (xmlStrEqual(att, fulln))
1557                                     break;
1558                                 i += 2;
1559                                 att = atts[i];
1560                             }
1561                         }
1562                         if (att == NULL) {
1563                             xmlSAX2AttributeInternal(ctxt, fulln,
1564                                                  attr->defaultValue, prefix);
1565                         }
1566                         if ((fulln != fn) && (fulln != attr->name))
1567                             xmlFree(fulln);
1568                     }
1569                 }
1570             }
1571             attr = attr->nexth;
1572         }
1573         if (internal == 1) {
1574             elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
1575                                              name, prefix);
1576             internal = 0;
1577             goto process_external_subset;
1578         }
1579     }
1580 }
1581
1582 /**
1583  * xmlSAX2StartElement:
1584  * @ctx: the user data (XML parser context)
1585  * @fullname:  The element name, including namespace prefix
1586  * @atts:  An array of name/value attributes pairs, NULL terminated
1587  *
1588  * called when an opening tag has been processed.
1589  */
1590 void
1591 xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1592 {
1593     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1594     xmlNodePtr ret;
1595     xmlNodePtr parent;
1596     xmlNsPtr ns;
1597     xmlChar *name;
1598     xmlChar *prefix;
1599     const xmlChar *att;
1600     const xmlChar *value;
1601     int i;
1602
1603     if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return;
1604     parent = ctxt->node;
1605 #ifdef DEBUG_SAX
1606     xmlGenericError(xmlGenericErrorContext,
1607             "SAX.xmlSAX2StartElement(%s)\n", fullname);
1608 #endif
1609
1610     /*
1611      * First check on validity:
1612      */
1613     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
1614         ((ctxt->myDoc->intSubset == NULL) ||
1615          ((ctxt->myDoc->intSubset->notations == NULL) &&
1616           (ctxt->myDoc->intSubset->elements == NULL) &&
1617           (ctxt->myDoc->intSubset->attributes == NULL) &&
1618           (ctxt->myDoc->intSubset->entities == NULL)))) {
1619         xmlErrValid(ctxt, XML_ERR_NO_DTD,
1620           "Validation failed: no DTD found !", NULL, NULL);
1621         ctxt->validate = 0;
1622     }
1623
1624
1625     /*
1626      * Split the full name into a namespace prefix and the tag name
1627      */
1628     name = xmlSplitQName(ctxt, fullname, &prefix);
1629
1630
1631     /*
1632      * Note : the namespace resolution is deferred until the end of the
1633      *        attributes parsing, since local namespace can be defined as
1634      *        an attribute at this level.
1635      */
1636     ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
1637     if (ret == NULL) {
1638         if (prefix != NULL)
1639             xmlFree(prefix);
1640         xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1641         return;
1642     }
1643     if (ctxt->myDoc->children == NULL) {
1644 #ifdef DEBUG_SAX_TREE
1645         xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
1646 #endif
1647         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1648     } else if (parent == NULL) {
1649         parent = ctxt->myDoc->children;
1650     }
1651     ctxt->nodemem = -1;
1652     if (ctxt->linenumbers) {
1653         if (ctxt->input != NULL) {
1654             if (ctxt->input->line < 65535)
1655                 ret->line = (short) ctxt->input->line;
1656             else
1657                 ret->line = 65535;
1658         }
1659     }
1660
1661     /*
1662      * We are parsing a new node.
1663      */
1664 #ifdef DEBUG_SAX_TREE
1665     xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
1666 #endif
1667     nodePush(ctxt, ret);
1668
1669     /*
1670      * Link the child element
1671      */
1672     if (parent != NULL) {
1673         if (parent->type == XML_ELEMENT_NODE) {
1674 #ifdef DEBUG_SAX_TREE
1675             xmlGenericError(xmlGenericErrorContext,
1676                     "adding child %s to %s\n", name, parent->name);
1677 #endif
1678             xmlAddChild(parent, ret);
1679         } else {
1680 #ifdef DEBUG_SAX_TREE
1681             xmlGenericError(xmlGenericErrorContext,
1682                     "adding sibling %s to ", name);
1683             xmlDebugDumpOneNode(stderr, parent, 0);
1684 #endif
1685             xmlAddSibling(parent, ret);
1686         }
1687     }
1688
1689     /*
1690      * Insert all the defaulted attributes from the DTD especially namespaces
1691      */
1692     if ((!ctxt->html) &&
1693         ((ctxt->myDoc->intSubset != NULL) ||
1694          (ctxt->myDoc->extSubset != NULL))) {
1695         xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
1696     }
1697
1698     /*
1699      * process all the attributes whose name start with "xmlns"
1700      */
1701     if (atts != NULL) {
1702         i = 0;
1703         att = atts[i++];
1704         value = atts[i++];
1705         if (!ctxt->html) {
1706             while ((att != NULL) && (value != NULL)) {
1707                 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
1708                     (att[3] == 'n') && (att[4] == 's'))
1709                     xmlSAX2AttributeInternal(ctxt, att, value, prefix);
1710
1711                 att = atts[i++];
1712                 value = atts[i++];
1713             }
1714         }
1715     }
1716
1717     /*
1718      * Search the namespace, note that since the attributes have been
1719      * processed, the local namespaces are available.
1720      */
1721     ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
1722     if ((ns == NULL) && (parent != NULL))
1723         ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
1724     if ((prefix != NULL) && (ns == NULL)) {
1725         ns = xmlNewNs(ret, NULL, prefix);
1726         xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
1727                      "Namespace prefix %s is not defined\n",
1728                      prefix, NULL);
1729     }
1730
1731     /*
1732      * set the namespace node, making sure that if the default namspace
1733      * is unbound on a parent we simply kee it NULL
1734      */
1735     if ((ns != NULL) && (ns->href != NULL) &&
1736         ((ns->href[0] != 0) || (ns->prefix != NULL)))
1737         xmlSetNs(ret, ns);
1738
1739     /*
1740      * process all the other attributes
1741      */
1742     if (atts != NULL) {
1743         i = 0;
1744         att = atts[i++];
1745         value = atts[i++];
1746         if (ctxt->html) {
1747             while (att != NULL) {
1748                 xmlSAX2AttributeInternal(ctxt, att, value, NULL);
1749                 att = atts[i++];
1750                 value = atts[i++];
1751             }
1752         } else {
1753             while ((att != NULL) && (value != NULL)) {
1754                 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
1755                     (att[3] != 'n') || (att[4] != 's'))
1756                     xmlSAX2AttributeInternal(ctxt, att, value, NULL);
1757
1758                 /*
1759                  * Next ones
1760                  */
1761                 att = atts[i++];
1762                 value = atts[i++];
1763             }
1764         }
1765     }
1766
1767 #ifdef LIBXML_VALID_ENABLED
1768     /*
1769      * If it's the Document root, finish the DTD validation and
1770      * check the document root element for validity
1771      */
1772     if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
1773         int chk;
1774
1775         chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
1776         if (chk <= 0)
1777             ctxt->valid = 0;
1778         if (chk < 0)
1779             ctxt->wellFormed = 0;
1780         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1781         ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
1782     }
1783 #endif /* LIBXML_VALID_ENABLED */
1784
1785     if (prefix != NULL)
1786         xmlFree(prefix);
1787
1788 }
1789
1790 /**
1791  * xmlSAX2EndElement:
1792  * @ctx: the user data (XML parser context)
1793  * @name:  The element name
1794  *
1795  * called when the end of an element has been detected.
1796  */
1797 void
1798 xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
1799 {
1800     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1801     xmlNodePtr cur;
1802
1803     if (ctx == NULL) return;
1804     cur = ctxt->node;
1805 #ifdef DEBUG_SAX
1806     if (name == NULL)
1807         xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n");
1808     else
1809         xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name);
1810 #endif
1811
1812     /* Capture end position and add node */
1813     if (cur != NULL && ctxt->record_info) {
1814       ctxt->nodeInfo->end_pos = ctxt->input->cur - ctxt->input->base;
1815       ctxt->nodeInfo->end_line = ctxt->input->line;
1816       ctxt->nodeInfo->node = cur;
1817       xmlParserAddNodeInfo(ctxt, ctxt->nodeInfo);
1818     }
1819     ctxt->nodemem = -1;
1820
1821 #ifdef LIBXML_VALID_ENABLED
1822     if (ctxt->validate && ctxt->wellFormed &&
1823         ctxt->myDoc && ctxt->myDoc->intSubset)
1824         ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1825                                              cur);
1826 #endif /* LIBXML_VALID_ENABLED */
1827
1828
1829     /*
1830      * end of parsing of this node.
1831      */
1832 #ifdef DEBUG_SAX_TREE
1833     xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
1834 #endif
1835     nodePop(ctxt);
1836 }
1837 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
1838
1839 /*
1840  * xmlSAX2TextNode:
1841  * @ctxt:  the parser context
1842  * @str:  the input string
1843  * @len: the string length
1844  *
1845  * Callback for a text node
1846  *
1847  * Returns the newly allocated string or NULL if not needed or error
1848  */
1849 static xmlNodePtr
1850 xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
1851     xmlNodePtr ret;
1852     const xmlChar *intern = NULL;
1853
1854     /*
1855      * Allocate
1856      */
1857     if (ctxt->freeElems != NULL) {
1858         ret = ctxt->freeElems;
1859         ctxt->freeElems = ret->next;
1860         ctxt->freeElemsNr--;
1861     } else {
1862         ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
1863     }
1864     if (ret == NULL) {
1865         xmlErrMemory(ctxt, "xmlSAX2Characters");
1866         return(NULL);
1867     }
1868     memset(ret, 0, sizeof(xmlNode));
1869     /*
1870      * intern the formatting blanks found between tags, or the
1871      * very short strings
1872      */
1873     if (ctxt->dictNames) {
1874         xmlChar cur = str[len];
1875
1876         if ((len < (int) (2 * sizeof(void *))) &&
1877             (ctxt->options & XML_PARSE_COMPACT)) {
1878             /* store the string in the node overriding properties and nsDef */
1879             xmlChar *tmp = (xmlChar *) &(ret->properties);
1880             memcpy(tmp, str, len);
1881             tmp[len] = 0;
1882             intern = tmp;
1883         } else if ((len <= 3) && ((cur == '"') || (cur == '\'') ||
1884             ((cur == '<') && (str[len + 1] != '!')))) {
1885             intern = xmlDictLookup(ctxt->dict, str, len);
1886         } else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') &&
1887                    (str[len + 1] != '!')) {
1888             int i;
1889
1890             for (i = 1;i < len;i++) {
1891                 if (!IS_BLANK_CH(str[i])) goto skip;
1892             }
1893             intern = xmlDictLookup(ctxt->dict, str, len);
1894         }
1895     }
1896 skip:
1897     ret->type = XML_TEXT_NODE;
1898
1899     ret->name = xmlStringText;
1900     if (intern == NULL) {
1901         ret->content = xmlStrndup(str, len);
1902         if (ret->content == NULL) {
1903             xmlSAX2ErrMemory(ctxt, "xmlSAX2TextNode");
1904             xmlFree(ret);
1905             return(NULL);
1906         }
1907     } else
1908         ret->content = (xmlChar *) intern;
1909
1910     if (ctxt->linenumbers) {
1911         if (ctxt->input != NULL) {
1912             if (ctxt->input->line < 65535)
1913                 ret->line = (short) ctxt->input->line;
1914             else {
1915                 ret->line = 65535;
1916                 if (ctxt->options & XML_PARSE_BIG_LINES)
1917                     ret->psvi = (void *) (long) ctxt->input->line;
1918             }
1919         }
1920     }
1921
1922     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
1923         xmlRegisterNodeDefaultValue(ret);
1924     return(ret);
1925 }
1926
1927 #ifdef LIBXML_VALID_ENABLED
1928 /*
1929  * xmlSAX2DecodeAttrEntities:
1930  * @ctxt:  the parser context
1931  * @str:  the input string
1932  * @len: the string length
1933  *
1934  * Remove the entities from an attribute value
1935  *
1936  * Returns the newly allocated string or NULL if not needed or error
1937  */
1938 static xmlChar *
1939 xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
1940                           const xmlChar *end) {
1941     const xmlChar *in;
1942     xmlChar *ret;
1943
1944     in = str;
1945     while (in < end)
1946         if (*in++ == '&')
1947             goto decode;
1948     return(NULL);
1949 decode:
1950     ctxt->depth++;
1951     ret = xmlStringLenDecodeEntities(ctxt, str, end - str,
1952                                      XML_SUBSTITUTE_REF, 0,0,0);
1953     ctxt->depth--;
1954     return(ret);
1955 }
1956 #endif /* LIBXML_VALID_ENABLED */
1957
1958 /**
1959  * xmlSAX2AttributeNs:
1960  * @ctx: the user data (XML parser context)
1961  * @localname:  the local name of the attribute
1962  * @prefix:  the attribute namespace prefix if available
1963  * @URI:  the attribute namespace name if available
1964  * @value:  Start of the attribute value
1965  * @valueend: end of the attribute value
1966  *
1967  * Handle an attribute that has been read by the parser.
1968  * The default handling is to convert the attribute into an
1969  * DOM subtree and past it in a new xmlAttr element added to
1970  * the element.
1971  */
1972 static void
1973 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
1974                    const xmlChar * localname,
1975                    const xmlChar * prefix,
1976                    const xmlChar * value,
1977                    const xmlChar * valueend)
1978 {
1979     xmlAttrPtr ret;
1980     xmlNsPtr namespace = NULL;
1981     xmlChar *dup = NULL;
1982
1983     /*
1984      * Note: if prefix == NULL, the attribute is not in the default namespace
1985      */
1986     if (prefix != NULL)
1987         namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
1988
1989     /*
1990      * allocate the node
1991      */
1992     if (ctxt->freeAttrs != NULL) {
1993         ret = ctxt->freeAttrs;
1994         ctxt->freeAttrs = ret->next;
1995         ctxt->freeAttrsNr--;
1996         memset(ret, 0, sizeof(xmlAttr));
1997         ret->type = XML_ATTRIBUTE_NODE;
1998
1999         ret->parent = ctxt->node;
2000         ret->doc = ctxt->myDoc;
2001         ret->ns = namespace;
2002
2003         if (ctxt->dictNames)
2004             ret->name = localname;
2005         else
2006             ret->name = xmlStrdup(localname);
2007
2008         /* link at the end to preserv order, TODO speed up with a last */
2009         if (ctxt->node->properties == NULL) {
2010             ctxt->node->properties = ret;
2011         } else {
2012             xmlAttrPtr prev = ctxt->node->properties;
2013
2014             while (prev->next != NULL) prev = prev->next;
2015             prev->next = ret;
2016             ret->prev = prev;
2017         }
2018
2019         if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
2020             xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
2021     } else {
2022         if (ctxt->dictNames)
2023             ret = xmlNewNsPropEatName(ctxt->node, namespace,
2024                                       (xmlChar *) localname, NULL);
2025         else
2026             ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL);
2027         if (ret == NULL) {
2028             xmlErrMemory(ctxt, "xmlSAX2AttributeNs");
2029             return;
2030         }
2031     }
2032
2033     if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
2034         xmlNodePtr tmp;
2035
2036         /*
2037          * We know that if there is an entity reference, then
2038          * the string has been dup'ed and terminates with 0
2039          * otherwise with ' or "
2040          */
2041         if (*valueend != 0) {
2042             tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
2043             ret->children = tmp;
2044             ret->last = tmp;
2045             if (tmp != NULL) {
2046                 tmp->doc = ret->doc;
2047                 tmp->parent = (xmlNodePtr) ret;
2048             }
2049         } else {
2050             ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
2051                                                     valueend - value);
2052             tmp = ret->children;
2053             while (tmp != NULL) {
2054                 tmp->doc = ret->doc;
2055                 tmp->parent = (xmlNodePtr) ret;
2056                 if (tmp->next == NULL)
2057                     ret->last = tmp;
2058                 tmp = tmp->next;
2059             }
2060         }
2061     } else if (value != NULL) {
2062         xmlNodePtr tmp;
2063
2064         tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
2065         ret->children = tmp;
2066         ret->last = tmp;
2067         if (tmp != NULL) {
2068             tmp->doc = ret->doc;
2069             tmp->parent = (xmlNodePtr) ret;
2070         }
2071     }
2072
2073 #ifdef LIBXML_VALID_ENABLED
2074     if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
2075         ctxt->myDoc && ctxt->myDoc->intSubset) {
2076         /*
2077          * If we don't substitute entities, the validation should be
2078          * done on a value with replaced entities anyway.
2079          */
2080         if (!ctxt->replaceEntities) {
2081             dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend);
2082             if (dup == NULL) {
2083                 if (*valueend == 0) {
2084                     ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2085                                     ctxt->myDoc, ctxt->node, ret, value);
2086                 } else {
2087                     /*
2088                      * That should already be normalized.
2089                      * cheaper to finally allocate here than duplicate
2090                      * entry points in the full validation code
2091                      */
2092                     dup = xmlStrndup(value, valueend - value);
2093
2094                     ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2095                                     ctxt->myDoc, ctxt->node, ret, dup);
2096                 }
2097             } else {
2098                 /*
2099                  * dup now contains a string of the flattened attribute
2100                  * content with entities substitued. Check if we need to
2101                  * apply an extra layer of normalization.
2102                  * It need to be done twice ... it's an extra burden related
2103                  * to the ability to keep references in attributes
2104                  */
2105                 if (ctxt->attsSpecial != NULL) {
2106                     xmlChar *nvalnorm;
2107                     xmlChar fn[50];
2108                     xmlChar *fullname;
2109
2110                     fullname = xmlBuildQName(localname, prefix, fn, 50);
2111                     if (fullname != NULL) {
2112                         ctxt->vctxt.valid = 1;
2113                         nvalnorm = xmlValidCtxtNormalizeAttributeValue(
2114                                          &ctxt->vctxt, ctxt->myDoc,
2115                                          ctxt->node, fullname, dup);
2116                         if (ctxt->vctxt.valid != 1)
2117                             ctxt->valid = 0;
2118
2119                         if ((fullname != fn) && (fullname != localname))
2120                             xmlFree(fullname);
2121                         if (nvalnorm != NULL) {
2122                             xmlFree(dup);
2123                             dup = nvalnorm;
2124                         }
2125                     }
2126                 }
2127
2128                 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2129                                 ctxt->myDoc, ctxt->node, ret, dup);
2130             }
2131         } else {
2132             /*
2133              * if entities already have been substitued, then
2134              * the attribute as passed is already normalized
2135              */
2136             dup = xmlStrndup(value, valueend - value);
2137
2138             ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2139                                      ctxt->myDoc, ctxt->node, ret, dup);
2140         }
2141     } else
2142 #endif /* LIBXML_VALID_ENABLED */
2143            if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
2144                (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
2145                 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
2146         /*
2147          * when validating, the ID registration is done at the attribute
2148          * validation level. Otherwise we have to do specific handling here.
2149          */
2150         if ((prefix == ctxt->str_xml) &&
2151                    (localname[0] == 'i') && (localname[1] == 'd') &&
2152                    (localname[2] == 0)) {
2153             /*
2154              * Add the xml:id value
2155              *
2156              * Open issue: normalization of the value.
2157              */
2158             if (dup == NULL)
2159                 dup = xmlStrndup(value, valueend - value);
2160 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
2161 #ifdef LIBXML_VALID_ENABLED
2162             if (xmlValidateNCName(dup, 1) != 0) {
2163                 xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
2164                       "xml:id : attribute value %s is not an NCName\n",
2165                             (const char *) dup, NULL);
2166             }
2167 #endif
2168 #endif
2169             xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
2170         } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
2171             /* might be worth duplicate entry points and not copy */
2172             if (dup == NULL)
2173                 dup = xmlStrndup(value, valueend - value);
2174             xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
2175         } else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
2176             if (dup == NULL)
2177                 dup = xmlStrndup(value, valueend - value);
2178             xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret);
2179         }
2180     }
2181     if (dup != NULL)
2182         xmlFree(dup);
2183 }
2184
2185 /**
2186  * xmlSAX2StartElementNs:
2187  * @ctx:  the user data (XML parser context)
2188  * @localname:  the local name of the element
2189  * @prefix:  the element namespace prefix if available
2190  * @URI:  the element namespace name if available
2191  * @nb_namespaces:  number of namespace definitions on that node
2192  * @namespaces:  pointer to the array of prefix/URI pairs namespace definitions
2193  * @nb_attributes:  the number of attributes on that node
2194  * @nb_defaulted:  the number of defaulted attributes.
2195  * @attributes:  pointer to the array of (localname/prefix/URI/value/end)
2196  *               attribute values.
2197  *
2198  * SAX2 callback when an element start has been detected by the parser.
2199  * It provides the namespace informations for the element, as well as
2200  * the new namespace declarations on the element.
2201  */
2202 void
2203 xmlSAX2StartElementNs(void *ctx,
2204                       const xmlChar *localname,
2205                       const xmlChar *prefix,
2206                       const xmlChar *URI,
2207                       int nb_namespaces,
2208                       const xmlChar **namespaces,
2209                       int nb_attributes,
2210                       int nb_defaulted,
2211                       const xmlChar **attributes)
2212 {
2213     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2214     xmlNodePtr ret;
2215     xmlNodePtr parent;
2216     xmlNsPtr last = NULL, ns;
2217     const xmlChar *uri, *pref;
2218     xmlChar *lname = NULL;
2219     int i, j;
2220
2221     if (ctx == NULL) return;
2222     parent = ctxt->node;
2223     /*
2224      * First check on validity:
2225      */
2226     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
2227         ((ctxt->myDoc->intSubset == NULL) ||
2228          ((ctxt->myDoc->intSubset->notations == NULL) &&
2229           (ctxt->myDoc->intSubset->elements == NULL) &&
2230           (ctxt->myDoc->intSubset->attributes == NULL) &&
2231           (ctxt->myDoc->intSubset->entities == NULL)))) {
2232         xmlErrValid(ctxt, XML_DTD_NO_DTD,
2233           "Validation failed: no DTD found !", NULL, NULL);
2234         ctxt->validate = 0;
2235     }
2236
2237     /*
2238      * Take care of the rare case of an undefined namespace prefix
2239      */
2240     if ((prefix != NULL) && (URI == NULL)) {
2241         if (ctxt->dictNames) {
2242             const xmlChar *fullname;
2243
2244             fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
2245             if (fullname != NULL)
2246                 localname = fullname;
2247         } else {
2248             lname = xmlBuildQName(localname, prefix, NULL, 0);
2249         }
2250     }
2251     /*
2252      * allocate the node
2253      */
2254     if (ctxt->freeElems != NULL) {
2255         ret = ctxt->freeElems;
2256         ctxt->freeElems = ret->next;
2257         ctxt->freeElemsNr--;
2258         memset(ret, 0, sizeof(xmlNode));
2259         ret->type = XML_ELEMENT_NODE;
2260
2261         if (ctxt->dictNames)
2262             ret->name = localname;
2263         else {
2264             if (lname == NULL)
2265                 ret->name = xmlStrdup(localname);
2266             else
2267                 ret->name = lname;
2268             if (ret->name == NULL) {
2269                 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2270                 return;
2271             }
2272         }
2273         if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
2274             xmlRegisterNodeDefaultValue(ret);
2275     } else {
2276         if (ctxt->dictNames)
2277             ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
2278                                        (xmlChar *) localname, NULL);
2279         else if (lname == NULL)
2280             ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
2281         else
2282             ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
2283                                        (xmlChar *) lname, NULL);
2284         if (ret == NULL) {
2285             xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2286             return;
2287         }
2288     }
2289     if (ctxt->linenumbers) {
2290         if (ctxt->input != NULL) {
2291             if (ctxt->input->line < 65535)
2292                 ret->line = (short) ctxt->input->line;
2293             else
2294                 ret->line = 65535;
2295         }
2296     }
2297
2298     if (parent == NULL) {
2299         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2300     }
2301     /*
2302      * Build the namespace list
2303      */
2304     for (i = 0,j = 0;j < nb_namespaces;j++) {
2305         pref = namespaces[i++];
2306         uri = namespaces[i++];
2307         ns = xmlNewNs(NULL, uri, pref);
2308         if (ns != NULL) {
2309             if (last == NULL) {
2310                 ret->nsDef = last = ns;
2311             } else {
2312                 last->next = ns;
2313                 last = ns;
2314             }
2315             if ((URI != NULL) && (prefix == pref))
2316                 ret->ns = ns;
2317         } else {
2318             /*
2319              * any out of memory error would already have been raised
2320              * but we can't be guaranteed it's the actual error due to the
2321              * API, best is to skip in this case
2322              */
2323             continue;
2324         }
2325 #ifdef LIBXML_VALID_ENABLED
2326         if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
2327             ctxt->myDoc && ctxt->myDoc->intSubset) {
2328             ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
2329                                                    ret, prefix, ns, uri);
2330         }
2331 #endif /* LIBXML_VALID_ENABLED */
2332     }
2333     ctxt->nodemem = -1;
2334
2335     /*
2336      * We are parsing a new node.
2337      */
2338     nodePush(ctxt, ret);
2339
2340     /*
2341      * Link the child element
2342      */
2343     if (parent != NULL) {
2344         if (parent->type == XML_ELEMENT_NODE) {
2345             xmlAddChild(parent, ret);
2346         } else {
2347             xmlAddSibling(parent, ret);
2348         }
2349     }
2350
2351     /*
2352      * Insert the defaulted attributes from the DTD only if requested:
2353      */
2354     if ((nb_defaulted != 0) &&
2355         ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0))
2356         nb_attributes -= nb_defaulted;
2357
2358     /*
2359      * Search the namespace if it wasn't already found
2360      * Note that, if prefix is NULL, this searches for the default Ns
2361      */
2362     if ((URI != NULL) && (ret->ns == NULL)) {
2363         ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
2364         if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
2365             ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
2366         }
2367         if (ret->ns == NULL) {
2368             ns = xmlNewNs(ret, NULL, prefix);
2369             if (ns == NULL) {
2370
2371                 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2372                 return;
2373             }
2374             if (prefix != NULL)
2375                 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
2376                              "Namespace prefix %s was not found\n",
2377                              prefix, NULL);
2378             else
2379                 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
2380                              "Namespace default prefix was not found\n",
2381                              NULL, NULL);
2382         }
2383     }
2384
2385     /*
2386      * process all the other attributes
2387      */
2388     if (nb_attributes > 0) {
2389         for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
2390             /*
2391              * Handle the rare case of an undefined atribute prefix
2392              */
2393             if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
2394                 if (ctxt->dictNames) {
2395                     const xmlChar *fullname;
2396
2397                     fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
2398                                               attributes[j]);
2399                     if (fullname != NULL) {
2400                         xmlSAX2AttributeNs(ctxt, fullname, NULL,
2401                                            attributes[j+3], attributes[j+4]);
2402                         continue;
2403                     }
2404                 } else {
2405                     lname = xmlBuildQName(attributes[j], attributes[j+1],
2406                                           NULL, 0);
2407                     if (lname != NULL) {
2408                         xmlSAX2AttributeNs(ctxt, lname, NULL,
2409                                            attributes[j+3], attributes[j+4]);
2410                         xmlFree(lname);
2411                         continue;
2412                     }
2413                 }
2414             }
2415             xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
2416                                attributes[j+3], attributes[j+4]);
2417         }
2418     }
2419
2420 #ifdef LIBXML_VALID_ENABLED
2421     /*
2422      * If it's the Document root, finish the DTD validation and
2423      * check the document root element for validity
2424      */
2425     if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
2426         int chk;
2427
2428         chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
2429         if (chk <= 0)
2430             ctxt->valid = 0;
2431         if (chk < 0)
2432             ctxt->wellFormed = 0;
2433         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
2434         ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
2435     }
2436 #endif /* LIBXML_VALID_ENABLED */
2437 }
2438
2439 /**
2440  * xmlSAX2EndElementNs:
2441  * @ctx:  the user data (XML parser context)
2442  * @localname:  the local name of the element
2443  * @prefix:  the element namespace prefix if available
2444  * @URI:  the element namespace name if available
2445  *
2446  * SAX2 callback when an element end has been detected by the parser.
2447  * It provides the namespace informations for the element.
2448  */
2449 void
2450 xmlSAX2EndElementNs(void *ctx,
2451                     const xmlChar * localname ATTRIBUTE_UNUSED,
2452                     const xmlChar * prefix ATTRIBUTE_UNUSED,
2453                     const xmlChar * URI ATTRIBUTE_UNUSED)
2454 {
2455     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2456     xmlParserNodeInfo node_info;
2457     xmlNodePtr cur;
2458
2459     if (ctx == NULL) return;
2460     cur = ctxt->node;
2461     /* Capture end position and add node */
2462     if ((ctxt->record_info) && (cur != NULL)) {
2463         node_info.end_pos = ctxt->input->cur - ctxt->input->base;
2464         node_info.end_line = ctxt->input->line;
2465         node_info.node = cur;
2466         xmlParserAddNodeInfo(ctxt, &node_info);
2467     }
2468     ctxt->nodemem = -1;
2469
2470 #ifdef LIBXML_VALID_ENABLED
2471     if (ctxt->validate && ctxt->wellFormed &&
2472         ctxt->myDoc && ctxt->myDoc->intSubset)
2473         ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur);
2474 #endif /* LIBXML_VALID_ENABLED */
2475
2476     /*
2477      * end of parsing of this node.
2478      */
2479     nodePop(ctxt);
2480 }
2481
2482 /**
2483  * xmlSAX2Reference:
2484  * @ctx: the user data (XML parser context)
2485  * @name:  The entity name
2486  *
2487  * called when an entity xmlSAX2Reference is detected.
2488  */
2489 void
2490 xmlSAX2Reference(void *ctx, const xmlChar *name)
2491 {
2492     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2493     xmlNodePtr ret;
2494
2495     if (ctx == NULL) return;
2496 #ifdef DEBUG_SAX
2497     xmlGenericError(xmlGenericErrorContext,
2498             "SAX.xmlSAX2Reference(%s)\n", name);
2499 #endif
2500     if (name[0] == '#')
2501         ret = xmlNewCharRef(ctxt->myDoc, name);
2502     else
2503         ret = xmlNewReference(ctxt->myDoc, name);
2504 #ifdef DEBUG_SAX_TREE
2505     xmlGenericError(xmlGenericErrorContext,
2506             "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name);
2507 #endif
2508     if (xmlAddChild(ctxt->node, ret) == NULL) {
2509         xmlFreeNode(ret);
2510     }
2511 }
2512
2513 /**
2514  * xmlSAX2Characters:
2515  * @ctx: the user data (XML parser context)
2516  * @ch:  a xmlChar string
2517  * @len: the number of xmlChar
2518  *
2519  * receiving some chars from the parser.
2520  */
2521 void
2522 xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
2523 {
2524     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2525     xmlNodePtr lastChild;
2526
2527     if (ctx == NULL) return;
2528 #ifdef DEBUG_SAX
2529     xmlGenericError(xmlGenericErrorContext,
2530             "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len);
2531 #endif
2532     /*
2533      * Handle the data if any. If there is no child
2534      * add it as content, otherwise if the last child is text,
2535      * concatenate it, else create a new node of type text.
2536      */
2537
2538     if (ctxt->node == NULL) {
2539 #ifdef DEBUG_SAX_TREE
2540         xmlGenericError(xmlGenericErrorContext,
2541                 "add chars: ctxt->node == NULL !\n");
2542 #endif
2543         return;
2544     }
2545     lastChild = ctxt->node->last;
2546 #ifdef DEBUG_SAX_TREE
2547     xmlGenericError(xmlGenericErrorContext,
2548             "add chars to %s \n", ctxt->node->name);
2549 #endif
2550
2551     /*
2552      * Here we needed an accelerator mechanism in case of very large
2553      * elements. Use an attribute in the structure !!!
2554      */
2555     if (lastChild == NULL) {
2556         lastChild = xmlSAX2TextNode(ctxt, ch, len);
2557         if (lastChild != NULL) {
2558             ctxt->node->children = lastChild;
2559             ctxt->node->last = lastChild;
2560             lastChild->parent = ctxt->node;
2561             lastChild->doc = ctxt->node->doc;
2562             ctxt->nodelen = len;
2563             ctxt->nodemem = len + 1;
2564         } else {
2565             xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2566             return;
2567         }
2568     } else {
2569         int coalesceText = (lastChild != NULL) &&
2570             (lastChild->type == XML_TEXT_NODE) &&
2571             (lastChild->name == xmlStringText);
2572         if ((coalesceText) && (ctxt->nodemem != 0)) {
2573             /*
2574              * The whole point of maintaining nodelen and nodemem,
2575              * xmlTextConcat is too costly, i.e. compute length,
2576              * reallocate a new buffer, move data, append ch. Here
2577              * We try to minimaze realloc() uses and avoid copying
2578              * and recomputing length over and over.
2579              */
2580             if (lastChild->content == (xmlChar *)&(lastChild->properties)) {
2581                 lastChild->content = xmlStrdup(lastChild->content);
2582                 lastChild->properties = NULL;
2583             } else if ((ctxt->nodemem == ctxt->nodelen + 1) &&
2584                        (xmlDictOwns(ctxt->dict, lastChild->content))) {
2585                 lastChild->content = xmlStrdup(lastChild->content);
2586             }
2587             if (lastChild->content == NULL) {
2588                 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL");
2589                 return;
2590             }
2591             if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) &&
2592                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
2593                 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
2594                 return;
2595             }
2596             if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len ||
2597                 (size_t)ctxt->nodemem + (size_t)len > SIZE_T_MAX / 2) {
2598                 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented");
2599                 return;
2600             }
2601             if (ctxt->nodelen + len >= ctxt->nodemem) {
2602                 xmlChar *newbuf;
2603                 size_t size;
2604
2605                 size = ctxt->nodemem + len;
2606                 size *= 2;
2607                 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
2608                 if (newbuf == NULL) {
2609                     xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2610                     return;
2611                 }
2612                 ctxt->nodemem = size;
2613                 lastChild->content = newbuf;
2614             }
2615             memcpy(&lastChild->content[ctxt->nodelen], ch, len);
2616             ctxt->nodelen += len;
2617             lastChild->content[ctxt->nodelen] = 0;
2618         } else if (coalesceText) {
2619             if (xmlTextConcat(lastChild, ch, len)) {
2620                 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2621             }
2622             if (ctxt->node->children != NULL) {
2623                 ctxt->nodelen = xmlStrlen(lastChild->content);
2624                 ctxt->nodemem = ctxt->nodelen + 1;
2625             }
2626         } else {
2627             /* Mixed content, first time */
2628             lastChild = xmlSAX2TextNode(ctxt, ch, len);
2629             if (lastChild != NULL) {
2630                 xmlAddChild(ctxt->node, lastChild);
2631                 if (ctxt->node->children != NULL) {
2632                     ctxt->nodelen = len;
2633                     ctxt->nodemem = len + 1;
2634                 }
2635             }
2636         }
2637     }
2638 }
2639
2640 /**
2641  * xmlSAX2IgnorableWhitespace:
2642  * @ctx: the user data (XML parser context)
2643  * @ch:  a xmlChar string
2644  * @len: the number of xmlChar
2645  *
2646  * receiving some ignorable whitespaces from the parser.
2647  * UNUSED: by default the DOM building will use xmlSAX2Characters
2648  */
2649 void
2650 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
2651 {
2652     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
2653 #ifdef DEBUG_SAX
2654     xmlGenericError(xmlGenericErrorContext,
2655             "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len);
2656 #endif
2657 }
2658
2659 /**
2660  * xmlSAX2ProcessingInstruction:
2661  * @ctx: the user data (XML parser context)
2662  * @target:  the target name
2663  * @data: the PI data's
2664  *
2665  * A processing instruction has been parsed.
2666  */
2667 void
2668 xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
2669                       const xmlChar *data)
2670 {
2671     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2672     xmlNodePtr ret;
2673     xmlNodePtr parent;
2674
2675     if (ctx == NULL) return;
2676     parent = ctxt->node;
2677 #ifdef DEBUG_SAX
2678     xmlGenericError(xmlGenericErrorContext,
2679             "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data);
2680 #endif
2681
2682     ret = xmlNewDocPI(ctxt->myDoc, target, data);
2683     if (ret == NULL) return;
2684
2685     if (ctxt->linenumbers) {
2686         if (ctxt->input != NULL) {
2687             if (ctxt->input->line < 65535)
2688                 ret->line = (short) ctxt->input->line;
2689             else
2690                 ret->line = 65535;
2691         }
2692     }
2693     if (ctxt->inSubset == 1) {
2694         xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
2695         return;
2696     } else if (ctxt->inSubset == 2) {
2697         xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
2698         return;
2699     }
2700     if (parent == NULL) {
2701 #ifdef DEBUG_SAX_TREE
2702             xmlGenericError(xmlGenericErrorContext,
2703                     "Setting PI %s as root\n", target);
2704 #endif
2705         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2706         return;
2707     }
2708     if (parent->type == XML_ELEMENT_NODE) {
2709 #ifdef DEBUG_SAX_TREE
2710         xmlGenericError(xmlGenericErrorContext,
2711                 "adding PI %s child to %s\n", target, parent->name);
2712 #endif
2713         xmlAddChild(parent, ret);
2714     } else {
2715 #ifdef DEBUG_SAX_TREE
2716         xmlGenericError(xmlGenericErrorContext,
2717                 "adding PI %s sibling to ", target);
2718         xmlDebugDumpOneNode(stderr, parent, 0);
2719 #endif
2720         xmlAddSibling(parent, ret);
2721     }
2722 }
2723
2724 /**
2725  * xmlSAX2Comment:
2726  * @ctx: the user data (XML parser context)
2727  * @value:  the xmlSAX2Comment content
2728  *
2729  * A xmlSAX2Comment has been parsed.
2730  */
2731 void
2732 xmlSAX2Comment(void *ctx, const xmlChar *value)
2733 {
2734     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2735     xmlNodePtr ret;
2736     xmlNodePtr parent;
2737
2738     if (ctx == NULL) return;
2739     parent = ctxt->node;
2740 #ifdef DEBUG_SAX
2741     xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value);
2742 #endif
2743     ret = xmlNewDocComment(ctxt->myDoc, value);
2744     if (ret == NULL) return;
2745     if (ctxt->linenumbers) {
2746         if (ctxt->input != NULL) {
2747             if (ctxt->input->line < 65535)
2748                 ret->line = (short) ctxt->input->line;
2749             else
2750                 ret->line = 65535;
2751         }
2752     }
2753
2754     if (ctxt->inSubset == 1) {
2755         xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
2756         return;
2757     } else if (ctxt->inSubset == 2) {
2758         xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
2759         return;
2760     }
2761     if (parent == NULL) {
2762 #ifdef DEBUG_SAX_TREE
2763             xmlGenericError(xmlGenericErrorContext,
2764                     "Setting xmlSAX2Comment as root\n");
2765 #endif
2766         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2767         return;
2768     }
2769     if (parent->type == XML_ELEMENT_NODE) {
2770 #ifdef DEBUG_SAX_TREE
2771         xmlGenericError(xmlGenericErrorContext,
2772                 "adding xmlSAX2Comment child to %s\n", parent->name);
2773 #endif
2774         xmlAddChild(parent, ret);
2775     } else {
2776 #ifdef DEBUG_SAX_TREE
2777         xmlGenericError(xmlGenericErrorContext,
2778                 "adding xmlSAX2Comment sibling to ");
2779         xmlDebugDumpOneNode(stderr, parent, 0);
2780 #endif
2781         xmlAddSibling(parent, ret);
2782     }
2783 }
2784
2785 /**
2786  * xmlSAX2CDataBlock:
2787  * @ctx: the user data (XML parser context)
2788  * @value:  The pcdata content
2789  * @len:  the block length
2790  *
2791  * called when a pcdata block has been parsed
2792  */
2793 void
2794 xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
2795 {
2796     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2797     xmlNodePtr ret, lastChild;
2798
2799     if (ctx == NULL) return;
2800 #ifdef DEBUG_SAX
2801     xmlGenericError(xmlGenericErrorContext,
2802             "SAX.pcdata(%.10s, %d)\n", value, len);
2803 #endif
2804     lastChild = xmlGetLastChild(ctxt->node);
2805 #ifdef DEBUG_SAX_TREE
2806     xmlGenericError(xmlGenericErrorContext,
2807             "add chars to %s \n", ctxt->node->name);
2808 #endif
2809     if ((lastChild != NULL) &&
2810         (lastChild->type == XML_CDATA_SECTION_NODE)) {
2811         xmlTextConcat(lastChild, value, len);
2812     } else {
2813         ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
2814         if (xmlAddChild(ctxt->node, ret) == NULL)
2815                 xmlFreeNode(ret);
2816     }
2817 }
2818
2819 static int xmlSAX2DefaultVersionValue = 2;
2820
2821 #ifdef LIBXML_SAX1_ENABLED
2822 /**
2823  * xmlSAXDefaultVersion:
2824  * @version:  the version, 1 or 2
2825  *
2826  * Set the default version of SAX used globally by the library.
2827  * By default, during initialization the default is set to 2.
2828  * Note that it is generally a better coding style to use
2829  * xmlSAXVersion() to set up the version explicitly for a given
2830  * parsing context.
2831  *
2832  * Returns the previous value in case of success and -1 in case of error.
2833  */
2834 int
2835 xmlSAXDefaultVersion(int version)
2836 {
2837     int ret = xmlSAX2DefaultVersionValue;
2838
2839     if ((version != 1) && (version != 2))
2840         return(-1);
2841     xmlSAX2DefaultVersionValue = version;
2842     return(ret);
2843 }
2844 #endif /* LIBXML_SAX1_ENABLED */
2845
2846 /**
2847  * xmlSAXVersion:
2848  * @hdlr:  the SAX handler
2849  * @version:  the version, 1 or 2
2850  *
2851  * Initialize the default XML SAX handler according to the version
2852  *
2853  * Returns 0 in case of success and -1 in case of error.
2854  */
2855 int
2856 xmlSAXVersion(xmlSAXHandler *hdlr, int version)
2857 {
2858     if (hdlr == NULL) return(-1);
2859     if (version == 2) {
2860         hdlr->startElement = NULL;
2861         hdlr->endElement = NULL;
2862         hdlr->startElementNs = xmlSAX2StartElementNs;
2863         hdlr->endElementNs = xmlSAX2EndElementNs;
2864         hdlr->serror = NULL;
2865         hdlr->initialized = XML_SAX2_MAGIC;
2866 #ifdef LIBXML_SAX1_ENABLED
2867     } else if (version == 1) {
2868         hdlr->startElement = xmlSAX2StartElement;
2869         hdlr->endElement = xmlSAX2EndElement;
2870         hdlr->initialized = 1;
2871 #endif /* LIBXML_SAX1_ENABLED */
2872     } else
2873         return(-1);
2874     hdlr->internalSubset = xmlSAX2InternalSubset;
2875     hdlr->externalSubset = xmlSAX2ExternalSubset;
2876     hdlr->isStandalone = xmlSAX2IsStandalone;
2877     hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
2878     hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
2879     hdlr->resolveEntity = xmlSAX2ResolveEntity;
2880     hdlr->getEntity = xmlSAX2GetEntity;
2881     hdlr->getParameterEntity = xmlSAX2GetParameterEntity;
2882     hdlr->entityDecl = xmlSAX2EntityDecl;
2883     hdlr->attributeDecl = xmlSAX2AttributeDecl;
2884     hdlr->elementDecl = xmlSAX2ElementDecl;
2885     hdlr->notationDecl = xmlSAX2NotationDecl;
2886     hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl;
2887     hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2888     hdlr->startDocument = xmlSAX2StartDocument;
2889     hdlr->endDocument = xmlSAX2EndDocument;
2890     hdlr->reference = xmlSAX2Reference;
2891     hdlr->characters = xmlSAX2Characters;
2892     hdlr->cdataBlock = xmlSAX2CDataBlock;
2893     hdlr->ignorableWhitespace = xmlSAX2Characters;
2894     hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
2895     hdlr->comment = xmlSAX2Comment;
2896     hdlr->warning = xmlParserWarning;
2897     hdlr->error = xmlParserError;
2898     hdlr->fatalError = xmlParserError;
2899
2900     return(0);
2901 }
2902
2903 /**
2904  * xmlSAX2InitDefaultSAXHandler:
2905  * @hdlr:  the SAX handler
2906  * @warning:  flag if non-zero sets the handler warning procedure
2907  *
2908  * Initialize the default XML SAX2 handler
2909  */
2910 void
2911 xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning)
2912 {
2913     if ((hdlr == NULL) || (hdlr->initialized != 0))
2914         return;
2915
2916     xmlSAXVersion(hdlr, xmlSAX2DefaultVersionValue);
2917     if (warning == 0)
2918         hdlr->warning = NULL;
2919     else
2920         hdlr->warning = xmlParserWarning;
2921 }
2922
2923 /**
2924  * xmlDefaultSAXHandlerInit:
2925  *
2926  * Initialize the default SAX2 handler
2927  */
2928 void
2929 xmlDefaultSAXHandlerInit(void)
2930 {
2931 #ifdef LIBXML_SAX1_ENABLED
2932     xmlSAXVersion((xmlSAXHandlerPtr) &xmlDefaultSAXHandler, 1);
2933 #endif /* LIBXML_SAX1_ENABLED */
2934 }
2935
2936 #ifdef LIBXML_HTML_ENABLED
2937
2938 /**
2939  * xmlSAX2InitHtmlDefaultSAXHandler:
2940  * @hdlr:  the SAX handler
2941  *
2942  * Initialize the default HTML SAX2 handler
2943  */
2944 void
2945 xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr)
2946 {
2947     if ((hdlr == NULL) || (hdlr->initialized != 0))
2948         return;
2949
2950     hdlr->internalSubset = xmlSAX2InternalSubset;
2951     hdlr->externalSubset = NULL;
2952     hdlr->isStandalone = NULL;
2953     hdlr->hasInternalSubset = NULL;
2954     hdlr->hasExternalSubset = NULL;
2955     hdlr->resolveEntity = NULL;
2956     hdlr->getEntity = xmlSAX2GetEntity;
2957     hdlr->getParameterEntity = NULL;
2958     hdlr->entityDecl = NULL;
2959     hdlr->attributeDecl = NULL;
2960     hdlr->elementDecl = NULL;
2961     hdlr->notationDecl = NULL;
2962     hdlr->unparsedEntityDecl = NULL;
2963     hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2964     hdlr->startDocument = xmlSAX2StartDocument;
2965     hdlr->endDocument = xmlSAX2EndDocument;
2966     hdlr->startElement = xmlSAX2StartElement;
2967     hdlr->endElement = xmlSAX2EndElement;
2968     hdlr->reference = NULL;
2969     hdlr->characters = xmlSAX2Characters;
2970     hdlr->cdataBlock = xmlSAX2CDataBlock;
2971     hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
2972     hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
2973     hdlr->comment = xmlSAX2Comment;
2974     hdlr->warning = xmlParserWarning;
2975     hdlr->error = xmlParserError;
2976     hdlr->fatalError = xmlParserError;
2977
2978     hdlr->initialized = 1;
2979 }
2980
2981 /**
2982  * htmlDefaultSAXHandlerInit:
2983  *
2984  * Initialize the default SAX handler
2985  */
2986 void
2987 htmlDefaultSAXHandlerInit(void)
2988 {
2989     xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr) &htmlDefaultSAXHandler);
2990 }
2991
2992 #endif /* LIBXML_HTML_ENABLED */
2993
2994 #ifdef LIBXML_DOCB_ENABLED
2995
2996 /**
2997  * xmlSAX2InitDocbDefaultSAXHandler:
2998  * @hdlr:  the SAX handler
2999  *
3000  * Initialize the default DocBook SAX2 handler
3001  */
3002 void
3003 xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr)
3004 {
3005     if ((hdlr == NULL) || (hdlr->initialized != 0))
3006         return;
3007
3008     hdlr->internalSubset = xmlSAX2InternalSubset;
3009     hdlr->externalSubset = NULL;
3010     hdlr->isStandalone = xmlSAX2IsStandalone;
3011     hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
3012     hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
3013     hdlr->resolveEntity = xmlSAX2ResolveEntity;
3014     hdlr->getEntity = xmlSAX2GetEntity;
3015     hdlr->getParameterEntity = NULL;
3016     hdlr->entityDecl = xmlSAX2EntityDecl;
3017     hdlr->attributeDecl = NULL;
3018     hdlr->elementDecl = NULL;
3019     hdlr->notationDecl = NULL;
3020     hdlr->unparsedEntityDecl = NULL;
3021     hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
3022     hdlr->startDocument = xmlSAX2StartDocument;
3023     hdlr->endDocument = xmlSAX2EndDocument;
3024     hdlr->startElement = xmlSAX2StartElement;
3025     hdlr->endElement = xmlSAX2EndElement;
3026     hdlr->reference = xmlSAX2Reference;
3027     hdlr->characters = xmlSAX2Characters;
3028     hdlr->cdataBlock = NULL;
3029     hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
3030     hdlr->processingInstruction = NULL;
3031     hdlr->comment = xmlSAX2Comment;
3032     hdlr->warning = xmlParserWarning;
3033     hdlr->error = xmlParserError;
3034     hdlr->fatalError = xmlParserError;
3035
3036     hdlr->initialized = 1;
3037 }
3038
3039 /**
3040  * docbDefaultSAXHandlerInit:
3041  *
3042  * Initialize the default SAX handler
3043  */
3044 void
3045 docbDefaultSAXHandlerInit(void)
3046 {
3047     xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr) &docbDefaultSAXHandler);
3048 }
3049
3050 #endif /* LIBXML_DOCB_ENABLED */
3051 #define bottom_SAX2
3052 #include "elfgcchack.h"