Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: third_party/libxml/parser.c

Issue 2951008: Update libxml to 2.7.7. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * parser.c : an XML 1.0 parser, namespaces and validity support are mostly 2 * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
3 * implemented on top of the SAX interfaces 3 * implemented on top of the SAX interfaces
4 * 4 *
5 * References: 5 * References:
6 * The XML specification: 6 * The XML specification:
7 * http://www.w3.org/TR/REC-xml 7 * http://www.w3.org/TR/REC-xml
8 * Original 1.0 version: 8 * Original 1.0 version:
9 * http://www.w3.org/TR/1998/REC-xml-19980210 9 * http://www.w3.org/TR/1998/REC-xml-19980210
10 * XML second edition working draft 10 * XML second edition working draft
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 #ifdef HAVE_FCNTL_H 73 #ifdef HAVE_FCNTL_H
74 #include <fcntl.h> 74 #include <fcntl.h>
75 #endif 75 #endif
76 #ifdef HAVE_UNISTD_H 76 #ifdef HAVE_UNISTD_H
77 #include <unistd.h> 77 #include <unistd.h>
78 #endif 78 #endif
79 #ifdef HAVE_ZLIB_H 79 #ifdef HAVE_ZLIB_H
80 #include <zlib.h> 80 #include <zlib.h>
81 #endif 81 #endif
82 82
83 static void
84 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
85
86 static xmlParserCtxtPtr
87 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
88 const xmlChar *base, xmlParserCtxtPtr pctx);
89
90 /************************************************************************
91 * *
92 * Arbitrary limits set in the parser. See XML_PARSE_HUGE *
93 * *
94 ************************************************************************/
95
96 #define XML_PARSER_BIG_ENTITY 1000
97 #define XML_PARSER_LOT_ENTITY 5000
98
99 /*
100 * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
101 * replacement over the size in byte of the input indicates that you have
102 * and eponential behaviour. A value of 10 correspond to at least 3 entity
103 * replacement per byte of input.
104 */
105 #define XML_PARSER_NON_LINEAR 10
106
107 /*
108 * xmlParserEntityCheck
109 *
110 * Function to check non-linear entity expansion behaviour
111 * This is here to detect and stop exponential linear entity expansion
112 * This is not a limitation of the parser but a safety
113 * boundary feature. It can be disabled with the XML_PARSE_HUGE
114 * parser option.
115 */
116 static int
117 xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long size,
118 xmlEntityPtr ent)
119 {
120 unsigned long consumed = 0;
121
122 if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
123 return (0);
124 if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
125 return (1);
126 if (size != 0) {
127 /*
128 * Do the check based on the replacement size of the entity
129 */
130 if (size < XML_PARSER_BIG_ENTITY)
131 return(0);
132
133 /*
134 * A limit on the amount of text data reasonably used
135 */
136 if (ctxt->input != NULL) {
137 consumed = ctxt->input->consumed +
138 (ctxt->input->cur - ctxt->input->base);
139 }
140 consumed += ctxt->sizeentities;
141
142 if ((size < XML_PARSER_NON_LINEAR * consumed) &&
143 (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
144 return (0);
145 } else if (ent != NULL) {
146 /*
147 * use the number of parsed entities in the replacement
148 */
149 size = ent->checked;
150
151 /*
152 * The amount of data parsed counting entities size only once
153 */
154 if (ctxt->input != NULL) {
155 consumed = ctxt->input->consumed +
156 (ctxt->input->cur - ctxt->input->base);
157 }
158 consumed += ctxt->sizeentities;
159
160 /*
161 * Check the density of entities for the amount of data
162 * knowing an entity reference will take at least 3 bytes
163 */
164 if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
165 return (0);
166 } else {
167 /*
168 * strange we got no data for checking just return
169 */
170 return (0);
171 }
172
173 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
174 return (1);
175 }
176
83 /** 177 /**
84 * xmlParserMaxDepth: 178 * xmlParserMaxDepth:
85 * 179 *
86 * arbitrary depth limit for the XML documents that we allow to 180 * arbitrary depth limit for the XML documents that we allow to
87 * process. This is not a limitation of the parser but a safety 181 * process. This is not a limitation of the parser but a safety
88 * boundary feature. 182 * boundary feature. It can be disabled with the XML_PARSE_HUGE
183 * parser option.
89 */ 184 */
90 unsigned int xmlParserMaxDepth = 1024; 185 unsigned int xmlParserMaxDepth = 256;
186
187
91 188
92 #define SAX2 1 189 #define SAX2 1
93
94 #define XML_PARSER_BIG_BUFFER_SIZE 300 190 #define XML_PARSER_BIG_BUFFER_SIZE 300
95 #define XML_PARSER_BUFFER_SIZE 100 191 #define XML_PARSER_BUFFER_SIZE 100
96
97 #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document" 192 #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
98 193
99 /* 194 /*
100 * List of XML prefixed PI allowed by W3C specs 195 * List of XML prefixed PI allowed by W3C specs
101 */ 196 */
102 197
103 static const char *xmlW3CPIs[] = { 198 static const char *xmlW3CPIs[] = {
104 "xml-stylesheet", 199 "xml-stylesheet",
105 NULL 200 NULL
106 }; 201 };
107 202
108 203
109 /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */ 204 /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
110 xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt, 205 static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
111 const xmlChar **str); 206 const xmlChar **str);
112 207
113 static xmlParserErrors 208 static xmlParserErrors
114 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, 209 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
115 xmlSAXHandlerPtr sax, 210 xmlSAXHandlerPtr sax,
116 void *user_data, int depth, const xmlChar *URL, 211 void *user_data, int depth, const xmlChar *URL,
117 const xmlChar *ID, xmlNodePtr *list); 212 const xmlChar *ID, xmlNodePtr *list);
118 213
214 static int
215 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
216 const char *encoding);
119 #ifdef LIBXML_LEGACY_ENABLED 217 #ifdef LIBXML_LEGACY_ENABLED
120 static void 218 static void
121 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode, 219 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
122 xmlNodePtr lastNode); 220 xmlNodePtr lastNode);
123 #endif /* LIBXML_LEGACY_ENABLED */ 221 #endif /* LIBXML_LEGACY_ENABLED */
124 222
125 static xmlParserErrors 223 static xmlParserErrors
126 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt, 224 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
127 const xmlChar *string, void *user_data, xmlNodePtr *lst); 225 const xmlChar *string, void *user_data, xmlNodePtr *lst);
128 226
(...skipping 16 matching lines...) Expand all
145 */ 243 */
146 static void 244 static void
147 xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix, 245 xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
148 const xmlChar * localname) 246 const xmlChar * localname)
149 { 247 {
150 if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 248 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
151 (ctxt->instate == XML_PARSER_EOF)) 249 (ctxt->instate == XML_PARSER_EOF))
152 return; 250 return;
153 if (ctxt != NULL) 251 if (ctxt != NULL)
154 ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED; 252 ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
253
155 if (prefix == NULL) 254 if (prefix == NULL)
156 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, 255 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
157 ctxt->errNo, XML_ERR_FATAL, NULL, 0, 256 XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
158 (const char *) localname, NULL, NULL, 0, 0, 257 (const char *) localname, NULL, NULL, 0, 0,
159 "Attribute %s redefined\n", localname); 258 "Attribute %s redefined\n", localname);
160 else 259 else
161 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, 260 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
162 ctxt->errNo, XML_ERR_FATAL, NULL, 0, 261 XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
163 (const char *) prefix, (const char *) localname, 262 (const char *) prefix, (const char *) localname,
164 NULL, 0, 0, "Attribute %s:%s redefined\n", prefix, 263 NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
165 localname); 264 localname);
166 if (ctxt != NULL) { 265 if (ctxt != NULL) {
167 ctxt->wellFormed = 0; 266 ctxt->wellFormed = 0;
168 if (ctxt->recovery == 0) 267 if (ctxt->recovery == 0)
169 ctxt->disableSAX = 1; 268 ctxt->disableSAX = 1;
170 } 269 }
171 } 270 }
172 271
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 static void 487 static void
389 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, 488 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
390 const char *msg) 489 const char *msg)
391 { 490 {
392 if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 491 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
393 (ctxt->instate == XML_PARSER_EOF)) 492 (ctxt->instate == XML_PARSER_EOF))
394 return; 493 return;
395 if (ctxt != NULL) 494 if (ctxt != NULL)
396 ctxt->errNo = error; 495 ctxt->errNo = error;
397 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, 496 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
398 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, msg); 497 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
399 if (ctxt != NULL) { 498 if (ctxt != NULL) {
400 ctxt->wellFormed = 0; 499 ctxt->wellFormed = 0;
401 if (ctxt->recovery == 0) 500 if (ctxt->recovery == 0)
402 ctxt->disableSAX = 1; 501 ctxt->disableSAX = 1;
403 } 502 }
404 } 503 }
405 504
406 /** 505 /**
407 * xmlWarningMsg: 506 * xmlWarningMsg:
408 * @ctxt: an XML parser context 507 * @ctxt: an XML parser context
409 * @error: the error number 508 * @error: the error number
410 * @msg: the error message 509 * @msg: the error message
411 * @str1: extra data 510 * @str1: extra data
412 * @str2: extra data 511 * @str2: extra data
413 * 512 *
414 * Handle a warning. 513 * Handle a warning.
415 */ 514 */
416 static void 515 static void
417 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, 516 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
418 const char *msg, const xmlChar *str1, const xmlChar *str2) 517 const char *msg, const xmlChar *str1, const xmlChar *str2)
419 { 518 {
420 xmlStructuredErrorFunc schannel = NULL; 519 xmlStructuredErrorFunc schannel = NULL;
421 520
422 if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 521 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
423 (ctxt->instate == XML_PARSER_EOF)) 522 (ctxt->instate == XML_PARSER_EOF))
424 return; 523 return;
425 if ((ctxt != NULL) && (ctxt->sax != NULL) && 524 if ((ctxt != NULL) && (ctxt->sax != NULL) &&
426 (ctxt->sax->initialized == XML_SAX2_MAGIC)) 525 (ctxt->sax->initialized == XML_SAX2_MAGIC))
427 schannel = ctxt->sax->serror; 526 schannel = ctxt->sax->serror;
428 __xmlRaiseError(schannel, 527 if (ctxt != NULL) {
528 __xmlRaiseError(schannel,
429 (ctxt->sax) ? ctxt->sax->warning : NULL, 529 (ctxt->sax) ? ctxt->sax->warning : NULL,
430 ctxt->userData, 530 ctxt->userData,
431 ctxt, NULL, XML_FROM_PARSER, error, 531 ctxt, NULL, XML_FROM_PARSER, error,
432 XML_ERR_WARNING, NULL, 0, 532 XML_ERR_WARNING, NULL, 0,
433 (const char *) str1, (const char *) str2, NULL, 0, 0, 533 (const char *) str1, (const char *) str2, NULL, 0, 0,
434 msg, (const char *) str1, (const char *) str2); 534 msg, (const char *) str1, (const char *) str2);
535 } else {
536 __xmlRaiseError(schannel, NULL, NULL,
537 ctxt, NULL, XML_FROM_PARSER, error,
538 XML_ERR_WARNING, NULL, 0,
539 (const char *) str1, (const char *) str2, NULL, 0, 0,
540 msg, (const char *) str1, (const char *) str2);
541 }
435 } 542 }
436 543
437 /** 544 /**
438 * xmlValidityError: 545 * xmlValidityError:
439 * @ctxt: an XML parser context 546 * @ctxt: an XML parser context
440 * @error: the error number 547 * @error: the error number
441 * @msg: the error message 548 * @msg: the error message
442 * @str1: extra data 549 * @str1: extra data
443 * 550 *
444 * Handle a validity error. 551 * Handle a validity error.
445 */ 552 */
446 static void 553 static void
447 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error, 554 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
448 const char *msg, const xmlChar *str1) 555 const char *msg, const xmlChar *str1, const xmlChar *str2)
449 { 556 {
450 xmlStructuredErrorFunc schannel = NULL; 557 xmlStructuredErrorFunc schannel = NULL;
451 558
452 if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 559 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
453 (ctxt->instate == XML_PARSER_EOF)) 560 (ctxt->instate == XML_PARSER_EOF))
454 return; 561 return;
455 if (ctxt != NULL) { 562 if (ctxt != NULL) {
456 ctxt->errNo = error; 563 ctxt->errNo = error;
457 if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC)) 564 if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
458 schannel = ctxt->sax->serror; 565 schannel = ctxt->sax->serror;
459 } 566 }
460 __xmlRaiseError(schannel, 567 if (ctxt != NULL) {
568 __xmlRaiseError(schannel,
461 ctxt->vctxt.error, ctxt->vctxt.userData, 569 ctxt->vctxt.error, ctxt->vctxt.userData,
462 ctxt, NULL, XML_FROM_DTD, error, 570 ctxt, NULL, XML_FROM_DTD, error,
463 XML_ERR_ERROR, NULL, 0, (const char *) str1, 571 XML_ERR_ERROR, NULL, 0, (const char *) str1,
464 » » NULL, NULL, 0, 0, 572 » » (const char *) str2, NULL, 0, 0,
465 » » msg, (const char *) str1); 573 » » msg, (const char *) str1, (const char *) str2);
466 if (ctxt != NULL) {
467 ctxt->valid = 0; 574 ctxt->valid = 0;
575 } else {
576 __xmlRaiseError(schannel, NULL, NULL,
577 ctxt, NULL, XML_FROM_DTD, error,
578 XML_ERR_ERROR, NULL, 0, (const char *) str1,
579 (const char *) str2, NULL, 0, 0,
580 msg, (const char *) str1, (const char *) str2);
468 } 581 }
469 } 582 }
470 583
471 /** 584 /**
472 * xmlFatalErrMsgInt: 585 * xmlFatalErrMsgInt:
473 * @ctxt: an XML parser context 586 * @ctxt: an XML parser context
474 * @error: the error number 587 * @error: the error number
475 * @msg: the error message 588 * @msg: the error message
476 * @val: an integer value 589 * @val: an integer value
477 * 590 *
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 if (ctxt != NULL) 716 if (ctxt != NULL)
604 ctxt->errNo = error; 717 ctxt->errNo = error;
605 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, 718 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
606 XML_ERR_ERROR, NULL, 0, (const char *) info1, 719 XML_ERR_ERROR, NULL, 0, (const char *) info1,
607 (const char *) info2, (const char *) info3, 0, 0, msg, 720 (const char *) info2, (const char *) info3, 0, 0, msg,
608 info1, info2, info3); 721 info1, info2, info3);
609 if (ctxt != NULL) 722 if (ctxt != NULL)
610 ctxt->nsWellFormed = 0; 723 ctxt->nsWellFormed = 0;
611 } 724 }
612 725
726 /**
727 * xmlNsWarn
728 * @ctxt: an XML parser context
729 * @error: the error number
730 * @msg: the message
731 * @info1: extra information string
732 * @info2: extra information string
733 *
734 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
735 */
736 static void
737 xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
738 const char *msg,
739 const xmlChar * info1, const xmlChar * info2,
740 const xmlChar * info3)
741 {
742 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
743 (ctxt->instate == XML_PARSER_EOF))
744 return;
745 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
746 XML_ERR_WARNING, NULL, 0, (const char *) info1,
747 (const char *) info2, (const char *) info3, 0, 0, msg,
748 info1, info2, info3);
749 }
750
613 /************************************************************************ 751 /************************************************************************
614 * * 752 * *
615 * Library wide options * 753 * Library wide options *
616 * * 754 * *
617 ************************************************************************/ 755 ************************************************************************/
618 756
619 /** 757 /**
620 * xmlHasFeature: 758 * xmlHasFeature:
621 * @feature: the feature to be examined 759 * @feature: the feature to be examined
622 * 760 *
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 #ifdef DEBUG_MEMORY_LOCATION 940 #ifdef DEBUG_MEMORY_LOCATION
803 return(1); 941 return(1);
804 #else 942 #else
805 return(0); 943 return(0);
806 #endif 944 #endif
807 case XML_WITH_DEBUG_RUN: 945 case XML_WITH_DEBUG_RUN:
808 #ifdef LIBXML_DEBUG_RUNTIME 946 #ifdef LIBXML_DEBUG_RUNTIME
809 return(1); 947 return(1);
810 #else 948 #else
811 return(0); 949 return(0);
812 #endif 950 #endif
813 case XML_WITH_ZLIB: 951 case XML_WITH_ZLIB:
814 #ifdef LIBXML_ZLIB_ENABLED 952 #ifdef LIBXML_ZLIB_ENABLED
815 return(1); 953 return(1);
816 #else 954 #else
817 return(0); 955 return(0);
818 #endif 956 #endif
819 case XML_WITH_ICU: 957 case XML_WITH_ICU:
820 #ifdef LIBXML_ICU_ENABLED 958 #ifdef LIBXML_ICU_ENABLED
821 return(1); 959 return(1);
822 #else 960 #else
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 (ctxt->str_xml_ns == NULL)) { 996 (ctxt->str_xml_ns == NULL)) {
859 xmlErrMemory(ctxt, NULL); 997 xmlErrMemory(ctxt, NULL);
860 } 998 }
861 } 999 }
862 1000
863 typedef struct _xmlDefAttrs xmlDefAttrs; 1001 typedef struct _xmlDefAttrs xmlDefAttrs;
864 typedef xmlDefAttrs *xmlDefAttrsPtr; 1002 typedef xmlDefAttrs *xmlDefAttrsPtr;
865 struct _xmlDefAttrs { 1003 struct _xmlDefAttrs {
866 int nbAttrs; /* number of defaulted attributes on that element */ 1004 int nbAttrs; /* number of defaulted attributes on that element */
867 int maxAttrs; /* the size of the array */ 1005 int maxAttrs; /* the size of the array */
868 const xmlChar *values[4]; /* array of localname/prefix/values */ 1006 const xmlChar *values[5]; /* array of localname/prefix/values/external */
869 }; 1007 };
870 1008
871 /** 1009 /**
872 * xmlAttrNormalizeSpace: 1010 * xmlAttrNormalizeSpace:
873 * @src: the source string 1011 * @src: the source string
874 * @dst: the target string 1012 * @dst: the target string
875 * 1013 *
876 * Normalize the space in non CDATA attribute values: 1014 * Normalize the space in non CDATA attribute values:
877 * If the attribute type is not CDATA, then the XML processor MUST further 1015 * If the attribute type is not CDATA, then the XML processor MUST further
878 * process the normalized attribute value by discarding any leading and 1016 * process the normalized attribute value by discarding any leading and
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 * @src: the source string 1050 * @src: the source string
913 * 1051 *
914 * Normalize the space in non CDATA attribute values, a slightly more complex 1052 * Normalize the space in non CDATA attribute values, a slightly more complex
915 * front end to avoid allocation problems when running on attribute values 1053 * front end to avoid allocation problems when running on attribute values
916 * coming from the input. 1054 * coming from the input.
917 * 1055 *
918 * Returns a pointer to the normalized value (dst) or NULL if no conversion 1056 * Returns a pointer to the normalized value (dst) or NULL if no conversion
919 * is needed. 1057 * is needed.
920 */ 1058 */
921 static const xmlChar * 1059 static const xmlChar *
922 xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, const xmlChar *src, int *len) 1060 xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
923 { 1061 {
924 int i; 1062 int i;
925 int remove_head = 0; 1063 int remove_head = 0;
926 int need_realloc = 0; 1064 int need_realloc = 0;
927 const xmlChar *cur; 1065 const xmlChar *cur;
928 1066
929 if ((ctxt == NULL) || (src == NULL) || (len == NULL)) 1067 if ((ctxt == NULL) || (src == NULL) || (len == NULL))
930 return(NULL); 1068 return(NULL);
931 i = *len; 1069 i = *len;
932 if (i <= 0) 1070 if (i <= 0)
(...skipping 20 matching lines...) Expand all
953 ret = xmlStrndup(src + remove_head, i - remove_head + 1); 1091 ret = xmlStrndup(src + remove_head, i - remove_head + 1);
954 if (ret == NULL) { 1092 if (ret == NULL) {
955 xmlErrMemory(ctxt, NULL); 1093 xmlErrMemory(ctxt, NULL);
956 return(NULL); 1094 return(NULL);
957 } 1095 }
958 xmlAttrNormalizeSpace(ret, ret); 1096 xmlAttrNormalizeSpace(ret, ret);
959 *len = (int) strlen((const char *)ret); 1097 *len = (int) strlen((const char *)ret);
960 return(ret); 1098 return(ret);
961 } else if (remove_head) { 1099 } else if (remove_head) {
962 *len -= remove_head; 1100 *len -= remove_head;
963 » return(src + remove_head); 1101 memmove(src, src + remove_head, 1 + *len);
1102 » return(src);
964 } 1103 }
965 return(NULL); 1104 return(NULL);
966 } 1105 }
967 1106
968 /** 1107 /**
969 * xmlAddDefAttrs: 1108 * xmlAddDefAttrs:
970 * @ctxt: an XML parser context 1109 * @ctxt: an XML parser context
971 * @fullname: the element fullname 1110 * @fullname: the element fullname
972 * @fullattr: the attribute fullname 1111 * @fullattr: the attribute fullname
973 * @value: the attribute value 1112 * @value: the attribute value
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 name = xmlDictLookup(ctxt->dict, name, -1); 1149 name = xmlDictLookup(ctxt->dict, name, -1);
1011 prefix = xmlDictLookup(ctxt->dict, fullname, len); 1150 prefix = xmlDictLookup(ctxt->dict, fullname, len);
1012 } 1151 }
1013 1152
1014 /* 1153 /*
1015 * make sure there is some storage 1154 * make sure there is some storage
1016 */ 1155 */
1017 defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix); 1156 defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
1018 if (defaults == NULL) { 1157 if (defaults == NULL) {
1019 defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) + 1158 defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
1020 » (4 * 4) * sizeof(const xmlChar *)); 1159 » (4 * 5) * sizeof(const xmlChar *));
1021 if (defaults == NULL) 1160 if (defaults == NULL)
1022 goto mem_error; 1161 goto mem_error;
1023 defaults->nbAttrs = 0; 1162 defaults->nbAttrs = 0;
1024 defaults->maxAttrs = 4; 1163 defaults->maxAttrs = 4;
1025 if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, 1164 if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1026 defaults, NULL) < 0) { 1165 defaults, NULL) < 0) {
1027 xmlFree(defaults); 1166 xmlFree(defaults);
1028 goto mem_error; 1167 goto mem_error;
1029 } 1168 }
1030 } else if (defaults->nbAttrs >= defaults->maxAttrs) { 1169 } else if (defaults->nbAttrs >= defaults->maxAttrs) {
1031 xmlDefAttrsPtr temp; 1170 xmlDefAttrsPtr temp;
1032 1171
1033 temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) + 1172 temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
1034 » » (2 * defaults->maxAttrs * 4) * sizeof(const xmlChar *)); 1173 » » (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
1035 if (temp == NULL) 1174 if (temp == NULL)
1036 goto mem_error; 1175 goto mem_error;
1037 defaults = temp; 1176 defaults = temp;
1038 defaults->maxAttrs *= 2; 1177 defaults->maxAttrs *= 2;
1039 if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, 1178 if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1040 defaults, NULL) < 0) { 1179 defaults, NULL) < 0) {
1041 xmlFree(defaults); 1180 xmlFree(defaults);
1042 goto mem_error; 1181 goto mem_error;
1043 } 1182 }
1044 } 1183 }
1045 1184
1046 /* 1185 /*
1047 * Split the element name into prefix:localname , the string found 1186 * Split the element name into prefix:localname , the string found
1048 * are within the DTD and hen not associated to namespace names. 1187 * are within the DTD and hen not associated to namespace names.
1049 */ 1188 */
1050 name = xmlSplitQName3(fullattr, &len); 1189 name = xmlSplitQName3(fullattr, &len);
1051 if (name == NULL) { 1190 if (name == NULL) {
1052 name = xmlDictLookup(ctxt->dict, fullattr, -1); 1191 name = xmlDictLookup(ctxt->dict, fullattr, -1);
1053 prefix = NULL; 1192 prefix = NULL;
1054 } else { 1193 } else {
1055 name = xmlDictLookup(ctxt->dict, name, -1); 1194 name = xmlDictLookup(ctxt->dict, name, -1);
1056 prefix = xmlDictLookup(ctxt->dict, fullattr, len); 1195 prefix = xmlDictLookup(ctxt->dict, fullattr, len);
1057 } 1196 }
1058 1197
1059 defaults->values[4 * defaults->nbAttrs] = name; 1198 defaults->values[5 * defaults->nbAttrs] = name;
1060 defaults->values[4 * defaults->nbAttrs + 1] = prefix; 1199 defaults->values[5 * defaults->nbAttrs + 1] = prefix;
1061 /* intern the string and precompute the end */ 1200 /* intern the string and precompute the end */
1062 len = xmlStrlen(value); 1201 len = xmlStrlen(value);
1063 value = xmlDictLookup(ctxt->dict, value, len); 1202 value = xmlDictLookup(ctxt->dict, value, len);
1064 defaults->values[4 * defaults->nbAttrs + 2] = value; 1203 defaults->values[5 * defaults->nbAttrs + 2] = value;
1065 defaults->values[4 * defaults->nbAttrs + 3] = value + len; 1204 defaults->values[5 * defaults->nbAttrs + 3] = value + len;
1205 if (ctxt->external)
1206 defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
1207 else
1208 defaults->values[5 * defaults->nbAttrs + 4] = NULL;
1066 defaults->nbAttrs++; 1209 defaults->nbAttrs++;
1067 1210
1068 return; 1211 return;
1069 1212
1070 mem_error: 1213 mem_error:
1071 xmlErrMemory(ctxt, NULL); 1214 xmlErrMemory(ctxt, NULL);
1072 return; 1215 return;
1073 } 1216 }
1074 1217
1075 /** 1218 /**
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 return (0); 1354 return (0);
1212 while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming * / 1355 while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming * /
1213 ((cur[0] >= 'a') && (cur[0] <= 'z'))) 1356 ((cur[0] >= 'a') && (cur[0] <= 'z')))
1214 cur++; 1357 cur++;
1215 } 1358 }
1216 return (1); 1359 return (1);
1217 } 1360 }
1218 1361
1219 /************************************************************************ 1362 /************************************************************************
1220 * * 1363 * *
1221 * » » Parser stacks related functions and macros» » * 1364 *» » Parser stacks related functions and macros» » *
1222 * * 1365 * *
1223 ************************************************************************/ 1366 ************************************************************************/
1224 1367
1225 xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, 1368 static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
1226 const xmlChar ** str); 1369 const xmlChar ** str);
1227 1370
1228 #ifdef SAX2 1371 #ifdef SAX2
1229 /** 1372 /**
1230 * nsPush: 1373 * nsPush:
1231 * @ctxt: an XML parser context 1374 * @ctxt: an XML parser context
1232 * @prefix: the namespace prefix or NULL 1375 * @prefix: the namespace prefix or NULL
1233 * @URL: the namespace name 1376 * @URL: the namespace name
1234 * 1377 *
1235 * Pushes a new parser namespace on top of the ns stack 1378 * Pushes a new parser namespace on top of the ns stack
1236 * 1379 *
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 { 1435 {
1293 int i; 1436 int i;
1294 1437
1295 if (ctxt->nsTab == NULL) return(0); 1438 if (ctxt->nsTab == NULL) return(0);
1296 if (ctxt->nsNr < nr) { 1439 if (ctxt->nsNr < nr) {
1297 xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr); 1440 xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
1298 nr = ctxt->nsNr; 1441 nr = ctxt->nsNr;
1299 } 1442 }
1300 if (ctxt->nsNr <= 0) 1443 if (ctxt->nsNr <= 0)
1301 return (0); 1444 return (0);
1302 1445
1303 for (i = 0;i < nr;i++) { 1446 for (i = 0;i < nr;i++) {
1304 ctxt->nsNr--; 1447 ctxt->nsNr--;
1305 ctxt->nsTab[ctxt->nsNr] = NULL; 1448 ctxt->nsTab[ctxt->nsNr] = NULL;
1306 } 1449 }
1307 return(nr); 1450 return(nr);
1308 } 1451 }
1309 #endif 1452 #endif
1310 1453
1311 static int 1454 static int
1312 xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) { 1455 xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
(...skipping 29 matching lines...) Expand all
1342 return(-1); 1485 return(-1);
1343 } 1486 }
1344 1487
1345 /** 1488 /**
1346 * inputPush: 1489 * inputPush:
1347 * @ctxt: an XML parser context 1490 * @ctxt: an XML parser context
1348 * @value: the parser input 1491 * @value: the parser input
1349 * 1492 *
1350 * Pushes a new parser input on top of the input stack 1493 * Pushes a new parser input on top of the input stack
1351 * 1494 *
1352 * Returns 0 in case of error, the index in the stack otherwise 1495 * Returns -1 in case of error, the index in the stack otherwise
1353 */ 1496 */
1354 int 1497 int
1355 inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value) 1498 inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
1356 { 1499 {
1357 if ((ctxt == NULL) || (value == NULL)) 1500 if ((ctxt == NULL) || (value == NULL))
1358 return(0); 1501 return(-1);
1359 if (ctxt->inputNr >= ctxt->inputMax) { 1502 if (ctxt->inputNr >= ctxt->inputMax) {
1360 ctxt->inputMax *= 2; 1503 ctxt->inputMax *= 2;
1361 ctxt->inputTab = 1504 ctxt->inputTab =
1362 (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab, 1505 (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
1363 ctxt->inputMax * 1506 ctxt->inputMax *
1364 sizeof(ctxt->inputTab[0])); 1507 sizeof(ctxt->inputTab[0]));
1365 if (ctxt->inputTab == NULL) { 1508 if (ctxt->inputTab == NULL) {
1366 xmlErrMemory(ctxt, NULL); 1509 xmlErrMemory(ctxt, NULL);
1367 return (0); 1510 » xmlFreeInputStream(value);
1511 » ctxt->inputMax /= 2;
1512 » value = NULL;
1513 return (-1);
1368 } 1514 }
1369 } 1515 }
1370 ctxt->inputTab[ctxt->inputNr] = value; 1516 ctxt->inputTab[ctxt->inputNr] = value;
1371 ctxt->input = value; 1517 ctxt->input = value;
1372 return (ctxt->inputNr++); 1518 return (ctxt->inputNr++);
1373 } 1519 }
1374 /** 1520 /**
1375 * inputPop: 1521 * inputPop:
1376 * @ctxt: an XML parser context 1522 * @ctxt: an XML parser context
1377 * 1523 *
(...skipping 19 matching lines...) Expand all
1397 ctxt->inputTab[ctxt->inputNr] = NULL; 1543 ctxt->inputTab[ctxt->inputNr] = NULL;
1398 return (ret); 1544 return (ret);
1399 } 1545 }
1400 /** 1546 /**
1401 * nodePush: 1547 * nodePush:
1402 * @ctxt: an XML parser context 1548 * @ctxt: an XML parser context
1403 * @value: the element node 1549 * @value: the element node
1404 * 1550 *
1405 * Pushes a new element node on top of the node stack 1551 * Pushes a new element node on top of the node stack
1406 * 1552 *
1407 * Returns 0 in case of error, the index in the stack otherwise 1553 * Returns -1 in case of error, the index in the stack otherwise
1408 */ 1554 */
1409 int 1555 int
1410 nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value) 1556 nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
1411 { 1557 {
1412 if (ctxt == NULL) return(0); 1558 if (ctxt == NULL) return(0);
1413 if (ctxt->nodeNr >= ctxt->nodeMax) { 1559 if (ctxt->nodeNr >= ctxt->nodeMax) {
1414 xmlNodePtr *tmp; 1560 xmlNodePtr *tmp;
1415 1561
1416 tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab, 1562 tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
1417 ctxt->nodeMax * 2 * 1563 ctxt->nodeMax * 2 *
1418 sizeof(ctxt->nodeTab[0])); 1564 sizeof(ctxt->nodeTab[0]));
1419 if (tmp == NULL) { 1565 if (tmp == NULL) {
1420 xmlErrMemory(ctxt, NULL); 1566 xmlErrMemory(ctxt, NULL);
1421 return (0); 1567 return (-1);
1422 } 1568 }
1423 ctxt->nodeTab = tmp; 1569 ctxt->nodeTab = tmp;
1424 ctxt->nodeMax *= 2; 1570 ctxt->nodeMax *= 2;
1425 } 1571 }
1426 if (((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) { 1572 if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
1573 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
1427 xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR, 1574 xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
1428 » » "Excessive depth in document: change xmlParserMaxDepth = %d\n", 1575 » » "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
1429 xmlParserMaxDepth); 1576 xmlParserMaxDepth);
1430 ctxt->instate = XML_PARSER_EOF; 1577 ctxt->instate = XML_PARSER_EOF;
1431 » return(0); 1578 » return(-1);
1432 } 1579 }
1433 ctxt->nodeTab[ctxt->nodeNr] = value; 1580 ctxt->nodeTab[ctxt->nodeNr] = value;
1434 ctxt->node = value; 1581 ctxt->node = value;
1435 return (ctxt->nodeNr++); 1582 return (ctxt->nodeNr++);
1436 } 1583 }
1584
1437 /** 1585 /**
1438 * nodePop: 1586 * nodePop:
1439 * @ctxt: an XML parser context 1587 * @ctxt: an XML parser context
1440 * 1588 *
1441 * Pops the top element node from the node stack 1589 * Pops the top element node from the node stack
1442 * 1590 *
1443 * Returns the node just removed 1591 * Returns the node just removed
1444 */ 1592 */
1445 xmlNodePtr 1593 xmlNodePtr
1446 nodePop(xmlParserCtxtPtr ctxt) 1594 nodePop(xmlParserCtxtPtr ctxt)
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 1741
1594 static int spacePush(xmlParserCtxtPtr ctxt, int val) { 1742 static int spacePush(xmlParserCtxtPtr ctxt, int val) {
1595 if (ctxt->spaceNr >= ctxt->spaceMax) { 1743 if (ctxt->spaceNr >= ctxt->spaceMax) {
1596 int *tmp; 1744 int *tmp;
1597 1745
1598 ctxt->spaceMax *= 2; 1746 ctxt->spaceMax *= 2;
1599 tmp = (int *) xmlRealloc(ctxt->spaceTab, 1747 tmp = (int *) xmlRealloc(ctxt->spaceTab,
1600 ctxt->spaceMax * sizeof(ctxt->spaceTab[0])); 1748 ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
1601 if (tmp == NULL) { 1749 if (tmp == NULL) {
1602 xmlErrMemory(ctxt, NULL); 1750 xmlErrMemory(ctxt, NULL);
1603 » return(0); 1751 » ctxt->spaceMax /=2;
1752 » return(-1);
1604 } 1753 }
1605 ctxt->spaceTab = tmp; 1754 ctxt->spaceTab = tmp;
1606 } 1755 }
1607 ctxt->spaceTab[ctxt->spaceNr] = val; 1756 ctxt->spaceTab[ctxt->spaceNr] = val;
1608 ctxt->space = &ctxt->spaceTab[ctxt->spaceNr]; 1757 ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
1609 return(ctxt->spaceNr++); 1758 return(ctxt->spaceNr++);
1610 } 1759 }
1611 1760
1612 static int spacePop(xmlParserCtxtPtr ctxt) { 1761 static int spacePop(xmlParserCtxtPtr ctxt) {
1613 int ret; 1762 int ret;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) 1863 (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
1715 xmlPopInput(ctxt); 1864 xmlPopInput(ctxt);
1716 } 1865 }
1717 1866
1718 #define GROW if ((ctxt->progressive == 0) && \ 1867 #define GROW if ((ctxt->progressive == 0) && \
1719 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \ 1868 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \
1720 xmlGROW (ctxt); 1869 xmlGROW (ctxt);
1721 1870
1722 static void xmlGROW (xmlParserCtxtPtr ctxt) { 1871 static void xmlGROW (xmlParserCtxtPtr ctxt) {
1723 xmlParserInputGrow(ctxt->input, INPUT_CHUNK); 1872 xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
1724 if ((*ctxt->input->cur == 0) && 1873 if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
1725 (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) 1874 (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
1726 xmlPopInput(ctxt); 1875 xmlPopInput(ctxt);
1727 } 1876 }
1728 1877
1729 #define SKIP_BLANKS xmlSkipBlankChars(ctxt) 1878 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
1730 1879
1731 #define NEXT xmlNextChar(ctxt) 1880 #define NEXT xmlNextChar(ctxt)
1732 1881
1733 #define NEXT1 { \ 1882 #define NEXT1 { \
1734 ctxt->input->col++; \ 1883 ctxt->input->col++; \
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1841 return(CUR); 1990 return(CUR);
1842 } 1991 }
1843 1992
1844 /** 1993 /**
1845 * xmlPushInput: 1994 * xmlPushInput:
1846 * @ctxt: an XML parser context 1995 * @ctxt: an XML parser context
1847 * @input: an XML parser input fragment (entity, XML fragment ...). 1996 * @input: an XML parser input fragment (entity, XML fragment ...).
1848 * 1997 *
1849 * xmlPushInput: switch to a new input stream which is stacked on top 1998 * xmlPushInput: switch to a new input stream which is stacked on top
1850 * of the previous one(s). 1999 * of the previous one(s).
2000 * Returns -1 in case of error or the index in the input stack
1851 */ 2001 */
1852 void 2002 int
1853 xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) { 2003 xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
1854 if (input == NULL) return; 2004 int ret;
2005 if (input == NULL) return(-1);
1855 2006
1856 if (xmlParserDebugEntities) { 2007 if (xmlParserDebugEntities) {
1857 if ((ctxt->input != NULL) && (ctxt->input->filename)) 2008 if ((ctxt->input != NULL) && (ctxt->input->filename))
1858 xmlGenericError(xmlGenericErrorContext, 2009 xmlGenericError(xmlGenericErrorContext,
1859 "%s(%d): ", ctxt->input->filename, 2010 "%s(%d): ", ctxt->input->filename,
1860 ctxt->input->line); 2011 ctxt->input->line);
1861 xmlGenericError(xmlGenericErrorContext, 2012 xmlGenericError(xmlGenericErrorContext,
1862 "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur); 2013 "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
1863 } 2014 }
1864 inputPush(ctxt, input); 2015 ret = inputPush(ctxt, input);
1865 GROW; 2016 GROW;
2017 return(ret);
1866 } 2018 }
1867 2019
1868 /** 2020 /**
1869 * xmlParseCharRef: 2021 * xmlParseCharRef:
1870 * @ctxt: an XML parser context 2022 * @ctxt: an XML parser context
1871 * 2023 *
1872 * parse Reference declarations 2024 * parse Reference declarations
1873 * 2025 *
1874 * [66] CharRef ::= '&#' [0-9]+ ';' | 2026 * [66] CharRef ::= '&#' [0-9]+ ';' |
1875 * '&#x' [0-9a-fA-F]+ ';' 2027 * '&#x' [0-9a-fA-F]+ ';'
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
2233 /* 2385 /*
2234 * [ VC: Entity Declared ] 2386 * [ VC: Entity Declared ]
2235 * In a document with an external subset or external 2387 * In a document with an external subset or external
2236 * parameter entities with "standalone='no'", ... 2388 * parameter entities with "standalone='no'", ...
2237 * ... The declaration of a parameter entity must precede 2389 * ... The declaration of a parameter entity must precede
2238 * any reference to it... 2390 * any reference to it...
2239 */ 2391 */
2240 if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) { 2392 if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
2241 xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY, 2393 xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
2242 "PEReference: %%%s; not found\n", 2394 "PEReference: %%%s; not found\n",
2243 » » » » name); 2395 » » » » name, NULL);
2244 } else 2396 } else
2245 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY, 2397 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
2246 "PEReference: %%%s; not found\n", 2398 "PEReference: %%%s; not found\n",
2247 name, NULL); 2399 name, NULL);
2248 ctxt->valid = 0; 2400 ctxt->valid = 0;
2249 } 2401 }
2250 } else if (ctxt->input->free != deallocblankswrapper) { 2402 } else if (ctxt->input->free != deallocblankswrapper) {
2251 input = xmlNewBlanksWrapperInputStream(ctxt, entity); 2403 input = xmlNewBlanksWrapperInputStream(ctxt, entity);
2252 » » xmlPushInput(ctxt, input); 2404 » » if (xmlPushInput(ctxt, input) < 0)
2405 » » return;
2253 } else { 2406 } else {
2254 if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) || 2407 if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
2255 (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) { 2408 (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
2256 xmlChar start[4]; 2409 xmlChar start[4];
2257 xmlCharEncoding enc; 2410 xmlCharEncoding enc;
2258 2411
2259 /* 2412 /*
2260 * handle the extra spaces added before and after 2413 * handle the extra spaces added before and after
2261 * c.f. http://www.w3.org/TR/REC-xml#as-PE 2414 * c.f. http://www.w3.org/TR/REC-xml#as-PE
2262 * this is done independently. 2415 * this is done independently.
2263 */ 2416 */
2264 input = xmlNewEntityInputStream(ctxt, entity); 2417 input = xmlNewEntityInputStream(ctxt, entity);
2265 » » xmlPushInput(ctxt, input); 2418 » » if (xmlPushInput(ctxt, input) < 0)
2419 » » return;
2266 2420
2267 /* 2421 /*
2268 * Get the 4 first bytes and decode the charset 2422 * Get the 4 first bytes and decode the charset
2269 * if enc != XML_CHAR_ENCODING_NONE 2423 * if enc != XML_CHAR_ENCODING_NONE
2270 * plug some encoding conversion routines. 2424 * plug some encoding conversion routines.
2271 * Note that, since we may have some non-UTF8 2425 * Note that, since we may have some non-UTF8
2272 * encoding (like UTF16, bug 135229), the 'length' 2426 * encoding (like UTF16, bug 135229), the 'length'
2273 * is not known, but we can calculate based upon 2427 * is not known, but we can calculate based upon
2274 * the amount of data in the buffer. 2428 * the amount of data in the buffer.
2275 */ 2429 */
(...skipping 22 matching lines...) Expand all
2298 } 2452 }
2299 } else { 2453 } else {
2300 xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL); 2454 xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
2301 } 2455 }
2302 } 2456 }
2303 } 2457 }
2304 2458
2305 /* 2459 /*
2306 * Macro used to grow the current buffer. 2460 * Macro used to grow the current buffer.
2307 */ 2461 */
2308 #define growBuffer(buffer) {» » » » » » \ 2462 #define growBuffer(buffer, n) {»» » » » » \
2309 xmlChar *tmp; \ 2463 xmlChar *tmp; \
2310 buffer##_size += XML_PARSER_BUFFER_SIZE ; \
2311 buffer##_size *= 2; \ 2464 buffer##_size *= 2; \
2465 buffer##_size += n; \
2312 tmp = (xmlChar *) \ 2466 tmp = (xmlChar *) \
2313 xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \ 2467 xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
2314 if (tmp == NULL) goto mem_error; \ 2468 if (tmp == NULL) goto mem_error; \
2315 buffer = tmp; \ 2469 buffer = tmp; \
2316 } 2470 }
2317 2471
2318 /** 2472 /**
2319 * xmlStringLenDecodeEntities: 2473 * xmlStringLenDecodeEntities:
2320 * @ctxt: the parser context 2474 * @ctxt: the parser context
2321 * @str: the input string 2475 * @str: the input string
(...skipping 22 matching lines...) Expand all
2344 xmlChar *rep = NULL; 2498 xmlChar *rep = NULL;
2345 const xmlChar *last; 2499 const xmlChar *last;
2346 xmlEntityPtr ent; 2500 xmlEntityPtr ent;
2347 int c,l; 2501 int c,l;
2348 int nbchars = 0; 2502 int nbchars = 0;
2349 2503
2350 if ((ctxt == NULL) || (str == NULL) || (len < 0)) 2504 if ((ctxt == NULL) || (str == NULL) || (len < 0))
2351 return(NULL); 2505 return(NULL);
2352 last = str + len; 2506 last = str + len;
2353 2507
2354 if (ctxt->depth > 40) { 2508 if (((ctxt->depth > 40) &&
2509 ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2510 » (ctxt->depth > 1024)) {
2355 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); 2511 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2356 return(NULL); 2512 return(NULL);
2357 } 2513 }
2358 2514
2359 /* 2515 /*
2360 * allocate a translation buffer. 2516 * allocate a translation buffer.
2361 */ 2517 */
2362 buffer_size = XML_PARSER_BIG_BUFFER_SIZE; 2518 buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
2363 buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar)); 2519 buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
2364 if (buffer == NULL) goto mem_error; 2520 if (buffer == NULL) goto mem_error;
2365 2521
2366 /* 2522 /*
2367 * OK loop until we reach one of the ending char or a size limit. 2523 * OK loop until we reach one of the ending char or a size limit.
2368 * we are operating on already parsed values. 2524 * we are operating on already parsed values.
2369 */ 2525 */
2370 if (str < last) 2526 if (str < last)
2371 c = CUR_SCHAR(str, l); 2527 c = CUR_SCHAR(str, l);
2372 else 2528 else
2373 c = 0; 2529 c = 0;
2374 while ((c != 0) && (c != end) && /* non input consuming loop */ 2530 while ((c != 0) && (c != end) && /* non input consuming loop */
2375 (c != end2) && (c != end3)) { 2531 (c != end2) && (c != end3)) {
2376 2532
2377 if (c == 0) break; 2533 if (c == 0) break;
2378 if ((c == '&') && (str[1] == '#')) { 2534 if ((c == '&') && (str[1] == '#')) {
2379 int val = xmlParseStringCharRef(ctxt, &str); 2535 int val = xmlParseStringCharRef(ctxt, &str);
2380 if (val != 0) { 2536 if (val != 0) {
2381 COPY_BUF(0,buffer,nbchars,val); 2537 COPY_BUF(0,buffer,nbchars,val);
2382 } 2538 }
2383 if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) { 2539 if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
2384 » growBuffer(buffer); 2540 » growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2385 } 2541 }
2386 } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) { 2542 } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
2387 if (xmlParserDebugEntities) 2543 if (xmlParserDebugEntities)
2388 xmlGenericError(xmlGenericErrorContext, 2544 xmlGenericError(xmlGenericErrorContext,
2389 "String decoding Entity Reference: %.30s\n", 2545 "String decoding Entity Reference: %.30s\n",
2390 str); 2546 str);
2391 ent = xmlParseStringEntityRef(ctxt, &str); 2547 ent = xmlParseStringEntityRef(ctxt, &str);
2548 if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
2549 (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
2550 goto int_error;
2551 if (ent != NULL)
2552 ctxt->nbentities += ent->checked;
2392 if ((ent != NULL) && 2553 if ((ent != NULL) &&
2393 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) { 2554 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
2394 if (ent->content != NULL) { 2555 if (ent->content != NULL) {
2395 COPY_BUF(0,buffer,nbchars,ent->content[0]); 2556 COPY_BUF(0,buffer,nbchars,ent->content[0]);
2396 if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) { 2557 if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
2397 » » » growBuffer(buffer); 2558 » » » growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2398 } 2559 }
2399 } else { 2560 } else {
2400 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, 2561 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
2401 "predefined entity has no content\n"); 2562 "predefined entity has no content\n");
2402 } 2563 }
2403 } else if ((ent != NULL) && (ent->content != NULL)) { 2564 } else if ((ent != NULL) && (ent->content != NULL)) {
2404 ctxt->depth++; 2565 ctxt->depth++;
2405 rep = xmlStringDecodeEntities(ctxt, ent->content, what, 2566 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2406 0, 0, 0); 2567 0, 0, 0);
2407 ctxt->depth--; 2568 ctxt->depth--;
2569
2408 if (rep != NULL) { 2570 if (rep != NULL) {
2409 current = rep; 2571 current = rep;
2410 while (*current != 0) { /* non input consuming loop */ 2572 while (*current != 0) { /* non input consuming loop */
2411 buffer[nbchars++] = *current++; 2573 buffer[nbchars++] = *current++;
2412 if (nbchars > 2574 if (nbchars >
2413 buffer_size - XML_PARSER_BUFFER_SIZE) { 2575 buffer_size - XML_PARSER_BUFFER_SIZE) {
2414 » » » growBuffer(buffer); 2576 » » » if (xmlParserEntityCheck(ctxt, nbchars, ent))
2577 » » » » goto int_error;
2578 » » » growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2415 } 2579 }
2416 } 2580 }
2417 xmlFree(rep); 2581 xmlFree(rep);
2418 rep = NULL; 2582 rep = NULL;
2419 } 2583 }
2420 } else if (ent != NULL) { 2584 } else if (ent != NULL) {
2421 int i = xmlStrlen(ent->name); 2585 int i = xmlStrlen(ent->name);
2422 const xmlChar *cur = ent->name; 2586 const xmlChar *cur = ent->name;
2423 2587
2424 buffer[nbchars++] = '&'; 2588 buffer[nbchars++] = '&';
2425 if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) { 2589 if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
2426 » » growBuffer(buffer); 2590 » » growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2427 } 2591 }
2428 for (;i > 0;i--) 2592 for (;i > 0;i--)
2429 buffer[nbchars++] = *cur++; 2593 buffer[nbchars++] = *cur++;
2430 buffer[nbchars++] = ';'; 2594 buffer[nbchars++] = ';';
2431 } 2595 }
2432 } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) { 2596 } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
2433 if (xmlParserDebugEntities) 2597 if (xmlParserDebugEntities)
2434 xmlGenericError(xmlGenericErrorContext, 2598 xmlGenericError(xmlGenericErrorContext,
2435 "String decoding PE Reference: %.30s\n", str); 2599 "String decoding PE Reference: %.30s\n", str);
2436 ent = xmlParseStringPEReference(ctxt, &str); 2600 ent = xmlParseStringPEReference(ctxt, &str);
2601 if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
2602 goto int_error;
2603 if (ent != NULL)
2604 ctxt->nbentities += ent->checked;
2437 if (ent != NULL) { 2605 if (ent != NULL) {
2438 if (ent->content == NULL) { 2606 if (ent->content == NULL) {
2439 » » if (xmlLoadEntityContent(ctxt, ent) < 0) { 2607 » » xmlLoadEntityContent(ctxt, ent);
2440 » » }
2441 } 2608 }
2442 ctxt->depth++; 2609 ctxt->depth++;
2443 rep = xmlStringDecodeEntities(ctxt, ent->content, what, 2610 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2444 0, 0, 0); 2611 0, 0, 0);
2445 ctxt->depth--; 2612 ctxt->depth--;
2446 if (rep != NULL) { 2613 if (rep != NULL) {
2447 current = rep; 2614 current = rep;
2448 while (*current != 0) { /* non input consuming loop */ 2615 while (*current != 0) { /* non input consuming loop */
2449 buffer[nbchars++] = *current++; 2616 buffer[nbchars++] = *current++;
2450 if (nbchars > 2617 if (nbchars >
2451 buffer_size - XML_PARSER_BUFFER_SIZE) { 2618 buffer_size - XML_PARSER_BUFFER_SIZE) {
2452 » » » growBuffer(buffer); 2619 » » » if (xmlParserEntityCheck(ctxt, nbchars, ent))
2620 » » » goto int_error;
2621 » » » growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2453 } 2622 }
2454 } 2623 }
2455 xmlFree(rep); 2624 xmlFree(rep);
2456 rep = NULL; 2625 rep = NULL;
2457 } 2626 }
2458 } 2627 }
2459 } else { 2628 } else {
2460 COPY_BUF(l,buffer,nbchars,c); 2629 COPY_BUF(l,buffer,nbchars,c);
2461 str += l; 2630 str += l;
2462 if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) { 2631 if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
2463 » growBuffer(buffer); 2632 » growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2464 } 2633 }
2465 } 2634 }
2466 if (str < last) 2635 if (str < last)
2467 c = CUR_SCHAR(str, l); 2636 c = CUR_SCHAR(str, l);
2468 else 2637 else
2469 c = 0; 2638 c = 0;
2470 } 2639 }
2471 buffer[nbchars++] = 0; 2640 buffer[nbchars] = 0;
2472 return(buffer); 2641 return(buffer);
2473 2642
2474 mem_error: 2643 mem_error:
2475 xmlErrMemory(ctxt, NULL); 2644 xmlErrMemory(ctxt, NULL);
2645 int_error:
2476 if (rep != NULL) 2646 if (rep != NULL)
2477 xmlFree(rep); 2647 xmlFree(rep);
2478 if (buffer != NULL) 2648 if (buffer != NULL)
2479 xmlFree(buffer); 2649 xmlFree(buffer);
2480 return(NULL); 2650 return(NULL);
2481 } 2651 }
2482 2652
2483 /** 2653 /**
2484 * xmlStringDecodeEntities: 2654 * xmlStringDecodeEntities:
2485 * @ctxt: the parser context 2655 * @ctxt: the parser context
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
2758 return(ret); 2928 return(ret);
2759 } 2929 }
2760 2930
2761 /************************************************************************ 2931 /************************************************************************
2762 * * 2932 * *
2763 * The parser itself * 2933 * The parser itself *
2764 * Relates to http://www.w3.org/TR/REC-xml * 2934 * Relates to http://www.w3.org/TR/REC-xml *
2765 * * 2935 * *
2766 ************************************************************************/ 2936 ************************************************************************/
2767 2937
2768 static const xmlChar * xmlParseNameComplex(xmlParserCtxtPtr ctxt); 2938 /************************************************************************
2939 *» » » » » » » » » *
2940 *» Routines to parse Name, NCName and NmToken» » » *
2941 *» » » » » » » » » *
2942 ************************************************************************/
2943 #ifdef DEBUG
2944 static unsigned long nbParseName = 0;
2945 static unsigned long nbParseNmToken = 0;
2946 static unsigned long nbParseNCName = 0;
2947 static unsigned long nbParseNCNameComplex = 0;
2948 static unsigned long nbParseNameComplex = 0;
2949 static unsigned long nbParseStringName = 0;
2950 #endif
2951
2952 /*
2953 * The two following functions are related to the change of accepted
2954 * characters for Name and NmToken in the Revision 5 of XML-1.0
2955 * They correspond to the modified production [4] and the new production [4a]
2956 * changes in that revision. Also note that the macros used for the
2957 * productions Letter, Digit, CombiningChar and Extender are not needed
2958 * anymore.
2959 * We still keep compatibility to pre-revision5 parsing semantic if the
2960 * new XML_PARSE_OLD10 option is given to the parser.
2961 */
2962 static int
2963 xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
2964 if ((ctxt->options & XML_PARSE_OLD10) == 0) {
2965 /*
2966 » * Use the new checks of production [4] [4a] amd [5] of the
2967 » * Update 5 of XML-1.0
2968 » */
2969 » if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
2970 » (((c >= 'a') && (c <= 'z')) ||
2971 » ((c >= 'A') && (c <= 'Z')) ||
2972 » (c == '_') || (c == ':') ||
2973 » ((c >= 0xC0) && (c <= 0xD6)) ||
2974 » ((c >= 0xD8) && (c <= 0xF6)) ||
2975 » ((c >= 0xF8) && (c <= 0x2FF)) ||
2976 » ((c >= 0x370) && (c <= 0x37D)) ||
2977 » ((c >= 0x37F) && (c <= 0x1FFF)) ||
2978 » ((c >= 0x200C) && (c <= 0x200D)) ||
2979 » ((c >= 0x2070) && (c <= 0x218F)) ||
2980 » ((c >= 0x2C00) && (c <= 0x2FEF)) ||
2981 » ((c >= 0x3001) && (c <= 0xD7FF)) ||
2982 » ((c >= 0xF900) && (c <= 0xFDCF)) ||
2983 » ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
2984 » ((c >= 0x10000) && (c <= 0xEFFFF))))
2985 » return(1);
2986 } else {
2987 if (IS_LETTER(c) || (c == '_') || (c == ':'))
2988 » return(1);
2989 }
2990 return(0);
2991 }
2992
2993 static int
2994 xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
2995 if ((ctxt->options & XML_PARSE_OLD10) == 0) {
2996 /*
2997 » * Use the new checks of production [4] [4a] amd [5] of the
2998 » * Update 5 of XML-1.0
2999 » */
3000 » if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3001 » (((c >= 'a') && (c <= 'z')) ||
3002 » ((c >= 'A') && (c <= 'Z')) ||
3003 » ((c >= '0') && (c <= '9')) || /* !start */
3004 » (c == '_') || (c == ':') ||
3005 » (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3006 » ((c >= 0xC0) && (c <= 0xD6)) ||
3007 » ((c >= 0xD8) && (c <= 0xF6)) ||
3008 » ((c >= 0xF8) && (c <= 0x2FF)) ||
3009 » ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3010 » ((c >= 0x370) && (c <= 0x37D)) ||
3011 » ((c >= 0x37F) && (c <= 0x1FFF)) ||
3012 » ((c >= 0x200C) && (c <= 0x200D)) ||
3013 » ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3014 » ((c >= 0x2070) && (c <= 0x218F)) ||
3015 » ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3016 » ((c >= 0x3001) && (c <= 0xD7FF)) ||
3017 » ((c >= 0xF900) && (c <= 0xFDCF)) ||
3018 » ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3019 » ((c >= 0x10000) && (c <= 0xEFFFF))))
3020 » return(1);
3021 } else {
3022 if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3023 (c == '.') || (c == '-') ||
3024 » (c == '_') || (c == ':') ||
3025 » (IS_COMBINING(c)) ||
3026 » (IS_EXTENDER(c)))
3027 » return(1);
3028 }
3029 return(0);
3030 }
3031
2769 static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, 3032 static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
2770 int *len, int *alloc, int normalize); 3033 int *len, int *alloc, int normalize);
2771 3034
3035 static const xmlChar *
3036 xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
3037 int len = 0, l;
3038 int c;
3039 int count = 0;
3040
3041 #ifdef DEBUG
3042 nbParseNameComplex++;
3043 #endif
3044
3045 /*
3046 * Handler for more complex cases
3047 */
3048 GROW;
3049 c = CUR_CHAR(l);
3050 if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3051 /*
3052 * Use the new checks of production [4] [4a] amd [5] of the
3053 * Update 5 of XML-1.0
3054 */
3055 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3056 (!(((c >= 'a') && (c <= 'z')) ||
3057 ((c >= 'A') && (c <= 'Z')) ||
3058 (c == '_') || (c == ':') ||
3059 ((c >= 0xC0) && (c <= 0xD6)) ||
3060 ((c >= 0xD8) && (c <= 0xF6)) ||
3061 ((c >= 0xF8) && (c <= 0x2FF)) ||
3062 ((c >= 0x370) && (c <= 0x37D)) ||
3063 ((c >= 0x37F) && (c <= 0x1FFF)) ||
3064 ((c >= 0x200C) && (c <= 0x200D)) ||
3065 ((c >= 0x2070) && (c <= 0x218F)) ||
3066 ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3067 ((c >= 0x3001) && (c <= 0xD7FF)) ||
3068 ((c >= 0xF900) && (c <= 0xFDCF)) ||
3069 ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3070 ((c >= 0x10000) && (c <= 0xEFFFF))))) {
3071 return(NULL);
3072 }
3073 len += l;
3074 NEXTL(l);
3075 c = CUR_CHAR(l);
3076 while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3077 (((c >= 'a') && (c <= 'z')) ||
3078 ((c >= 'A') && (c <= 'Z')) ||
3079 ((c >= '0') && (c <= '9')) || /* !start */
3080 (c == '_') || (c == ':') ||
3081 (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3082 ((c >= 0xC0) && (c <= 0xD6)) ||
3083 ((c >= 0xD8) && (c <= 0xF6)) ||
3084 ((c >= 0xF8) && (c <= 0x2FF)) ||
3085 ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3086 ((c >= 0x370) && (c <= 0x37D)) ||
3087 ((c >= 0x37F) && (c <= 0x1FFF)) ||
3088 ((c >= 0x200C) && (c <= 0x200D)) ||
3089 ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3090 ((c >= 0x2070) && (c <= 0x218F)) ||
3091 ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3092 ((c >= 0x3001) && (c <= 0xD7FF)) ||
3093 ((c >= 0xF900) && (c <= 0xFDCF)) ||
3094 ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3095 ((c >= 0x10000) && (c <= 0xEFFFF))
3096 )) {
3097 if (count++ > 100) {
3098 count = 0;
3099 GROW;
3100 }
3101 len += l;
3102 NEXTL(l);
3103 c = CUR_CHAR(l);
3104 }
3105 } else {
3106 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3107 (!IS_LETTER(c) && (c != '_') &&
3108 (c != ':'))) {
3109 return(NULL);
3110 }
3111 len += l;
3112 NEXTL(l);
3113 c = CUR_CHAR(l);
3114
3115 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3116 ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3117 (c == '.') || (c == '-') ||
3118 (c == '_') || (c == ':') ||
3119 (IS_COMBINING(c)) ||
3120 (IS_EXTENDER(c)))) {
3121 if (count++ > 100) {
3122 count = 0;
3123 GROW;
3124 }
3125 len += l;
3126 NEXTL(l);
3127 c = CUR_CHAR(l);
3128 }
3129 }
3130 if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
3131 return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
3132 return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3133 }
3134
2772 /** 3135 /**
2773 * xmlParseName: 3136 * xmlParseName:
2774 * @ctxt: an XML parser context 3137 * @ctxt: an XML parser context
2775 * 3138 *
2776 * parse an XML name. 3139 * parse an XML name.
2777 * 3140 *
2778 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 3141 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
2779 * CombiningChar | Extender 3142 * CombiningChar | Extender
2780 * 3143 *
2781 * [5] Name ::= (Letter | '_' | ':') (NameChar)* 3144 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
2782 * 3145 *
2783 * [6] Names ::= Name (#x20 Name)* 3146 * [6] Names ::= Name (#x20 Name)*
2784 * 3147 *
2785 * Returns the Name parsed or NULL 3148 * Returns the Name parsed or NULL
2786 */ 3149 */
2787 3150
2788 const xmlChar * 3151 const xmlChar *
2789 xmlParseName(xmlParserCtxtPtr ctxt) { 3152 xmlParseName(xmlParserCtxtPtr ctxt) {
2790 const xmlChar *in; 3153 const xmlChar *in;
2791 const xmlChar *ret; 3154 const xmlChar *ret;
2792 int count = 0; 3155 int count = 0;
2793 3156
2794 GROW; 3157 GROW;
2795 3158
3159 #ifdef DEBUG
3160 nbParseName++;
3161 #endif
3162
2796 /* 3163 /*
2797 * Accelerator for simple ASCII names 3164 * Accelerator for simple ASCII names
2798 */ 3165 */
2799 in = ctxt->input->cur; 3166 in = ctxt->input->cur;
2800 if (((*in >= 0x61) && (*in <= 0x7A)) || 3167 if (((*in >= 0x61) && (*in <= 0x7A)) ||
2801 ((*in >= 0x41) && (*in <= 0x5A)) || 3168 ((*in >= 0x41) && (*in <= 0x5A)) ||
2802 (*in == '_') || (*in == ':')) { 3169 (*in == '_') || (*in == ':')) {
2803 in++; 3170 in++;
2804 while (((*in >= 0x61) && (*in <= 0x7A)) || 3171 while (((*in >= 0x61) && (*in <= 0x7A)) ||
2805 ((*in >= 0x41) && (*in <= 0x5A)) || 3172 ((*in >= 0x41) && (*in <= 0x5A)) ||
2806 ((*in >= 0x30) && (*in <= 0x39)) || 3173 ((*in >= 0x30) && (*in <= 0x39)) ||
2807 (*in == '_') || (*in == '-') || 3174 (*in == '_') || (*in == '-') ||
2808 (*in == ':') || (*in == '.')) 3175 (*in == ':') || (*in == '.'))
2809 in++; 3176 in++;
2810 if ((*in > 0) && (*in < 0x80)) { 3177 if ((*in > 0) && (*in < 0x80)) {
2811 count = in - ctxt->input->cur; 3178 count = in - ctxt->input->cur;
2812 ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count); 3179 ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
2813 ctxt->input->cur = in; 3180 ctxt->input->cur = in;
2814 ctxt->nbChars += count; 3181 ctxt->nbChars += count;
2815 ctxt->input->col += count; 3182 ctxt->input->col += count;
2816 if (ret == NULL) 3183 if (ret == NULL)
2817 xmlErrMemory(ctxt, NULL); 3184 xmlErrMemory(ctxt, NULL);
2818 return(ret); 3185 return(ret);
2819 } 3186 }
2820 } 3187 }
3188 /* accelerator for special cases */
2821 return(xmlParseNameComplex(ctxt)); 3189 return(xmlParseNameComplex(ctxt));
2822 } 3190 }
2823 3191
3192 static const xmlChar *
3193 xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
3194 int len = 0, l;
3195 int c;
3196 int count = 0;
3197
3198 #ifdef DEBUG
3199 nbParseNCNameComplex++;
3200 #endif
3201
3202 /*
3203 * Handler for more complex cases
3204 */
3205 GROW;
3206 c = CUR_CHAR(l);
3207 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3208 (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
3209 return(NULL);
3210 }
3211
3212 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3213 (xmlIsNameChar(ctxt, c) && (c != ':'))) {
3214 if (count++ > 100) {
3215 count = 0;
3216 GROW;
3217 }
3218 len += l;
3219 NEXTL(l);
3220 c = CUR_CHAR(l);
3221 }
3222 return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3223 }
3224
3225 /**
3226 * xmlParseNCName:
3227 * @ctxt: an XML parser context
3228 * @len: lenght of the string parsed
3229 *
3230 * parse an XML name.
3231 *
3232 * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
3233 * CombiningChar | Extender
3234 *
3235 * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
3236 *
3237 * Returns the Name parsed or NULL
3238 */
3239
3240 static const xmlChar *
3241 xmlParseNCName(xmlParserCtxtPtr ctxt) {
3242 const xmlChar *in;
3243 const xmlChar *ret;
3244 int count = 0;
3245
3246 #ifdef DEBUG
3247 nbParseNCName++;
3248 #endif
3249
3250 /*
3251 * Accelerator for simple ASCII names
3252 */
3253 in = ctxt->input->cur;
3254 if (((*in >= 0x61) && (*in <= 0x7A)) ||
3255 ((*in >= 0x41) && (*in <= 0x5A)) ||
3256 (*in == '_')) {
3257 in++;
3258 while (((*in >= 0x61) && (*in <= 0x7A)) ||
3259 ((*in >= 0x41) && (*in <= 0x5A)) ||
3260 ((*in >= 0x30) && (*in <= 0x39)) ||
3261 (*in == '_') || (*in == '-') ||
3262 (*in == '.'))
3263 in++;
3264 if ((*in > 0) && (*in < 0x80)) {
3265 count = in - ctxt->input->cur;
3266 ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3267 ctxt->input->cur = in;
3268 ctxt->nbChars += count;
3269 ctxt->input->col += count;
3270 if (ret == NULL) {
3271 xmlErrMemory(ctxt, NULL);
3272 }
3273 return(ret);
3274 }
3275 }
3276 return(xmlParseNCNameComplex(ctxt));
3277 }
3278
2824 /** 3279 /**
2825 * xmlParseNameAndCompare: 3280 * xmlParseNameAndCompare:
2826 * @ctxt: an XML parser context 3281 * @ctxt: an XML parser context
2827 * 3282 *
2828 * parse an XML name and compares for match 3283 * parse an XML name and compares for match
2829 * (specialized for endtag parsing) 3284 * (specialized for endtag parsing)
2830 * 3285 *
2831 * Returns NULL for an illegal name, (xmlChar*) 1 for success 3286 * Returns NULL for an illegal name, (xmlChar*) 1 for success
2832 * and the name for mismatch 3287 * and the name for mismatch
2833 */ 3288 */
2834 3289
2835 static const xmlChar * 3290 static const xmlChar *
2836 xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) { 3291 xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
2837 register const xmlChar *cmp = other; 3292 register const xmlChar *cmp = other;
2838 register const xmlChar *in; 3293 register const xmlChar *in;
2839 const xmlChar *ret; 3294 const xmlChar *ret;
2840 3295
2841 GROW; 3296 GROW;
2842 3297
2843 in = ctxt->input->cur; 3298 in = ctxt->input->cur;
2844 while (*in != 0 && *in == *cmp) { 3299 while (*in != 0 && *in == *cmp) {
2845 » ++in; 3300 » ++in;
2846 ++cmp; 3301 ++cmp;
2847 ctxt->input->col++; 3302 ctxt->input->col++;
2848 } 3303 }
2849 if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) { 3304 if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
2850 » /* success */ 3305 » /* success */
2851 ctxt->input->cur = in; 3306 ctxt->input->cur = in;
2852 return (const xmlChar*) 1; 3307 return (const xmlChar*) 1;
2853 } 3308 }
2854 /* failure (or end of input buffer), check with full function */ 3309 /* failure (or end of input buffer), check with full function */
2855 ret = xmlParseName (ctxt); 3310 ret = xmlParseName (ctxt);
2856 /* strings coming from the dictionnary direct compare possible */ 3311 /* strings coming from the dictionnary direct compare possible */
2857 if (ret == other) { 3312 if (ret == other) {
2858 return (const xmlChar*) 1; 3313 return (const xmlChar*) 1;
2859 } 3314 }
2860 return ret; 3315 return ret;
2861 } 3316 }
2862 3317
2863 static const xmlChar *
2864 xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
2865 int len = 0, l;
2866 int c;
2867 int count = 0;
2868
2869 /*
2870 * Handler for more complex cases
2871 */
2872 GROW;
2873 c = CUR_CHAR(l);
2874 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
2875 (!IS_LETTER(c) && (c != '_') &&
2876 (c != ':'))) {
2877 return(NULL);
2878 }
2879
2880 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
2881 ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
2882 (c == '.') || (c == '-') ||
2883 (c == '_') || (c == ':') ||
2884 (IS_COMBINING(c)) ||
2885 (IS_EXTENDER(c)))) {
2886 if (count++ > 100) {
2887 count = 0;
2888 GROW;
2889 }
2890 len += l;
2891 NEXTL(l);
2892 c = CUR_CHAR(l);
2893 }
2894 if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
2895 return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
2896 return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
2897 }
2898
2899 /** 3318 /**
2900 * xmlParseStringName: 3319 * xmlParseStringName:
2901 * @ctxt: an XML parser context 3320 * @ctxt: an XML parser context
2902 * @str: a pointer to the string pointer (IN/OUT) 3321 * @str: a pointer to the string pointer (IN/OUT)
2903 * 3322 *
2904 * parse an XML name. 3323 * parse an XML name.
2905 * 3324 *
2906 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 3325 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
2907 * CombiningChar | Extender 3326 * CombiningChar | Extender
2908 * 3327 *
2909 * [5] Name ::= (Letter | '_' | ':') (NameChar)* 3328 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
2910 * 3329 *
2911 * [6] Names ::= Name (#x20 Name)* 3330 * [6] Names ::= Name (#x20 Name)*
2912 * 3331 *
2913 * Returns the Name parsed or NULL. The @str pointer 3332 * Returns the Name parsed or NULL. The @str pointer
2914 * is updated to the current location in the string. 3333 * is updated to the current location in the string.
2915 */ 3334 */
2916 3335
2917 static xmlChar * 3336 static xmlChar *
2918 xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) { 3337 xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
2919 xmlChar buf[XML_MAX_NAMELEN + 5]; 3338 xmlChar buf[XML_MAX_NAMELEN + 5];
2920 const xmlChar *cur = *str; 3339 const xmlChar *cur = *str;
2921 int len = 0, l; 3340 int len = 0, l;
2922 int c; 3341 int c;
2923 3342
3343 #ifdef DEBUG
3344 nbParseStringName++;
3345 #endif
3346
2924 c = CUR_SCHAR(cur, l); 3347 c = CUR_SCHAR(cur, l);
2925 if (!IS_LETTER(c) && (c != '_') && 3348 if (!xmlIsNameStartChar(ctxt, c)) {
2926 (c != ':')) {
2927 return(NULL); 3349 return(NULL);
2928 } 3350 }
2929 3351
2930 while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigentname.xml */ 3352 COPY_BUF(l,buf,len,c);
2931 (c == '.') || (c == '-') || 3353 cur += l;
2932 » (c == '_') || (c == ':') || 3354 c = CUR_SCHAR(cur, l);
2933 » (IS_COMBINING(c)) || 3355 while (xmlIsNameChar(ctxt, c)) {
2934 » (IS_EXTENDER(c))) {
2935 COPY_BUF(l,buf,len,c); 3356 COPY_BUF(l,buf,len,c);
2936 cur += l; 3357 cur += l;
2937 c = CUR_SCHAR(cur, l); 3358 c = CUR_SCHAR(cur, l);
2938 if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */ 3359 if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
2939 /* 3360 /*
2940 * Okay someone managed to make a huge name, so he's ready to pay 3361 * Okay someone managed to make a huge name, so he's ready to pay
2941 * for the processing speed. 3362 * for the processing speed.
2942 */ 3363 */
2943 xmlChar *buffer; 3364 xmlChar *buffer;
2944 int max = len * 2; 3365 int max = len * 2;
2945 » 3366
2946 buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); 3367 buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
2947 if (buffer == NULL) { 3368 if (buffer == NULL) {
2948 xmlErrMemory(ctxt, NULL); 3369 xmlErrMemory(ctxt, NULL);
2949 return(NULL); 3370 return(NULL);
2950 } 3371 }
2951 memcpy(buffer, buf, len); 3372 memcpy(buffer, buf, len);
2952 » while ((IS_LETTER(c)) || (IS_DIGIT(c)) || 3373 » while (xmlIsNameChar(ctxt, c)) {
2953 » /* test bigentname.xml */
2954 » » (c == '.') || (c == '-') ||
2955 » » (c == '_') || (c == ':') ||
2956 » » (IS_COMBINING(c)) ||
2957 » » (IS_EXTENDER(c))) {
2958 if (len + 10 > max) { 3374 if (len + 10 > max) {
2959 xmlChar *tmp; 3375 xmlChar *tmp;
2960 max *= 2; 3376 max *= 2;
2961 tmp = (xmlChar *) xmlRealloc(buffer, 3377 tmp = (xmlChar *) xmlRealloc(buffer,
2962 max * sizeof(xmlChar)); 3378 max * sizeof(xmlChar));
2963 if (tmp == NULL) { 3379 if (tmp == NULL) {
2964 xmlErrMemory(ctxt, NULL); 3380 xmlErrMemory(ctxt, NULL);
2965 xmlFree(buffer); 3381 xmlFree(buffer);
2966 return(NULL); 3382 return(NULL);
2967 } 3383 }
2968 buffer = tmp; 3384 buffer = tmp;
2969 } 3385 }
2970 COPY_BUF(l,buffer,len,c); 3386 COPY_BUF(l,buffer,len,c);
2971 cur += l; 3387 cur += l;
2972 c = CUR_SCHAR(cur, l); 3388 c = CUR_SCHAR(cur, l);
2973 } 3389 }
2974 buffer[len] = 0; 3390 buffer[len] = 0;
2975 *str = cur; 3391 *str = cur;
2976 return(buffer); 3392 return(buffer);
2977 } 3393 }
2978 } 3394 }
2979 *str = cur; 3395 *str = cur;
2980 return(xmlStrndup(buf, len)); 3396 return(xmlStrndup(buf, len));
2981 } 3397 }
2982 3398
2983 /** 3399 /**
2984 * xmlParseNmtoken: 3400 * xmlParseNmtoken:
2985 * @ctxt: an XML parser context 3401 * @ctxt: an XML parser context
2986 * 3402 *
2987 * parse an XML Nmtoken. 3403 * parse an XML Nmtoken.
2988 * 3404 *
2989 * [7] Nmtoken ::= (NameChar)+ 3405 * [7] Nmtoken ::= (NameChar)+
2990 * 3406 *
2991 * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)* 3407 * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
2992 * 3408 *
2993 * Returns the Nmtoken parsed or NULL 3409 * Returns the Nmtoken parsed or NULL
2994 */ 3410 */
2995 3411
2996 xmlChar * 3412 xmlChar *
2997 xmlParseNmtoken(xmlParserCtxtPtr ctxt) { 3413 xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
2998 xmlChar buf[XML_MAX_NAMELEN + 5]; 3414 xmlChar buf[XML_MAX_NAMELEN + 5];
2999 int len = 0, l; 3415 int len = 0, l;
3000 int c; 3416 int c;
3001 int count = 0; 3417 int count = 0;
3002 3418
3419 #ifdef DEBUG
3420 nbParseNmToken++;
3421 #endif
3422
3003 GROW; 3423 GROW;
3004 c = CUR_CHAR(l); 3424 c = CUR_CHAR(l);
3005 3425
3006 while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */ 3426 while (xmlIsNameChar(ctxt, c)) {
3007 (c == '.') || (c == '-') ||
3008 » (c == '_') || (c == ':') ||
3009 » (IS_COMBINING(c)) ||
3010 » (IS_EXTENDER(c))) {
3011 if (count++ > 100) { 3427 if (count++ > 100) {
3012 count = 0; 3428 count = 0;
3013 GROW; 3429 GROW;
3014 } 3430 }
3015 COPY_BUF(l,buf,len,c); 3431 COPY_BUF(l,buf,len,c);
3016 NEXTL(l); 3432 NEXTL(l);
3017 c = CUR_CHAR(l); 3433 c = CUR_CHAR(l);
3018 if (len >= XML_MAX_NAMELEN) { 3434 if (len >= XML_MAX_NAMELEN) {
3019 /* 3435 /*
3020 * Okay someone managed to make a huge token, so he's ready to pay 3436 * Okay someone managed to make a huge token, so he's ready to pay
3021 * for the processing speed. 3437 * for the processing speed.
3022 */ 3438 */
3023 xmlChar *buffer; 3439 xmlChar *buffer;
3024 int max = len * 2; 3440 int max = len * 2;
3025 » 3441
3026 buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); 3442 buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3027 if (buffer == NULL) { 3443 if (buffer == NULL) {
3028 xmlErrMemory(ctxt, NULL); 3444 xmlErrMemory(ctxt, NULL);
3029 return(NULL); 3445 return(NULL);
3030 } 3446 }
3031 memcpy(buffer, buf, len); 3447 memcpy(buffer, buf, len);
3032 » while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */ 3448 » while (xmlIsNameChar(ctxt, c)) {
3033 » » (c == '.') || (c == '-') ||
3034 » » (c == '_') || (c == ':') ||
3035 » » (IS_COMBINING(c)) ||
3036 » » (IS_EXTENDER(c))) {
3037 if (count++ > 100) { 3449 if (count++ > 100) {
3038 count = 0; 3450 count = 0;
3039 GROW; 3451 GROW;
3040 } 3452 }
3041 if (len + 10 > max) { 3453 if (len + 10 > max) {
3042 xmlChar *tmp; 3454 xmlChar *tmp;
3043 3455
3044 max *= 2; 3456 max *= 2;
3045 tmp = (xmlChar *) xmlRealloc(buffer, 3457 tmp = (xmlChar *) xmlRealloc(buffer,
3046 max * sizeof(xmlChar)); 3458 max * sizeof(xmlChar));
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
3255 (IS_CHAR(c)) && (c != '<')) { 3667 (IS_CHAR(c)) && (c != '<')) {
3256 if (c == 0) break; 3668 if (c == 0) break;
3257 if (c == '&') { 3669 if (c == '&') {
3258 in_space = 0; 3670 in_space = 0;
3259 if (NXT(1) == '#') { 3671 if (NXT(1) == '#') {
3260 int val = xmlParseCharRef(ctxt); 3672 int val = xmlParseCharRef(ctxt);
3261 3673
3262 if (val == '&') { 3674 if (val == '&') {
3263 if (ctxt->replaceEntities) { 3675 if (ctxt->replaceEntities) {
3264 if (len > buf_size - 10) { 3676 if (len > buf_size - 10) {
3265 » » » growBuffer(buf); 3677 » » » growBuffer(buf, 10);
3266 } 3678 }
3267 buf[len++] = '&'; 3679 buf[len++] = '&';
3268 } else { 3680 } else {
3269 /* 3681 /*
3270 * The reparsing will be done in xmlStringGetNodeList() 3682 * The reparsing will be done in xmlStringGetNodeList()
3271 * called by the attribute() function in SAX.c 3683 * called by the attribute() function in SAX.c
3272 */ 3684 */
3273 if (len > buf_size - 10) { 3685 if (len > buf_size - 10) {
3274 » » » growBuffer(buf); 3686 » » » growBuffer(buf, 10);
3275 } 3687 }
3276 buf[len++] = '&'; 3688 buf[len++] = '&';
3277 buf[len++] = '#'; 3689 buf[len++] = '#';
3278 buf[len++] = '3'; 3690 buf[len++] = '3';
3279 buf[len++] = '8'; 3691 buf[len++] = '8';
3280 buf[len++] = ';'; 3692 buf[len++] = ';';
3281 } 3693 }
3282 } else if (val != 0) { 3694 } else if (val != 0) {
3283 if (len > buf_size - 10) { 3695 if (len > buf_size - 10) {
3284 » » » growBuffer(buf); 3696 » » » growBuffer(buf, 10);
3285 } 3697 }
3286 len += xmlCopyChar(0, &buf[len], val); 3698 len += xmlCopyChar(0, &buf[len], val);
3287 } 3699 }
3288 } else { 3700 } else {
3289 ent = xmlParseEntityRef(ctxt); 3701 ent = xmlParseEntityRef(ctxt);
3702 ctxt->nbentities++;
3703 if (ent != NULL)
3704 ctxt->nbentities += ent->owner;
3290 if ((ent != NULL) && 3705 if ((ent != NULL) &&
3291 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) { 3706 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
3292 if (len > buf_size - 10) { 3707 if (len > buf_size - 10) {
3293 » » » growBuffer(buf); 3708 » » » growBuffer(buf, 10);
3294 } 3709 }
3295 if ((ctxt->replaceEntities == 0) && 3710 if ((ctxt->replaceEntities == 0) &&
3296 (ent->content[0] == '&')) { 3711 (ent->content[0] == '&')) {
3297 buf[len++] = '&'; 3712 buf[len++] = '&';
3298 buf[len++] = '#'; 3713 buf[len++] = '#';
3299 buf[len++] = '3'; 3714 buf[len++] = '3';
3300 buf[len++] = '8'; 3715 buf[len++] = '8';
3301 buf[len++] = ';'; 3716 buf[len++] = ';';
3302 } else { 3717 } else {
3303 buf[len++] = ent->content[0]; 3718 buf[len++] = ent->content[0];
3304 } 3719 }
3305 } else if ((ent != NULL) && 3720 } else if ((ent != NULL) &&
3306 (ctxt->replaceEntities != 0)) { 3721 (ctxt->replaceEntities != 0)) {
3307 if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) { 3722 if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
3308 rep = xmlStringDecodeEntities(ctxt, ent->content, 3723 rep = xmlStringDecodeEntities(ctxt, ent->content,
3309 XML_SUBSTITUTE_REF, 3724 XML_SUBSTITUTE_REF,
3310 0, 0, 0); 3725 0, 0, 0);
3311 if (rep != NULL) { 3726 if (rep != NULL) {
3312 current = rep; 3727 current = rep;
3313 while (*current != 0) { /* non input consuming */ 3728 while (*current != 0) { /* non input consuming */
3314 » » » » buf[len++] = *current++; 3729 if ((*current == 0xD) || (*current == 0xA) ||
3730 (*current == 0x9)) {
3731 buf[len++] = 0x20;
3732 current++;
3733 } else
3734 buf[len++] = *current++;
3315 if (len > buf_size - 10) { 3735 if (len > buf_size - 10) {
3316 » » » » growBuffer(buf); 3736 » » » » growBuffer(buf, 10);
3317 } 3737 }
3318 } 3738 }
3319 xmlFree(rep); 3739 xmlFree(rep);
3320 rep = NULL; 3740 rep = NULL;
3321 } 3741 }
3322 } else { 3742 } else {
3323 if (len > buf_size - 10) { 3743 if (len > buf_size - 10) {
3324 » » » growBuffer(buf); 3744 » » » growBuffer(buf, 10);
3325 } 3745 }
3326 if (ent->content != NULL) 3746 if (ent->content != NULL)
3327 buf[len++] = ent->content[0]; 3747 buf[len++] = ent->content[0];
3328 } 3748 }
3329 } else if (ent != NULL) { 3749 } else if (ent != NULL) {
3330 int i = xmlStrlen(ent->name); 3750 int i = xmlStrlen(ent->name);
3331 const xmlChar *cur = ent->name; 3751 const xmlChar *cur = ent->name;
3332 3752
3333 /* 3753 /*
3334 * This may look absurd but is needed to detect 3754 * This may look absurd but is needed to detect
3335 * entities problems 3755 * entities problems
3336 */ 3756 */
3337 if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) && 3757 if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
3338 (ent->content != NULL)) { 3758 (ent->content != NULL)) {
3339 rep = xmlStringDecodeEntities(ctxt, ent->content, 3759 rep = xmlStringDecodeEntities(ctxt, ent->content,
3340 XML_SUBSTITUTE_REF, 0, 0, 0); 3760 XML_SUBSTITUTE_REF, 0, 0, 0);
3341 if (rep != NULL) { 3761 if (rep != NULL) {
3342 xmlFree(rep); 3762 xmlFree(rep);
3343 rep = NULL; 3763 rep = NULL;
3344 } 3764 }
3345 } 3765 }
3346 3766
3347 /* 3767 /*
3348 * Just output the reference 3768 * Just output the reference
3349 */ 3769 */
3350 buf[len++] = '&'; 3770 buf[len++] = '&';
3351 while (len > buf_size - i - 10) { 3771 while (len > buf_size - i - 10) {
3352 » » » growBuffer(buf); 3772 » » » growBuffer(buf, i + 10);
3353 } 3773 }
3354 for (;i > 0;i--) 3774 for (;i > 0;i--)
3355 buf[len++] = *cur++; 3775 buf[len++] = *cur++;
3356 buf[len++] = ';'; 3776 buf[len++] = ';';
3357 } 3777 }
3358 } 3778 }
3359 } else { 3779 } else {
3360 if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) { 3780 if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
3361 if ((len != 0) || (!normalize)) { 3781 if ((len != 0) || (!normalize)) {
3362 if ((!normalize) || (!in_space)) { 3782 if ((!normalize) || (!in_space)) {
3363 COPY_BUF(l,buf,len,0x20); 3783 COPY_BUF(l,buf,len,0x20);
3364 » » » if (len > buf_size - 10) { 3784 » » » while (len > buf_size - 10) {
3365 » » » growBuffer(buf); 3785 » » » growBuffer(buf, 10);
3366 } 3786 }
3367 } 3787 }
3368 in_space = 1; 3788 in_space = 1;
3369 } 3789 }
3370 } else { 3790 } else {
3371 in_space = 0; 3791 in_space = 0;
3372 COPY_BUF(l,buf,len,c); 3792 COPY_BUF(l,buf,len,c);
3373 if (len > buf_size - 10) { 3793 if (len > buf_size - 10) {
3374 » » growBuffer(buf); 3794 » » growBuffer(buf, 10);
3375 } 3795 }
3376 } 3796 }
3377 NEXTL(l); 3797 NEXTL(l);
3378 } 3798 }
3379 GROW; 3799 GROW;
3380 c = CUR_CHAR(l); 3800 c = CUR_CHAR(l);
3381 } 3801 }
3382 if ((in_space) && (normalize)) { 3802 if ((in_space) && (normalize)) {
3383 while (buf[len - 1] == 0x20) len--; 3803 while (buf[len - 1] == 0x20) len--;
3384 } 3804 }
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
3594 buf[len] = 0; 4014 buf[len] = 0;
3595 if (cur != stop) { 4015 if (cur != stop) {
3596 xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL); 4016 xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
3597 } else { 4017 } else {
3598 NEXT; 4018 NEXT;
3599 } 4019 }
3600 ctxt->instate = oldstate; 4020 ctxt->instate = oldstate;
3601 return(buf); 4021 return(buf);
3602 } 4022 }
3603 4023
3604 void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata); 4024 static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
3605 4025
3606 /* 4026 /*
3607 * used for the test in the inner loop of the char data testing 4027 * used for the test in the inner loop of the char data testing
3608 */ 4028 */
3609 static const unsigned char test_char_data[256] = { 4029 static const unsigned char test_char_data[256] = {
3610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4030 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3611 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */ 4031 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
3612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4032 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4033 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3614 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */ 4034 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
3758 } 4178 }
3759 line = ctxt->input->line; 4179 line = ctxt->input->line;
3760 col = ctxt->input->col; 4180 col = ctxt->input->col;
3761 } else if (ctxt->sax != NULL) { 4181 } else if (ctxt->sax != NULL) {
3762 if (ctxt->sax->characters != NULL) 4182 if (ctxt->sax->characters != NULL)
3763 ctxt->sax->characters(ctxt->userData, 4183 ctxt->sax->characters(ctxt->userData,
3764 ctxt->input->cur, nbchar); 4184 ctxt->input->cur, nbchar);
3765 line = ctxt->input->line; 4185 line = ctxt->input->line;
3766 col = ctxt->input->col; 4186 col = ctxt->input->col;
3767 } 4187 }
4188 /* something really bad happened in the SAX callback */
4189 if (ctxt->instate != XML_PARSER_CONTENT)
4190 return;
3768 } 4191 }
3769 ctxt->input->cur = in; 4192 ctxt->input->cur = in;
3770 if (*in == 0xD) { 4193 if (*in == 0xD) {
3771 in++; 4194 in++;
3772 if (*in == 0xA) { 4195 if (*in == 0xA) {
3773 ctxt->input->cur = in; 4196 ctxt->input->cur = in;
3774 in++; 4197 in++;
3775 ctxt->input->line++; ctxt->input->col = 1; 4198 ctxt->input->line++; ctxt->input->col = 1;
3776 continue; /* while */ 4199 continue; /* while */
3777 } 4200 }
(...skipping 18 matching lines...) Expand all
3796 4219
3797 /** 4220 /**
3798 * xmlParseCharDataComplex: 4221 * xmlParseCharDataComplex:
3799 * @ctxt: an XML parser context 4222 * @ctxt: an XML parser context
3800 * @cdata: int indicating whether we are within a CDATA section 4223 * @cdata: int indicating whether we are within a CDATA section
3801 * 4224 *
3802 * parse a CharData section.this is the fallback function 4225 * parse a CharData section.this is the fallback function
3803 * of xmlParseCharData() when the parsing requires handling 4226 * of xmlParseCharData() when the parsing requires handling
3804 * of non-ASCII characters. 4227 * of non-ASCII characters.
3805 */ 4228 */
3806 void 4229 static void
3807 xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) { 4230 xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
3808 xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5]; 4231 xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
3809 int nbchar = 0; 4232 int nbchar = 0;
3810 int cur, l; 4233 int cur, l;
3811 int count = 0; 4234 int count = 0;
3812 4235
3813 SHRINK; 4236 SHRINK;
3814 GROW; 4237 GROW;
3815 cur = CUR_CHAR(l); 4238 cur = CUR_CHAR(l);
3816 while ((cur != '<') && /* checked */ 4239 while ((cur != '<') && /* checked */
(...skipping 21 matching lines...) Expand all
3838 } else { 4261 } else {
3839 if (ctxt->sax->characters != NULL) 4262 if (ctxt->sax->characters != NULL)
3840 ctxt->sax->characters(ctxt->userData, buf, nbchar); 4263 ctxt->sax->characters(ctxt->userData, buf, nbchar);
3841 if ((ctxt->sax->characters != 4264 if ((ctxt->sax->characters !=
3842 ctxt->sax->ignorableWhitespace) && 4265 ctxt->sax->ignorableWhitespace) &&
3843 (*ctxt->space == -1)) 4266 (*ctxt->space == -1))
3844 *ctxt->space = -2; 4267 *ctxt->space = -2;
3845 } 4268 }
3846 } 4269 }
3847 nbchar = 0; 4270 nbchar = 0;
4271 /* something really bad happened in the SAX callback */
4272 if (ctxt->instate != XML_PARSER_CONTENT)
4273 return;
3848 } 4274 }
3849 count++; 4275 count++;
3850 if (count > 50) { 4276 if (count > 50) {
3851 GROW; 4277 GROW;
3852 count = 0; 4278 count = 0;
3853 } 4279 }
3854 NEXTL(l); 4280 NEXTL(l);
3855 cur = CUR_CHAR(l); 4281 cur = CUR_CHAR(l);
3856 } 4282 }
3857 if (nbchar != 0) { 4283 if (nbchar != 0) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3976 * must not occur within comments. " 4402 * must not occur within comments. "
3977 * This is the slow routine in case the accelerator for ascii didn't work 4403 * This is the slow routine in case the accelerator for ascii didn't work
3978 * 4404 *
3979 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->' 4405 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
3980 */ 4406 */
3981 static void 4407 static void
3982 xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, int len, int size) { 4408 xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, int len, int size) {
3983 int q, ql; 4409 int q, ql;
3984 int r, rl; 4410 int r, rl;
3985 int cur, l; 4411 int cur, l;
3986 xmlParserInputPtr input = ctxt->input;
3987 int count = 0; 4412 int count = 0;
4413 int inputid;
4414
4415 inputid = ctxt->input->id;
3988 4416
3989 if (buf == NULL) { 4417 if (buf == NULL) {
3990 len = 0; 4418 len = 0;
3991 size = XML_PARSER_BUFFER_SIZE; 4419 size = XML_PARSER_BUFFER_SIZE;
3992 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); 4420 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3993 if (buf == NULL) { 4421 if (buf == NULL) {
3994 xmlErrMemory(ctxt, NULL); 4422 xmlErrMemory(ctxt, NULL);
3995 return; 4423 return;
3996 } 4424 }
3997 } 4425 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4059 } 4487 }
4060 buf[len] = 0; 4488 buf[len] = 0;
4061 if (cur == 0) { 4489 if (cur == 0) {
4062 xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED, 4490 xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4063 "Comment not terminated \n<!--%.50s\n", buf); 4491 "Comment not terminated \n<!--%.50s\n", buf);
4064 } else if (!IS_CHAR(cur)) { 4492 } else if (!IS_CHAR(cur)) {
4065 xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR, 4493 xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4066 "xmlParseComment: invalid xmlChar value %d\n", 4494 "xmlParseComment: invalid xmlChar value %d\n",
4067 cur); 4495 cur);
4068 } else { 4496 } else {
4069 » if (input != ctxt->input) { 4497 » if (inputid != ctxt->input->id) {
4070 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, 4498 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4071 "Comment doesn't start and stop in the same entity\n"); 4499 "Comment doesn't start and stop in the same entity\n");
4072 } 4500 }
4073 NEXT; 4501 NEXT;
4074 if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) && 4502 if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4075 (!ctxt->disableSAX)) 4503 (!ctxt->disableSAX))
4076 ctxt->sax->comment(ctxt->userData, buf); 4504 ctxt->sax->comment(ctxt->userData, buf);
4077 } 4505 }
4078 xmlFree(buf); 4506 xmlFree(buf);
4079 return; 4507 return;
(...skipping 15 matching lines...) Expand all
4095 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->' 4523 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4096 */ 4524 */
4097 void 4525 void
4098 xmlParseComment(xmlParserCtxtPtr ctxt) { 4526 xmlParseComment(xmlParserCtxtPtr ctxt) {
4099 xmlChar *buf = NULL; 4527 xmlChar *buf = NULL;
4100 int size = XML_PARSER_BUFFER_SIZE; 4528 int size = XML_PARSER_BUFFER_SIZE;
4101 int len = 0; 4529 int len = 0;
4102 xmlParserInputState state; 4530 xmlParserInputState state;
4103 const xmlChar *in; 4531 const xmlChar *in;
4104 int nbchar = 0, ccol; 4532 int nbchar = 0, ccol;
4533 int inputid;
4105 4534
4106 /* 4535 /*
4107 * Check that there is a comment right here. 4536 * Check that there is a comment right here.
4108 */ 4537 */
4109 if ((RAW != '<') || (NXT(1) != '!') || 4538 if ((RAW != '<') || (NXT(1) != '!') ||
4110 (NXT(2) != '-') || (NXT(3) != '-')) return; 4539 (NXT(2) != '-') || (NXT(3) != '-')) return;
4111
4112 state = ctxt->instate; 4540 state = ctxt->instate;
4113 ctxt->instate = XML_PARSER_COMMENT; 4541 ctxt->instate = XML_PARSER_COMMENT;
4542 inputid = ctxt->input->id;
4114 SKIP(4); 4543 SKIP(4);
4115 SHRINK; 4544 SHRINK;
4116 GROW; 4545 GROW;
4117 4546
4118 /* 4547 /*
4119 * Accelerated common case where input don't need to be 4548 * Accelerated common case where input don't need to be
4120 * modified before passing it to the handler. 4549 * modified before passing it to the handler.
4121 */ 4550 */
4122 in = ctxt->input->cur; 4551 in = ctxt->input->cur;
4123 do { 4552 do {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4194 continue; /* while */ 4623 continue; /* while */
4195 } 4624 }
4196 in--; 4625 in--;
4197 } 4626 }
4198 SHRINK; 4627 SHRINK;
4199 GROW; 4628 GROW;
4200 in = ctxt->input->cur; 4629 in = ctxt->input->cur;
4201 if (*in == '-') { 4630 if (*in == '-') {
4202 if (in[1] == '-') { 4631 if (in[1] == '-') {
4203 if (in[2] == '>') { 4632 if (in[2] == '>') {
4633 if (ctxt->input->id != inputid) {
4634 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4635 "comment doesn't start and stop in the same entity\n");
4636 }
4204 SKIP(3); 4637 SKIP(3);
4205 if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) && 4638 if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4206 (!ctxt->disableSAX)) { 4639 (!ctxt->disableSAX)) {
4207 if (buf != NULL) 4640 if (buf != NULL)
4208 ctxt->sax->comment(ctxt->userData, buf); 4641 ctxt->sax->comment(ctxt->userData, buf);
4209 else 4642 else
4210 ctxt->sax->comment(ctxt->userData, BAD_CAST ""); 4643 ctxt->sax->comment(ctxt->userData, BAD_CAST "");
4211 } 4644 }
4212 if (buf != NULL) 4645 if (buf != NULL)
4213 xmlFree(buf); 4646 xmlFree(buf);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4267 } 4700 }
4268 for (i = 0;;i++) { 4701 for (i = 0;;i++) {
4269 if (xmlW3CPIs[i] == NULL) break; 4702 if (xmlW3CPIs[i] == NULL) break;
4270 if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i])) 4703 if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
4271 return(name); 4704 return(name);
4272 } 4705 }
4273 xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME, 4706 xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
4274 "xmlParsePITarget: invalid name prefix 'xml'\n", 4707 "xmlParsePITarget: invalid name prefix 'xml'\n",
4275 NULL, NULL); 4708 NULL, NULL);
4276 } 4709 }
4710 if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
4711 xmlNsErr(ctxt, XML_NS_ERR_COLON,
4712 "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
4713 }
4277 return(name); 4714 return(name);
4278 } 4715 }
4279 4716
4280 #ifdef LIBXML_CATALOG_ENABLED 4717 #ifdef LIBXML_CATALOG_ENABLED
4281 /** 4718 /**
4282 * xmlParseCatalogPI: 4719 * xmlParseCatalogPI:
4283 * @ctxt: an XML parser context 4720 * @ctxt: an XML parser context
4284 * @catalog: the PI value string 4721 * @catalog: the PI value string
4285 * 4722 *
4286 * parse an XML Catalog Processing Instruction. 4723 * parse an XML Catalog Processing Instruction.
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
4510 name = xmlParseName(ctxt); 4947 name = xmlParseName(ctxt);
4511 if (name == NULL) { 4948 if (name == NULL) {
4512 xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL); 4949 xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
4513 return; 4950 return;
4514 } 4951 }
4515 if (!IS_BLANK_CH(CUR)) { 4952 if (!IS_BLANK_CH(CUR)) {
4516 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, 4953 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4517 "Space required after the NOTATION name'\n"); 4954 "Space required after the NOTATION name'\n");
4518 return; 4955 return;
4519 } 4956 }
4957 if (xmlStrchr(name, ':') != NULL) {
4958 xmlNsErr(ctxt, XML_NS_ERR_COLON,
4959 "colon are forbidden from notation names '%s'\n",
4960 name, NULL, NULL);
4961 }
4520 SKIP_BLANKS; 4962 SKIP_BLANKS;
4521 4963
4522 /* 4964 /*
4523 * Parse the IDs. 4965 * Parse the IDs.
4524 */ 4966 */
4525 Systemid = xmlParseExternalID(ctxt, &Pubid, 0); 4967 Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
4526 SKIP_BLANKS; 4968 SKIP_BLANKS;
4527 4969
4528 if (RAW == '>') { 4970 if (RAW == '>') {
4529 if (input != ctxt->input) { 4971 if (input != ctxt->input) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
4594 } 5036 }
4595 isParameter = 1; 5037 isParameter = 1;
4596 } 5038 }
4597 5039
4598 name = xmlParseName(ctxt); 5040 name = xmlParseName(ctxt);
4599 if (name == NULL) { 5041 if (name == NULL) {
4600 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, 5042 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
4601 "xmlParseEntityDecl: no name\n"); 5043 "xmlParseEntityDecl: no name\n");
4602 return; 5044 return;
4603 } 5045 }
5046 if (xmlStrchr(name, ':') != NULL) {
5047 xmlNsErr(ctxt, XML_NS_ERR_COLON,
5048 "colon are forbidden from entities names '%s'\n",
5049 name, NULL, NULL);
5050 }
4604 skipped = SKIP_BLANKS; 5051 skipped = SKIP_BLANKS;
4605 if (skipped == 0) { 5052 if (skipped == 0) {
4606 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, 5053 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4607 "Space required after the entity name\n"); 5054 "Space required after the entity name\n");
4608 } 5055 }
4609 5056
4610 ctxt->instate = XML_PARSER_ENTITY_DECL; 5057 ctxt->instate = XML_PARSER_ENTITY_DECL;
4611 /* 5058 /*
4612 * handle the various case of definitions... 5059 * handle the various case of definitions...
4613 */ 5060 */
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4669 * For expat compatibility in SAX mode. 5116 * For expat compatibility in SAX mode.
4670 */ 5117 */
4671 if ((ctxt->myDoc == NULL) || 5118 if ((ctxt->myDoc == NULL) ||
4672 (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) { 5119 (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
4673 if (ctxt->myDoc == NULL) { 5120 if (ctxt->myDoc == NULL) {
4674 ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE); 5121 ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
4675 if (ctxt->myDoc == NULL) { 5122 if (ctxt->myDoc == NULL) {
4676 xmlErrMemory(ctxt, "New Doc failed"); 5123 xmlErrMemory(ctxt, "New Doc failed");
4677 return; 5124 return;
4678 } 5125 }
5126 ctxt->myDoc->properties = XML_DOC_INTERNAL;
4679 } 5127 }
4680 if (ctxt->myDoc->intSubset == NULL) 5128 if (ctxt->myDoc->intSubset == NULL)
4681 ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc, 5129 ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
4682 BAD_CAST "fake", NULL, NULL); 5130 BAD_CAST "fake", NULL, NULL);
4683 5131
4684 xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY, 5132 xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
4685 NULL, NULL, value); 5133 NULL, NULL, value);
4686 } 5134 }
4687 } else { 5135 } else {
4688 URI = xmlParseExternalID(ctxt, &literal, 1); 5136 URI = xmlParseExternalID(ctxt, &literal, 1);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4741 */ 5189 */
4742 if ((ctxt->replaceEntities != 0) && 5190 if ((ctxt->replaceEntities != 0) &&
4743 ((ctxt->myDoc == NULL) || 5191 ((ctxt->myDoc == NULL) ||
4744 (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) { 5192 (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
4745 if (ctxt->myDoc == NULL) { 5193 if (ctxt->myDoc == NULL) {
4746 ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE); 5194 ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
4747 if (ctxt->myDoc == NULL) { 5195 if (ctxt->myDoc == NULL) {
4748 xmlErrMemory(ctxt, "New Doc failed"); 5196 xmlErrMemory(ctxt, "New Doc failed");
4749 return; 5197 return;
4750 } 5198 }
5199 ctxt->myDoc->properties = XML_DOC_INTERNAL;
4751 } 5200 }
4752 5201
4753 if (ctxt->myDoc->intSubset == NULL) 5202 if (ctxt->myDoc->intSubset == NULL)
4754 ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc, 5203 ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
4755 BAD_CAST "fake", NULL, NULL); 5204 BAD_CAST "fake", NULL, NULL);
4756 xmlSAX2EntityDecl(ctxt, name, 5205 xmlSAX2EntityDecl(ctxt, name,
4757 XML_EXTERNAL_GENERAL_PARSED_ENTITY, 5206 XML_EXTERNAL_GENERAL_PARSED_ENTITY,
4758 literal, URI, NULL); 5207 literal, URI, NULL);
4759 } 5208 }
4760 } 5209 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
4879 * [ VC: Notation Attributes ] 5328 * [ VC: Notation Attributes ]
4880 * Values of this type must match one of the notation names included 5329 * Values of this type must match one of the notation names included
4881 * in the declaration; all notation names in the declaration must be declared. 5330 * in the declaration; all notation names in the declaration must be declared.
4882 * 5331 *
4883 * Returns: the notation attribute tree built while parsing 5332 * Returns: the notation attribute tree built while parsing
4884 */ 5333 */
4885 5334
4886 xmlEnumerationPtr 5335 xmlEnumerationPtr
4887 xmlParseNotationType(xmlParserCtxtPtr ctxt) { 5336 xmlParseNotationType(xmlParserCtxtPtr ctxt) {
4888 const xmlChar *name; 5337 const xmlChar *name;
4889 xmlEnumerationPtr ret = NULL, last = NULL, cur; 5338 xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
4890 5339
4891 if (RAW != '(') { 5340 if (RAW != '(') {
4892 xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL); 5341 xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
4893 return(NULL); 5342 return(NULL);
4894 } 5343 }
4895 SHRINK; 5344 SHRINK;
4896 do { 5345 do {
4897 NEXT; 5346 NEXT;
4898 SKIP_BLANKS; 5347 SKIP_BLANKS;
4899 name = xmlParseName(ctxt); 5348 name = xmlParseName(ctxt);
4900 if (name == NULL) { 5349 if (name == NULL) {
4901 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, 5350 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
4902 "Name expected in NOTATION declaration\n"); 5351 "Name expected in NOTATION declaration\n");
4903 xmlFreeEnumeration(ret); 5352 xmlFreeEnumeration(ret);
4904 return(NULL); 5353 » return(NULL);
4905 } 5354 }
4906 » cur = xmlCreateEnumeration(name); 5355 » tmp = ret;
4907 if (cur == NULL) { 5356 » while (tmp != NULL) {
4908 xmlFreeEnumeration(ret); 5357 » if (xmlStrEqual(name, tmp->name)) {
4909 return(NULL); 5358 » » xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
4910 } 5359 » "standalone: attribute notation value token %s duplicated\n",
4911 » if (last == NULL) ret = last = cur; 5360 » » » » name, NULL);
4912 » else { 5361 » » if (!xmlDictOwns(ctxt->dict, name))
4913 » last->next = cur; 5362 » » xmlFree((xmlChar *) name);
4914 » last = cur; 5363 » » break;
5364 » }
5365 » tmp = tmp->next;
5366 » }
5367 » if (tmp == NULL) {
5368 » cur = xmlCreateEnumeration(name);
5369 » if (cur == NULL) {
5370 xmlFreeEnumeration(ret);
5371 return(NULL);
5372 }
5373 » if (last == NULL) ret = last = cur;
5374 » else {
5375 » » last->next = cur;
5376 » » last = cur;
5377 » }
4915 } 5378 }
4916 SKIP_BLANKS; 5379 SKIP_BLANKS;
4917 } while (RAW == '|'); 5380 } while (RAW == '|');
4918 if (RAW != ')') { 5381 if (RAW != ')') {
4919 xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL); 5382 xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
4920 xmlFreeEnumeration(ret); 5383 xmlFreeEnumeration(ret);
4921 return(NULL); 5384 » return(NULL);
4922 } 5385 }
4923 NEXT; 5386 NEXT;
4924 return(ret); 5387 return(ret);
4925 } 5388 }
4926 5389
4927 /** 5390 /**
4928 * xmlParseEnumerationType: 5391 * xmlParseEnumerationType:
4929 * @ctxt: an XML parser context 5392 * @ctxt: an XML parser context
4930 * 5393 *
4931 * parse an Enumeration attribute type. 5394 * parse an Enumeration attribute type.
4932 * 5395 *
4933 * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')' 5396 * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
4934 * 5397 *
4935 * [ VC: Enumeration ] 5398 * [ VC: Enumeration ]
4936 * Values of this type must match one of the Nmtoken tokens in 5399 * Values of this type must match one of the Nmtoken tokens in
4937 * the declaration 5400 * the declaration
4938 * 5401 *
4939 * Returns: the enumeration attribute tree built while parsing 5402 * Returns: the enumeration attribute tree built while parsing
4940 */ 5403 */
4941 5404
4942 xmlEnumerationPtr 5405 xmlEnumerationPtr
4943 xmlParseEnumerationType(xmlParserCtxtPtr ctxt) { 5406 xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
4944 xmlChar *name; 5407 xmlChar *name;
4945 xmlEnumerationPtr ret = NULL, last = NULL, cur; 5408 xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
4946 5409
4947 if (RAW != '(') { 5410 if (RAW != '(') {
4948 xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL); 5411 xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
4949 return(NULL); 5412 return(NULL);
4950 } 5413 }
4951 SHRINK; 5414 SHRINK;
4952 do { 5415 do {
4953 NEXT; 5416 NEXT;
4954 SKIP_BLANKS; 5417 SKIP_BLANKS;
4955 name = xmlParseNmtoken(ctxt); 5418 name = xmlParseNmtoken(ctxt);
4956 if (name == NULL) { 5419 if (name == NULL) {
4957 xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL); 5420 xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
4958 return(ret); 5421 return(ret);
4959 } 5422 }
4960 » cur = xmlCreateEnumeration(name); 5423 » tmp = ret;
4961 » xmlFree(name); 5424 » while (tmp != NULL) {
4962 if (cur == NULL) { 5425 » if (xmlStrEqual(name, tmp->name)) {
4963 xmlFreeEnumeration(ret); 5426 » » xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
4964 return(NULL); 5427 » "standalone: attribute enumeration value token %s duplicated\n",
4965 } 5428 » » » » name, NULL);
4966 » if (last == NULL) ret = last = cur; 5429 » » if (!xmlDictOwns(ctxt->dict, name))
4967 » else { 5430 » » xmlFree(name);
4968 » last->next = cur; 5431 » » break;
4969 » last = cur; 5432 » }
5433 » tmp = tmp->next;
5434 » }
5435 » if (tmp == NULL) {
5436 » cur = xmlCreateEnumeration(name);
5437 » if (!xmlDictOwns(ctxt->dict, name))
5438 » » xmlFree(name);
5439 » if (cur == NULL) {
5440 xmlFreeEnumeration(ret);
5441 return(NULL);
5442 }
5443 » if (last == NULL) ret = last = cur;
5444 » else {
5445 » » last->next = cur;
5446 » » last = cur;
5447 » }
4970 } 5448 }
4971 SKIP_BLANKS; 5449 SKIP_BLANKS;
4972 } while (RAW == '|'); 5450 } while (RAW == '|');
4973 if (RAW != ')') { 5451 if (RAW != ')') {
4974 xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL); 5452 xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
4975 return(ret); 5453 return(ret);
4976 } 5454 }
4977 NEXT; 5455 NEXT;
4978 return(ret); 5456 return(ret);
4979 } 5457 }
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
5206 } 5684 }
5207 if (ctxt->sax2) { 5685 if (ctxt->sax2) {
5208 xmlAddSpecialAttr(ctxt, elemName, attrName, type); 5686 xmlAddSpecialAttr(ctxt, elemName, attrName, type);
5209 } 5687 }
5210 if (defaultValue != NULL) 5688 if (defaultValue != NULL)
5211 xmlFree(defaultValue); 5689 xmlFree(defaultValue);
5212 GROW; 5690 GROW;
5213 } 5691 }
5214 if (RAW == '>') { 5692 if (RAW == '>') {
5215 if (input != ctxt->input) { 5693 if (input != ctxt->input) {
5216 » » xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, 5694 » » xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
5217 "Attribute list declaration doesn't start and stop in the same entity\n"); 5695 "Attribute list declaration doesn't start and stop in the same entity\n",
5696 NULL, NULL);
5218 } 5697 }
5219 NEXT; 5698 NEXT;
5220 } 5699 }
5221 } 5700 }
5222 } 5701 }
5223 5702
5224 /** 5703 /**
5225 * xmlParseElementMixedContentDecl: 5704 * xmlParseElementMixedContentDecl:
5226 * @ctxt: an XML parser context 5705 * @ctxt: an XML parser context
5227 * @inputchk: the input used for the current entity, needed for boundary checks 5706 * @inputchk: the input used for the current entity, needed for boundary checks
(...skipping 19 matching lines...) Expand all
5247 5726
5248 GROW; 5727 GROW;
5249 if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) { 5728 if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
5250 SKIP(7); 5729 SKIP(7);
5251 SKIP_BLANKS; 5730 SKIP_BLANKS;
5252 SHRINK; 5731 SHRINK;
5253 if (RAW == ')') { 5732 if (RAW == ')') {
5254 if ((ctxt->validate) && (ctxt->input->id != inputchk)) { 5733 if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
5255 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY, 5734 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
5256 "Element content declaration doesn't start and stop in the same entity\n", 5735 "Element content declaration doesn't start and stop in the same entity\n",
5257 NULL); 5736 NULL, NULL);
5258 } 5737 }
5259 NEXT; 5738 NEXT;
5260 ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT _PCDATA); 5739 ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT _PCDATA);
5261 if (ret == NULL) 5740 if (ret == NULL)
5262 return(NULL); 5741 return(NULL);
5263 if (RAW == '*') { 5742 if (RAW == '*') {
5264 ret->ocur = XML_ELEMENT_CONTENT_MULT; 5743 ret->ocur = XML_ELEMENT_CONTENT_MULT;
5265 NEXT; 5744 NEXT;
5266 } 5745 }
5267 return(ret); 5746 return(ret);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5301 SKIP_BLANKS; 5780 SKIP_BLANKS;
5302 GROW; 5781 GROW;
5303 } 5782 }
5304 if ((RAW == ')') && (NXT(1) == '*')) { 5783 if ((RAW == ')') && (NXT(1) == '*')) {
5305 if (elem != NULL) { 5784 if (elem != NULL) {
5306 cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem, 5785 cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
5307 XML_ELEMENT_CONTENT_ELEMENT); 5786 XML_ELEMENT_CONTENT_ELEMENT);
5308 if (cur->c2 != NULL) 5787 if (cur->c2 != NULL)
5309 cur->c2->parent = cur; 5788 cur->c2->parent = cur;
5310 } 5789 }
5311 » ret->ocur = XML_ELEMENT_CONTENT_MULT; 5790 if (ret != NULL)
5791 ret->ocur = XML_ELEMENT_CONTENT_MULT;
5312 if ((ctxt->validate) && (ctxt->input->id != inputchk)) { 5792 if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
5313 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY, 5793 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
5314 "Element content declaration doesn't start and stop in the same entity\n", 5794 "Element content declaration doesn't start and stop in the same entity\n",
5315 » » » » NULL); 5795 » » » » NULL, NULL);
5316 } 5796 }
5317 SKIP(2); 5797 SKIP(2);
5318 } else { 5798 } else {
5319 xmlFreeDocElementContent(ctxt->myDoc, ret); 5799 xmlFreeDocElementContent(ctxt->myDoc, ret);
5320 xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL); 5800 xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
5321 return(NULL); 5801 return(NULL);
5322 } 5802 }
5323 5803
5324 } else { 5804 } else {
5325 xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL); 5805 xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
5326 } 5806 }
5327 return(ret); 5807 return(ret);
5328 } 5808 }
5329 5809
5330 /** 5810 /**
5331 * xmlParseElementChildrenContentDecl: 5811 * xmlParseElementChildrenContentDeclPriv:
5332 * @ctxt: an XML parser context 5812 * @ctxt: an XML parser context
5333 * @inputchk: the input used for the current entity, needed for boundary checks 5813 * @inputchk: the input used for the current entity, needed for boundary checks
5814 * @depth: the level of recursion
5334 * 5815 *
5335 * parse the declaration for a Mixed Element content 5816 * parse the declaration for a Mixed Element content
5336 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl 5817 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
5337 * 5818 *
5338 * 5819 *
5339 * [47] children ::= (choice | seq) ('?' | '*' | '+')? 5820 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
5340 * 5821 *
5341 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')? 5822 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
5342 * 5823 *
5343 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')' 5824 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
5344 * 5825 *
5345 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')' 5826 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
5346 * 5827 *
5347 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50] 5828 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
5348 * TODO Parameter-entity replacement text must be properly nested 5829 * TODO Parameter-entity replacement text must be properly nested
5349 * with parenthesized groups. That is to say, if either of the 5830 * with parenthesized groups. That is to say, if either of the
5350 * opening or closing parentheses in a choice, seq, or Mixed 5831 * opening or closing parentheses in a choice, seq, or Mixed
5351 * construct is contained in the replacement text for a parameter 5832 * construct is contained in the replacement text for a parameter
5352 * entity, both must be contained in the same replacement text. For 5833 * entity, both must be contained in the same replacement text. For
5353 * interoperability, if a parameter-entity reference appears in a 5834 * interoperability, if a parameter-entity reference appears in a
5354 * choice, seq, or Mixed construct, its replacement text should not 5835 * choice, seq, or Mixed construct, its replacement text should not
5355 * be empty, and neither the first nor last non-blank character of 5836 * be empty, and neither the first nor last non-blank character of
5356 * the replacement text should be a connector (| or ,). 5837 * the replacement text should be a connector (| or ,).
5357 * 5838 *
5358 * Returns the tree of xmlElementContentPtr describing the element 5839 * Returns the tree of xmlElementContentPtr describing the element
5359 * hierarchy. 5840 * hierarchy.
5360 */ 5841 */
5361 xmlElementContentPtr 5842 static xmlElementContentPtr
5362 xmlParseElementChildrenContentDecl (xmlParserCtxtPtr ctxt, int inputchk) { 5843 xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
5844 int depth) {
5363 xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL; 5845 xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
5364 const xmlChar *elem; 5846 const xmlChar *elem;
5365 xmlChar type = 0; 5847 xmlChar type = 0;
5366 5848
5367 if (ctxt->depth > 128) { 5849 if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
5850 (depth > 2048)) {
5368 xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, 5851 xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
5369 "xmlParseElementChildrenContentDecl : depth %d too deep\n", 5852 "xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
5370 ctxt->depth); 5853 depth);
5371 return(NULL); 5854 » return(NULL);
5372 } 5855 }
5373 SKIP_BLANKS; 5856 SKIP_BLANKS;
5374 GROW; 5857 GROW;
5375 if (RAW == '(') { 5858 if (RAW == '(') {
5376 int inputid = ctxt->input->id; 5859 int inputid = ctxt->input->id;
5377 5860
5378 /* Recurse on first child */ 5861 /* Recurse on first child */
5379 NEXT; 5862 NEXT;
5380 SKIP_BLANKS; 5863 SKIP_BLANKS;
5381 ctxt->depth++; 5864 cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
5382 cur = ret = xmlParseElementChildrenContentDecl(ctxt, inputid); 5865 depth + 1);
5383 ctxt->depth--;
5384 SKIP_BLANKS; 5866 SKIP_BLANKS;
5385 GROW; 5867 GROW;
5386 } else { 5868 } else {
5387 elem = xmlParseName(ctxt); 5869 elem = xmlParseName(ctxt);
5388 if (elem == NULL) { 5870 if (elem == NULL) {
5389 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL); 5871 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
5390 return(NULL); 5872 return(NULL);
5391 } 5873 }
5392 cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTE NT_ELEMENT); 5874 cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTE NT_ELEMENT);
5393 if (cur == NULL) { 5875 if (cur == NULL) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
5505 return(NULL); 5987 return(NULL);
5506 } 5988 }
5507 GROW; 5989 GROW;
5508 SKIP_BLANKS; 5990 SKIP_BLANKS;
5509 GROW; 5991 GROW;
5510 if (RAW == '(') { 5992 if (RAW == '(') {
5511 int inputid = ctxt->input->id; 5993 int inputid = ctxt->input->id;
5512 /* Recurse on second child */ 5994 /* Recurse on second child */
5513 NEXT; 5995 NEXT;
5514 SKIP_BLANKS; 5996 SKIP_BLANKS;
5515 ctxt->depth++; 5997 » last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
5516 » last = xmlParseElementChildrenContentDecl(ctxt, inputid); 5998 depth + 1);
5517 ctxt->depth--;
5518 SKIP_BLANKS; 5999 SKIP_BLANKS;
5519 } else { 6000 } else {
5520 elem = xmlParseName(ctxt); 6001 elem = xmlParseName(ctxt);
5521 if (elem == NULL) { 6002 if (elem == NULL) {
5522 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL); 6003 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
5523 if (ret != NULL) 6004 if (ret != NULL)
5524 xmlFreeDocElementContent(ctxt->myDoc, ret); 6005 xmlFreeDocElementContent(ctxt->myDoc, ret);
5525 return(NULL); 6006 return(NULL);
5526 } 6007 }
5527 last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTEN T_ELEMENT); 6008 last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTEN T_ELEMENT);
(...skipping 19 matching lines...) Expand all
5547 GROW; 6028 GROW;
5548 } 6029 }
5549 if ((cur != NULL) && (last != NULL)) { 6030 if ((cur != NULL) && (last != NULL)) {
5550 cur->c2 = last; 6031 cur->c2 = last;
5551 if (last != NULL) 6032 if (last != NULL)
5552 last->parent = cur; 6033 last->parent = cur;
5553 } 6034 }
5554 if ((ctxt->validate) && (ctxt->input->id != inputchk)) { 6035 if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
5555 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY, 6036 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
5556 "Element content declaration doesn't start and stop in the same entity\n", 6037 "Element content declaration doesn't start and stop in the same entity\n",
5557 » » » NULL); 6038 » » » NULL, NULL);
5558 } 6039 }
5559 NEXT; 6040 NEXT;
5560 if (RAW == '?') { 6041 if (RAW == '?') {
5561 if (ret != NULL) { 6042 if (ret != NULL) {
5562 if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) || 6043 if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
5563 (ret->ocur == XML_ELEMENT_CONTENT_MULT)) 6044 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
5564 ret->ocur = XML_ELEMENT_CONTENT_MULT; 6045 ret->ocur = XML_ELEMENT_CONTENT_MULT;
5565 else 6046 else
5566 ret->ocur = XML_ELEMENT_CONTENT_OPT; 6047 ret->ocur = XML_ELEMENT_CONTENT_OPT;
5567 } 6048 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5618 } 6099 }
5619 if (found) 6100 if (found)
5620 ret->ocur = XML_ELEMENT_CONTENT_MULT; 6101 ret->ocur = XML_ELEMENT_CONTENT_MULT;
5621 } 6102 }
5622 NEXT; 6103 NEXT;
5623 } 6104 }
5624 return(ret); 6105 return(ret);
5625 } 6106 }
5626 6107
5627 /** 6108 /**
6109 * xmlParseElementChildrenContentDecl:
6110 * @ctxt: an XML parser context
6111 * @inputchk: the input used for the current entity, needed for boundary checks
6112 *
6113 * parse the declaration for a Mixed Element content
6114 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6115 *
6116 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6117 *
6118 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6119 *
6120 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6121 *
6122 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6123 *
6124 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6125 * TODO Parameter-entity replacement text must be properly nested
6126 * with parenthesized groups. That is to say, if either of the
6127 * opening or closing parentheses in a choice, seq, or Mixed
6128 * construct is contained in the replacement text for a parameter
6129 * entity, both must be contained in the same replacement text. For
6130 * interoperability, if a parameter-entity reference appears in a
6131 * choice, seq, or Mixed construct, its replacement text should not
6132 * be empty, and neither the first nor last non-blank character of
6133 * the replacement text should be a connector (| or ,).
6134 *
6135 * Returns the tree of xmlElementContentPtr describing the element
6136 * hierarchy.
6137 */
6138 xmlElementContentPtr
6139 xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6140 /* stub left for API/ABI compat */
6141 return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
6142 }
6143
6144 /**
5628 * xmlParseElementContentDecl: 6145 * xmlParseElementContentDecl:
5629 * @ctxt: an XML parser context 6146 * @ctxt: an XML parser context
5630 * @name: the name of the element being defined. 6147 * @name: the name of the element being defined.
5631 * @result: the Element Content pointer will be stored here if any 6148 * @result: the Element Content pointer will be stored here if any
5632 * 6149 *
5633 * parse the declaration for an Element content either Mixed or Children, 6150 * parse the declaration for an Element content either Mixed or Children,
5634 * the cases EMPTY and ANY are handled directly in xmlParseElementDecl 6151 * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
5635 * 6152 *
5636 * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children 6153 * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
5637 * 6154 *
(...skipping 15 matching lines...) Expand all
5653 "xmlParseElementContentDecl : %s '(' expected\n", name); 6170 "xmlParseElementContentDecl : %s '(' expected\n", name);
5654 return(-1); 6171 return(-1);
5655 } 6172 }
5656 NEXT; 6173 NEXT;
5657 GROW; 6174 GROW;
5658 SKIP_BLANKS; 6175 SKIP_BLANKS;
5659 if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) { 6176 if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
5660 tree = xmlParseElementMixedContentDecl(ctxt, inputid); 6177 tree = xmlParseElementMixedContentDecl(ctxt, inputid);
5661 res = XML_ELEMENT_TYPE_MIXED; 6178 res = XML_ELEMENT_TYPE_MIXED;
5662 } else { 6179 } else {
5663 tree = xmlParseElementChildrenContentDecl(ctxt, inputid); 6180 tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
5664 res = XML_ELEMENT_TYPE_ELEMENT; 6181 res = XML_ELEMENT_TYPE_ELEMENT;
5665 } 6182 }
5666 SKIP_BLANKS; 6183 SKIP_BLANKS;
5667 *result = tree; 6184 *result = tree;
5668 return(res); 6185 return(res);
5669 } 6186 }
5670 6187
5671 /** 6188 /**
5672 * xmlParseElementDecl: 6189 * xmlParseElementDecl:
5673 * @ctxt: an XML parser context 6190 * @ctxt: an XML parser context
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
5789 * 6306 *
5790 * [61] conditionalSect ::= includeSect | ignoreSect 6307 * [61] conditionalSect ::= includeSect | ignoreSect
5791 * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>' 6308 * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
5792 * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>' 6309 * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
5793 * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)* 6310 * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
5794 * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*) 6311 * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
5795 */ 6312 */
5796 6313
5797 static void 6314 static void
5798 xmlParseConditionalSections(xmlParserCtxtPtr ctxt) { 6315 xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
6316 int id = ctxt->input->id;
6317
5799 SKIP(3); 6318 SKIP(3);
5800 SKIP_BLANKS; 6319 SKIP_BLANKS;
5801 if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) { 6320 if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
5802 SKIP(7); 6321 SKIP(7);
5803 SKIP_BLANKS; 6322 SKIP_BLANKS;
5804 if (RAW != '[') { 6323 if (RAW != '[') {
5805 xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL); 6324 xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
5806 } else { 6325 } else {
6326 if (ctxt->input->id != id) {
6327 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6328 "All markup of the conditional section is not in the same entity\n",
6329 NULL, NULL);
6330 }
5807 NEXT; 6331 NEXT;
5808 } 6332 }
5809 if (xmlParserDebugEntities) { 6333 if (xmlParserDebugEntities) {
5810 if ((ctxt->input != NULL) && (ctxt->input->filename)) 6334 if ((ctxt->input != NULL) && (ctxt->input->filename))
5811 xmlGenericError(xmlGenericErrorContext, 6335 xmlGenericError(xmlGenericErrorContext,
5812 "%s(%d): ", ctxt->input->filename, 6336 "%s(%d): ", ctxt->input->filename,
5813 ctxt->input->line); 6337 ctxt->input->line);
5814 xmlGenericError(xmlGenericErrorContext, 6338 xmlGenericError(xmlGenericErrorContext,
5815 "Entering INCLUDE Conditional Section\n"); 6339 "Entering INCLUDE Conditional Section\n");
5816 } 6340 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
5852 } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) { 6376 } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
5853 int state; 6377 int state;
5854 xmlParserInputState instate; 6378 xmlParserInputState instate;
5855 int depth = 0; 6379 int depth = 0;
5856 6380
5857 SKIP(6); 6381 SKIP(6);
5858 SKIP_BLANKS; 6382 SKIP_BLANKS;
5859 if (RAW != '[') { 6383 if (RAW != '[') {
5860 xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL); 6384 xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
5861 } else { 6385 } else {
6386 if (ctxt->input->id != id) {
6387 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6388 "All markup of the conditional section is not in the same entity\n",
6389 NULL, NULL);
6390 }
5862 NEXT; 6391 NEXT;
5863 } 6392 }
5864 if (xmlParserDebugEntities) { 6393 if (xmlParserDebugEntities) {
5865 if ((ctxt->input != NULL) && (ctxt->input->filename)) 6394 if ((ctxt->input != NULL) && (ctxt->input->filename))
5866 xmlGenericError(xmlGenericErrorContext, 6395 xmlGenericError(xmlGenericErrorContext,
5867 "%s(%d): ", ctxt->input->filename, 6396 "%s(%d): ", ctxt->input->filename,
5868 ctxt->input->line); 6397 ctxt->input->line);
5869 xmlGenericError(xmlGenericErrorContext, 6398 xmlGenericError(xmlGenericErrorContext,
5870 "Entering IGNORE Conditional Section\n"); 6399 "Entering IGNORE Conditional Section\n");
5871 } 6400 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5908 } else { 6437 } else {
5909 xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL); 6438 xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
5910 } 6439 }
5911 6440
5912 if (RAW == 0) 6441 if (RAW == 0)
5913 SHRINK; 6442 SHRINK;
5914 6443
5915 if (RAW == 0) { 6444 if (RAW == 0) {
5916 xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL); 6445 xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
5917 } else { 6446 } else {
6447 if (ctxt->input->id != id) {
6448 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6449 "All markup of the conditional section is not in the same entity\n",
6450 NULL, NULL);
6451 }
5918 SKIP(3); 6452 SKIP(3);
5919 } 6453 }
5920 } 6454 }
5921 6455
5922 /** 6456 /**
5923 * xmlParseMarkupDecl: 6457 * xmlParseMarkupDecl:
5924 * @ctxt: an XML parser context 6458 * @ctxt: an XML parser context
5925 * 6459 *
5926 * parse Markup declarations 6460 * parse Markup declarations
5927 * 6461 *
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
5986 xmlParseConditionalSections(ctxt); 6520 xmlParseConditionalSections(ctxt);
5987 } 6521 }
5988 } 6522 }
5989 6523
5990 ctxt->instate = XML_PARSER_DTD; 6524 ctxt->instate = XML_PARSER_DTD;
5991 } 6525 }
5992 6526
5993 /** 6527 /**
5994 * xmlParseTextDecl: 6528 * xmlParseTextDecl:
5995 * @ctxt: an XML parser context 6529 * @ctxt: an XML parser context
5996 * 6530 *
5997 * parse an XML declaration header for external entities 6531 * parse an XML declaration header for external entities
5998 * 6532 *
5999 * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>' 6533 * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
6000 *
6001 * Question: Seems that EncodingDecl is mandatory ? Is that a typo ?
6002 */ 6534 */
6003 6535
6004 void 6536 void
6005 xmlParseTextDecl(xmlParserCtxtPtr ctxt) { 6537 xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
6006 xmlChar *version; 6538 xmlChar *version;
6007 const xmlChar *encoding; 6539 const xmlChar *encoding;
6008 6540
6009 /* 6541 /*
6010 * We know that '<?xml' is here. 6542 * We know that '<?xml' is here.
6011 */ 6543 */
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
6102 if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) { 6634 if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
6103 /* 6635 /*
6104 * The XML REC instructs us to stop parsing right here 6636 * The XML REC instructs us to stop parsing right here
6105 */ 6637 */
6106 ctxt->instate = XML_PARSER_EOF; 6638 ctxt->instate = XML_PARSER_EOF;
6107 return; 6639 return;
6108 } 6640 }
6109 } 6641 }
6110 if (ctxt->myDoc == NULL) { 6642 if (ctxt->myDoc == NULL) {
6111 ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0"); 6643 ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
6644 if (ctxt->myDoc == NULL) {
6645 xmlErrMemory(ctxt, "New Doc failed");
6646 return;
6647 }
6648 ctxt->myDoc->properties = XML_DOC_INTERNAL;
6112 } 6649 }
6113 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL)) 6650 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
6114 xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID); 6651 xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
6115 6652
6116 ctxt->instate = XML_PARSER_DTD; 6653 ctxt->instate = XML_PARSER_DTD;
6117 ctxt->external = 1; 6654 ctxt->external = 1;
6118 while (((RAW == '<') && (NXT(1) == '?')) || 6655 while (((RAW == '<') && (NXT(1) == '?')) ||
6119 ((RAW == '<') && (NXT(1) == '!')) || 6656 ((RAW == '<') && (NXT(1) == '!')) ||
6120 (RAW == '%') || IS_BLANK_CH(CUR)) { 6657 (RAW == '%') || IS_BLANK_CH(CUR)) {
6121 const xmlChar *check = CUR_PTR; 6658 const xmlChar *check = CUR_PTR;
(...skipping 23 matching lines...) Expand all
6145 6682
6146 if (RAW != 0) { 6683 if (RAW != 0) {
6147 xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL); 6684 xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6148 } 6685 }
6149 6686
6150 } 6687 }
6151 6688
6152 /** 6689 /**
6153 * xmlParseReference: 6690 * xmlParseReference:
6154 * @ctxt: an XML parser context 6691 * @ctxt: an XML parser context
6155 * 6692 *
6156 * parse and handle entity references in content, depending on the SAX 6693 * parse and handle entity references in content, depending on the SAX
6157 * interface, this may end-up in a call to character() if this is a 6694 * interface, this may end-up in a call to character() if this is a
6158 * CharRef, a predefined entity, if there is no reference() callback. 6695 * CharRef, a predefined entity, if there is no reference() callback.
6159 * or if the parser was asked to switch to that mode. 6696 * or if the parser was asked to switch to that mode.
6160 * 6697 *
6161 * [67] Reference ::= EntityRef | CharRef 6698 * [67] Reference ::= EntityRef | CharRef
6162 */ 6699 */
6163 void 6700 void
6164 xmlParseReference(xmlParserCtxtPtr ctxt) { 6701 xmlParseReference(xmlParserCtxtPtr ctxt) {
6165 xmlEntityPtr ent; 6702 xmlEntityPtr ent;
6166 xmlChar *val; 6703 xmlChar *val;
6167 if (RAW != '&') return; 6704 int was_checked;
6705 xmlNodePtr list = NULL;
6706 xmlParserErrors ret = XML_ERR_OK;
6168 6707
6708
6709 if (RAW != '&')
6710 return;
6711
6712 /*
6713 * Simple case of a CharRef
6714 */
6169 if (NXT(1) == '#') { 6715 if (NXT(1) == '#') {
6170 int i = 0; 6716 int i = 0;
6171 xmlChar out[10]; 6717 xmlChar out[10];
6172 int hex = NXT(2); 6718 int hex = NXT(2);
6173 int value = xmlParseCharRef(ctxt); 6719 int value = xmlParseCharRef(ctxt);
6174 » 6720
6175 if (value == 0) 6721 if (value == 0)
6176 return; 6722 return;
6177 if (ctxt->charset != XML_CHAR_ENCODING_UTF8) { 6723 if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
6178 /* 6724 /*
6179 * So we are using non-UTF-8 buffers 6725 * So we are using non-UTF-8 buffers
6180 * Check that the char fit on 8bits, if not 6726 * Check that the char fit on 8bits, if not
6181 * generate a CharRef. 6727 * generate a CharRef.
6182 */ 6728 */
6183 if (value <= 0xFF) { 6729 if (value <= 0xFF) {
6184 out[0] = value; 6730 out[0] = value;
(...skipping 13 matching lines...) Expand all
6198 } else { 6744 } else {
6199 /* 6745 /*
6200 * Just encode the value in UTF-8 6746 * Just encode the value in UTF-8
6201 */ 6747 */
6202 COPY_BUF(0 ,out, i, value); 6748 COPY_BUF(0 ,out, i, value);
6203 out[i] = 0; 6749 out[i] = 0;
6204 if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) && 6750 if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
6205 (!ctxt->disableSAX)) 6751 (!ctxt->disableSAX))
6206 ctxt->sax->characters(ctxt->userData, out, i); 6752 ctxt->sax->characters(ctxt->userData, out, i);
6207 } 6753 }
6208 } else { 6754 » return;
6209 int was_checked; 6755 }
6210 6756
6211 » ent = xmlParseEntityRef(ctxt); 6757 /*
6212 » if (ent == NULL) return; 6758 * We are seeing an entity reference
6213 » if (!ctxt->wellFormed) 6759 */
6760 ent = xmlParseEntityRef(ctxt);
6761 if (ent == NULL) return;
6762 if (!ctxt->wellFormed)
6763 » return;
6764 was_checked = ent->checked;
6765
6766 /* special case of predefined entities */
6767 if ((ent->name == NULL) ||
6768 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
6769 » val = ent->content;
6770 » if (val == NULL) return;
6771 » /*
6772 » * inline the entity.
6773 » */
6774 » if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
6775 » (!ctxt->disableSAX))
6776 » ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
6777 » return;
6778 }
6779
6780 /*
6781 * The first reference to the entity trigger a parsing phase
6782 * where the ent->children is filled with the result from
6783 * the parsing.
6784 */
6785 if (ent->checked == 0) {
6786 » unsigned long oldnbent = ctxt->nbentities;
6787
6788 » /*
6789 » * This is a bit hackish but this seems the best
6790 » * way to make sure both SAX and DOM entity support
6791 » * behaves okay.
6792 » */
6793 » void *user_data;
6794 » if (ctxt->userData == ctxt)
6795 » user_data = NULL;
6796 » else
6797 » user_data = ctxt->userData;
6798
6799 » /*
6800 » * Check that this entity is well formed
6801 » * 4.3.2: An internal general parsed entity is well-formed
6802 » * if its replacement text matches the production labeled
6803 » * content.
6804 » */
6805 » if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
6806 » ctxt->depth++;
6807 » ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
6808 » user_data, &list);
6809 » ctxt->depth--;
6810
6811 » } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
6812 » ctxt->depth++;
6813 » ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
6814 » user_data, ctxt->depth, ent->URI,
6815 » » » » » ent->ExternalID, &list);
6816 » ctxt->depth--;
6817 » } else {
6818 » ret = XML_ERR_ENTITY_PE_INTERNAL;
6819 » xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
6820 » » » "invalid entity type found\n", NULL);
6821 » }
6822
6823 » /*
6824 » * Store the number of entities needing parsing for this entity
6825 » * content and do checkings
6826 » */
6827 » ent->checked = ctxt->nbentities - oldnbent;
6828 » if (ret == XML_ERR_ENTITY_LOOP) {
6829 » xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
6830 » xmlFreeNodeList(list);
6214 return; 6831 return;
6215 » was_checked = ent->checked; 6832 » }
6216 » if ((ent->name != NULL) && 6833 » if (xmlParserEntityCheck(ctxt, 0, ent)) {
6217 » (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) { 6834 » xmlFreeNodeList(list);
6218 » xmlNodePtr list = NULL; 6835 » return;
6219 » xmlParserErrors ret = XML_ERR_OK; 6836 » }
6220 6837
6221 6838 » if ((ret == XML_ERR_OK) && (list != NULL)) {
6839 » if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
6840 » (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
6841 » » (ent->children == NULL)) {
6842 » » ent->children = list;
6843 » » if (ctxt->replaceEntities) {
6844 » » /*
6845 » » * Prune it directly in the generated document
6846 » » * except for single text nodes.
6847 » » */
6848 » » if (((list->type == XML_TEXT_NODE) &&
6849 » » » (list->next == NULL)) ||
6850 » » » (ctxt->parseMode == XML_PARSE_READER)) {
6851 » » » list->parent = (xmlNodePtr) ent;
6852 » » » list = NULL;
6853 » » » ent->owner = 1;
6854 » » } else {
6855 » » » ent->owner = 0;
6856 » » » while (list != NULL) {
6857 » » » list->parent = (xmlNodePtr) ctxt->node;
6858 » » » list->doc = ctxt->myDoc;
6859 » » » if (list->next == NULL)
6860 » » » » ent->last = list;
6861 » » » list = list->next;
6862 » » » }
6863 » » » list = ent->children;
6864 #ifdef LIBXML_LEGACY_ENABLED
6865 » » » if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
6866 » » » xmlAddEntityReference(ent, list, NULL);
6867 #endif /* LIBXML_LEGACY_ENABLED */
6868 » » }
6869 » » } else {
6870 » » ent->owner = 1;
6871 » » while (list != NULL) {
6872 » » » list->parent = (xmlNodePtr) ent;
6873 » » » if (list->next == NULL)
6874 » » » ent->last = list;
6875 » » » list = list->next;
6876 » » }
6877 » » }
6878 » } else {
6879 » » xmlFreeNodeList(list);
6880 » » list = NULL;
6881 » }
6882 » } else if ((ret != XML_ERR_OK) &&
6883 » » (ret != XML_WAR_UNDECLARED_ENTITY)) {
6884 » xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
6885 » » "Entity '%s' failed to parse\n", ent->name);
6886 » } else if (list != NULL) {
6887 » xmlFreeNodeList(list);
6888 » list = NULL;
6889 » }
6890 » if (ent->checked == 0)
6891 » ent->checked = 1;
6892 } else if (ent->checked != 1) {
6893 » ctxt->nbentities += ent->checked;
6894 }
6895
6896 /*
6897 * Now that the entity content has been gathered
6898 * provide it to the application, this can take different forms based
6899 * on the parsing modes.
6900 */
6901 if (ent->children == NULL) {
6902 » /*
6903 » * Probably running in SAX mode and the callbacks don't
6904 » * build the entity content. So unless we already went
6905 » * though parsing for first checking go though the entity
6906 » * content to generate callbacks associated to the entity
6907 » */
6908 » if (was_checked != 0) {
6909 » void *user_data;
6222 /* 6910 /*
6223 » * The first reference to the entity trigger a parsing phase 6911 » * This is a bit hackish but this seems the best
6224 » * where the ent->children is filled with the result from 6912 » * way to make sure both SAX and DOM entity support
6225 » * the parsing. 6913 » * behaves okay.
6226 */ 6914 */
6227 » if (ent->checked == 0) { 6915 » if (ctxt->userData == ctxt)
6228 » » xmlChar *value; 6916 » » user_data = NULL;
6229 6917 » else
6230 » » value = ent->content; 6918 » » user_data = ctxt->userData;
6231 6919
6232 » » /* 6920 » if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
6233 » » * Check that this entity is well formed 6921 » » ctxt->depth++;
6234 » » */ 6922 » » ret = xmlParseBalancedChunkMemoryInternal(ctxt,
6235 » » if ((value != NULL) && (value[0] != 0) && 6923 » » » » ent->content, user_data, NULL);
6236 » » (value[1] == 0) && (value[0] == '<') && 6924 » » ctxt->depth--;
6237 » » (xmlStrEqual(ent->name, BAD_CAST "lt"))) { 6925 » } else if (ent->etype ==
6238 » » /* 6926 » » XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
6239 » » * DONE: get definite answer on this !!! 6927 » » ctxt->depth++;
6240 » » * Lots of entity decls are used to declare a single 6928 » » ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
6241 » » * char 6929 » » » ctxt->sax, user_data, ctxt->depth,
6242 » » * <!ENTITY lt "<"> 6930 » » » ent->URI, ent->ExternalID, NULL);
6243 » » * Which seems to be valid since 6931 » » ctxt->depth--;
6244 » » * 2.4: The ampersand character (&) and the left angle 6932 » } else {
6245 » » * bracket (<) may appear in their literal form only 6933 » » ret = XML_ERR_ENTITY_PE_INTERNAL;
6246 » » * when used ... They are also legal within the literal 6934 » » xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
6247 » » * entity value of an internal entity declaration;i 6935 » » » "invalid entity type found\n", NULL);
6248 » » * see "4.3.2 Well-Formed Parsed Entities".
6249 » » * IMHO 2.4 and 4.3.2 are directly in contradiction.
6250 » » * Looking at the OASIS test suite and James Clark
6251 » » * tests, this is broken. However the XML REC uses
6252 » » * it. Is the XML REC not well-formed ????
6253 » » * This is a hack to avoid this problem
6254 » » *
6255 » » * ANSWER: since lt gt amp .. are already defined,
6256 » » * this is a redefinition and hence the fact that the
6257 » » * content is not well balanced is not a Wf error, this
6258 » » * is lousy but acceptable.
6259 » » */
6260 » » list = xmlNewDocText(ctxt->myDoc, value);
6261 » » if (list != NULL) {
6262 » » » if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) &&
6263 » » » (ent->children == NULL)) {
6264 » » » ent->children = list;
6265 » » » ent->last = list;
6266 » » » ent->owner = 1;
6267 » » » list->parent = (xmlNodePtr) ent;
6268 » » » } else {
6269 » » » xmlFreeNodeList(list);
6270 » » » }
6271 » » } else if (list != NULL) {
6272 » » » xmlFreeNodeList(list);
6273 » » }
6274 » » } else {
6275 » » /*
6276 » » * 4.3.2: An internal general parsed entity is well-formed
6277 » » * if its replacement text matches the production labeled
6278 » » * content.
6279 » » */
6280
6281 » » void *user_data;
6282 » » /*
6283 » » * This is a bit hackish but this seems the best
6284 » » * way to make sure both SAX and DOM entity support
6285 » » * behaves okay.
6286 » » */
6287 » » if (ctxt->userData == ctxt)
6288 » » » user_data = NULL;
6289 » » else
6290 » » » user_data = ctxt->userData;
6291
6292 » » if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
6293 » » » ctxt->depth++;
6294 » » » ret = xmlParseBalancedChunkMemoryInternal(ctxt,
6295 » » » » » value, user_data, &list);
6296 » » » ctxt->depth--;
6297 » » } else if (ent->etype ==
6298 » » » XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
6299 » » » ctxt->depth++;
6300 » » » ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
6301 » » » » ctxt->sax, user_data, ctxt->depth,
6302 » » » » ent->URI, ent->ExternalID, &list);
6303 » » » ctxt->depth--;
6304 » » } else {
6305 » » » ret = XML_ERR_ENTITY_PE_INTERNAL;
6306 » » » xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
6307 » » » » "invalid entity type found\n", NULL);
6308 » » }
6309 » » if (ret == XML_ERR_ENTITY_LOOP) {
6310 » » » xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
6311 » » » return;
6312 » » } else if ((ret == XML_ERR_OK) && (list != NULL)) {
6313 » » » if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
6314 » » » (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
6315 » » » (ent->children == NULL)) {
6316 » » » ent->children = list;
6317 » » » if (ctxt->replaceEntities) {
6318 » » » » /*
6319 » » » » * Prune it directly in the generated document
6320 » » » » * except for single text nodes.
6321 » » » » */
6322 » » » » if (((list->type == XML_TEXT_NODE) &&
6323 » » » » (list->next == NULL)) ||
6324 » » » » (ctxt->parseMode == XML_PARSE_READER)) {
6325 » » » » list->parent = (xmlNodePtr) ent;
6326 » » » » list = NULL;
6327 » » » » ent->owner = 1;
6328 » » » » } else {
6329 » » » » ent->owner = 0;
6330 » » » » while (list != NULL) {
6331 » » » » » list->parent = (xmlNodePtr) ctxt->node;
6332 » » » » » list->doc = ctxt->myDoc;
6333 » » » » » if (list->next == NULL)
6334 » » » » » ent->last = list;
6335 » » » » » list = list->next;
6336 » » » » }
6337 » » » » list = ent->children;
6338 #ifdef LIBXML_LEGACY_ENABLED
6339 » » » » if (ent->etype == XML_EXTERNAL_GENERAL_PARSE D_ENTITY)
6340 » » » » xmlAddEntityReference(ent, list, NULL);
6341 #endif /* LIBXML_LEGACY_ENABLED */
6342 » » » » }
6343 » » » } else {
6344 » » » » ent->owner = 1;
6345 » » » » while (list != NULL) {
6346 » » » » list->parent = (xmlNodePtr) ent;
6347 » » » » if (list->next == NULL)
6348 » » » » » ent->last = list;
6349 » » » » list = list->next;
6350 » » » » }
6351 » » » }
6352 » » » } else {
6353 » » » xmlFreeNodeList(list);
6354 » » » list = NULL;
6355 » » » }
6356 » » } else if ((ret != XML_ERR_OK) &&
6357 » » (ret != XML_WAR_UNDECLARED_ENTITY)) {
6358 » » » xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
6359 » » » » "Entity '%s' failed to parse\n", ent->name);
6360 » » } else if (list != NULL) {
6361 » » » xmlFreeNodeList(list);
6362 » » » list = NULL;
6363 » » }
6364 » » }
6365 » » ent->checked = 1;
6366 } 6936 }
6367 6937 » if (ret == XML_ERR_ENTITY_LOOP) {
6368 if (ent->children == NULL) { 6938 » » xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
6369 » » /*
6370 » » * Probably running in SAX mode and the callbacks don't
6371 » » * build the entity content. So unless we already went
6372 » » * though parsing for first checking go though the entity
6373 » » * content to generate callbacks associated to the entity
6374 » » */
6375 » » if (was_checked == 1) {
6376 » » void *user_data;
6377 » » /*
6378 » » * This is a bit hackish but this seems the best
6379 » » * way to make sure both SAX and DOM entity support
6380 » » * behaves okay.
6381 » » */
6382 » » if (ctxt->userData == ctxt)
6383 » » » user_data = NULL;
6384 » » else
6385 » » » user_data = ctxt->userData;
6386
6387 » » if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
6388 » » » ctxt->depth++;
6389 » » » ret = xmlParseBalancedChunkMemoryInternal(ctxt,
6390 » » » » » ent->content, user_data, NULL);
6391 » » » ctxt->depth--;
6392 » » } else if (ent->etype ==
6393 » » » XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
6394 » » » ctxt->depth++;
6395 » » » ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
6396 » » » » ctxt->sax, user_data, ctxt->depth,
6397 » » » » ent->URI, ent->ExternalID, NULL);
6398 » » » ctxt->depth--;
6399 » » } else {
6400 » » » ret = XML_ERR_ENTITY_PE_INTERNAL;
6401 » » » xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
6402 » » » » "invalid entity type found\n", NULL);
6403 » » }
6404 » » if (ret == XML_ERR_ENTITY_LOOP) {
6405 » » » xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
6406 » » » return;
6407 » » }
6408 » » }
6409 » » if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
6410 » » (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
6411 » » /*
6412 » » * Entity reference callback comes second, it's somewhat
6413 » » * superfluous but a compatibility to historical behaviour
6414 » » */
6415 » » ctxt->sax->reference(ctxt->userData, ent->name);
6416 » » }
6417 return; 6939 return;
6418 } 6940 }
6419 » if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) && 6941 » }
6420 » (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) { 6942 » if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
6943 » (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
6944 » /*
6945 » * Entity reference callback comes second, it's somewhat
6946 » * superfluous but a compatibility to historical behaviour
6947 » */
6948 » ctxt->sax->reference(ctxt->userData, ent->name);
6949 » }
6950 » return;
6951 }
6952
6953 /*
6954 * If we didn't get any children for the entity being built
6955 */
6956 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
6957 » (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
6958 » /*
6959 » * Create a node.
6960 » */
6961 » ctxt->sax->reference(ctxt->userData, ent->name);
6962 » return;
6963 }
6964
6965 if ((ctxt->replaceEntities) || (ent->children == NULL)) {
6966 » /*
6967 » * There is a problem on the handling of _private for entities
6968 » * (bug 155816): Should we copy the content of the field from
6969 » * the entity (possibly overwriting some value set by the user
6970 » * when a copy is created), should we leave it alone, or should
6971 » * we try to take care of different situations? The problem
6972 » * is exacerbated by the usage of this field by the xmlReader.
6973 » * To fix this bug, we look at _private on the created node
6974 » * and, if it's NULL, we copy in whatever was in the entity.
6975 » * If it's not NULL we leave it alone. This is somewhat of a
6976 » * hack - maybe we should have further tests to determine
6977 » * what to do.
6978 » */
6979 » if ((ctxt->node != NULL) && (ent->children != NULL)) {
6980 » /*
6981 » * Seems we are generating the DOM content, do
6982 » * a simple tree copy for all references except the first
6983 » * In the first occurrence list contains the replacement.
6984 » * progressive == 2 means we are operating on the Reader
6985 » * and since nodes are discarded we must copy all the time.
6986 » */
6987 » if (((list == NULL) && (ent->owner == 0)) ||
6988 » » (ctxt->parseMode == XML_PARSE_READER)) {
6989 » » xmlNodePtr nw = NULL, cur, firstChild = NULL;
6990
6421 /* 6991 /*
6422 » » * Create a node. 6992 » » * when operating on a reader, the entities definitions
6993 » » * are always owning the entities subtree.
6994 » » if (ctxt->parseMode == XML_PARSE_READER)
6995 » » ent->owner = 1;
6423 */ 6996 */
6424 » » ctxt->sax->reference(ctxt->userData, ent->name); 6997
6425 » » return; 6998 » » cur = ent->children;
6999 » » while (cur != NULL) {
7000 » » nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7001 » » if (nw != NULL) {
7002 » » » if (nw->_private == NULL)
7003 » » » nw->_private = cur->_private;
7004 » » » if (firstChild == NULL){
7005 » » » firstChild = nw;
7006 » » » }
7007 » » » nw = xmlAddChild(ctxt->node, nw);
7008 » » }
7009 » » if (cur == ent->last) {
7010 » » » /*
7011 » » » * needed to detect some strange empty
7012 » » » * node cases in the reader tests
7013 » » » */
7014 » » » if ((ctxt->parseMode == XML_PARSE_READER) &&
7015 » » » (nw != NULL) &&
7016 » » » (nw->type == XML_ELEMENT_NODE) &&
7017 » » » (nw->children == NULL))
7018 » » » nw->extra = 1;
7019
7020 » » » break;
7021 » » }
7022 » » cur = cur->next;
7023 » » }
7024 #ifdef LIBXML_LEGACY_ENABLED
7025 » » if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7026 » » xmlAddEntityReference(ent, firstChild, nw);
7027 #endif /* LIBXML_LEGACY_ENABLED */
7028 » } else if (list == NULL) {
7029 » » xmlNodePtr nw = NULL, cur, next, last,
7030 » » » firstChild = NULL;
7031 » » /*
7032 » » * Copy the entity child list and make it the new
7033 » » * entity child list. The goal is to make sure any
7034 » » * ID or REF referenced will be the one from the
7035 » » * document content and not the entity copy.
7036 » » */
7037 » » cur = ent->children;
7038 » » ent->children = NULL;
7039 » » last = ent->last;
7040 » » ent->last = NULL;
7041 » » while (cur != NULL) {
7042 » » next = cur->next;
7043 » » cur->next = NULL;
7044 » » cur->parent = NULL;
7045 » » nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7046 » » if (nw != NULL) {
7047 » » » if (nw->_private == NULL)
7048 » » » nw->_private = cur->_private;
7049 » » » if (firstChild == NULL){
7050 » » » firstChild = cur;
7051 » » » }
7052 » » » xmlAddChild((xmlNodePtr) ent, nw);
7053 » » » xmlAddChild(ctxt->node, cur);
7054 » » }
7055 » » if (cur == last)
7056 » » » break;
7057 » » cur = next;
7058 » » }
7059 » » if (ent->owner == 0)
7060 » » ent->owner = 1;
7061 #ifdef LIBXML_LEGACY_ENABLED
7062 » » if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7063 » » xmlAddEntityReference(ent, firstChild, nw);
7064 #endif /* LIBXML_LEGACY_ENABLED */
7065 » } else {
7066 » » const xmlChar *nbktext;
7067
7068 » » /*
7069 » » * the name change is to avoid coalescing of the
7070 » » * node with a possible previous text one which
7071 » » * would make ent->children a dangling pointer
7072 » » */
7073 » » nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
7074 » » » » » -1);
7075 » » if (ent->children->type == XML_TEXT_NODE)
7076 » » ent->children->name = nbktext;
7077 » » if ((ent->last != ent->children) &&
7078 » » (ent->last->type == XML_TEXT_NODE))
7079 » » ent->last->name = nbktext;
7080 » » xmlAddChildList(ctxt->node, ent->children);
6426 } 7081 }
6427 » if ((ctxt->replaceEntities) || (ent->children == NULL)) { 7082
6428 » » /*
6429 » » * There is a problem on the handling of _private for entities
6430 » » * (bug 155816): Should we copy the content of the field from
6431 » » * the entity (possibly overwriting some value set by the user
6432 » » * when a copy is created), should we leave it alone, or should
6433 » » * we try to take care of different situations? The problem
6434 » » * is exacerbated by the usage of this field by the xmlReader.
6435 » » * To fix this bug, we look at _private on the created node
6436 » » * and, if it's NULL, we copy in whatever was in the entity.
6437 » » * If it's not NULL we leave it alone. This is somewhat of a
6438 » » * hack - maybe we should have further tests to determine
6439 » » * what to do.
6440 » » */
6441 » » if ((ctxt->node != NULL) && (ent->children != NULL)) {
6442 » » /*
6443 » » * Seems we are generating the DOM content, do
6444 » » * a simple tree copy for all references except the first
6445 » » * In the first occurrence list contains the replacement.
6446 » » * progressive == 2 means we are operating on the Reader
6447 » » * and since nodes are discarded we must copy all the time.
6448 » » */
6449 » » if (((list == NULL) && (ent->owner == 0)) ||
6450 » » (ctxt->parseMode == XML_PARSE_READER)) {
6451 » » » xmlNodePtr nw = NULL, cur, firstChild = NULL;
6452
6453 » » » /*
6454 » » » * when operating on a reader, the entities definitions
6455 » » » * are always owning the entities subtree.
6456 » » » if (ctxt->parseMode == XML_PARSE_READER)
6457 » » » ent->owner = 1;
6458 » » » */
6459
6460 » » » cur = ent->children;
6461 » » » while (cur != NULL) {
6462 » » » nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
6463 » » » if (nw != NULL) {
6464 » » » » if (nw->_private == NULL)
6465 » » » » nw->_private = cur->_private;
6466 » » » » if (firstChild == NULL){
6467 » » » » firstChild = nw;
6468 » » » » }
6469 » » » » nw = xmlAddChild(ctxt->node, nw);
6470 » » » }
6471 » » » if (cur == ent->last) {
6472 » » » /*
6473 » » » » * needed to detect some strange empty
6474 » » » » * node cases in the reader tests
6475 » » » » */
6476 » » » if ((ctxt->parseMode == XML_PARSE_READER) &&
6477 » » » » (nw != NULL) &&
6478 » » » » (nw->type == XML_ELEMENT_NODE) &&
6479 » » » » (nw->children == NULL))
6480 » » » » nw->extra = 1;
6481
6482 » » » » break;
6483 » » » }
6484 » » » cur = cur->next;
6485 » » » }
6486 #ifdef LIBXML_LEGACY_ENABLED
6487 » » » if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)» » »
6488 » » » xmlAddEntityReference(ent, firstChild, nw);
6489 #endif /* LIBXML_LEGACY_ENABLED */
6490 » » } else if (list == NULL) {
6491 » » » xmlNodePtr nw = NULL, cur, next, last,
6492 » » » firstChild = NULL;
6493 » » » /*
6494 » » » * Copy the entity child list and make it the new
6495 » » » * entity child list. The goal is to make sure any
6496 » » » * ID or REF referenced will be the one from the
6497 » » » * document content and not the entity copy.
6498 » » » */
6499 » » » cur = ent->children;
6500 » » » ent->children = NULL;
6501 » » » last = ent->last;
6502 » » » ent->last = NULL;
6503 » » » while (cur != NULL) {
6504 » » » next = cur->next;
6505 » » » cur->next = NULL;
6506 » » » cur->parent = NULL;
6507 » » » nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
6508 » » » if (nw != NULL) {
6509 » » » » if (nw->_private == NULL)
6510 » » » » nw->_private = cur->_private;
6511 » » » » if (firstChild == NULL){
6512 » » » » firstChild = cur;
6513 » » » » }
6514 » » » » xmlAddChild((xmlNodePtr) ent, nw);
6515 » » » » xmlAddChild(ctxt->node, cur);
6516 » » » }
6517 » » » if (cur == last)
6518 » » » » break;
6519 » » » cur = next;
6520 » » » }
6521 » » » ent->owner = 1;
6522 #ifdef LIBXML_LEGACY_ENABLED
6523 » » » if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)» » »
6524 » » » xmlAddEntityReference(ent, firstChild, nw);
6525 #endif /* LIBXML_LEGACY_ENABLED */
6526 » » } else {
6527 » » const xmlChar *nbktext;
6528
6529 » » » /*
6530 » » » * the name change is to avoid coalescing of the
6531 » » » * node with a possible previous text one which
6532 » » » * would make ent->children a dangling pointer
6533 » » » */
6534 » » » nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
6535 » » » -1);
6536 » » » if (ent->children->type == XML_TEXT_NODE)
6537 » » » ent->children->name = nbktext;
6538 » » » if ((ent->last != ent->children) &&
6539 » » » (ent->last->type == XML_TEXT_NODE))
6540 » » » ent->last->name = nbktext;
6541 » » » xmlAddChildList(ctxt->node, ent->children);
6542 » » }
6543
6544 » » /*
6545 » » * This is to avoid a nasty side effect, see
6546 » » * characters() in SAX.c
6547 » » */
6548 » » ctxt->nodemem = 0;
6549 » » ctxt->nodelen = 0;
6550 » » return;
6551 » » }
6552 » }
6553 » } else {
6554 » val = ent->content;
6555 » if (val == NULL) return;
6556 /* 7083 /*
6557 » * inline the entity. 7084 » * This is to avoid a nasty side effect, see
7085 » * characters() in SAX.c
6558 */ 7086 */
6559 » if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) && 7087 » ctxt->nodemem = 0;
6560 » » (!ctxt->disableSAX)) 7088 » ctxt->nodelen = 0;
6561 » » ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val)); 7089 » return;
6562 } 7090 }
6563 } 7091 }
6564 } 7092 }
6565 7093
6566 /** 7094 /**
6567 * xmlParseEntityRef: 7095 * xmlParseEntityRef:
6568 * @ctxt: an XML parser context 7096 * @ctxt: an XML parser context
6569 * 7097 *
6570 * parse ENTITY references declarations 7098 * parse ENTITY references declarations
6571 * 7099 *
(...skipping 18 matching lines...) Expand all
6590 * An entity reference must not contain the name of an unparsed entity 7118 * An entity reference must not contain the name of an unparsed entity
6591 * 7119 *
6592 * Returns the xmlEntityPtr if found, or NULL otherwise. 7120 * Returns the xmlEntityPtr if found, or NULL otherwise.
6593 */ 7121 */
6594 xmlEntityPtr 7122 xmlEntityPtr
6595 xmlParseEntityRef(xmlParserCtxtPtr ctxt) { 7123 xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
6596 const xmlChar *name; 7124 const xmlChar *name;
6597 xmlEntityPtr ent = NULL; 7125 xmlEntityPtr ent = NULL;
6598 7126
6599 GROW; 7127 GROW;
6600 7128
6601 if (RAW == '&') { 7129 if (RAW != '&')
6602 NEXT; 7130 return(NULL);
6603 name = xmlParseName(ctxt); 7131 NEXT;
6604 » if (name == NULL) { 7132 name = xmlParseName(ctxt);
6605 » xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, 7133 if (name == NULL) {
6606 » » » "xmlParseEntityRef: no name\n"); 7134 » xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7135 » » "xmlParseEntityRef: no name\n");
7136 return(NULL);
7137 }
7138 if (RAW != ';') {
7139 » xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7140 » return(NULL);
7141 }
7142 NEXT;
7143
7144 /*
7145 * Predefined entites override any extra definition
7146 */
7147 if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7148 ent = xmlGetPredefinedEntity(name);
7149 if (ent != NULL)
7150 return(ent);
7151 }
7152
7153 /*
7154 * Increate the number of entity references parsed
7155 */
7156 ctxt->nbentities++;
7157
7158 /*
7159 * Ask first SAX for entity resolution, otherwise try the
7160 * entities which may have stored in the parser context.
7161 */
7162 if (ctxt->sax != NULL) {
7163 » if (ctxt->sax->getEntity != NULL)
7164 » ent = ctxt->sax->getEntity(ctxt->userData, name);
7165 » if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7166 » (ctxt->options & XML_PARSE_OLDSAX))
7167 » ent = xmlGetPredefinedEntity(name);
7168 » if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7169 » (ctxt->userData==ctxt)) {
7170 » ent = xmlSAX2GetEntity(ctxt, name);
7171 » }
7172 }
7173 /*
7174 * [ WFC: Entity Declared ]
7175 * In a document without any DTD, a document with only an
7176 * internal DTD subset which contains no parameter entity
7177 * references, or a document with "standalone='yes'", the
7178 * Name given in the entity reference must match that in an
7179 * entity declaration, except that well-formed documents
7180 * need not declare any of the following entities: amp, lt,
7181 * gt, apos, quot.
7182 * The declaration of a parameter entity must precede any
7183 * reference to it.
7184 * Similarly, the declaration of a general entity must
7185 * precede any reference to it which appears in a default
7186 * value in an attribute-list declaration. Note that if
7187 * entities are declared in the external subset or in
7188 * external parameter entities, a non-validating processor
7189 * is not obligated to read and process their declarations;
7190 * for such documents, the rule that an entity must be
7191 * declared is a well-formedness constraint only if
7192 * standalone='yes'.
7193 */
7194 if (ent == NULL) {
7195 » if ((ctxt->standalone == 1) ||
7196 » ((ctxt->hasExternalSubset == 0) &&
7197 » (ctxt->hasPErefs == 0))) {
7198 » xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7199 » » "Entity '%s' not defined\n", name);
6607 } else { 7200 } else {
6608 » if (RAW == ';') { 7201 » xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
6609 » NEXT; 7202 » » "Entity '%s' not defined\n", name);
6610 » » /* 7203 » if ((ctxt->inSubset == 0) &&
6611 » » * Ask first SAX for entity resolution, otherwise try the 7204 » » (ctxt->sax != NULL) &&
6612 » » * predefined set. 7205 » » (ctxt->sax->reference != NULL)) {
6613 » » */ 7206 » » ctxt->sax->reference(ctxt->userData, name);
6614 » » if (ctxt->sax != NULL) {
6615 » » if (ctxt->sax->getEntity != NULL)
6616 » » » ent = ctxt->sax->getEntity(ctxt->userData, name);
6617 » » if ((ctxt->wellFormed == 1 ) && (ent == NULL))
6618 » » ent = xmlGetPredefinedEntity(name);
6619 » » if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
6620 » » » (ctxt->userData==ctxt)) {
6621 » » » ent = xmlSAX2GetEntity(ctxt, name);
6622 » » }
6623 » » }
6624 » » /*
6625 » » * [ WFC: Entity Declared ]
6626 » » * In a document without any DTD, a document with only an
6627 » » * internal DTD subset which contains no parameter entity
6628 » » * references, or a document with "standalone='yes'", the
6629 » » * Name given in the entity reference must match that in an
6630 » » * entity declaration, except that well-formed documents
6631 » » * need not declare any of the following entities: amp, lt,
6632 » » * gt, apos, quot.
6633 » » * The declaration of a parameter entity must precede any
6634 » » * reference to it.
6635 » » * Similarly, the declaration of a general entity must
6636 » » * precede any reference to it which appears in a default
6637 » » * value in an attribute-list declaration. Note that if
6638 » » * entities are declared in the external subset or in
6639 » » * external parameter entities, a non-validating processor
6640 » » * is not obligated to read and process their declarations;
6641 » » * for such documents, the rule that an entity must be
6642 » » * declared is a well-formedness constraint only if
6643 » » * standalone='yes'.
6644 » » */
6645 » » if (ent == NULL) {
6646 » » if ((ctxt->standalone == 1) ||
6647 » » ((ctxt->hasExternalSubset == 0) &&
6648 » » » (ctxt->hasPErefs == 0))) {
6649 » » » xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
6650 » » » » "Entity '%s' not defined\n", name);
6651 » » } else {
6652 » » xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
6653 » » » » "Entity '%s' not defined\n", name);
6654 » » » if ((ctxt->inSubset == 0) &&
6655 » » (ctxt->sax != NULL) &&
6656 » » (ctxt->sax->reference != NULL)) {
6657 » » » ctxt->sax->reference(ctxt->userData, name);
6658 » » » }
6659 » » }
6660 » » ctxt->valid = 0;
6661 » » }
6662
6663 » » /*
6664 » » * [ WFC: Parsed Entity ]
6665 » » * An entity reference must not contain the name of an
6666 » » * unparsed entity
6667 » » */
6668 » » else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
6669 » » xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
6670 » » » "Entity reference to unparsed entity %s\n", name);
6671 » » }
6672
6673 » » /*
6674 » » * [ WFC: No External Entity References ]
6675 » » * Attribute values cannot contain direct or indirect
6676 » » * entity references to external entities.
6677 » » */
6678 » » else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
6679 » » (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
6680 » » xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
6681 » » » "Attribute references external entity '%s'\n", name);
6682 » » }
6683 » » /*
6684 » » * [ WFC: No < in Attribute Values ]
6685 » » * The replacement text of any entity referred to directly or
6686 » » * indirectly in an attribute value (other than "&lt;") must
6687 » » * not contain a <.
6688 » » */
6689 » » else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
6690 » » (ent != NULL) &&
6691 » » » (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
6692 » » (ent->content != NULL) &&
6693 » » » (xmlStrchr(ent->content, '<'))) {
6694 » » xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
6695 » "'<' in entity '%s' is not allowed in attributes values\n", name);
6696 » » }
6697
6698 » » /*
6699 » » * Internal check, no parameter entities here ...
6700 » » */
6701 » » else {
6702 » » switch (ent->etype) {
6703 » » » case XML_INTERNAL_PARAMETER_ENTITY:
6704 » » » case XML_EXTERNAL_PARAMETER_ENTITY:
6705 » » » xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
6706 » » » "Attempt to reference the parameter entity '%s'\n",
6707 » » name);
6708 » » » break;
6709 » » » default:
6710 » » » break;
6711 » » }
6712 » » }
6713
6714 » » /*
6715 » » * [ WFC: No Recursion ]
6716 » » * A parsed entity must not contain a recursive reference
6717 » » * to itself, either directly or indirectly.
6718 » » * Done somewhere else
6719 » » */
6720
6721 » } else {
6722 » » xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
6723 } 7207 }
6724 } 7208 }
7209 ctxt->valid = 0;
6725 } 7210 }
7211
7212 /*
7213 * [ WFC: Parsed Entity ]
7214 * An entity reference must not contain the name of an
7215 * unparsed entity
7216 */
7217 else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7218 xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7219 "Entity reference to unparsed entity %s\n", name);
7220 }
7221
7222 /*
7223 * [ WFC: No External Entity References ]
7224 * Attribute values cannot contain direct or indirect
7225 * entity references to external entities.
7226 */
7227 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7228 (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7229 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7230 "Attribute references external entity '%s'\n", name);
7231 }
7232 /*
7233 * [ WFC: No < in Attribute Values ]
7234 * The replacement text of any entity referred to directly or
7235 * indirectly in an attribute value (other than "&lt;") must
7236 * not contain a <.
7237 */
7238 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7239 (ent != NULL) && (ent->content != NULL) &&
7240 (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
7241 (xmlStrchr(ent->content, '<'))) {
7242 xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7243 "'<' in entity '%s' is not allowed in attributes values\n", name);
7244 }
7245
7246 /*
7247 * Internal check, no parameter entities here ...
7248 */
7249 else {
7250 switch (ent->etype) {
7251 case XML_INTERNAL_PARAMETER_ENTITY:
7252 case XML_EXTERNAL_PARAMETER_ENTITY:
7253 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7254 "Attempt to reference the parameter entity '%s'\n",
7255 name);
7256 break;
7257 default:
7258 break;
7259 }
7260 }
7261
7262 /*
7263 * [ WFC: No Recursion ]
7264 * A parsed entity must not contain a recursive reference
7265 * to itself, either directly or indirectly.
7266 * Done somewhere else
7267 */
6726 return(ent); 7268 return(ent);
6727 } 7269 }
6728 7270
6729 /** 7271 /**
6730 * xmlParseStringEntityRef: 7272 * xmlParseStringEntityRef:
6731 * @ctxt: an XML parser context 7273 * @ctxt: an XML parser context
6732 * @str: a pointer to an index in the string 7274 * @str: a pointer to an index in the string
6733 * 7275 *
6734 * parse ENTITY references declarations, but this version parses it from 7276 * parse ENTITY references declarations, but this version parses it from
6735 * a string value. 7277 * a string value.
(...skipping 14 matching lines...) Expand all
6750 * processor is not obligated to read and process their declarations; 7292 * processor is not obligated to read and process their declarations;
6751 * for such documents, the rule that an entity must be declared is a 7293 * for such documents, the rule that an entity must be declared is a
6752 * well-formedness constraint only if standalone='yes'. 7294 * well-formedness constraint only if standalone='yes'.
6753 * 7295 *
6754 * [ WFC: Parsed Entity ] 7296 * [ WFC: Parsed Entity ]
6755 * An entity reference must not contain the name of an unparsed entity 7297 * An entity reference must not contain the name of an unparsed entity
6756 * 7298 *
6757 * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer 7299 * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
6758 * is updated to the current location in the string. 7300 * is updated to the current location in the string.
6759 */ 7301 */
6760 xmlEntityPtr 7302 static xmlEntityPtr
6761 xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) { 7303 xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
6762 xmlChar *name; 7304 xmlChar *name;
6763 const xmlChar *ptr; 7305 const xmlChar *ptr;
6764 xmlChar cur; 7306 xmlChar cur;
6765 xmlEntityPtr ent = NULL; 7307 xmlEntityPtr ent = NULL;
6766 7308
6767 if ((str == NULL) || (*str == NULL)) 7309 if ((str == NULL) || (*str == NULL))
6768 return(NULL); 7310 return(NULL);
6769 ptr = *str; 7311 ptr = *str;
6770 cur = *ptr; 7312 cur = *ptr;
6771 if (cur == '&') { 7313 if (cur != '&')
6772 ptr++; 7314 » return(NULL);
6773 » cur = *ptr;
6774 name = xmlParseStringName(ctxt, &ptr);
6775 » if (name == NULL) {
6776 » xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6777 » » » "xmlParseStringEntityRef: no name\n");
6778 » } else {
6779 » if (*ptr == ';') {
6780 » ptr++;
6781 » » /*
6782 » » * Ask first SAX for entity resolution, otherwise try the
6783 » » * predefined set.
6784 » » */
6785 » » if (ctxt->sax != NULL) {
6786 » » if (ctxt->sax->getEntity != NULL)
6787 » » » ent = ctxt->sax->getEntity(ctxt->userData, name);
6788 » » if (ent == NULL)
6789 » » ent = xmlGetPredefinedEntity(name);
6790 » » if ((ent == NULL) && (ctxt->userData==ctxt)) {
6791 » » » ent = xmlSAX2GetEntity(ctxt, name);
6792 » » }
6793 » » }
6794 » » /*
6795 » » * [ WFC: Entity Declared ]
6796 » » * In a document without any DTD, a document with only an
6797 » » * internal DTD subset which contains no parameter entity
6798 » » * references, or a document with "standalone='yes'", the
6799 » » * Name given in the entity reference must match that in an
6800 » » * entity declaration, except that well-formed documents
6801 » » * need not declare any of the following entities: amp, lt,
6802 » » * gt, apos, quot.
6803 » » * The declaration of a parameter entity must precede any
6804 » » * reference to it.
6805 » » * Similarly, the declaration of a general entity must
6806 » » * precede any reference to it which appears in a default
6807 » » * value in an attribute-list declaration. Note that if
6808 » » * entities are declared in the external subset or in
6809 » » * external parameter entities, a non-validating processor
6810 » » * is not obligated to read and process their declarations;
6811 » » * for such documents, the rule that an entity must be
6812 » » * declared is a well-formedness constraint only if
6813 » » * standalone='yes'.
6814 » » */
6815 » » if (ent == NULL) {
6816 » » if ((ctxt->standalone == 1) ||
6817 » » ((ctxt->hasExternalSubset == 0) &&
6818 » » » (ctxt->hasPErefs == 0))) {
6819 » » » xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
6820 » » » » "Entity '%s' not defined\n", name);
6821 » » } else {
6822 » » » xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
6823 » » » » "Entity '%s' not defined\n",
6824 » » » » name);
6825 » » }
6826 » » /* TODO ? check regressions ctxt->valid = 0; */
6827 » » }
6828 7315
6829 » » /* 7316 ptr++;
6830 » » * [ WFC: Parsed Entity ] 7317 name = xmlParseStringName(ctxt, &ptr);
6831 » » * An entity reference must not contain the name of an 7318 if (name == NULL) {
6832 » » * unparsed entity 7319 » xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6833 » » */ 7320 » » "xmlParseStringEntityRef: no name\n");
6834 » » else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) { 7321 » *str = ptr;
6835 » » xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY, 7322 » return(NULL);
6836 » » » "Entity reference to unparsed entity %s\n", name); 7323 }
6837 » » } 7324 if (*ptr != ';') {
7325 » xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7326 xmlFree(name);
7327 » *str = ptr;
7328 » return(NULL);
7329 }
7330 ptr++;
6838 7331
6839 /*
6840 * [ WFC: No External Entity References ]
6841 * Attribute values cannot contain direct or indirect
6842 * entity references to external entities.
6843 */
6844 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
6845 (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
6846 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
6847 "Attribute references external entity '%s'\n", name);
6848 }
6849 /*
6850 * [ WFC: No < in Attribute Values ]
6851 * The replacement text of any entity referred to directly or
6852 * indirectly in an attribute value (other than "&lt;") must
6853 * not contain a <.
6854 */
6855 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
6856 (ent != NULL) &&
6857 (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
6858 (ent->content != NULL) &&
6859 (xmlStrchr(ent->content, '<'))) {
6860 xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
6861 "'<' in entity '%s' is not allowed in attributes values\n",
6862 name);
6863 }
6864 7332
6865 » » /* 7333 /*
6866 » » * Internal check, no parameter entities here ... 7334 * Predefined entites override any extra definition
6867 » » */ 7335 */
6868 » » else { 7336 if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
6869 » » switch (ent->etype) { 7337 ent = xmlGetPredefinedEntity(name);
6870 » » » case XML_INTERNAL_PARAMETER_ENTITY: 7338 if (ent != NULL) {
6871 » » » case XML_EXTERNAL_PARAMETER_ENTITY: 7339 xmlFree(name);
6872 » » » xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER, 7340 *str = ptr;
6873 » » » "Attempt to reference the parameter entity '%s'\n", 7341 return(ent);
6874 » » » name); 7342 }
6875 » » » break; 7343 }
6876 » » » default:
6877 » » » break;
6878 » » }
6879 » » }
6880 7344
6881 » » /* 7345 /*
6882 » » * [ WFC: No Recursion ] 7346 * Increate the number of entity references parsed
6883 » » * A parsed entity must not contain a recursive reference 7347 */
6884 » » * to itself, either directly or indirectly. 7348 ctxt->nbentities++;
6885 » » * Done somewhere else
6886 » » */
6887 7349
6888 » } else { 7350 /*
6889 » » xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL); 7351 * Ask first SAX for entity resolution, otherwise try the
6890 » } 7352 * entities which may have stored in the parser context.
6891 » xmlFree(name); 7353 */
7354 if (ctxt->sax != NULL) {
7355 » if (ctxt->sax->getEntity != NULL)
7356 » ent = ctxt->sax->getEntity(ctxt->userData, name);
7357 » if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
7358 » ent = xmlGetPredefinedEntity(name);
7359 » if ((ent == NULL) && (ctxt->userData==ctxt)) {
7360 » ent = xmlSAX2GetEntity(ctxt, name);
6892 } 7361 }
6893 } 7362 }
7363
7364 /*
7365 * [ WFC: Entity Declared ]
7366 * In a document without any DTD, a document with only an
7367 * internal DTD subset which contains no parameter entity
7368 * references, or a document with "standalone='yes'", the
7369 * Name given in the entity reference must match that in an
7370 * entity declaration, except that well-formed documents
7371 * need not declare any of the following entities: amp, lt,
7372 * gt, apos, quot.
7373 * The declaration of a parameter entity must precede any
7374 * reference to it.
7375 * Similarly, the declaration of a general entity must
7376 * precede any reference to it which appears in a default
7377 * value in an attribute-list declaration. Note that if
7378 * entities are declared in the external subset or in
7379 * external parameter entities, a non-validating processor
7380 * is not obligated to read and process their declarations;
7381 * for such documents, the rule that an entity must be
7382 * declared is a well-formedness constraint only if
7383 * standalone='yes'.
7384 */
7385 if (ent == NULL) {
7386 if ((ctxt->standalone == 1) ||
7387 ((ctxt->hasExternalSubset == 0) &&
7388 (ctxt->hasPErefs == 0))) {
7389 xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7390 "Entity '%s' not defined\n", name);
7391 } else {
7392 xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7393 "Entity '%s' not defined\n",
7394 name);
7395 }
7396 /* TODO ? check regressions ctxt->valid = 0; */
7397 }
7398
7399 /*
7400 * [ WFC: Parsed Entity ]
7401 * An entity reference must not contain the name of an
7402 * unparsed entity
7403 */
7404 else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7405 xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7406 "Entity reference to unparsed entity %s\n", name);
7407 }
7408
7409 /*
7410 * [ WFC: No External Entity References ]
7411 * Attribute values cannot contain direct or indirect
7412 * entity references to external entities.
7413 */
7414 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7415 (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7416 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7417 "Attribute references external entity '%s'\n", name);
7418 }
7419 /*
7420 * [ WFC: No < in Attribute Values ]
7421 * The replacement text of any entity referred to directly or
7422 * indirectly in an attribute value (other than "&lt;") must
7423 * not contain a <.
7424 */
7425 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7426 (ent != NULL) && (ent->content != NULL) &&
7427 (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
7428 (xmlStrchr(ent->content, '<'))) {
7429 xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7430 "'<' in entity '%s' is not allowed in attributes values\n",
7431 name);
7432 }
7433
7434 /*
7435 * Internal check, no parameter entities here ...
7436 */
7437 else {
7438 switch (ent->etype) {
7439 case XML_INTERNAL_PARAMETER_ENTITY:
7440 case XML_EXTERNAL_PARAMETER_ENTITY:
7441 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7442 "Attempt to reference the parameter entity '%s'\n",
7443 name);
7444 break;
7445 default:
7446 break;
7447 }
7448 }
7449
7450 /*
7451 * [ WFC: No Recursion ]
7452 * A parsed entity must not contain a recursive reference
7453 * to itself, either directly or indirectly.
7454 * Done somewhere else
7455 */
7456
7457 xmlFree(name);
6894 *str = ptr; 7458 *str = ptr;
6895 return(ent); 7459 return(ent);
6896 } 7460 }
6897 7461
6898 /** 7462 /**
6899 * xmlParsePEReference: 7463 * xmlParsePEReference:
6900 * @ctxt: an XML parser context 7464 * @ctxt: an XML parser context
6901 * 7465 *
6902 * parse PEReference declarations 7466 * parse PEReference declarations
6903 * The entity content is handled directly by pushing it's content as 7467 * The entity content is handled directly by pushing it's content as
(...skipping 20 matching lines...) Expand all
6924 * Parameter-entity references may only appear in the DTD. 7488 * Parameter-entity references may only appear in the DTD.
6925 * NOTE: misleading but this is handled. 7489 * NOTE: misleading but this is handled.
6926 */ 7490 */
6927 void 7491 void
6928 xmlParsePEReference(xmlParserCtxtPtr ctxt) 7492 xmlParsePEReference(xmlParserCtxtPtr ctxt)
6929 { 7493 {
6930 const xmlChar *name; 7494 const xmlChar *name;
6931 xmlEntityPtr entity = NULL; 7495 xmlEntityPtr entity = NULL;
6932 xmlParserInputPtr input; 7496 xmlParserInputPtr input;
6933 7497
6934 if (RAW == '%') { 7498 if (RAW != '%')
6935 NEXT; 7499 return;
6936 name = xmlParseName(ctxt); 7500 NEXT;
6937 if (name == NULL) { 7501 name = xmlParseName(ctxt);
6938 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, 7502 if (name == NULL) {
6939 "xmlParsePEReference: no name\n"); 7503 » xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6940 } else { 7504 » » "xmlParsePEReference: no name\n");
6941 if (RAW == ';') { 7505 » return;
6942 NEXT;
6943 if ((ctxt->sax != NULL) &&
6944 (ctxt->sax->getParameterEntity != NULL))
6945 entity = ctxt->sax->getParameterEntity(ctxt->userData,
6946 name);
6947 if (entity == NULL) {
6948 /*
6949 * [ WFC: Entity Declared ]
6950 * In a document without any DTD, a document with only an
6951 * internal DTD subset which contains no parameter entity
6952 * references, or a document with "standalone='yes'", ...
6953 * ... The declaration of a parameter entity must precede
6954 * any reference to it...
6955 */
6956 if ((ctxt->standalone == 1) ||
6957 ((ctxt->hasExternalSubset == 0) &&
6958 (ctxt->hasPErefs == 0))) {
6959 xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
6960 "PEReference: %%%s; not found\n",
6961 name);
6962 } else {
6963 /*
6964 * [ VC: Entity Declared ]
6965 * In a document with an external subset or external
6966 * parameter entities with "standalone='no'", ...
6967 * ... The declaration of a parameter entity must
6968 » » » * precede any reference to it...
6969 */
6970 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
6971 "PEReference: %%%s; not found\n",
6972 name, NULL);
6973 ctxt->valid = 0;
6974 }
6975 } else {
6976 /*
6977 * Internal checking in case the entity quest barfed
6978 */
6979 if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
6980 (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
6981 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
6982 » » » "Internal: %%%s; is not a parameter entity\n",
6983 name, NULL);
6984 } else if (ctxt->input->free != deallocblankswrapper) {
6985 input =
6986 xmlNewBlanksWrapperInputStream(ctxt, entity);
6987 xmlPushInput(ctxt, input);
6988 } else {
6989 /*
6990 * TODO !!!
6991 * handle the extra spaces added before and after
6992 * c.f. http://www.w3.org/TR/REC-xml#as-PE
6993 */
6994 input = xmlNewEntityInputStream(ctxt, entity);
6995 xmlPushInput(ctxt, input);
6996 if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
6997 » » » (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
6998 » » » (IS_BLANK_CH(NXT(5)))) {
6999 xmlParseTextDecl(ctxt);
7000 if (ctxt->errNo ==
7001 XML_ERR_UNSUPPORTED_ENCODING) {
7002 /*
7003 * The XML REC instructs us to stop parsing
7004 * right here
7005 */
7006 ctxt->instate = XML_PARSER_EOF;
7007 return;
7008 }
7009 }
7010 }
7011 }
7012 ctxt->hasPErefs = 1;
7013 } else {
7014 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7015 }
7016 }
7017 } 7506 }
7507 if (RAW != ';') {
7508 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7509 return;
7510 }
7511
7512 NEXT;
7513
7514 /*
7515 * Increate the number of entity references parsed
7516 */
7517 ctxt->nbentities++;
7518
7519 /*
7520 * Request the entity from SAX
7521 */
7522 if ((ctxt->sax != NULL) &&
7523 (ctxt->sax->getParameterEntity != NULL))
7524 entity = ctxt->sax->getParameterEntity(ctxt->userData,
7525 name);
7526 if (entity == NULL) {
7527 /*
7528 * [ WFC: Entity Declared ]
7529 * In a document without any DTD, a document with only an
7530 * internal DTD subset which contains no parameter entity
7531 * references, or a document with "standalone='yes'", ...
7532 * ... The declaration of a parameter entity must precede
7533 * any reference to it...
7534 */
7535 if ((ctxt->standalone == 1) ||
7536 ((ctxt->hasExternalSubset == 0) &&
7537 (ctxt->hasPErefs == 0))) {
7538 xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7539 "PEReference: %%%s; not found\n",
7540 name);
7541 } else {
7542 /*
7543 * [ VC: Entity Declared ]
7544 * In a document with an external subset or external
7545 * parameter entities with "standalone='no'", ...
7546 * ... The declaration of a parameter entity must
7547 * precede any reference to it...
7548 */
7549 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7550 "PEReference: %%%s; not found\n",
7551 name, NULL);
7552 ctxt->valid = 0;
7553 }
7554 } else {
7555 /*
7556 * Internal checking in case the entity quest barfed
7557 */
7558 if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
7559 (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
7560 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7561 "Internal: %%%s; is not a parameter entity\n",
7562 name, NULL);
7563 } else if (ctxt->input->free != deallocblankswrapper) {
7564 input = xmlNewBlanksWrapperInputStream(ctxt, entity);
7565 if (xmlPushInput(ctxt, input) < 0)
7566 return;
7567 } else {
7568 /*
7569 * TODO !!!
7570 * handle the extra spaces added before and after
7571 * c.f. http://www.w3.org/TR/REC-xml#as-PE
7572 */
7573 input = xmlNewEntityInputStream(ctxt, entity);
7574 if (xmlPushInput(ctxt, input) < 0)
7575 return;
7576 if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
7577 (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
7578 (IS_BLANK_CH(NXT(5)))) {
7579 xmlParseTextDecl(ctxt);
7580 if (ctxt->errNo ==
7581 XML_ERR_UNSUPPORTED_ENCODING) {
7582 /*
7583 * The XML REC instructs us to stop parsing
7584 * right here
7585 */
7586 ctxt->instate = XML_PARSER_EOF;
7587 return;
7588 }
7589 }
7590 }
7591 }
7592 ctxt->hasPErefs = 1;
7018 } 7593 }
7019 7594
7020 /** 7595 /**
7021 * xmlLoadEntityContent: 7596 * xmlLoadEntityContent:
7022 * @ctxt: an XML parser context 7597 * @ctxt: an XML parser context
7023 * @entity: an unloaded system entity 7598 * @entity: an unloaded system entity
7024 * 7599 *
7025 * Load the original content of the given system entity from the 7600 * Load the original content of the given system entity from the
7026 * ExternalID/SystemID given. This is to be used for Included in Literal 7601 * ExternalID/SystemID given. This is to be used for Included in Literal
7027 * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references 7602 * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
7060 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, 7635 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
7061 "xmlLoadEntityContent input error"); 7636 "xmlLoadEntityContent input error");
7062 xmlBufferFree(buf); 7637 xmlBufferFree(buf);
7063 return(-1); 7638 return(-1);
7064 } 7639 }
7065 7640
7066 /* 7641 /*
7067 * Push the entity as the current input, read char by char 7642 * Push the entity as the current input, read char by char
7068 * saving to the buffer until the end of the entity or an error 7643 * saving to the buffer until the end of the entity or an error
7069 */ 7644 */
7070 xmlPushInput(ctxt, input); 7645 if (xmlPushInput(ctxt, input) < 0) {
7646 xmlBufferFree(buf);
7647 » return(-1);
7648 }
7649
7071 GROW; 7650 GROW;
7072 c = CUR_CHAR(l); 7651 c = CUR_CHAR(l);
7073 while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) && 7652 while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
7074 (IS_CHAR(c))) { 7653 (IS_CHAR(c))) {
7075 xmlBufferAdd(buf, ctxt->input->cur, l); 7654 xmlBufferAdd(buf, ctxt->input->cur, l);
7076 if (count++ > 100) { 7655 if (count++ > 100) {
7077 count = 0; 7656 count = 0;
7078 GROW; 7657 GROW;
7079 } 7658 }
7080 NEXTL(l); 7659 NEXTL(l);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
7121 * with "standalone='no'", ... ... The declaration of a parameter entity 7700 * with "standalone='no'", ... ... The declaration of a parameter entity
7122 * must precede any reference to it... 7701 * must precede any reference to it...
7123 * 7702 *
7124 * [ WFC: In DTD ] 7703 * [ WFC: In DTD ]
7125 * Parameter-entity references may only appear in the DTD. 7704 * Parameter-entity references may only appear in the DTD.
7126 * NOTE: misleading but this is handled. 7705 * NOTE: misleading but this is handled.
7127 * 7706 *
7128 * Returns the string of the entity content. 7707 * Returns the string of the entity content.
7129 * str is updated to the current value of the index 7708 * str is updated to the current value of the index
7130 */ 7709 */
7131 xmlEntityPtr 7710 static xmlEntityPtr
7132 xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) { 7711 xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
7133 const xmlChar *ptr; 7712 const xmlChar *ptr;
7134 xmlChar cur; 7713 xmlChar cur;
7135 xmlChar *name; 7714 xmlChar *name;
7136 xmlEntityPtr entity = NULL; 7715 xmlEntityPtr entity = NULL;
7137 7716
7138 if ((str == NULL) || (*str == NULL)) return(NULL); 7717 if ((str == NULL) || (*str == NULL)) return(NULL);
7139 ptr = *str; 7718 ptr = *str;
7140 cur = *ptr; 7719 cur = *ptr;
7141 if (cur == '%') { 7720 if (cur != '%')
7142 ptr++; 7721 return(NULL);
7143 » cur = *ptr; 7722 ptr++;
7144 name = xmlParseStringName(ctxt, &ptr); 7723 name = xmlParseStringName(ctxt, &ptr);
7145 » if (name == NULL) { 7724 if (name == NULL) {
7146 » xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, 7725 » xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7147 » » » "xmlParseStringPEReference: no name\n"); 7726 » » "xmlParseStringPEReference: no name\n");
7727 » *str = ptr;
7728 » return(NULL);
7729 }
7730 cur = *ptr;
7731 if (cur != ';') {
7732 » xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7733 » xmlFree(name);
7734 » *str = ptr;
7735 » return(NULL);
7736 }
7737 ptr++;
7738
7739 /*
7740 * Increate the number of entity references parsed
7741 */
7742 ctxt->nbentities++;
7743
7744 /*
7745 * Request the entity from SAX
7746 */
7747 if ((ctxt->sax != NULL) &&
7748 » (ctxt->sax->getParameterEntity != NULL))
7749 » entity = ctxt->sax->getParameterEntity(ctxt->userData,
7750 » » » » » name);
7751 if (entity == NULL) {
7752 » /*
7753 » * [ WFC: Entity Declared ]
7754 » * In a document without any DTD, a document with only an
7755 » * internal DTD subset which contains no parameter entity
7756 » * references, or a document with "standalone='yes'", ...
7757 » * ... The declaration of a parameter entity must precede
7758 » * any reference to it...
7759 » */
7760 » if ((ctxt->standalone == 1) ||
7761 » ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
7762 » xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7763 » » "PEReference: %%%s; not found\n", name);
7148 } else { 7764 } else {
7149 » cur = *ptr; 7765 » /*
7150 » if (cur == ';') { 7766 » * [ VC: Entity Declared ]
7151 » » ptr++; 7767 » * In a document with an external subset or external
7152 » » cur = *ptr; 7768 » * parameter entities with "standalone='no'", ...
7153 » » if ((ctxt->sax != NULL) && 7769 » * ... The declaration of a parameter entity must
7154 » » (ctxt->sax->getParameterEntity != NULL)) 7770 » * precede any reference to it...
7155 » » entity = ctxt->sax->getParameterEntity(ctxt->userData, 7771 » */
7156 » » name); 7772 » xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7157 » » if (entity == NULL) { 7773 » » » "PEReference: %%%s; not found\n",
7158 » » /* 7774 » » » name, NULL);
7159 » » * [ WFC: Entity Declared ] 7775 » ctxt->valid = 0;
7160 » » * In a document without any DTD, a document with only an 7776 » }
7161 » » * internal DTD subset which contains no parameter entity 7777 } else {
7162 » » * references, or a document with "standalone='yes'", ... 7778 » /*
7163 » » * ... The declaration of a parameter entity must precede 7779 » * Internal checking in case the entity quest barfed
7164 » » * any reference to it... 7780 » */
7165 » » */ 7781 » if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
7166 » » if ((ctxt->standalone == 1) || 7782 » (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
7167 » » » ((ctxt->hasExternalSubset == 0) && 7783 » xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7168 » » » (ctxt->hasPErefs == 0))) { 7784 » » » "%%%s; is not a parameter entity\n",
7169 » » » xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY, 7785 » » » name, NULL);
7170 » » » "PEReference: %%%s; not found\n", name);
7171 » » } else {
7172 » » » /*
7173 » » » * [ VC: Entity Declared ]
7174 » » » * In a document with an external subset or external
7175 » » » * parameter entities with "standalone='no'", ...
7176 » » » * ... The declaration of a parameter entity must
7177 » » » * precede any reference to it...
7178 » » » */
7179 » » » xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7180 » » » » "PEReference: %%%s; not found\n",
7181 » » » name, NULL);
7182 » » » ctxt->valid = 0;
7183 » » }
7184 » » } else {
7185 » » /*
7186 » » * Internal checking in case the entity quest barfed
7187 » » */
7188 » » if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
7189 » » (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
7190 » » » xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7191 » » » "%%%s; is not a parameter entity\n",
7192 » » » » name, NULL);
7193 » » }
7194 » » }
7195 » » ctxt->hasPErefs = 1;
7196 » } else {
7197 » » xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7198 » }
7199 » xmlFree(name);
7200 } 7786 }
7201 } 7787 }
7788 ctxt->hasPErefs = 1;
7789 xmlFree(name);
7202 *str = ptr; 7790 *str = ptr;
7203 return(entity); 7791 return(entity);
7204 } 7792 }
7205 7793
7206 /** 7794 /**
7207 * xmlParseDocTypeDecl: 7795 * xmlParseDocTypeDecl:
7208 * @ctxt: an XML parser context 7796 * @ctxt: an XML parser context
7209 * 7797 *
7210 * parse a DOCTYPE declaration 7798 * parse a DOCTYPE declaration
7211 * 7799 *
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
7668 xmlParseEndTag1(ctxt, 0); 8256 xmlParseEndTag1(ctxt, 0);
7669 } 8257 }
7670 #endif /* LIBXML_SAX1_ENABLED */ 8258 #endif /* LIBXML_SAX1_ENABLED */
7671 8259
7672 /************************************************************************ 8260 /************************************************************************
7673 * * 8261 * *
7674 * SAX 2 specific operations * 8262 * SAX 2 specific operations *
7675 * * 8263 * *
7676 ************************************************************************/ 8264 ************************************************************************/
7677 8265
7678 static const xmlChar *
7679 xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
7680 int len = 0, l;
7681 int c;
7682 int count = 0;
7683
7684 /*
7685 * Handler for more complex cases
7686 */
7687 GROW;
7688 c = CUR_CHAR(l);
7689 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
7690 (!IS_LETTER(c) && (c != '_'))) {
7691 return(NULL);
7692 }
7693
7694 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
7695 ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
7696 (c == '.') || (c == '-') || (c == '_') ||
7697 (IS_COMBINING(c)) ||
7698 (IS_EXTENDER(c)))) {
7699 if (count++ > 100) {
7700 count = 0;
7701 GROW;
7702 }
7703 len += l;
7704 NEXTL(l);
7705 c = CUR_CHAR(l);
7706 }
7707 return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
7708 }
7709
7710 /* 8266 /*
7711 * xmlGetNamespace: 8267 * xmlGetNamespace:
7712 * @ctxt: an XML parser context 8268 * @ctxt: an XML parser context
7713 * @prefix: the prefix to lookup 8269 * @prefix: the prefix to lookup
7714 * 8270 *
7715 * Lookup the namespace name for the @prefix (which ca be NULL) 8271 * Lookup the namespace name for the @prefix (which ca be NULL)
7716 * The prefix must come from the @ctxt->dict dictionnary 8272 * The prefix must come from the @ctxt->dict dictionnary
7717 * 8273 *
7718 * Returns the namespace name or NULL if not bound 8274 * Returns the namespace name or NULL if not bound
7719 */ 8275 */
7720 static const xmlChar * 8276 static const xmlChar *
7721 xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) { 8277 xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
7722 int i; 8278 int i;
7723 8279
7724 if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns); 8280 if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
7725 for (i = ctxt->nsNr - 2;i >= 0;i-=2) 8281 for (i = ctxt->nsNr - 2;i >= 0;i-=2)
7726 if (ctxt->nsTab[i] == prefix) { 8282 if (ctxt->nsTab[i] == prefix) {
7727 if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0)) 8283 if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
7728 return(NULL); 8284 return(NULL);
7729 return(ctxt->nsTab[i + 1]); 8285 return(ctxt->nsTab[i + 1]);
7730 } 8286 }
7731 if (ctxt->nsParent) return xmlGetNamespace(ctxt->nsParent, prefix);
7732 return(NULL); 8287 return(NULL);
7733 } 8288 }
7734 8289
7735 /** 8290 /**
7736 * xmlParseNCName:
7737 * @ctxt: an XML parser context
7738 * @len: lenght of the string parsed
7739 *
7740 * parse an XML name.
7741 *
7742 * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
7743 * CombiningChar | Extender
7744 *
7745 * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
7746 *
7747 * Returns the Name parsed or NULL
7748 */
7749
7750 static const xmlChar *
7751 xmlParseNCName(xmlParserCtxtPtr ctxt) {
7752 const xmlChar *in;
7753 const xmlChar *ret;
7754 int count = 0;
7755
7756 /*
7757 * Accelerator for simple ASCII names
7758 */
7759 in = ctxt->input->cur;
7760 if (((*in >= 0x61) && (*in <= 0x7A)) ||
7761 ((*in >= 0x41) && (*in <= 0x5A)) ||
7762 (*in == '_')) {
7763 in++;
7764 while (((*in >= 0x61) && (*in <= 0x7A)) ||
7765 ((*in >= 0x41) && (*in <= 0x5A)) ||
7766 ((*in >= 0x30) && (*in <= 0x39)) ||
7767 (*in == '_') || (*in == '-') ||
7768 (*in == '.'))
7769 in++;
7770 if ((*in > 0) && (*in < 0x80)) {
7771 count = in - ctxt->input->cur;
7772 ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
7773 ctxt->input->cur = in;
7774 ctxt->nbChars += count;
7775 ctxt->input->col += count;
7776 if (ret == NULL) {
7777 xmlErrMemory(ctxt, NULL);
7778 }
7779 return(ret);
7780 }
7781 }
7782 return(xmlParseNCNameComplex(ctxt));
7783 }
7784
7785 /**
7786 * xmlParseQName: 8291 * xmlParseQName:
7787 * @ctxt: an XML parser context 8292 * @ctxt: an XML parser context
7788 * @prefix: pointer to store the prefix part 8293 * @prefix: pointer to store the prefix part
7789 * 8294 *
7790 * parse an XML Namespace QName 8295 * parse an XML Namespace QName
7791 * 8296 *
7792 * [6] QName ::= (Prefix ':')? LocalPart 8297 * [6] QName ::= (Prefix ':')? LocalPart
7793 * [7] Prefix ::= NCName 8298 * [7] Prefix ::= NCName
7794 * [8] LocalPart ::= NCName 8299 * [8] LocalPart ::= NCName
7795 * 8300 *
(...skipping 21 matching lines...) Expand all
7817 } 8322 }
7818 if (CUR == ':') { 8323 if (CUR == ':') {
7819 NEXT; 8324 NEXT;
7820 p = l; 8325 p = l;
7821 l = xmlParseNCName(ctxt); 8326 l = xmlParseNCName(ctxt);
7822 if (l == NULL) { 8327 if (l == NULL) {
7823 xmlChar *tmp; 8328 xmlChar *tmp;
7824 8329
7825 xmlNsErr(ctxt, XML_NS_ERR_QNAME, 8330 xmlNsErr(ctxt, XML_NS_ERR_QNAME,
7826 "Failed to parse QName '%s:'\n", p, NULL, NULL); 8331 "Failed to parse QName '%s:'\n", p, NULL, NULL);
7827 » tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0); 8332 » l = xmlParseNmtoken(ctxt);
8333 » if (l == NULL)
8334 » » tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
8335 » else {
8336 » » tmp = xmlBuildQName(l, p, NULL, 0);
8337 » » xmlFree((char *)l);
8338 » }
7828 p = xmlDictLookup(ctxt->dict, tmp, -1); 8339 p = xmlDictLookup(ctxt->dict, tmp, -1);
7829 if (tmp != NULL) xmlFree(tmp); 8340 if (tmp != NULL) xmlFree(tmp);
7830 *prefix = NULL; 8341 *prefix = NULL;
7831 return(p); 8342 return(p);
7832 } 8343 }
7833 if (CUR == ':') { 8344 if (CUR == ':') {
7834 xmlChar *tmp; 8345 xmlChar *tmp;
7835 8346
7836 xmlNsErr(ctxt, XML_NS_ERR_QNAME, 8347 xmlNsErr(ctxt, XML_NS_ERR_QNAME,
7837 "Failed to parse QName '%s:%s:'\n", p, l, NULL); 8348 "Failed to parse QName '%s:%s:'\n", p, l, NULL);
(...skipping 27 matching lines...) Expand all
7865 * parse an XML name and compares for match 8376 * parse an XML name and compares for match
7866 * (specialized for endtag parsing) 8377 * (specialized for endtag parsing)
7867 * 8378 *
7868 * Returns NULL for an illegal name, (xmlChar*) 1 for success 8379 * Returns NULL for an illegal name, (xmlChar*) 1 for success
7869 * and the name for mismatch 8380 * and the name for mismatch
7870 */ 8381 */
7871 8382
7872 static const xmlChar * 8383 static const xmlChar *
7873 xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name, 8384 xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
7874 xmlChar const *prefix) { 8385 xmlChar const *prefix) {
7875 const xmlChar *cmp = name; 8386 const xmlChar *cmp;
7876 const xmlChar *in; 8387 const xmlChar *in;
7877 const xmlChar *ret; 8388 const xmlChar *ret;
7878 const xmlChar *prefix2; 8389 const xmlChar *prefix2;
7879 8390
7880 if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name)); 8391 if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
7881 8392
7882 GROW; 8393 GROW;
7883 in = ctxt->input->cur; 8394 in = ctxt->input->cur;
7884 8395
7885 cmp = prefix; 8396 cmp = prefix;
7886 while (*in != 0 && *in == *cmp) { 8397 while (*in != 0 && *in == *cmp) {
7887 ++in; 8398 ++in;
7888 ++cmp; 8399 ++cmp;
7889 } 8400 }
7890 if ((*cmp == 0) && (*in == ':')) { 8401 if ((*cmp == 0) && (*in == ':')) {
7891 in++; 8402 in++;
7892 cmp = name; 8403 cmp = name;
7893 while (*in != 0 && *in == *cmp) { 8404 while (*in != 0 && *in == *cmp) {
7894 ++in; 8405 ++in;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
8125 /* 8636 /*
8126 * Sometimes a second normalisation pass for spaces is needed 8637 * Sometimes a second normalisation pass for spaces is needed
8127 * but that only happens if charrefs or entities refernces 8638 * but that only happens if charrefs or entities refernces
8128 * have been used in the attribute value, i.e. the attribute 8639 * have been used in the attribute value, i.e. the attribute
8129 * value have been extracted in an allocated string already. 8640 * value have been extracted in an allocated string already.
8130 */ 8641 */
8131 if (*alloc) { 8642 if (*alloc) {
8132 const xmlChar *val2; 8643 const xmlChar *val2;
8133 8644
8134 val2 = xmlAttrNormalizeSpace2(ctxt, val, len); 8645 val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
8135 » » if (val2 != NULL) { 8646 » » if ((val2 != NULL) && (val2 != val)) {
8136 xmlFree(val); 8647 xmlFree(val);
8137 val = (xmlChar *) val2; 8648 val = (xmlChar *) val2;
8138 } 8649 }
8139 } 8650 }
8140 } 8651 }
8141 ctxt->instate = XML_PARSER_CONTENT; 8652 ctxt->instate = XML_PARSER_CONTENT;
8142 } else { 8653 } else {
8143 xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE, 8654 xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8144 "Specification mandate value for attribute %s\n", 8655 "Specification mandate value for attribute %s\n",
8145 name); 8656 name);
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
8288 } 8799 }
8289 if ((attname != NULL) && (attvalue != NULL)) { 8800 if ((attname != NULL) && (attvalue != NULL)) {
8290 if (len < 0) len = xmlStrlen(attvalue); 8801 if (len < 0) len = xmlStrlen(attvalue);
8291 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) { 8802 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
8292 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len); 8803 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
8293 xmlURIPtr uri; 8804 xmlURIPtr uri;
8294 8805
8295 if (*URL != 0) { 8806 if (*URL != 0) {
8296 uri = xmlParseURI((const char *) URL); 8807 uri = xmlParseURI((const char *) URL);
8297 if (uri == NULL) { 8808 if (uri == NULL) {
8298 » » » xmlWarningMsg(ctxt, XML_WAR_NS_URI, 8809 » » » xmlNsErr(ctxt, XML_WAR_NS_URI,
8299 » » » » "xmlns: %s not a valid URI\n", 8810 » » » "xmlns: '%s' is not a valid URI\n",
8300 » » » » URL, NULL); 8811 » » » » » URL, NULL, NULL);
8301 } else { 8812 } else {
8302 if (uri->scheme == NULL) { 8813 if (uri->scheme == NULL) {
8303 » » » xmlWarningMsg(ctxt, XML_WAR_NS_URI_RELATIVE, 8814 » » » xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
8304 » » » » "xmlns: URI %s is not absolute\n", 8815 » » » » "xmlns: URI %s is not absolute\n",
8305 » » » » URL, NULL); 8816 » » » » URL, NULL, NULL);
8306 } 8817 }
8307 xmlFreeURI(uri); 8818 xmlFreeURI(uri);
8308 } 8819 }
8820 if (URL == ctxt->str_xml_ns) {
8821 if (attname != ctxt->str_xml) {
8822 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8823 "xml namespace URI cannot be the default namespace\n",
8824 NULL, NULL, NULL);
8825 }
8826 goto skip_default_ns;
8827 }
8828 if ((len == 29) &&
8829 (xmlStrEqual(URL,
8830 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
8831 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8832 "reuse of the xmlns namespace name is forbidden\n",
8833 NULL, NULL, NULL);
8834 goto skip_default_ns;
8835 }
8309 } 8836 }
8310 /* 8837 /*
8311 * check that it's not a defined namespace 8838 * check that it's not a defined namespace
8312 */ 8839 */
8313 for (j = 1;j <= nbNs;j++) 8840 for (j = 1;j <= nbNs;j++)
8314 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL) 8841 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
8315 break; 8842 break;
8316 if (j <= nbNs) 8843 if (j <= nbNs)
8317 xmlErrAttributeDup(ctxt, NULL, attname); 8844 xmlErrAttributeDup(ctxt, NULL, attname);
8318 else 8845 else
8319 if (nsPush(ctxt, NULL, URL) > 0) nbNs++; 8846 if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
8847 skip_default_ns:
8320 if (alloc != 0) xmlFree(attvalue); 8848 if (alloc != 0) xmlFree(attvalue);
8321 SKIP_BLANKS; 8849 SKIP_BLANKS;
8322 continue; 8850 continue;
8323 } 8851 }
8324 if (aprefix == ctxt->str_xmlns) { 8852 if (aprefix == ctxt->str_xmlns) {
8325 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len); 8853 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
8326 xmlURIPtr uri; 8854 xmlURIPtr uri;
8327 8855
8328 if (attname == ctxt->str_xml) { 8856 if (attname == ctxt->str_xml) {
8329 if (URL != ctxt->str_xml_ns) { 8857 if (URL != ctxt->str_xml_ns) {
8330 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, 8858 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8331 "xml namespace prefix mapped to wrong URI\n", 8859 "xml namespace prefix mapped to wrong URI\n",
8332 NULL, NULL, NULL); 8860 NULL, NULL, NULL);
8333 } 8861 }
8334 /* 8862 /*
8335 * Do not keep a namespace definition node 8863 * Do not keep a namespace definition node
8336 */ 8864 */
8337 » » if (alloc != 0) xmlFree(attvalue); 8865 » » goto skip_ns;
8338 » » SKIP_BLANKS;
8339 » » continue;
8340 } 8866 }
8341 » » uri = xmlParseURI((const char *) URL); 8867 if (URL == ctxt->str_xml_ns) {
8342 » » if (uri == NULL) { 8868 » » if (attname != ctxt->str_xml) {
8343 » » xmlWarningMsg(ctxt, XML_WAR_NS_URI, 8869 » » xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8344 » » » "xmlns:%s: '%s' is not a valid URI\n", 8870 » » » "xml namespace URI mapped to wrong prefix\n",
8345 » » » » attname, URL); 8871 » » » NULL, NULL, NULL);
8872 » » }
8873 » » goto skip_ns;
8874 » » }
8875 if (attname == ctxt->str_xmlns) {
8876 » » xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8877 » » » "redefinition of the xmlns prefix is forbidden\n",
8878 » » » NULL, NULL, NULL);
8879 » » goto skip_ns;
8880 » » }
8881 » » if ((len == 29) &&
8882 » » (xmlStrEqual(URL,
8883 » » BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
8884 » » xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8885 » » » "reuse of the xmlns namespace name is forbidden\n",
8886 » » » NULL, NULL, NULL);
8887 » » goto skip_ns;
8888 » » }
8889 » » if ((URL == NULL) || (URL[0] == 0)) {
8890 » » xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8891 » » "xmlns:%s: Empty XML namespace is not allowed\n",
8892 » » » attname, NULL, NULL);
8893 » » goto skip_ns;
8346 } else { 8894 } else {
8347 » » if ((ctxt->pedantic) && (uri->scheme == NULL)) { 8895 » » uri = xmlParseURI((const char *) URL);
8348 » » » xmlWarningMsg(ctxt, XML_WAR_NS_URI_RELATIVE, 8896 » » if (uri == NULL) {
8897 » » » xmlNsErr(ctxt, XML_WAR_NS_URI,
8898 » » » "xmlns:%s: '%s' is not a valid URI\n",
8899 » » » » » attname, URL, NULL);
8900 » » } else {
8901 » » » if ((ctxt->pedantic) && (uri->scheme == NULL)) {
8902 » » » xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
8349 "xmlns:%s: URI %s is not absolute\n", 8903 "xmlns:%s: URI %s is not absolute\n",
8350 » » » attname, URL); 8904 » » » » attname, URL, NULL);
8905 » » » }
8906 » » » xmlFreeURI(uri);
8351 } 8907 }
8352 xmlFreeURI(uri);
8353 } 8908 }
8354 8909
8355 /* 8910 /*
8356 * check that it's not a defined namespace 8911 * check that it's not a defined namespace
8357 */ 8912 */
8358 for (j = 1;j <= nbNs;j++) 8913 for (j = 1;j <= nbNs;j++)
8359 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname) 8914 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
8360 break; 8915 break;
8361 if (j <= nbNs) 8916 if (j <= nbNs)
8362 xmlErrAttributeDup(ctxt, aprefix, attname); 8917 xmlErrAttributeDup(ctxt, aprefix, attname);
8363 else 8918 else
8364 if (nsPush(ctxt, attname, URL) > 0) nbNs++; 8919 if (nsPush(ctxt, attname, URL) > 0) nbNs++;
8920 skip_ns:
8365 if (alloc != 0) xmlFree(attvalue); 8921 if (alloc != 0) xmlFree(attvalue);
8366 SKIP_BLANKS; 8922 SKIP_BLANKS;
8367 if (ctxt->input->base != base) goto base_changed; 8923 if (ctxt->input->base != base) goto base_changed;
8368 continue; 8924 continue;
8369 } 8925 }
8370 8926
8371 /* 8927 /*
8372 * Add the pair to atts 8928 * Add the pair to atts
8373 */ 8929 */
8374 if ((atts == NULL) || (nbatts + 5 > maxatts)) { 8930 if ((atts == NULL) || (nbatts + 5 > maxatts)) {
(...skipping 14 matching lines...) Expand all
8389 atts[nbatts++] = attvalue; 8945 atts[nbatts++] = attvalue;
8390 /* 8946 /*
8391 * tag if some deallocation is needed 8947 * tag if some deallocation is needed
8392 */ 8948 */
8393 if (alloc != 0) attval = 1; 8949 if (alloc != 0) attval = 1;
8394 } else { 8950 } else {
8395 if ((attvalue != NULL) && (attvalue[len] == 0)) 8951 if ((attvalue != NULL) && (attvalue[len] == 0))
8396 xmlFree(attvalue); 8952 xmlFree(attvalue);
8397 } 8953 }
8398 8954
8399 failed: 8955 failed:
8400 8956
8401 GROW 8957 GROW
8402 if (ctxt->input->base != base) goto base_changed; 8958 if (ctxt->input->base != base) goto base_changed;
8403 if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>')))) 8959 if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
8404 break; 8960 break;
8405 if (!IS_BLANK_CH(RAW)) { 8961 if (!IS_BLANK_CH(RAW)) {
8406 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, 8962 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
8407 "attributes construct error\n"); 8963 "attributes construct error\n");
8408 break; 8964 break;
8409 } 8965 }
(...skipping 10 matching lines...) Expand all
8420 8976
8421 /* 8977 /*
8422 * The attributes defaulting 8978 * The attributes defaulting
8423 */ 8979 */
8424 if (ctxt->attsDefault != NULL) { 8980 if (ctxt->attsDefault != NULL) {
8425 xmlDefAttrsPtr defaults; 8981 xmlDefAttrsPtr defaults;
8426 8982
8427 defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix); 8983 defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
8428 if (defaults != NULL) { 8984 if (defaults != NULL) {
8429 for (i = 0;i < defaults->nbAttrs;i++) { 8985 for (i = 0;i < defaults->nbAttrs;i++) {
8430 » attname = defaults->values[4 * i]; 8986 » attname = defaults->values[5 * i];
8431 » » aprefix = defaults->values[4 * i + 1]; 8987 » » aprefix = defaults->values[5 * i + 1];
8432 8988
8433 /* 8989 /*
8434 * special work for namespaces defaulted defs 8990 * special work for namespaces defaulted defs
8435 */ 8991 */
8436 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) { 8992 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
8437 /* 8993 /*
8438 * check that it's not a defined namespace 8994 * check that it's not a defined namespace
8439 */ 8995 */
8440 for (j = 1;j <= nbNs;j++) 8996 for (j = 1;j <= nbNs;j++)
8441 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL) 8997 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
8442 break; 8998 break;
8443 if (j <= nbNs) continue; 8999 if (j <= nbNs) continue;
8444 9000
8445 nsname = xmlGetNamespace(ctxt, NULL); 9001 nsname = xmlGetNamespace(ctxt, NULL);
8446 » » if (nsname != defaults->values[4 * i + 2]) { 9002 » » if (nsname != defaults->values[5 * i + 2]) {
8447 if (nsPush(ctxt, NULL, 9003 if (nsPush(ctxt, NULL,
8448 » » » defaults->values[4 * i + 2]) > 0) 9004 » » » defaults->values[5 * i + 2]) > 0)
8449 nbNs++; 9005 nbNs++;
8450 } 9006 }
8451 } else if (aprefix == ctxt->str_xmlns) { 9007 } else if (aprefix == ctxt->str_xmlns) {
8452 /* 9008 /*
8453 * check that it's not a defined namespace 9009 * check that it's not a defined namespace
8454 */ 9010 */
8455 for (j = 1;j <= nbNs;j++) 9011 for (j = 1;j <= nbNs;j++)
8456 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname) 9012 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
8457 break; 9013 break;
8458 if (j <= nbNs) continue; 9014 if (j <= nbNs) continue;
8459 9015
8460 nsname = xmlGetNamespace(ctxt, attname); 9016 nsname = xmlGetNamespace(ctxt, attname);
8461 if (nsname != defaults->values[2]) { 9017 if (nsname != defaults->values[2]) {
8462 if (nsPush(ctxt, attname, 9018 if (nsPush(ctxt, attname,
8463 » » » defaults->values[4 * i + 2]) > 0) 9019 » » » defaults->values[5 * i + 2]) > 0)
8464 nbNs++; 9020 nbNs++;
8465 } 9021 }
8466 } else { 9022 } else {
8467 /* 9023 /*
8468 * check that it's not a defined attribute 9024 * check that it's not a defined attribute
8469 */ 9025 */
8470 for (j = 0;j < nbatts;j+=5) { 9026 for (j = 0;j < nbatts;j+=5) {
8471 if ((attname == atts[j]) && (aprefix == atts[j+1])) 9027 if ((attname == atts[j]) && (aprefix == atts[j+1]))
8472 break; 9028 break;
8473 } 9029 }
8474 if (j < nbatts) continue; 9030 if (j < nbatts) continue;
8475 9031
8476 if ((atts == NULL) || (nbatts + 5 > maxatts)) { 9032 if ((atts == NULL) || (nbatts + 5 > maxatts)) {
8477 if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) { 9033 if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
8478 return(NULL); 9034 return(NULL);
8479 } 9035 }
8480 maxatts = ctxt->maxatts; 9036 maxatts = ctxt->maxatts;
8481 atts = ctxt->atts; 9037 atts = ctxt->atts;
8482 } 9038 }
8483 atts[nbatts++] = attname; 9039 atts[nbatts++] = attname;
8484 atts[nbatts++] = aprefix; 9040 atts[nbatts++] = aprefix;
8485 if (aprefix == NULL) 9041 if (aprefix == NULL)
8486 atts[nbatts++] = NULL; 9042 atts[nbatts++] = NULL;
8487 else 9043 else
8488 atts[nbatts++] = xmlGetNamespace(ctxt, aprefix); 9044 atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
8489 » » atts[nbatts++] = defaults->values[4 * i + 2]; 9045 » » atts[nbatts++] = defaults->values[5 * i + 2];
8490 » » atts[nbatts++] = defaults->values[4 * i + 3]; 9046 » » atts[nbatts++] = defaults->values[5 * i + 3];
9047 » » if ((ctxt->standalone == 1) &&
9048 » » (defaults->values[5 * i + 4] != NULL)) {
9049 » » » xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
9050 » "standalone: attribute %s on %s defaulted from external subset\n",
9051 » attname, localname);
9052 » » }
8491 nbdef++; 9053 nbdef++;
8492 } 9054 }
8493 } 9055 }
8494 } 9056 }
8495 } 9057 }
8496 9058
8497 /* 9059 /*
8498 * The attributes checkings 9060 * The attributes checkings
8499 */ 9061 */
8500 for (i = 0; i < nbatts;i += 5) { 9062 for (i = 0; i < nbatts;i += 5) {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
8637 NEXT1; 9199 NEXT1;
8638 9200
8639 /* 9201 /*
8640 * [ WFC: Element Type Match ] 9202 * [ WFC: Element Type Match ]
8641 * The Name in an element's end-tag must match the element type in the 9203 * The Name in an element's end-tag must match the element type in the
8642 * start-tag. 9204 * start-tag.
8643 * 9205 *
8644 */ 9206 */
8645 if (name != (xmlChar*)1) { 9207 if (name != (xmlChar*)1) {
8646 if (name == NULL) name = BAD_CAST "unparseable"; 9208 if (name == NULL) name = BAD_CAST "unparseable";
9209 if ((line == 0) && (ctxt->node != NULL))
9210 line = ctxt->node->line;
8647 xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH, 9211 xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
8648 "Opening and ending tag mismatch: %s line %d and %s\n", 9212 "Opening and ending tag mismatch: %s line %d and %s\n",
8649 ctxt->name, line, name); 9213 ctxt->name, line, name);
8650 } 9214 }
8651 9215
8652 /* 9216 /*
8653 * SAX: End of Tag 9217 * SAX: End of Tag
8654 */ 9218 */
8655 done: 9219 done:
8656 if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) && 9220 if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
8856 * 9420 *
8857 * [ WFC: Element Type Match ] 9421 * [ WFC: Element Type Match ]
8858 * The Name in an element's end-tag must match the element type in the 9422 * The Name in an element's end-tag must match the element type in the
8859 * start-tag. 9423 * start-tag.
8860 * 9424 *
8861 */ 9425 */
8862 9426
8863 void 9427 void
8864 xmlParseElement(xmlParserCtxtPtr ctxt) { 9428 xmlParseElement(xmlParserCtxtPtr ctxt) {
8865 const xmlChar *name; 9429 const xmlChar *name;
8866 const xmlChar *prefix; 9430 const xmlChar *prefix = NULL;
8867 const xmlChar *URI; 9431 const xmlChar *URI = NULL;
8868 xmlParserNodeInfo node_info; 9432 xmlParserNodeInfo node_info;
8869 int line, tlen; 9433 int line, tlen;
8870 xmlNodePtr ret; 9434 xmlNodePtr ret;
8871 int nsNr = ctxt->nsNr; 9435 int nsNr = ctxt->nsNr;
8872 9436
8873 if ((unsigned int) ctxt->nameNr > xmlParserMaxDepth) { 9437 if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
8874 xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR, 9438 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8875 » "Excessive depth in document: change xmlParserMaxDepth = %d\n", 9439 » xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
8876 » xmlParserMaxDepth); 9440 » » "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
9441 » » » xmlParserMaxDepth);
8877 ctxt->instate = XML_PARSER_EOF; 9442 ctxt->instate = XML_PARSER_EOF;
8878 return; 9443 return;
8879 } 9444 }
8880 9445
8881 /* Capture start position */ 9446 /* Capture start position */
8882 if (ctxt->record_info) { 9447 if (ctxt->record_info) {
8883 node_info.begin_pos = ctxt->input->consumed + 9448 node_info.begin_pos = ctxt->input->consumed +
8884 (CUR_PTR - ctxt->input->base); 9449 (CUR_PTR - ctxt->input->base);
8885 node_info.begin_line = ctxt->input->line; 9450 node_info.begin_line = ctxt->input->line;
8886 } 9451 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
9020 xmlParserAddNodeInfo(ctxt, &node_info); 9585 xmlParserAddNodeInfo(ctxt, &node_info);
9021 } 9586 }
9022 } 9587 }
9023 9588
9024 /** 9589 /**
9025 * xmlParseVersionNum: 9590 * xmlParseVersionNum:
9026 * @ctxt: an XML parser context 9591 * @ctxt: an XML parser context
9027 * 9592 *
9028 * parse the XML version value. 9593 * parse the XML version value.
9029 * 9594 *
9030 * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+ 9595 * [26] VersionNum ::= '1.' [0-9]+
9596 *
9597 * In practice allow [0-9].[0-9]+ at that level
9031 * 9598 *
9032 * Returns the string giving the XML version number, or NULL 9599 * Returns the string giving the XML version number, or NULL
9033 */ 9600 */
9034 xmlChar * 9601 xmlChar *
9035 xmlParseVersionNum(xmlParserCtxtPtr ctxt) { 9602 xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
9036 xmlChar *buf = NULL; 9603 xmlChar *buf = NULL;
9037 int len = 0; 9604 int len = 0;
9038 int size = 10; 9605 int size = 10;
9039 xmlChar cur; 9606 xmlChar cur;
9040 9607
9041 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); 9608 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
9042 if (buf == NULL) { 9609 if (buf == NULL) {
9043 xmlErrMemory(ctxt, NULL); 9610 xmlErrMemory(ctxt, NULL);
9044 return(NULL); 9611 return(NULL);
9045 } 9612 }
9046 cur = CUR; 9613 cur = CUR;
9047 while (((cur >= 'a') && (cur <= 'z')) || 9614 if (!((cur >= '0') && (cur <= '9'))) {
9048 ((cur >= 'A') && (cur <= 'Z')) || 9615 » xmlFree(buf);
9049 ((cur >= '0') && (cur <= '9')) || 9616 » return(NULL);
9050 (cur == '_') || (cur == '.') || 9617 }
9051 » (cur == ':') || (cur == '-')) { 9618 buf[len++] = cur;
9619 NEXT;
9620 cur=CUR;
9621 if (cur != '.') {
9622 » xmlFree(buf);
9623 » return(NULL);
9624 }
9625 buf[len++] = cur;
9626 NEXT;
9627 cur=CUR;
9628 while ((cur >= '0') && (cur <= '9')) {
9052 if (len + 1 >= size) { 9629 if (len + 1 >= size) {
9053 xmlChar *tmp; 9630 xmlChar *tmp;
9054 9631
9055 size *= 2; 9632 size *= 2;
9056 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar)); 9633 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
9057 if (tmp == NULL) { 9634 if (tmp == NULL) {
9058 xmlFree(buf); 9635 xmlFree(buf);
9059 xmlErrMemory(ctxt, NULL); 9636 xmlErrMemory(ctxt, NULL);
9060 return(NULL); 9637 return(NULL);
9061 } 9638 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
9134 xmlChar cur; 9711 xmlChar cur;
9135 9712
9136 cur = CUR; 9713 cur = CUR;
9137 if (((cur >= 'a') && (cur <= 'z')) || 9714 if (((cur >= 'a') && (cur <= 'z')) ||
9138 ((cur >= 'A') && (cur <= 'Z'))) { 9715 ((cur >= 'A') && (cur <= 'Z'))) {
9139 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); 9716 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
9140 if (buf == NULL) { 9717 if (buf == NULL) {
9141 xmlErrMemory(ctxt, NULL); 9718 xmlErrMemory(ctxt, NULL);
9142 return(NULL); 9719 return(NULL);
9143 } 9720 }
9144 » 9721
9145 buf[len++] = cur; 9722 buf[len++] = cur;
9146 NEXT; 9723 NEXT;
9147 cur = CUR; 9724 cur = CUR;
9148 while (((cur >= 'a') && (cur <= 'z')) || 9725 while (((cur >= 'a') && (cur <= 'z')) ||
9149 ((cur >= 'A') && (cur <= 'Z')) || 9726 ((cur >= 'A') && (cur <= 'Z')) ||
9150 ((cur >= '0') && (cur <= '9')) || 9727 ((cur >= '0') && (cur <= '9')) ||
9151 (cur == '.') || (cur == '_') || 9728 (cur == '.') || (cur == '_') ||
9152 (cur == '-')) { 9729 (cur == '-')) {
9153 if (len + 1 >= size) { 9730 if (len + 1 >= size) {
9154 xmlChar *tmp; 9731 xmlChar *tmp;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
9222 } else { 9799 } else {
9223 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL); 9800 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
9224 } 9801 }
9225 /* 9802 /*
9226 * UTF-16 encoding stwich has already taken place at this stage, 9803 * UTF-16 encoding stwich has already taken place at this stage,
9227 * more over the little-endian/big-endian selection is already done 9804 * more over the little-endian/big-endian selection is already done
9228 */ 9805 */
9229 if ((encoding != NULL) && 9806 if ((encoding != NULL) &&
9230 ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) || 9807 ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
9231 (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) { 9808 (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
9809 /*
9810 * If no encoding was passed to the parser, that we are
9811 * using UTF-16 and no decoder is present i.e. the
9812 * document is apparently UTF-8 compatible, then raise an
9813 * encoding mismatch fatal error
9814 */
9815 if ((ctxt->encoding == NULL) &&
9816 (ctxt->input->buf != NULL) &&
9817 (ctxt->input->buf->encoder == NULL)) {
9818 xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
9819 "Document labelled UTF-16 but has UTF-8 content\n");
9820 }
9232 if (ctxt->encoding != NULL) 9821 if (ctxt->encoding != NULL)
9233 xmlFree((xmlChar *) ctxt->encoding); 9822 xmlFree((xmlChar *) ctxt->encoding);
9234 ctxt->encoding = encoding; 9823 ctxt->encoding = encoding;
9235 } 9824 }
9236 /* 9825 /*
9237 * UTF-8 encoding is handled natively 9826 * UTF-8 encoding is handled natively
9238 */ 9827 */
9239 else if ((encoding != NULL) && 9828 else if ((encoding != NULL) &&
9240 ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) || 9829 ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
9241 (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) { 9830 (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
9380 9969
9381 /* 9970 /*
9382 * We must have the VersionInfo here. 9971 * We must have the VersionInfo here.
9383 */ 9972 */
9384 version = xmlParseVersionInfo(ctxt); 9973 version = xmlParseVersionInfo(ctxt);
9385 if (version == NULL) { 9974 if (version == NULL) {
9386 xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL); 9975 xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
9387 } else { 9976 } else {
9388 if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) { 9977 if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
9389 /* 9978 /*
9390 » * TODO: Blueberry should be detected here 9979 » * Changed here for XML-1.0 5th edition
9391 */ 9980 */
9392 » xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION, 9981 » if (ctxt->options & XML_PARSE_OLD10) {
9393 » » "Unsupported version '%s'\n", 9982 » » xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
9394 » » » version, NULL); 9983 » » » "Unsupported version '%s'\n",
9984 » » » version);
9985 » } else {
9986 » if ((version[0] == '1') && ((version[1] == '.'))) {
9987 » » xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
9988 » » "Unsupported version '%s'\n",
9989 » » » » version, NULL);
9990 » » } else {
9991 » » xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
9992 » » » » "Unsupported version '%s'\n",
9993 » » » » version);
9994 » » }
9995 » }
9395 } 9996 }
9396 if (ctxt->version != NULL) 9997 if (ctxt->version != NULL)
9397 xmlFree((void *) ctxt->version); 9998 xmlFree((void *) ctxt->version);
9398 ctxt->version = version; 9999 ctxt->version = version;
9399 } 10000 }
9400 10001
9401 /* 10002 /*
9402 * We may have the encoding declaration 10003 * We may have the encoding declaration
9403 */ 10004 */
9404 if (!IS_BLANK_CH(RAW)) { 10005 if (!IS_BLANK_CH(RAW)) {
(...skipping 14 matching lines...) Expand all
9419 /* 10020 /*
9420 * We may have the standalone status. 10021 * We may have the standalone status.
9421 */ 10022 */
9422 if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) { 10023 if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
9423 if ((RAW == '?') && (NXT(1) == '>')) { 10024 if ((RAW == '?') && (NXT(1) == '>')) {
9424 SKIP(2); 10025 SKIP(2);
9425 return; 10026 return;
9426 } 10027 }
9427 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n"); 10028 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
9428 } 10029 }
10030
10031 /*
10032 * We can grow the input buffer freely at that point
10033 */
10034 GROW;
10035
9429 SKIP_BLANKS; 10036 SKIP_BLANKS;
9430 ctxt->input->standalone = xmlParseSDDecl(ctxt); 10037 ctxt->input->standalone = xmlParseSDDecl(ctxt);
9431 10038
9432 SKIP_BLANKS; 10039 SKIP_BLANKS;
9433 if ((RAW == '?') && (NXT(1) == '>')) { 10040 if ((RAW == '?') && (NXT(1) == '>')) {
9434 SKIP(2); 10041 SKIP(2);
9435 } else if (RAW == '>') { 10042 } else if (RAW == '>') {
9436 /* Deprecated old WD ... */ 10043 /* Deprecated old WD ... */
9437 xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL); 10044 xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
9438 NEXT; 10045 NEXT;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
9521 } 10128 }
9522 } 10129 }
9523 10130
9524 10131
9525 if (CUR == 0) { 10132 if (CUR == 0) {
9526 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL); 10133 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
9527 } 10134 }
9528 10135
9529 /* 10136 /*
9530 * Check for the XMLDecl in the Prolog. 10137 * Check for the XMLDecl in the Prolog.
10138 * do not GROW here to avoid the detected encoder to decode more
10139 * than just the first line, unless the amount of data is really
10140 * too small to hold "<?xml version="1.0" encoding="foo"
9531 */ 10141 */
9532 GROW; 10142 if ((ctxt->input->end - ctxt->input->cur) < 35) {
10143 GROW;
10144 }
9533 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) { 10145 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
9534 10146
9535 /* 10147 /*
9536 * Note that we will switch encoding on the fly. 10148 * Note that we will switch encoding on the fly.
9537 */ 10149 */
9538 xmlParseXMLDecl(ctxt); 10150 xmlParseXMLDecl(ctxt);
9539 if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) { 10151 if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
9540 /* 10152 /*
9541 * The XML REC instructs us to stop parsing right here 10153 * The XML REC instructs us to stop parsing right here
9542 */ 10154 */
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
9618 10230
9619 /* 10231 /*
9620 * Remove locally kept entity definitions if the tree was not built 10232 * Remove locally kept entity definitions if the tree was not built
9621 */ 10233 */
9622 if ((ctxt->myDoc != NULL) && 10234 if ((ctxt->myDoc != NULL) &&
9623 (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) { 10235 (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
9624 xmlFreeDoc(ctxt->myDoc); 10236 xmlFreeDoc(ctxt->myDoc);
9625 ctxt->myDoc = NULL; 10237 ctxt->myDoc = NULL;
9626 } 10238 }
9627 10239
10240 if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
10241 ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
10242 if (ctxt->valid)
10243 ctxt->myDoc->properties |= XML_DOC_DTDVALID;
10244 if (ctxt->nsWellFormed)
10245 ctxt->myDoc->properties |= XML_DOC_NSVALID;
10246 if (ctxt->options & XML_PARSE_OLD10)
10247 ctxt->myDoc->properties |= XML_DOC_OLD10;
10248 }
9628 if (! ctxt->wellFormed) { 10249 if (! ctxt->wellFormed) {
9629 ctxt->valid = 0; 10250 ctxt->valid = 0;
9630 return(-1); 10251 return(-1);
9631 } 10252 }
9632 return(0); 10253 return(0);
9633 } 10254 }
9634 10255
9635 /** 10256 /**
9636 * xmlParseExtParsedEnt: 10257 * xmlParseExtParsedEnt:
9637 * @ctxt: an XML parser context 10258 * @ctxt: an XML parser context
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after
10180 ctxt->sax->startDocument(ctxt->userData); 10801 ctxt->sax->startDocument(ctxt->userData);
10181 ctxt->instate = XML_PARSER_MISC; 10802 ctxt->instate = XML_PARSER_MISC;
10182 #ifdef DEBUG_PUSH 10803 #ifdef DEBUG_PUSH
10183 xmlGenericError(xmlGenericErrorContext, 10804 xmlGenericError(xmlGenericErrorContext,
10184 "PP: entering MISC\n"); 10805 "PP: entering MISC\n");
10185 #endif 10806 #endif
10186 } 10807 }
10187 break; 10808 break;
10188 case XML_PARSER_START_TAG: { 10809 case XML_PARSER_START_TAG: {
10189 const xmlChar *name; 10810 const xmlChar *name;
10190 » » const xmlChar *prefix; 10811 » » const xmlChar *prefix = NULL;
10191 » » const xmlChar *URI; 10812 » » const xmlChar *URI = NULL;
10192 int nsNr = ctxt->nsNr; 10813 int nsNr = ctxt->nsNr;
10193 10814
10194 if ((avail < 2) && (ctxt->inputNr == 1)) 10815 if ((avail < 2) && (ctxt->inputNr == 1))
10195 goto done; 10816 goto done;
10196 cur = ctxt->input->cur[0]; 10817 cur = ctxt->input->cur[0];
10197 if (cur != '<') { 10818 if (cur != '<') {
10198 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL); 10819 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10199 ctxt->instate = XML_PARSER_EOF; 10820 ctxt->instate = XML_PARSER_EOF;
10200 if ((ctxt->sax) && (ctxt->sax->endDocument != NULL)) 10821 if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10201 ctxt->sax->endDocument(ctxt->userData); 10822 ctxt->sax->endDocument(ctxt->userData);
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
10895 * @terminate: last chunk indicator 11516 * @terminate: last chunk indicator
10896 * 11517 *
10897 * Parse a Chunk of memory 11518 * Parse a Chunk of memory
10898 * 11519 *
10899 * Returns zero if no error, the xmlParserErrors otherwise. 11520 * Returns zero if no error, the xmlParserErrors otherwise.
10900 */ 11521 */
10901 int 11522 int
10902 xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size, 11523 xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
10903 int terminate) { 11524 int terminate) {
10904 int end_in_lf = 0; 11525 int end_in_lf = 0;
11526 int remain = 0;
10905 11527
10906 if (ctxt == NULL) 11528 if (ctxt == NULL)
10907 return(XML_ERR_INTERNAL_ERROR); 11529 return(XML_ERR_INTERNAL_ERROR);
10908 if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1)) 11530 if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
10909 return(ctxt->errNo); 11531 return(ctxt->errNo);
10910 if (ctxt->instate == XML_PARSER_START) 11532 if (ctxt->instate == XML_PARSER_START)
10911 xmlDetectSAX2(ctxt); 11533 xmlDetectSAX2(ctxt);
10912 if ((size > 0) && (chunk != NULL) && (!terminate) && 11534 if ((size > 0) && (chunk != NULL) && (!terminate) &&
10913 (chunk[size - 1] == '\r')) { 11535 (chunk[size - 1] == '\r')) {
10914 end_in_lf = 1; 11536 end_in_lf = 1;
10915 size--; 11537 size--;
10916 } 11538 }
11539
11540 xmldecl_done:
11541
10917 if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) && 11542 if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
10918 (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) { 11543 (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
10919 int base = ctxt->input->base - ctxt->input->buf->buffer->content; 11544 int base = ctxt->input->base - ctxt->input->buf->buffer->content;
10920 int cur = ctxt->input->cur - ctxt->input->base; 11545 int cur = ctxt->input->cur - ctxt->input->base;
10921 int res; 11546 int res;
10922 » 11547
11548 /* Chromium note: commenting out the following block of code is a gory
11549 * hack, meant to partially undo
11550 * http://git.gnome.org/browse/libxml2/commit/?id=a6c76a
11551 *
11552 * WebKit and libxml disagree about who is responsible for the
11553 * document encoding.
11554 *
11555 * This bug:
11556 * https://bugs.webkit.org/show_bug.cgi?id=30508
11557 * has links to test cases, libxml bug reports, and mailing list threads
11558 * arguing about it; for now, though, we can just undo the change that
11559 * caused libxml to regress.
11560 */
11561 #if 0
11562 /*
11563 * Specific handling if we autodetected an encoding, we should not
11564 * push more than the first line ... which depend on the encoding
11565 * And only push the rest once the final encoding was detected
11566 */
11567 if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
11568 (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
11569 unsigned int len = 45;
11570
11571 if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11572 BAD_CAST "UTF-16")) ||
11573 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11574 BAD_CAST "UTF16")))
11575 len = 90;
11576 else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11577 BAD_CAST "UCS-4")) ||
11578 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11579 BAD_CAST "UCS4")))
11580 len = 180;
11581
11582 if (ctxt->input->buf->rawconsumed < len)
11583 len -= ctxt->input->buf->rawconsumed;
11584
11585 /*
11586 * Change size for reading the initial declaration only
11587 * if size is greater than len. Otherwise, memmove in xmlBufferAdd
11588 * will blindly copy extra bytes from memory.
11589 */
11590 if (size > len) {
11591 remain = size - len;
11592 size = len;
11593 } else {
11594 remain = 0;
11595 }
11596 }
11597 #endif
10923 res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk); 11598 res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
10924 if (res < 0) { 11599 if (res < 0) {
10925 ctxt->errNo = XML_PARSER_EOF; 11600 ctxt->errNo = XML_PARSER_EOF;
10926 ctxt->disableSAX = 1; 11601 ctxt->disableSAX = 1;
10927 return (XML_PARSER_EOF); 11602 return (XML_PARSER_EOF);
10928 } 11603 }
10929 ctxt->input->base = ctxt->input->buf->buffer->content + base; 11604 ctxt->input->base = ctxt->input->buf->buffer->content + base;
10930 ctxt->input->cur = ctxt->input->base + cur; 11605 ctxt->input->cur = ctxt->input->base + cur;
10931 ctxt->input->end = 11606 ctxt->input->end =
10932 &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use]; 11607 &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
10933 #ifdef DEBUG_PUSH 11608 #ifdef DEBUG_PUSH
10934 xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size); 11609 xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
10935 #endif 11610 #endif
10936 11611
10937 } else if (ctxt->instate != XML_PARSER_EOF) { 11612 } else if (ctxt->instate != XML_PARSER_EOF) {
10938 if ((ctxt->input != NULL) && ctxt->input->buf != NULL) { 11613 if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
10939 xmlParserInputBufferPtr in = ctxt->input->buf; 11614 xmlParserInputBufferPtr in = ctxt->input->buf;
10940 if ((in->encoder != NULL) && (in->buffer != NULL) && 11615 if ((in->encoder != NULL) && (in->buffer != NULL) &&
10941 (in->raw != NULL)) { 11616 (in->raw != NULL)) {
10942 int nbchars; 11617 int nbchars;
10943 » » 11618
10944 nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw); 11619 nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
10945 if (nbchars < 0) { 11620 if (nbchars < 0) {
10946 /* TODO 2.6.0 */ 11621 /* TODO 2.6.0 */
10947 xmlGenericError(xmlGenericErrorContext, 11622 xmlGenericError(xmlGenericErrorContext,
10948 "xmlParseChunk: encoder error\n"); 11623 "xmlParseChunk: encoder error\n");
10949 return(XML_ERR_INVALID_ENCODING); 11624 return(XML_ERR_INVALID_ENCODING);
10950 } 11625 }
10951 } 11626 }
10952 } 11627 }
10953 } 11628 }
10954 xmlParseTryOrFinish(ctxt, terminate); 11629 if (remain != 0)
11630 xmlParseTryOrFinish(ctxt, 0);
11631 else
11632 xmlParseTryOrFinish(ctxt, terminate);
11633 if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11634 return(ctxt->errNo);
11635
11636 if (remain != 0) {
11637 chunk += size;
11638 size = remain;
11639 remain = 0;
11640 goto xmldecl_done;
11641 }
10955 if ((end_in_lf == 1) && (ctxt->input != NULL) && 11642 if ((end_in_lf == 1) && (ctxt->input != NULL) &&
10956 (ctxt->input->buf != NULL)) { 11643 (ctxt->input->buf != NULL)) {
10957 xmlParserInputBufferPush(ctxt->input->buf, 1, "\r"); 11644 xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
10958 } 11645 }
10959 if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
10960 return(ctxt->errNo);
10961 if (terminate) { 11646 if (terminate) {
10962 /* 11647 /*
10963 * Check for termination 11648 * Check for termination
10964 */ 11649 */
10965 int avail = 0; 11650 int avail = 0;
10966 11651
10967 if (ctxt->input != NULL) { 11652 if (ctxt->input != NULL) {
10968 if (ctxt->input->buf == NULL) 11653 if (ctxt->input->buf == NULL)
10969 avail = ctxt->input->length - 11654 avail = ctxt->input->length -
10970 (ctxt->input->cur - ctxt->input->base); 11655 (ctxt->input->cur - ctxt->input->base);
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
11262 if (pinput == NULL) { 11947 if (pinput == NULL) {
11263 if (sax != NULL) ctxt->sax = NULL; 11948 if (sax != NULL) ctxt->sax = NULL;
11264 xmlFreeParserInputBuffer(input); 11949 xmlFreeParserInputBuffer(input);
11265 xmlFreeParserCtxt(ctxt); 11950 xmlFreeParserCtxt(ctxt);
11266 return(NULL); 11951 return(NULL);
11267 } 11952 }
11268 11953
11269 /* 11954 /*
11270 * plug some encoding conversion routines here. 11955 * plug some encoding conversion routines here.
11271 */ 11956 */
11272 xmlPushInput(ctxt, pinput); 11957 if (xmlPushInput(ctxt, pinput) < 0) {
11958 if (sax != NULL) ctxt->sax = NULL;
11959 » xmlFreeParserCtxt(ctxt);
11960 » return(NULL);
11961 }
11273 if (enc != XML_CHAR_ENCODING_NONE) { 11962 if (enc != XML_CHAR_ENCODING_NONE) {
11274 xmlSwitchEncoding(ctxt, enc); 11963 xmlSwitchEncoding(ctxt, enc);
11275 } 11964 }
11276 11965
11277 pinput->filename = NULL; 11966 pinput->filename = NULL;
11278 pinput->line = 1; 11967 pinput->line = 1;
11279 pinput->col = 1; 11968 pinput->col = 1;
11280 pinput->base = ctxt->input->cur; 11969 pinput->base = ctxt->input->cur;
11281 pinput->cur = ctxt->input->cur; 11970 pinput->cur = ctxt->input->cur;
11282 pinput->free = NULL; 11971 pinput->free = NULL;
11283 11972
11284 /* 11973 /*
11285 * let's parse that entity knowing it's an external subset. 11974 * let's parse that entity knowing it's an external subset.
11286 */ 11975 */
11287 ctxt->inSubset = 2; 11976 ctxt->inSubset = 2;
11288 ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0"); 11977 ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
11978 if (ctxt->myDoc == NULL) {
11979 xmlErrMemory(ctxt, "New Doc failed");
11980 return(NULL);
11981 }
11982 ctxt->myDoc->properties = XML_DOC_INTERNAL;
11289 ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none", 11983 ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
11290 BAD_CAST "none", BAD_CAST "none"); 11984 BAD_CAST "none", BAD_CAST "none");
11291 11985
11292 if ((enc == XML_CHAR_ENCODING_NONE) && 11986 if ((enc == XML_CHAR_ENCODING_NONE) &&
11293 ((ctxt->input->end - ctxt->input->cur) >= 4)) { 11987 ((ctxt->input->end - ctxt->input->cur) >= 4)) {
11294 /* 11988 /*
11295 * Get the 4 first bytes and decode the charset 11989 * Get the 4 first bytes and decode the charset
11296 * if enc != XML_CHAR_ENCODING_NONE 11990 * if enc != XML_CHAR_ENCODING_NONE
11297 * plug some encoding conversion routines. 11991 * plug some encoding conversion routines.
11298 */ 11992 */
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
11391 if (sax != NULL) ctxt->sax = NULL; 12085 if (sax != NULL) ctxt->sax = NULL;
11392 xmlFreeParserCtxt(ctxt); 12086 xmlFreeParserCtxt(ctxt);
11393 if (systemIdCanonic != NULL) 12087 if (systemIdCanonic != NULL)
11394 xmlFree(systemIdCanonic); 12088 xmlFree(systemIdCanonic);
11395 return(NULL); 12089 return(NULL);
11396 } 12090 }
11397 12091
11398 /* 12092 /*
11399 * plug some encoding conversion routines here. 12093 * plug some encoding conversion routines here.
11400 */ 12094 */
11401 xmlPushInput(ctxt, input); 12095 if (xmlPushInput(ctxt, input) < 0) {
12096 if (sax != NULL) ctxt->sax = NULL;
12097 » xmlFreeParserCtxt(ctxt);
12098 » if (systemIdCanonic != NULL)
12099 » xmlFree(systemIdCanonic);
12100 » return(NULL);
12101 }
11402 if ((ctxt->input->end - ctxt->input->cur) >= 4) { 12102 if ((ctxt->input->end - ctxt->input->cur) >= 4) {
11403 enc = xmlDetectCharEncoding(ctxt->input->cur, 4); 12103 enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
11404 xmlSwitchEncoding(ctxt, enc); 12104 xmlSwitchEncoding(ctxt, enc);
11405 } 12105 }
11406 12106
11407 if (input->filename == NULL) 12107 if (input->filename == NULL)
11408 input->filename = (char *) systemIdCanonic; 12108 input->filename = (char *) systemIdCanonic;
11409 else 12109 else
11410 xmlFree(systemIdCanonic); 12110 xmlFree(systemIdCanonic);
11411 input->line = 1; 12111 input->line = 1;
11412 input->col = 1; 12112 input->col = 1;
11413 input->base = ctxt->input->cur; 12113 input->base = ctxt->input->cur;
11414 input->cur = ctxt->input->cur; 12114 input->cur = ctxt->input->cur;
11415 input->free = NULL; 12115 input->free = NULL;
11416 12116
11417 /* 12117 /*
11418 * let's parse that entity knowing it's an external subset. 12118 * let's parse that entity knowing it's an external subset.
11419 */ 12119 */
11420 ctxt->inSubset = 2; 12120 ctxt->inSubset = 2;
11421 ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0"); 12121 ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12122 if (ctxt->myDoc == NULL) {
12123 xmlErrMemory(ctxt, "New Doc failed");
12124 if (sax != NULL) ctxt->sax = NULL;
12125 xmlFreeParserCtxt(ctxt);
12126 return(NULL);
12127 }
12128 ctxt->myDoc->properties = XML_DOC_INTERNAL;
11422 ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none", 12129 ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
11423 ExternalID, SystemID); 12130 ExternalID, SystemID);
11424 xmlParseExternalSubset(ctxt, ExternalID, SystemID); 12131 xmlParseExternalSubset(ctxt, ExternalID, SystemID);
11425 12132
11426 if (ctxt->myDoc != NULL) { 12133 if (ctxt->myDoc != NULL) {
11427 if (ctxt->wellFormed) { 12134 if (ctxt->wellFormed) {
11428 ret = ctxt->myDoc->extSubset; 12135 ret = ctxt->myDoc->extSubset;
11429 ctxt->myDoc->extSubset = NULL; 12136 ctxt->myDoc->extSubset = NULL;
11430 if (ret != NULL) { 12137 if (ret != NULL) {
11431 xmlNodePtr tmp; 12138 xmlNodePtr tmp;
11432 12139
11433 ret->doc = NULL; 12140 ret->doc = NULL;
11434 tmp = ret->children; 12141 tmp = ret->children;
11435 while (tmp != NULL) { 12142 while (tmp != NULL) {
11436 tmp->doc = NULL; 12143 tmp->doc = NULL;
11437 tmp = tmp->next; 12144 tmp = tmp->next;
11438 } 12145 }
11439 } 12146 }
11440 } else { 12147 } else {
11441 ret = NULL; 12148 ret = NULL;
11442 } 12149 }
11443 xmlFreeDoc(ctxt->myDoc); 12150 xmlFreeDoc(ctxt->myDoc);
11444 ctxt->myDoc = NULL; 12151 ctxt->myDoc = NULL;
11445 } 12152 }
11446 if (sax != NULL) ctxt->sax = NULL; 12153 if (sax != NULL) ctxt->sax = NULL;
11447 xmlFreeParserCtxt(ctxt); 12154 xmlFreeParserCtxt(ctxt);
11448 12155
11449 return(ret); 12156 return(ret);
11450 } 12157 }
11451 12158
11452 12159
11453 /** 12160 /**
11454 * xmlParseDTD: 12161 * xmlParseDTD:
11455 * @ExternalID: a NAME* containing the External ID of the DTD 12162 * @ExternalID: a NAME* containing the External ID of the DTD
11456 * @SystemID: a NAME* containing the URL to the DTD 12163 * @SystemID: a NAME* containing the URL to the DTD
11457 * 12164 *
11458 * Load and parse an external subset. 12165 * Load and parse an external subset.
11459 * 12166 *
11460 * Returns the resulting xmlDtdPtr or NULL in case of error. 12167 * Returns the resulting xmlDtdPtr or NULL in case of error.
11461 */ 12168 */
11462 12169
11463 xmlDtdPtr 12170 xmlDtdPtr
11464 xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) { 12171 xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
11465 return(xmlSAXParseDTD(NULL, ExternalID, SystemID)); 12172 return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
11466 } 12173 }
11467 #endif /* LIBXML_VALID_ENABLED */ 12174 #endif /* LIBXML_VALID_ENABLED */
11468 12175
11469 /************************************************************************ 12176 /************************************************************************
(...skipping 22 matching lines...) Expand all
11492 int 12199 int
11493 xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL, 12200 xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
11494 const xmlChar *ID, xmlNodePtr *lst) { 12201 const xmlChar *ID, xmlNodePtr *lst) {
11495 xmlParserCtxtPtr ctxt; 12202 xmlParserCtxtPtr ctxt;
11496 xmlDocPtr newDoc; 12203 xmlDocPtr newDoc;
11497 xmlNodePtr newRoot; 12204 xmlNodePtr newRoot;
11498 xmlSAXHandlerPtr oldsax = NULL; 12205 xmlSAXHandlerPtr oldsax = NULL;
11499 int ret = 0; 12206 int ret = 0;
11500 xmlChar start[4]; 12207 xmlChar start[4];
11501 xmlCharEncoding enc; 12208 xmlCharEncoding enc;
11502 xmlParserInputPtr inputStream;
11503 char *directory = NULL;
11504 12209
11505 if (ctx == NULL) return(-1); 12210 if (ctx == NULL) return(-1);
11506 12211
11507 if (ctx->depth > 40) { 12212 if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
12213 (ctx->depth > 1024)) {
11508 return(XML_ERR_ENTITY_LOOP); 12214 return(XML_ERR_ENTITY_LOOP);
11509 } 12215 }
11510 12216
11511 if (lst != NULL) 12217 if (lst != NULL)
11512 *lst = NULL; 12218 *lst = NULL;
11513 if ((URL == NULL) && (ID == NULL)) 12219 if ((URL == NULL) && (ID == NULL))
11514 return(-1); 12220 return(-1);
11515 if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */ 12221 if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
11516 return(-1); 12222 return(-1);
11517 12223
11518 ctxt = xmlNewParserCtxt(); 12224 ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
11519 if (ctxt == NULL) { 12225 if (ctxt == NULL) {
11520 return(-1); 12226 return(-1);
11521 } 12227 }
11522
11523 ctxt->userData = ctxt;
11524 ctxt->_private = ctx->_private;
11525
11526 inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
11527 if (inputStream == NULL) {
11528 xmlFreeParserCtxt(ctxt);
11529 return(-1);
11530 }
11531 12228
11532 inputPush(ctxt, inputStream);
11533
11534 if ((ctxt->directory == NULL) && (directory == NULL))
11535 directory = xmlParserGetDirectory((char *)URL);
11536 if ((ctxt->directory == NULL) && (directory != NULL))
11537 ctxt->directory = directory;
11538
11539 oldsax = ctxt->sax; 12229 oldsax = ctxt->sax;
11540 ctxt->sax = ctx->sax; 12230 ctxt->sax = ctx->sax;
11541 xmlDetectSAX2(ctxt); 12231 xmlDetectSAX2(ctxt);
11542 newDoc = xmlNewDoc(BAD_CAST "1.0"); 12232 newDoc = xmlNewDoc(BAD_CAST "1.0");
11543 if (newDoc == NULL) { 12233 if (newDoc == NULL) {
11544 xmlFreeParserCtxt(ctxt); 12234 xmlFreeParserCtxt(ctxt);
11545 return(-1); 12235 return(-1);
11546 } 12236 }
12237 newDoc->properties = XML_DOC_INTERNAL;
11547 if (ctx->myDoc->dict) { 12238 if (ctx->myDoc->dict) {
11548 newDoc->dict = ctx->myDoc->dict; 12239 newDoc->dict = ctx->myDoc->dict;
11549 xmlDictReference(newDoc->dict); 12240 xmlDictReference(newDoc->dict);
11550 } 12241 }
11551 if (ctx->myDoc != NULL) { 12242 if (ctx->myDoc != NULL) {
11552 newDoc->intSubset = ctx->myDoc->intSubset; 12243 newDoc->intSubset = ctx->myDoc->intSubset;
11553 newDoc->extSubset = ctx->myDoc->extSubset; 12244 newDoc->extSubset = ctx->myDoc->extSubset;
11554 } 12245 }
11555 if (ctx->myDoc->URL != NULL) { 12246 if (ctx->myDoc->URL != NULL) {
11556 newDoc->URL = xmlStrdup(ctx->myDoc->URL); 12247 newDoc->URL = xmlStrdup(ctx->myDoc->URL);
11557 } 12248 }
11558 newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL); 12249 newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
11559 if (newRoot == NULL) { 12250 if (newRoot == NULL) {
11560 ctxt->sax = oldsax; 12251 ctxt->sax = oldsax;
11561 xmlFreeParserCtxt(ctxt); 12252 xmlFreeParserCtxt(ctxt);
11562 newDoc->intSubset = NULL; 12253 newDoc->intSubset = NULL;
11563 newDoc->extSubset = NULL; 12254 newDoc->extSubset = NULL;
11564 xmlFreeDoc(newDoc); 12255 xmlFreeDoc(newDoc);
11565 return(-1); 12256 return(-1);
11566 } 12257 }
11567 xmlAddChild((xmlNodePtr) newDoc, newRoot); 12258 xmlAddChild((xmlNodePtr) newDoc, newRoot);
11568 nodePush(ctxt, newDoc->children); 12259 nodePush(ctxt, newDoc->children);
11569 if (ctx->myDoc == NULL) { 12260 if (ctx->myDoc == NULL) {
11570 ctxt->myDoc = newDoc; 12261 ctxt->myDoc = newDoc;
11571 } else { 12262 } else {
11572 ctxt->myDoc = ctx->myDoc; 12263 ctxt->myDoc = ctx->myDoc;
11573 newDoc->children->doc = ctx->myDoc; 12264 newDoc->children->doc = ctx->myDoc;
11574 } 12265 }
11575 12266
11576 /* 12267 /*
11577 * Get the 4 first bytes and decode the charset 12268 * Get the 4 first bytes and decode the charset
11578 * if enc != XML_CHAR_ENCODING_NONE 12269 * if enc != XML_CHAR_ENCODING_NONE
11579 * plug some encoding conversion routines. 12270 * plug some encoding conversion routines.
11580 */ 12271 */
11581 GROW 12272 GROW
11582 if ((ctxt->input->end - ctxt->input->cur) >= 4) { 12273 if ((ctxt->input->end - ctxt->input->cur) >= 4) {
11583 start[0] = RAW; 12274 start[0] = RAW;
11584 start[1] = NXT(1); 12275 start[1] = NXT(1);
11585 start[2] = NXT(2); 12276 start[2] = NXT(2);
11586 start[3] = NXT(3); 12277 start[3] = NXT(3);
11587 enc = xmlDetectCharEncoding(start, 4); 12278 enc = xmlDetectCharEncoding(start, 4);
11588 if (enc != XML_CHAR_ENCODING_NONE) { 12279 if (enc != XML_CHAR_ENCODING_NONE) {
11589 xmlSwitchEncoding(ctxt, enc); 12280 xmlSwitchEncoding(ctxt, enc);
11590 } 12281 }
11591 } 12282 }
11592 12283
11593 /* 12284 /*
11594 * Parse a possible text declaration first 12285 * Parse a possible text declaration first
11595 */ 12286 */
11596 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) { 12287 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
11597 xmlParseTextDecl(ctxt); 12288 xmlParseTextDecl(ctxt);
12289 /*
12290 * An XML-1.0 document can't reference an entity not XML-1.0
12291 */
12292 if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
12293 (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
12294 xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
12295 "Version mismatch between document and entity\n");
12296 }
11598 } 12297 }
11599 12298
11600 /* 12299 /*
11601 * Doing validity checking on chunk doesn't make sense 12300 * Doing validity checking on chunk doesn't make sense
11602 */ 12301 */
11603 ctxt->instate = XML_PARSER_CONTENT; 12302 ctxt->instate = XML_PARSER_CONTENT;
11604 ctxt->validate = ctx->validate; 12303 ctxt->validate = ctx->validate;
11605 ctxt->valid = ctx->valid; 12304 ctxt->valid = ctx->valid;
11606 ctxt->loadsubset = ctx->loadsubset; 12305 ctxt->loadsubset = ctx->loadsubset;
11607 ctxt->depth = ctx->depth + 1; 12306 ctxt->depth = ctx->depth + 1;
(...skipping 13 matching lines...) Expand all
11621 ctxt->dict = ctx->dict; 12320 ctxt->dict = ctx->dict;
11622 ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3); 12321 ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
11623 ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5); 12322 ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
11624 ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36); 12323 ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
11625 ctxt->dictNames = ctx->dictNames; 12324 ctxt->dictNames = ctx->dictNames;
11626 ctxt->attsDefault = ctx->attsDefault; 12325 ctxt->attsDefault = ctx->attsDefault;
11627 ctxt->attsSpecial = ctx->attsSpecial; 12326 ctxt->attsSpecial = ctx->attsSpecial;
11628 ctxt->linenumbers = ctx->linenumbers; 12327 ctxt->linenumbers = ctx->linenumbers;
11629 12328
11630 xmlParseContent(ctxt); 12329 xmlParseContent(ctxt);
11631 12330
11632 ctx->validate = ctxt->validate; 12331 ctx->validate = ctxt->validate;
11633 ctx->valid = ctxt->valid; 12332 ctx->valid = ctxt->valid;
11634 if ((RAW == '<') && (NXT(1) == '/')) { 12333 if ((RAW == '<') && (NXT(1) == '/')) {
11635 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL); 12334 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11636 } else if (RAW != 0) { 12335 } else if (RAW != 0) {
11637 xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL); 12336 xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
11638 } 12337 }
11639 if (ctxt->node != newDoc->children) { 12338 if (ctxt->node != newDoc->children) {
11640 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL); 12339 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11641 } 12340 }
(...skipping 22 matching lines...) Expand all
11664 ret = 0; 12363 ret = 0;
11665 } 12364 }
11666 ctxt->sax = oldsax; 12365 ctxt->sax = oldsax;
11667 ctxt->dict = NULL; 12366 ctxt->dict = NULL;
11668 ctxt->attsDefault = NULL; 12367 ctxt->attsDefault = NULL;
11669 ctxt->attsSpecial = NULL; 12368 ctxt->attsSpecial = NULL;
11670 xmlFreeParserCtxt(ctxt); 12369 xmlFreeParserCtxt(ctxt);
11671 newDoc->intSubset = NULL; 12370 newDoc->intSubset = NULL;
11672 newDoc->extSubset = NULL; 12371 newDoc->extSubset = NULL;
11673 xmlFreeDoc(newDoc); 12372 xmlFreeDoc(newDoc);
11674 12373
11675 return(ret); 12374 return(ret);
11676 } 12375 }
11677 12376
11678 /** 12377 /**
11679 * xmlParseExternalEntityPrivate: 12378 * xmlParseExternalEntityPrivate:
11680 * @doc: the document the chunk pertains to 12379 * @doc: the document the chunk pertains to
11681 * @oldctxt: the previous parser context if available 12380 * @oldctxt: the previous parser context if available
11682 * @sax: the SAX handler bloc (possibly NULL) 12381 * @sax: the SAX handler bloc (possibly NULL)
11683 * @user_data: The user data returned on SAX callbacks (possibly NULL) 12382 * @user_data: The user data returned on SAX callbacks (possibly NULL)
11684 * @depth: Used for loop detection, use 0 12383 * @depth: Used for loop detection, use 0
(...skipping 13 matching lines...) Expand all
11698 void *user_data, int depth, const xmlChar *URL, 12397 void *user_data, int depth, const xmlChar *URL,
11699 const xmlChar *ID, xmlNodePtr *list) { 12398 const xmlChar *ID, xmlNodePtr *list) {
11700 xmlParserCtxtPtr ctxt; 12399 xmlParserCtxtPtr ctxt;
11701 xmlDocPtr newDoc; 12400 xmlDocPtr newDoc;
11702 xmlNodePtr newRoot; 12401 xmlNodePtr newRoot;
11703 xmlSAXHandlerPtr oldsax = NULL; 12402 xmlSAXHandlerPtr oldsax = NULL;
11704 xmlParserErrors ret = XML_ERR_OK; 12403 xmlParserErrors ret = XML_ERR_OK;
11705 xmlChar start[4]; 12404 xmlChar start[4];
11706 xmlCharEncoding enc; 12405 xmlCharEncoding enc;
11707 12406
11708 if (depth > 40) { 12407 if (((depth > 40) &&
12408 » ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
12409 » (depth > 1024)) {
11709 return(XML_ERR_ENTITY_LOOP); 12410 return(XML_ERR_ENTITY_LOOP);
11710 } 12411 }
11711 12412
11712
11713
11714 if (list != NULL) 12413 if (list != NULL)
11715 *list = NULL; 12414 *list = NULL;
11716 if ((URL == NULL) && (ID == NULL)) 12415 if ((URL == NULL) && (ID == NULL))
11717 return(XML_ERR_INTERNAL_ERROR); 12416 return(XML_ERR_INTERNAL_ERROR);
11718 if (doc == NULL) 12417 if (doc == NULL)
11719 return(XML_ERR_INTERNAL_ERROR); 12418 return(XML_ERR_INTERNAL_ERROR);
11720 12419
11721 12420
11722 ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL); 12421 ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
11723 if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY); 12422 if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
11724 ctxt->userData = ctxt; 12423 ctxt->userData = ctxt;
11725 if (oldctxt != NULL) { 12424 if (oldctxt != NULL) {
11726 ctxt->_private = oldctxt->_private; 12425 ctxt->_private = oldctxt->_private;
11727 ctxt->loadsubset = oldctxt->loadsubset; 12426 ctxt->loadsubset = oldctxt->loadsubset;
11728 ctxt->validate = oldctxt->validate; 12427 ctxt->validate = oldctxt->validate;
11729 ctxt->external = oldctxt->external; 12428 ctxt->external = oldctxt->external;
11730 ctxt->record_info = oldctxt->record_info; 12429 ctxt->record_info = oldctxt->record_info;
11731 ctxt->node_seq.maximum = oldctxt->node_seq.maximum; 12430 ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
11732 ctxt->node_seq.length = oldctxt->node_seq.length; 12431 ctxt->node_seq.length = oldctxt->node_seq.length;
(...skipping 16 matching lines...) Expand all
11749 } 12448 }
11750 xmlDetectSAX2(ctxt); 12449 xmlDetectSAX2(ctxt);
11751 newDoc = xmlNewDoc(BAD_CAST "1.0"); 12450 newDoc = xmlNewDoc(BAD_CAST "1.0");
11752 if (newDoc == NULL) { 12451 if (newDoc == NULL) {
11753 ctxt->node_seq.maximum = 0; 12452 ctxt->node_seq.maximum = 0;
11754 ctxt->node_seq.length = 0; 12453 ctxt->node_seq.length = 0;
11755 ctxt->node_seq.buffer = NULL; 12454 ctxt->node_seq.buffer = NULL;
11756 xmlFreeParserCtxt(ctxt); 12455 xmlFreeParserCtxt(ctxt);
11757 return(XML_ERR_INTERNAL_ERROR); 12456 return(XML_ERR_INTERNAL_ERROR);
11758 } 12457 }
12458 newDoc->properties = XML_DOC_INTERNAL;
11759 newDoc->intSubset = doc->intSubset; 12459 newDoc->intSubset = doc->intSubset;
11760 newDoc->extSubset = doc->extSubset; 12460 newDoc->extSubset = doc->extSubset;
11761 newDoc->dict = doc->dict; 12461 newDoc->dict = doc->dict;
11762 xmlDictReference(newDoc->dict); 12462 xmlDictReference(newDoc->dict);
11763 12463
11764 if (doc->URL != NULL) { 12464 if (doc->URL != NULL) {
11765 newDoc->URL = xmlStrdup(doc->URL); 12465 newDoc->URL = xmlStrdup(doc->URL);
11766 } 12466 }
11767 newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL); 12467 newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
11768 if (newRoot == NULL) { 12468 if (newRoot == NULL) {
11769 if (sax != NULL) 12469 if (sax != NULL)
11770 ctxt->sax = oldsax; 12470 ctxt->sax = oldsax;
11771 ctxt->node_seq.maximum = 0; 12471 ctxt->node_seq.maximum = 0;
11772 ctxt->node_seq.length = 0; 12472 ctxt->node_seq.length = 0;
11773 ctxt->node_seq.buffer = NULL; 12473 ctxt->node_seq.buffer = NULL;
11774 xmlFreeParserCtxt(ctxt); 12474 xmlFreeParserCtxt(ctxt);
11775 newDoc->intSubset = NULL; 12475 newDoc->intSubset = NULL;
11776 newDoc->extSubset = NULL; 12476 newDoc->extSubset = NULL;
11777 xmlFreeDoc(newDoc); 12477 xmlFreeDoc(newDoc);
11778 return(XML_ERR_INTERNAL_ERROR); 12478 return(XML_ERR_INTERNAL_ERROR);
11779 } 12479 }
11780 xmlAddChild((xmlNodePtr) newDoc, newRoot); 12480 xmlAddChild((xmlNodePtr) newDoc, newRoot);
11781 nodePush(ctxt, newDoc->children); 12481 nodePush(ctxt, newDoc->children);
11782 ctxt->myDoc = doc; 12482 ctxt->myDoc = doc;
11783 newRoot->doc = doc; 12483 newRoot->doc = doc;
11784 12484
11785 /* 12485 /*
11786 * Get the 4 first bytes and decode the charset 12486 * Get the 4 first bytes and decode the charset
11787 * if enc != XML_CHAR_ENCODING_NONE 12487 * if enc != XML_CHAR_ENCODING_NONE
11788 * plug some encoding conversion routines. 12488 * plug some encoding conversion routines.
11789 */ 12489 */
11790 GROW; 12490 GROW;
11791 if ((ctxt->input->end - ctxt->input->cur) >= 4) { 12491 if ((ctxt->input->end - ctxt->input->cur) >= 4) {
11792 start[0] = RAW; 12492 start[0] = RAW;
11793 start[1] = NXT(1); 12493 start[1] = NXT(1);
11794 start[2] = NXT(2); 12494 start[2] = NXT(2);
11795 start[3] = NXT(3); 12495 start[3] = NXT(3);
11796 enc = xmlDetectCharEncoding(start, 4); 12496 enc = xmlDetectCharEncoding(start, 4);
11797 if (enc != XML_CHAR_ENCODING_NONE) { 12497 if (enc != XML_CHAR_ENCODING_NONE) {
11798 xmlSwitchEncoding(ctxt, enc); 12498 xmlSwitchEncoding(ctxt, enc);
11799 } 12499 }
11800 } 12500 }
11801 12501
11802 /* 12502 /*
11803 * Parse a possible text declaration first 12503 * Parse a possible text declaration first
11804 */ 12504 */
11805 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) { 12505 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
11806 xmlParseTextDecl(ctxt); 12506 xmlParseTextDecl(ctxt);
11807 } 12507 }
11808 12508
11809 ctxt->instate = XML_PARSER_CONTENT; 12509 ctxt->instate = XML_PARSER_CONTENT;
11810 ctxt->depth = depth; 12510 ctxt->depth = depth;
11811 12511
11812 xmlParseContent(ctxt); 12512 xmlParseContent(ctxt);
11813 12513
11814 if ((RAW == '<') && (NXT(1) == '/')) { 12514 if ((RAW == '<') && (NXT(1) == '/')) {
11815 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL); 12515 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11816 } else if (RAW != 0) { 12516 } else if (RAW != 0) {
11817 xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL); 12517 xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
11818 } 12518 }
11819 if (ctxt->node != newDoc->children) { 12519 if (ctxt->node != newDoc->children) {
11820 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL); 12520 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11821 } 12521 }
11822 12522
11823 if (!ctxt->wellFormed) { 12523 if (!ctxt->wellFormed) {
(...skipping 12 matching lines...) Expand all
11836 cur = newDoc->children->children; 12536 cur = newDoc->children->children;
11837 *list = cur; 12537 *list = cur;
11838 while (cur != NULL) { 12538 while (cur != NULL) {
11839 cur->parent = NULL; 12539 cur->parent = NULL;
11840 cur = cur->next; 12540 cur = cur->next;
11841 } 12541 }
11842 newDoc->children->children = NULL; 12542 newDoc->children->children = NULL;
11843 } 12543 }
11844 ret = XML_ERR_OK; 12544 ret = XML_ERR_OK;
11845 } 12545 }
12546
12547 /*
12548 * Record in the parent context the number of entities replacement
12549 * done when parsing that reference.
12550 */
12551 if (oldctxt != NULL)
12552 oldctxt->nbentities += ctxt->nbentities;
12553
12554 /*
12555 * Also record the size of the entity parsed
12556 */
12557 if (ctxt->input != NULL) {
12558 oldctxt->sizeentities += ctxt->input->consumed;
12559 oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
12560 }
12561 /*
12562 * And record the last error if any
12563 */
12564 if (ctxt->lastError.code != XML_ERR_OK)
12565 xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
12566
11846 if (sax != NULL) 12567 if (sax != NULL)
11847 ctxt->sax = oldsax; 12568 ctxt->sax = oldsax;
11848 oldctxt->node_seq.maximum = ctxt->node_seq.maximum; 12569 oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
11849 oldctxt->node_seq.length = ctxt->node_seq.length; 12570 oldctxt->node_seq.length = ctxt->node_seq.length;
11850 oldctxt->node_seq.buffer = ctxt->node_seq.buffer; 12571 oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
11851 ctxt->node_seq.maximum = 0; 12572 ctxt->node_seq.maximum = 0;
11852 ctxt->node_seq.length = 0; 12573 ctxt->node_seq.length = 0;
11853 ctxt->node_seq.buffer = NULL; 12574 ctxt->node_seq.buffer = NULL;
11854 xmlFreeParserCtxt(ctxt); 12575 xmlFreeParserCtxt(ctxt);
11855 newDoc->intSubset = NULL; 12576 newDoc->intSubset = NULL;
11856 newDoc->extSubset = NULL; 12577 newDoc->extSubset = NULL;
11857 xmlFreeDoc(newDoc); 12578 xmlFreeDoc(newDoc);
11858 12579
11859 return(ret); 12580 return(ret);
11860 } 12581 }
11861 12582
11862 #ifdef LIBXML_SAX1_ENABLED 12583 #ifdef LIBXML_SAX1_ENABLED
11863 /** 12584 /**
11864 * xmlParseExternalEntity: 12585 * xmlParseExternalEntity:
11865 * @doc: the document the chunk pertains to 12586 * @doc: the document the chunk pertains to
11866 * @sax: the SAX handler bloc (possibly NULL) 12587 * @sax: the SAX handler bloc (possibly NULL)
11867 * @user_data: The user data returned on SAX callbacks (possibly NULL) 12588 * @user_data: The user data returned on SAX callbacks (possibly NULL)
11868 * @depth: Used for loop detection, use 0 12589 * @depth: Used for loop detection, use 0
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
11925 * 12646 *
11926 * Parse a well-balanced chunk of an XML document 12647 * Parse a well-balanced chunk of an XML document
11927 * called by the parser 12648 * called by the parser
11928 * The allowed sequence for the Well Balanced Chunk is the one defined by 12649 * The allowed sequence for the Well Balanced Chunk is the one defined by
11929 * the content production in the XML grammar: 12650 * the content production in the XML grammar:
11930 * 12651 *
11931 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)* 12652 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
11932 * 12653 *
11933 * Returns XML_ERR_OK if the chunk is well balanced, and the parser 12654 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
11934 * error code otherwise 12655 * error code otherwise
11935 * 12656 *
11936 * In case recover is set to 1, the nodelist will not be empty even if 12657 * In case recover is set to 1, the nodelist will not be empty even if
11937 * the parsed chunk is not well balanced. 12658 * the parsed chunk is not well balanced.
11938 */ 12659 */
11939 static xmlParserErrors 12660 static xmlParserErrors
11940 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt, 12661 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
11941 const xmlChar *string, void *user_data, xmlNodePtr *lst) { 12662 const xmlChar *string, void *user_data, xmlNodePtr *lst) {
11942 xmlParserCtxtPtr ctxt; 12663 xmlParserCtxtPtr ctxt;
11943 xmlDocPtr newDoc = NULL; 12664 xmlDocPtr newDoc = NULL;
11944 xmlNodePtr newRoot; 12665 xmlNodePtr newRoot;
11945 xmlSAXHandlerPtr oldsax = NULL; 12666 xmlSAXHandlerPtr oldsax = NULL;
11946 xmlNodePtr content = NULL; 12667 xmlNodePtr content = NULL;
11947 xmlNodePtr last = NULL; 12668 xmlNodePtr last = NULL;
11948 int size; 12669 int size;
11949 xmlParserErrors ret = XML_ERR_OK; 12670 xmlParserErrors ret = XML_ERR_OK;
12671 #ifdef SAX2
12672 int i;
12673 #endif
11950 12674
11951 if (oldctxt->depth > 40) { 12675 if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
12676 (oldctxt->depth > 1024)) {
11952 return(XML_ERR_ENTITY_LOOP); 12677 return(XML_ERR_ENTITY_LOOP);
11953 } 12678 }
11954 12679
11955 12680
11956 if (lst != NULL) 12681 if (lst != NULL)
11957 *lst = NULL; 12682 *lst = NULL;
11958 if (string == NULL) 12683 if (string == NULL)
11959 return(XML_ERR_INTERNAL_ERROR); 12684 return(XML_ERR_INTERNAL_ERROR);
11960 12685
11961 size = xmlStrlen(string); 12686 size = xmlStrlen(string);
11962 12687
11963 ctxt = xmlCreateMemoryParserCtxt((char *) string, size); 12688 ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
11964 if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY); 12689 if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
11965 if (user_data != NULL) 12690 if (user_data != NULL)
11966 ctxt->userData = user_data; 12691 ctxt->userData = user_data;
11967 else 12692 else
11968 ctxt->userData = ctxt; 12693 ctxt->userData = ctxt;
11969 if (ctxt->dict != NULL) xmlDictFree(ctxt->dict); 12694 if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
11970 ctxt->dict = oldctxt->dict; 12695 ctxt->dict = oldctxt->dict;
11971 ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3); 12696 ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
11972 ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5); 12697 ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
11973 ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36); 12698 ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
11974 12699
11975 ctxt->nsParent = oldctxt; 12700 #ifdef SAX2
12701 /* propagate namespaces down the entity */
12702 for (i = 0;i < oldctxt->nsNr;i += 2) {
12703 nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
12704 }
12705 #endif
11976 12706
11977 oldsax = ctxt->sax; 12707 oldsax = ctxt->sax;
11978 ctxt->sax = oldctxt->sax; 12708 ctxt->sax = oldctxt->sax;
11979 xmlDetectSAX2(ctxt); 12709 xmlDetectSAX2(ctxt);
11980 ctxt->replaceEntities = oldctxt->replaceEntities; 12710 ctxt->replaceEntities = oldctxt->replaceEntities;
11981 ctxt->options = oldctxt->options; 12711 ctxt->options = oldctxt->options;
11982 12712
11983 ctxt->_private = oldctxt->_private; 12713 ctxt->_private = oldctxt->_private;
11984 if (oldctxt->myDoc == NULL) { 12714 if (oldctxt->myDoc == NULL) {
11985 newDoc = xmlNewDoc(BAD_CAST "1.0"); 12715 newDoc = xmlNewDoc(BAD_CAST "1.0");
11986 if (newDoc == NULL) { 12716 if (newDoc == NULL) {
11987 ctxt->sax = oldsax; 12717 ctxt->sax = oldsax;
11988 ctxt->dict = NULL; 12718 ctxt->dict = NULL;
11989 xmlFreeParserCtxt(ctxt); 12719 xmlFreeParserCtxt(ctxt);
11990 return(XML_ERR_INTERNAL_ERROR); 12720 return(XML_ERR_INTERNAL_ERROR);
11991 } 12721 }
12722 newDoc->properties = XML_DOC_INTERNAL;
11992 newDoc->dict = ctxt->dict; 12723 newDoc->dict = ctxt->dict;
11993 xmlDictReference(newDoc->dict); 12724 xmlDictReference(newDoc->dict);
11994 ctxt->myDoc = newDoc; 12725 ctxt->myDoc = newDoc;
11995 } else { 12726 } else {
11996 ctxt->myDoc = oldctxt->myDoc; 12727 ctxt->myDoc = oldctxt->myDoc;
11997 content = ctxt->myDoc->children; 12728 content = ctxt->myDoc->children;
11998 last = ctxt->myDoc->last; 12729 last = ctxt->myDoc->last;
11999 } 12730 }
12000 newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL); 12731 newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
12001 if (newRoot == NULL) { 12732 if (newRoot == NULL) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
12037 } 12768 }
12038 12769
12039 if (!ctxt->wellFormed) { 12770 if (!ctxt->wellFormed) {
12040 if (ctxt->errNo == 0) 12771 if (ctxt->errNo == 0)
12041 ret = XML_ERR_INTERNAL_ERROR; 12772 ret = XML_ERR_INTERNAL_ERROR;
12042 else 12773 else
12043 ret = (xmlParserErrors)ctxt->errNo; 12774 ret = (xmlParserErrors)ctxt->errNo;
12044 } else { 12775 } else {
12045 ret = XML_ERR_OK; 12776 ret = XML_ERR_OK;
12046 } 12777 }
12047 12778
12048 if ((lst != NULL) && (ret == XML_ERR_OK)) { 12779 if ((lst != NULL) && (ret == XML_ERR_OK)) {
12049 xmlNodePtr cur; 12780 xmlNodePtr cur;
12050 12781
12051 /* 12782 /*
12052 * Return the newly created nodeset after unlinking it from 12783 * Return the newly created nodeset after unlinking it from
12053 * they pseudo parent. 12784 * they pseudo parent.
12054 */ 12785 */
12055 cur = ctxt->myDoc->children->children; 12786 cur = ctxt->myDoc->children->children;
12056 *lst = cur; 12787 *lst = cur;
12057 while (cur != NULL) { 12788 while (cur != NULL) {
12058 #ifdef LIBXML_VALID_ENABLED 12789 #ifdef LIBXML_VALID_ENABLED
12059 if ((oldctxt->validate) && (oldctxt->wellFormed) && 12790 if ((oldctxt->validate) && (oldctxt->wellFormed) &&
12060 (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) && 12791 (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
12061 (cur->type == XML_ELEMENT_NODE)) { 12792 (cur->type == XML_ELEMENT_NODE)) {
12062 oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt, 12793 oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
12063 oldctxt->myDoc, cur); 12794 oldctxt->myDoc, cur);
12064 } 12795 }
12065 #endif /* LIBXML_VALID_ENABLED */ 12796 #endif /* LIBXML_VALID_ENABLED */
12066 cur->parent = NULL; 12797 cur->parent = NULL;
12067 cur = cur->next; 12798 cur = cur->next;
12068 } 12799 }
12069 ctxt->myDoc->children->children = NULL; 12800 ctxt->myDoc->children->children = NULL;
12070 } 12801 }
12071 if (ctxt->myDoc != NULL) { 12802 if (ctxt->myDoc != NULL) {
12072 xmlFreeNode(ctxt->myDoc->children); 12803 xmlFreeNode(ctxt->myDoc->children);
12073 ctxt->myDoc->children = content; 12804 ctxt->myDoc->children = content;
12074 ctxt->myDoc->last = last; 12805 ctxt->myDoc->last = last;
12075 } 12806 }
12076 » 12807
12808 /*
12809 * Record in the parent context the number of entities replacement
12810 * done when parsing that reference.
12811 */
12812 if (oldctxt != NULL)
12813 oldctxt->nbentities += ctxt->nbentities;
12814
12815 /*
12816 * Also record the last error if any
12817 */
12818 if (ctxt->lastError.code != XML_ERR_OK)
12819 xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
12820
12077 ctxt->sax = oldsax; 12821 ctxt->sax = oldsax;
12078 ctxt->dict = NULL; 12822 ctxt->dict = NULL;
12079 ctxt->attsDefault = NULL; 12823 ctxt->attsDefault = NULL;
12080 ctxt->attsSpecial = NULL; 12824 ctxt->attsSpecial = NULL;
12081 xmlFreeParserCtxt(ctxt); 12825 xmlFreeParserCtxt(ctxt);
12082 if (newDoc != NULL) { 12826 if (newDoc != NULL) {
12083 xmlFreeDoc(newDoc); 12827 xmlFreeDoc(newDoc);
12084 } 12828 }
12085 12829
12086 return(ret); 12830 return(ret);
12087 } 12831 }
12088 12832
12089 /** 12833 /**
12090 * xmlParseInNodeContext: 12834 * xmlParseInNodeContext:
12091 * @node: the context node 12835 * @node: the context node
12092 * @data: the input string 12836 * @data: the input string
12093 * @datalen: the input string length in bytes 12837 * @datalen: the input string length in bytes
12094 * @options: a combination of xmlParserOption 12838 * @options: a combination of xmlParserOption
12095 * @lst: the return value for the set of parsed nodes 12839 * @lst: the return value for the set of parsed nodes
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
12149 if (doc == NULL) 12893 if (doc == NULL)
12150 return(XML_ERR_INTERNAL_ERROR); 12894 return(XML_ERR_INTERNAL_ERROR);
12151 12895
12152 /* 12896 /*
12153 * allocate a context and set-up everything not related to the 12897 * allocate a context and set-up everything not related to the
12154 * node position in the tree 12898 * node position in the tree
12155 */ 12899 */
12156 if (doc->type == XML_DOCUMENT_NODE) 12900 if (doc->type == XML_DOCUMENT_NODE)
12157 ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen); 12901 ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
12158 #ifdef LIBXML_HTML_ENABLED 12902 #ifdef LIBXML_HTML_ENABLED
12159 else if (doc->type == XML_HTML_DOCUMENT_NODE) 12903 else if (doc->type == XML_HTML_DOCUMENT_NODE) {
12160 ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen); 12904 ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
12905 /*
12906 * When parsing in context, it makes no sense to add implied
12907 * elements like html/body/etc...
12908 */
12909 options |= HTML_PARSE_NOIMPLIED;
12910 }
12161 #endif 12911 #endif
12162 else 12912 else
12163 return(XML_ERR_INTERNAL_ERROR); 12913 return(XML_ERR_INTERNAL_ERROR);
12164 12914
12165 if (ctxt == NULL) 12915 if (ctxt == NULL)
12166 return(XML_ERR_NO_MEMORY); 12916 return(XML_ERR_NO_MEMORY);
12167 fake = xmlNewComment(NULL);
12168 if (fake == NULL) {
12169 xmlFreeParserCtxt(ctxt);
12170 return(XML_ERR_NO_MEMORY);
12171 }
12172 xmlAddChild(node, fake);
12173 12917
12174 /* 12918 /*
12175 * Use input doc's dict if present, else assure XML_PARSE_NODICT is set. 12919 * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
12176 * We need a dictionary for xmlDetectSAX2, so if there's no doc dict 12920 * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
12177 * we must wait until the last moment to free the original one. 12921 * we must wait until the last moment to free the original one.
12178 */ 12922 */
12179 if (doc->dict != NULL) { 12923 if (doc->dict != NULL) {
12180 if (ctxt->dict != NULL) 12924 if (ctxt->dict != NULL)
12181 xmlDictFree(ctxt->dict); 12925 xmlDictFree(ctxt->dict);
12182 ctxt->dict = doc->dict; 12926 ctxt->dict = doc->dict;
12183 } else 12927 } else
12184 options |= XML_PARSE_NODICT; 12928 options |= XML_PARSE_NODICT;
12185 12929
12186 xmlCtxtUseOptions(ctxt, options); 12930 if (doc->encoding != NULL) {
12931 xmlCharEncodingHandlerPtr hdlr;
12932
12933 if (ctxt->encoding != NULL)
12934 » xmlFree((xmlChar *) ctxt->encoding);
12935 ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
12936
12937 hdlr = xmlFindCharEncodingHandler(doc->encoding);
12938 if (hdlr != NULL) {
12939 xmlSwitchToEncoding(ctxt, hdlr);
12940 » } else {
12941 return(XML_ERR_UNSUPPORTED_ENCODING);
12942 }
12943 }
12944
12945 xmlCtxtUseOptionsInternal(ctxt, options, NULL);
12187 xmlDetectSAX2(ctxt); 12946 xmlDetectSAX2(ctxt);
12188 ctxt->myDoc = doc; 12947 ctxt->myDoc = doc;
12189 12948
12949 fake = xmlNewComment(NULL);
12950 if (fake == NULL) {
12951 xmlFreeParserCtxt(ctxt);
12952 return(XML_ERR_NO_MEMORY);
12953 }
12954 xmlAddChild(node, fake);
12955
12190 if (node->type == XML_ELEMENT_NODE) { 12956 if (node->type == XML_ELEMENT_NODE) {
12191 nodePush(ctxt, node); 12957 nodePush(ctxt, node);
12192 /* 12958 /*
12193 * initialize the SAX2 namespaces stack 12959 * initialize the SAX2 namespaces stack
12194 */ 12960 */
12195 cur = node; 12961 cur = node;
12196 while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) { 12962 while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
12197 xmlNsPtr ns = cur->nsDef; 12963 xmlNsPtr ns = cur->nsDef;
12198 const xmlChar *iprefix, *ihref; 12964 const xmlChar *iprefix, *ihref;
12199 12965
12200 while (ns != NULL) { 12966 while (ns != NULL) {
12201 if (ctxt->dict) { 12967 if (ctxt->dict) {
12202 iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1); 12968 iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
12203 ihref = xmlDictLookup(ctxt->dict, ns->href, -1); 12969 ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
12204 } else { 12970 } else {
12205 iprefix = ns->prefix; 12971 iprefix = ns->prefix;
12206 ihref = ns->href; 12972 ihref = ns->href;
12207 } 12973 }
12208 12974
12209 if (xmlGetNamespace(ctxt, iprefix) == NULL) { 12975 if (xmlGetNamespace(ctxt, iprefix) == NULL) {
12210 nsPush(ctxt, iprefix, ihref); 12976 nsPush(ctxt, iprefix, ihref);
12211 nsnr++; 12977 nsnr++;
12212 } 12978 }
12213 ns = ns->next; 12979 ns = ns->next;
12214 } 12980 }
12215 cur = cur->parent; 12981 cur = cur->parent;
12216 } 12982 }
12217 ctxt->instate = XML_PARSER_CONTENT; 12983 ctxt->instate = XML_PARSER_CONTENT;
12218 } 12984 }
12219 12985
12220 if ((ctxt->validate) || (ctxt->replaceEntities != 0)) { 12986 if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
12221 /* 12987 /*
12222 * ID/IDREF registration will be done in xmlValidateElement below 12988 * ID/IDREF registration will be done in xmlValidateElement below
12223 */ 12989 */
12224 ctxt->loadsubset |= XML_SKIP_IDS; 12990 ctxt->loadsubset |= XML_SKIP_IDS;
12225 } 12991 }
12226 12992
12227 #ifdef LIBXML_HTML_ENABLED 12993 #ifdef LIBXML_HTML_ENABLED
12228 if (doc->type == XML_HTML_DOCUMENT_NODE) 12994 if (doc->type == XML_HTML_DOCUMENT_NODE)
(...skipping 14 matching lines...) Expand all
12243 } 13009 }
12244 13010
12245 if (!ctxt->wellFormed) { 13011 if (!ctxt->wellFormed) {
12246 if (ctxt->errNo == 0) 13012 if (ctxt->errNo == 0)
12247 ret = XML_ERR_INTERNAL_ERROR; 13013 ret = XML_ERR_INTERNAL_ERROR;
12248 else 13014 else
12249 ret = (xmlParserErrors)ctxt->errNo; 13015 ret = (xmlParserErrors)ctxt->errNo;
12250 } else { 13016 } else {
12251 ret = XML_ERR_OK; 13017 ret = XML_ERR_OK;
12252 } 13018 }
12253 13019
12254 /* 13020 /*
12255 * Return the newly created nodeset after unlinking it from 13021 * Return the newly created nodeset after unlinking it from
12256 * the pseudo sibling. 13022 * the pseudo sibling.
12257 */ 13023 */
12258 13024
12259 cur = fake->next; 13025 cur = fake->next;
12260 fake->next = NULL; 13026 fake->next = NULL;
12261 node->last = fake; 13027 node->last = fake;
12262 13028
12263 if (cur != NULL) { 13029 if (cur != NULL) {
12264 cur->prev = NULL; 13030 cur->prev = NULL;
12265 } 13031 }
12266 13032
12267 *lst = cur; 13033 *lst = cur;
12268 13034
12269 while (cur != NULL) { 13035 while (cur != NULL) {
12270 cur->parent = NULL; 13036 cur->parent = NULL;
12271 cur = cur->next; 13037 cur = cur->next;
12272 } 13038 }
12273 13039
12274 xmlUnlinkNode(fake); 13040 xmlUnlinkNode(fake);
12275 xmlFreeNode(fake); 13041 xmlFreeNode(fake);
12276 13042
12277 13043
12278 if (ret != XML_ERR_OK) { 13044 if (ret != XML_ERR_OK) {
12279 xmlFreeNodeList(*lst); 13045 xmlFreeNodeList(*lst);
12280 *lst = NULL; 13046 *lst = NULL;
12281 } 13047 }
12282 13048
12283 if (doc->dict != NULL) 13049 if (doc->dict != NULL)
12284 ctxt->dict = NULL; 13050 ctxt->dict = NULL;
12285 xmlFreeParserCtxt(ctxt); 13051 xmlFreeParserCtxt(ctxt);
12286 13052
12287 return(ret); 13053 return(ret);
12288 #else /* !SAX2 */ 13054 #else /* !SAX2 */
12289 return(XML_ERR_INTERNAL_ERROR); 13055 return(XML_ERR_INTERNAL_ERROR);
12290 #endif 13056 #endif
12291 } 13057 }
12292 13058
12293 #ifdef LIBXML_SAX1_ENABLED 13059 #ifdef LIBXML_SAX1_ENABLED
12294 /** 13060 /**
12295 * xmlParseBalancedChunkMemoryRecover: 13061 * xmlParseBalancedChunkMemoryRecover:
12296 * @doc: the document the chunk pertains to 13062 * @doc: the document the chunk pertains to
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
12346 oldsax = ctxt->sax; 13112 oldsax = ctxt->sax;
12347 ctxt->sax = sax; 13113 ctxt->sax = sax;
12348 if (user_data != NULL) 13114 if (user_data != NULL)
12349 ctxt->userData = user_data; 13115 ctxt->userData = user_data;
12350 } 13116 }
12351 newDoc = xmlNewDoc(BAD_CAST "1.0"); 13117 newDoc = xmlNewDoc(BAD_CAST "1.0");
12352 if (newDoc == NULL) { 13118 if (newDoc == NULL) {
12353 xmlFreeParserCtxt(ctxt); 13119 xmlFreeParserCtxt(ctxt);
12354 return(-1); 13120 return(-1);
12355 } 13121 }
13122 newDoc->properties = XML_DOC_INTERNAL;
12356 if ((doc != NULL) && (doc->dict != NULL)) { 13123 if ((doc != NULL) && (doc->dict != NULL)) {
12357 xmlDictFree(ctxt->dict); 13124 xmlDictFree(ctxt->dict);
12358 ctxt->dict = doc->dict; 13125 ctxt->dict = doc->dict;
12359 xmlDictReference(ctxt->dict); 13126 xmlDictReference(ctxt->dict);
12360 ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3); 13127 ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
12361 ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5); 13128 ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
12362 ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36); 13129 ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
12363 ctxt->dictNames = 1; 13130 ctxt->dictNames = 1;
12364 } else { 13131 } else {
12365 » xmlCtxtUseOptions(ctxt, XML_PARSE_NODICT); 13132 » xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
12366 } 13133 }
12367 if (doc != NULL) { 13134 if (doc != NULL) {
12368 newDoc->intSubset = doc->intSubset; 13135 newDoc->intSubset = doc->intSubset;
12369 newDoc->extSubset = doc->extSubset; 13136 newDoc->extSubset = doc->extSubset;
12370 } 13137 }
12371 newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL); 13138 newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
12372 if (newRoot == NULL) { 13139 if (newRoot == NULL) {
12373 if (sax != NULL) 13140 if (sax != NULL)
12374 ctxt->sax = oldsax; 13141 ctxt->sax = oldsax;
12375 xmlFreeParserCtxt(ctxt); 13142 xmlFreeParserCtxt(ctxt);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
12418 } 13185 }
12419 13186
12420 if (!ctxt->wellFormed) { 13187 if (!ctxt->wellFormed) {
12421 if (ctxt->errNo == 0) 13188 if (ctxt->errNo == 0)
12422 ret = 1; 13189 ret = 1;
12423 else 13190 else
12424 ret = ctxt->errNo; 13191 ret = ctxt->errNo;
12425 } else { 13192 } else {
12426 ret = 0; 13193 ret = 0;
12427 } 13194 }
12428 13195
12429 if ((lst != NULL) && ((ret == 0) || (recover == 1))) { 13196 if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
12430 xmlNodePtr cur; 13197 xmlNodePtr cur;
12431 13198
12432 /* 13199 /*
12433 * Return the newly created nodeset after unlinking it from 13200 * Return the newly created nodeset after unlinking it from
12434 * they pseudo parent. 13201 * they pseudo parent.
12435 */ 13202 */
12436 cur = newDoc->children->children; 13203 cur = newDoc->children->children;
12437 *lst = cur; 13204 *lst = cur;
12438 while (cur != NULL) { 13205 while (cur != NULL) {
12439 xmlSetTreeDoc(cur, doc); 13206 xmlSetTreeDoc(cur, doc);
12440 cur->parent = NULL; 13207 cur->parent = NULL;
12441 cur = cur->next; 13208 cur = cur->next;
12442 } 13209 }
12443 newDoc->children->children = NULL; 13210 newDoc->children->children = NULL;
12444 } 13211 }
12445 » 13212
12446 if (sax != NULL) 13213 if (sax != NULL)
12447 ctxt->sax = oldsax; 13214 ctxt->sax = oldsax;
12448 xmlFreeParserCtxt(ctxt); 13215 xmlFreeParserCtxt(ctxt);
12449 newDoc->intSubset = NULL; 13216 newDoc->intSubset = NULL;
12450 newDoc->extSubset = NULL; 13217 newDoc->extSubset = NULL;
12451 newDoc->oldNs = NULL; 13218 newDoc->oldNs = NULL;
12452 xmlFreeDoc(newDoc); 13219 xmlFreeDoc(newDoc);
12453 13220
12454 return(ret); 13221 return(ret);
12455 } 13222 }
12456 13223
12457 /** 13224 /**
12458 * xmlSAXParseEntity: 13225 * xmlSAXParseEntity:
12459 * @sax: the SAX handler block 13226 * @sax: the SAX handler block
12460 * @filename: the filename 13227 * @filename: the filename
12461 * 13228 *
12462 * parse an XML external entity out of context and build a tree. 13229 * parse an XML external entity out of context and build a tree.
12463 * It use the given SAX function block to handle the parsing callback. 13230 * It use the given SAX function block to handle the parsing callback.
(...skipping 27 matching lines...) Expand all
12491 if (ctxt->wellFormed) 13258 if (ctxt->wellFormed)
12492 ret = ctxt->myDoc; 13259 ret = ctxt->myDoc;
12493 else { 13260 else {
12494 ret = NULL; 13261 ret = NULL;
12495 xmlFreeDoc(ctxt->myDoc); 13262 xmlFreeDoc(ctxt->myDoc);
12496 ctxt->myDoc = NULL; 13263 ctxt->myDoc = NULL;
12497 } 13264 }
12498 if (sax != NULL) 13265 if (sax != NULL)
12499 ctxt->sax = NULL; 13266 ctxt->sax = NULL;
12500 xmlFreeParserCtxt(ctxt); 13267 xmlFreeParserCtxt(ctxt);
12501 13268
12502 return(ret); 13269 return(ret);
12503 } 13270 }
12504 13271
12505 /** 13272 /**
12506 * xmlParseEntity: 13273 * xmlParseEntity:
12507 * @filename: the filename 13274 * @filename: the filename
12508 * 13275 *
12509 * parse an XML external entity out of context and build a tree. 13276 * parse an XML external entity out of context and build a tree.
12510 * 13277 *
12511 * [78] extParsedEnt ::= TextDecl? content 13278 * [78] extParsedEnt ::= TextDecl? content
12512 * 13279 *
12513 * This correspond to a "Well Balanced" chunk 13280 * This correspond to a "Well Balanced" chunk
12514 * 13281 *
12515 * Returns the resulting document tree 13282 * Returns the resulting document tree
12516 */ 13283 */
12517 13284
12518 xmlDocPtr 13285 xmlDocPtr
12519 xmlParseEntity(const char *filename) { 13286 xmlParseEntity(const char *filename) {
12520 return(xmlSAXParseEntity(NULL, filename)); 13287 return(xmlSAXParseEntity(NULL, filename));
12521 } 13288 }
12522 #endif /* LIBXML_SAX1_ENABLED */ 13289 #endif /* LIBXML_SAX1_ENABLED */
12523 13290
12524 /** 13291 /**
12525 * xmlCreateEntityParserCtxt: 13292 * xmlCreateEntityParserCtxtInternal:
12526 * @URL: the entity URL 13293 * @URL: the entity URL
12527 * @ID: the entity PUBLIC ID 13294 * @ID: the entity PUBLIC ID
12528 * @base: a possible base for the target URI 13295 * @base: a possible base for the target URI
13296 * @pctx: parser context used to set options on new context
12529 * 13297 *
12530 * Create a parser context for an external entity 13298 * Create a parser context for an external entity
12531 * Automatic support for ZLIB/Compress compressed document is provided 13299 * Automatic support for ZLIB/Compress compressed document is provided
12532 * by default if found at compile-time. 13300 * by default if found at compile-time.
12533 * 13301 *
12534 * Returns the new parser context or NULL 13302 * Returns the new parser context or NULL
12535 */ 13303 */
12536 xmlParserCtxtPtr 13304 static xmlParserCtxtPtr
12537 xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID, 13305 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
12538 » const xmlChar *base) { 13306 » const xmlChar *base, xmlParserCtxtPtr pctx) {
12539 xmlParserCtxtPtr ctxt; 13307 xmlParserCtxtPtr ctxt;
12540 xmlParserInputPtr inputStream; 13308 xmlParserInputPtr inputStream;
12541 char *directory = NULL; 13309 char *directory = NULL;
12542 xmlChar *uri; 13310 xmlChar *uri;
12543 13311
12544 ctxt = xmlNewParserCtxt(); 13312 ctxt = xmlNewParserCtxt();
12545 if (ctxt == NULL) { 13313 if (ctxt == NULL) {
12546 return(NULL); 13314 return(NULL);
12547 } 13315 }
12548 13316
13317 if (pctx != NULL) {
13318 ctxt->options = pctx->options;
13319 ctxt->_private = pctx->_private;
13320 }
13321
12549 uri = xmlBuildURI(URL, base); 13322 uri = xmlBuildURI(URL, base);
12550 13323
12551 if (uri == NULL) { 13324 if (uri == NULL) {
12552 inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt); 13325 inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
12553 if (inputStream == NULL) { 13326 if (inputStream == NULL) {
12554 xmlFreeParserCtxt(ctxt); 13327 xmlFreeParserCtxt(ctxt);
12555 return(NULL); 13328 return(NULL);
12556 } 13329 }
12557 13330
12558 inputPush(ctxt, inputStream); 13331 inputPush(ctxt, inputStream);
(...skipping 14 matching lines...) Expand all
12573 13346
12574 if ((ctxt->directory == NULL) && (directory == NULL)) 13347 if ((ctxt->directory == NULL) && (directory == NULL))
12575 directory = xmlParserGetDirectory((char *)uri); 13348 directory = xmlParserGetDirectory((char *)uri);
12576 if ((ctxt->directory == NULL) && (directory != NULL)) 13349 if ((ctxt->directory == NULL) && (directory != NULL))
12577 ctxt->directory = directory; 13350 ctxt->directory = directory;
12578 xmlFree(uri); 13351 xmlFree(uri);
12579 } 13352 }
12580 return(ctxt); 13353 return(ctxt);
12581 } 13354 }
12582 13355
13356 /**
13357 * xmlCreateEntityParserCtxt:
13358 * @URL: the entity URL
13359 * @ID: the entity PUBLIC ID
13360 * @base: a possible base for the target URI
13361 *
13362 * Create a parser context for an external entity
13363 * Automatic support for ZLIB/Compress compressed document is provided
13364 * by default if found at compile-time.
13365 *
13366 * Returns the new parser context or NULL
13367 */
13368 xmlParserCtxtPtr
13369 xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
13370 const xmlChar *base) {
13371 return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
13372
13373 }
13374
12583 /************************************************************************ 13375 /************************************************************************
12584 * * 13376 * *
12585 * » » Front ends when parsing from a file» » » * 13377 *» » Front ends when parsing from a file» » » *
12586 * * 13378 * *
12587 ************************************************************************/ 13379 ************************************************************************/
12588 13380
12589 /** 13381 /**
12590 * xmlCreateURLParserCtxt: 13382 * xmlCreateURLParserCtxt:
12591 * @filename: the filename or URL 13383 * @filename: the filename or URL
12592 * @options: a combination of xmlParserOption 13384 * @options: a combination of xmlParserOption
12593 * 13385 *
12594 * Create a parser context for a file or URL content. 13386 * Create a parser context for a file or URL content.
12595 * Automatic support for ZLIB/Compress compressed document is provided 13387 * Automatic support for ZLIB/Compress compressed document is provided
12596 * by default if found at compile-time and for file accesses 13388 * by default if found at compile-time and for file accesses
12597 * 13389 *
12598 * Returns the new parser context or NULL 13390 * Returns the new parser context or NULL
12599 */ 13391 */
12600 xmlParserCtxtPtr 13392 xmlParserCtxtPtr
12601 xmlCreateURLParserCtxt(const char *filename, int options) 13393 xmlCreateURLParserCtxt(const char *filename, int options)
12602 { 13394 {
12603 xmlParserCtxtPtr ctxt; 13395 xmlParserCtxtPtr ctxt;
12604 xmlParserInputPtr inputStream; 13396 xmlParserInputPtr inputStream;
12605 char *directory = NULL; 13397 char *directory = NULL;
12606 13398
12607 ctxt = xmlNewParserCtxt(); 13399 ctxt = xmlNewParserCtxt();
12608 if (ctxt == NULL) { 13400 if (ctxt == NULL) {
12609 xmlErrMemory(NULL, "cannot allocate parser context"); 13401 xmlErrMemory(NULL, "cannot allocate parser context");
12610 return(NULL); 13402 return(NULL);
12611 } 13403 }
12612 13404
12613 if (options) 13405 if (options)
12614 » xmlCtxtUseOptions(ctxt, options); 13406 » xmlCtxtUseOptionsInternal(ctxt, options, NULL);
12615 ctxt->linenumbers = 1; 13407 ctxt->linenumbers = 1;
12616 13408
12617 inputStream = xmlLoadExternalEntity(filename, NULL, ctxt); 13409 inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
12618 if (inputStream == NULL) { 13410 if (inputStream == NULL) {
12619 xmlFreeParserCtxt(ctxt); 13411 xmlFreeParserCtxt(ctxt);
12620 return(NULL); 13412 return(NULL);
12621 } 13413 }
12622 13414
12623 inputPush(ctxt, inputStream); 13415 inputPush(ctxt, inputStream);
12624 if ((ctxt->directory == NULL) && (directory == NULL)) 13416 if ((ctxt->directory == NULL) && (directory == NULL))
12625 directory = xmlParserGetDirectory(filename); 13417 directory = xmlParserGetDirectory(filename);
12626 if ((ctxt->directory == NULL) && (directory != NULL)) 13418 if ((ctxt->directory == NULL) && (directory != NULL))
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
12741 * @cur: a pointer to an array of xmlChar 13533 * @cur: a pointer to an array of xmlChar
12742 * 13534 *
12743 * parse an XML in-memory document and build a tree. 13535 * parse an XML in-memory document and build a tree.
12744 * In the case the document is not Well Formed, a attempt to build a 13536 * In the case the document is not Well Formed, a attempt to build a
12745 * tree is tried anyway 13537 * tree is tried anyway
12746 * 13538 *
12747 * Returns the resulting document tree or NULL in case of failure 13539 * Returns the resulting document tree or NULL in case of failure
12748 */ 13540 */
12749 13541
12750 xmlDocPtr 13542 xmlDocPtr
12751 xmlRecoverDoc(xmlChar *cur) { 13543 xmlRecoverDoc(const xmlChar *cur) {
12752 return(xmlSAXParseDoc(NULL, cur, 1)); 13544 return(xmlSAXParseDoc(NULL, cur, 1));
12753 } 13545 }
12754 13546
12755 /** 13547 /**
12756 * xmlParseFile: 13548 * xmlParseFile:
12757 * @filename: the filename 13549 * @filename: the filename
12758 * 13550 *
12759 * parse an XML file and build a tree. Automatic support for ZLIB/Compress 13551 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
12760 * compressed document is provided by default if found at compile-time. 13552 * compressed document is provided by default if found at compile-time.
12761 * 13553 *
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
12943 * 13735 *
12944 * Returns the resulting document tree 13736 * Returns the resulting document tree
12945 */ 13737 */
12946 13738
12947 xmlDocPtr 13739 xmlDocPtr
12948 xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer, 13740 xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
12949 int size, int recovery, void *data) { 13741 int size, int recovery, void *data) {
12950 xmlDocPtr ret; 13742 xmlDocPtr ret;
12951 xmlParserCtxtPtr ctxt; 13743 xmlParserCtxtPtr ctxt;
12952 13744
13745 xmlInitParser();
13746
12953 ctxt = xmlCreateMemoryParserCtxt(buffer, size); 13747 ctxt = xmlCreateMemoryParserCtxt(buffer, size);
12954 if (ctxt == NULL) return(NULL); 13748 if (ctxt == NULL) return(NULL);
12955 if (sax != NULL) { 13749 if (sax != NULL) {
12956 if (ctxt->sax != NULL) 13750 if (ctxt->sax != NULL)
12957 xmlFree(ctxt->sax); 13751 xmlFree(ctxt->sax);
12958 ctxt->sax = sax; 13752 ctxt->sax = sax;
12959 } 13753 }
12960 xmlDetectSAX2(ctxt); 13754 xmlDetectSAX2(ctxt);
12961 if (data!=NULL) { 13755 if (data!=NULL) {
12962 ctxt->_private=data; 13756 ctxt->_private=data;
12963 } 13757 }
12964 13758
12965 ctxt->recovery = recovery; 13759 ctxt->recovery = recovery;
12966 13760
12967 xmlParseDocument(ctxt); 13761 xmlParseDocument(ctxt);
12968 13762
12969 if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc; 13763 if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
12970 else { 13764 else {
12971 ret = NULL; 13765 ret = NULL;
12972 xmlFreeDoc(ctxt->myDoc); 13766 xmlFreeDoc(ctxt->myDoc);
12973 ctxt->myDoc = NULL; 13767 ctxt->myDoc = NULL;
12974 } 13768 }
12975 if (sax != NULL) 13769 if (sax != NULL)
12976 ctxt->sax = NULL; 13770 ctxt->sax = NULL;
12977 xmlFreeParserCtxt(ctxt); 13771 xmlFreeParserCtxt(ctxt);
12978 13772
12979 return(ret); 13773 return(ret);
12980 } 13774 }
12981 13775
12982 /** 13776 /**
12983 * xmlSAXParseMemory: 13777 * xmlSAXParseMemory:
12984 * @sax: the SAX handler block 13778 * @sax: the SAX handler block
12985 * @buffer: an pointer to a char array 13779 * @buffer: an pointer to a char array
12986 * @size: the size of the array 13780 * @size: the size of the array
12987 * @recovery: work in recovery mode, i.e. tries to read not Well Formed 13781 * @recovery: work in recovery mode, i.e. tries to read not Well Formed
12988 * documents 13782 * documents
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
13031 13825
13032 /** 13826 /**
13033 * xmlSAXUserParseMemory: 13827 * xmlSAXUserParseMemory:
13034 * @sax: a SAX handler 13828 * @sax: a SAX handler
13035 * @user_data: The user data returned on SAX callbacks 13829 * @user_data: The user data returned on SAX callbacks
13036 * @buffer: an in-memory XML document input 13830 * @buffer: an in-memory XML document input
13037 * @size: the length of the XML document in bytes 13831 * @size: the length of the XML document in bytes
13038 * 13832 *
13039 * A better SAX parsing routine. 13833 * A better SAX parsing routine.
13040 * parse an XML in-memory buffer and call the given SAX handler routines. 13834 * parse an XML in-memory buffer and call the given SAX handler routines.
13041 * 13835 *
13042 * Returns 0 in case of success or a error number otherwise 13836 * Returns 0 in case of success or a error number otherwise
13043 */ 13837 */
13044 int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data, 13838 int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
13045 const char *buffer, int size) { 13839 const char *buffer, int size) {
13046 int ret = 0; 13840 int ret = 0;
13047 xmlParserCtxtPtr ctxt; 13841 xmlParserCtxtPtr ctxt;
13048 13842
13843 xmlInitParser();
13844
13049 ctxt = xmlCreateMemoryParserCtxt(buffer, size); 13845 ctxt = xmlCreateMemoryParserCtxt(buffer, size);
13050 if (ctxt == NULL) return -1; 13846 if (ctxt == NULL) return -1;
13051 if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler) 13847 if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
13052 xmlFree(ctxt->sax); 13848 xmlFree(ctxt->sax);
13053 ctxt->sax = sax; 13849 ctxt->sax = sax;
13054 xmlDetectSAX2(ctxt); 13850 xmlDetectSAX2(ctxt);
13055 13851
13056 if (user_data != NULL) 13852 if (user_data != NULL)
13057 ctxt->userData = user_data; 13853 ctxt->userData = user_data;
13058 13854
13059 xmlParseDocument(ctxt); 13855 xmlParseDocument(ctxt);
13060 13856
13061 if (ctxt->wellFormed) 13857 if (ctxt->wellFormed)
13062 ret = 0; 13858 ret = 0;
13063 else { 13859 else {
13064 if (ctxt->errNo != 0) 13860 if (ctxt->errNo != 0)
13065 ret = ctxt->errNo; 13861 ret = ctxt->errNo;
13066 else 13862 else
13067 ret = -1; 13863 ret = -1;
13068 } 13864 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
13222 14018
13223 void 14019 void
13224 xmlInitParser(void) { 14020 xmlInitParser(void) {
13225 if (xmlParserInitialized != 0) 14021 if (xmlParserInitialized != 0)
13226 return; 14022 return;
13227 14023
13228 #ifdef LIBXML_THREAD_ENABLED 14024 #ifdef LIBXML_THREAD_ENABLED
13229 __xmlGlobalInitMutexLock(); 14025 __xmlGlobalInitMutexLock();
13230 if (xmlParserInitialized == 0) { 14026 if (xmlParserInitialized == 0) {
13231 #endif 14027 #endif
14028 xmlInitGlobals();
14029 xmlInitThreads();
13232 if ((xmlGenericError == xmlGenericErrorDefaultFunc) || 14030 if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
13233 (xmlGenericError == NULL)) 14031 (xmlGenericError == NULL))
13234 initGenericErrorDefaultFunc(NULL); 14032 initGenericErrorDefaultFunc(NULL);
13235 xmlInitGlobals();
13236 xmlInitThreads();
13237 xmlInitMemory(); 14033 xmlInitMemory();
13238 xmlInitCharEncodingHandlers(); 14034 xmlInitCharEncodingHandlers();
13239 xmlDefaultSAXHandlerInit(); 14035 xmlDefaultSAXHandlerInit();
13240 xmlRegisterDefaultInputCallbacks(); 14036 xmlRegisterDefaultInputCallbacks();
13241 #ifdef LIBXML_OUTPUT_ENABLED 14037 #ifdef LIBXML_OUTPUT_ENABLED
13242 xmlRegisterDefaultOutputCallbacks(); 14038 xmlRegisterDefaultOutputCallbacks();
13243 #endif /* LIBXML_OUTPUT_ENABLED */ 14039 #endif /* LIBXML_OUTPUT_ENABLED */
13244 #ifdef LIBXML_HTML_ENABLED 14040 #ifdef LIBXML_HTML_ENABLED
13245 htmlInitAutoClose(); 14041 htmlInitAutoClose();
13246 htmlDefaultSAXHandlerInit(); 14042 htmlDefaultSAXHandlerInit();
(...skipping 13 matching lines...) Expand all
13260 * 14056 *
13261 * This function name is somewhat misleading. It does not clean up 14057 * This function name is somewhat misleading. It does not clean up
13262 * parser state, it cleans up memory allocated by the library itself. 14058 * parser state, it cleans up memory allocated by the library itself.
13263 * It is a cleanup function for the XML library. It tries to reclaim all 14059 * It is a cleanup function for the XML library. It tries to reclaim all
13264 * related global memory allocated for the library processing. 14060 * related global memory allocated for the library processing.
13265 * It doesn't deallocate any document related memory. One should 14061 * It doesn't deallocate any document related memory. One should
13266 * call xmlCleanupParser() only when the process has finished using 14062 * call xmlCleanupParser() only when the process has finished using
13267 * the library and all XML/HTML documents built with it. 14063 * the library and all XML/HTML documents built with it.
13268 * See also xmlInitParser() which has the opposite function of preparing 14064 * See also xmlInitParser() which has the opposite function of preparing
13269 * the library for operations. 14065 * the library for operations.
14066 *
14067 * WARNING: if your application is multithreaded or has plugin support
14068 * calling this may crash the application if another thread or
14069 * a plugin is still using libxml2. It's sometimes very hard to
14070 * guess if libxml2 is in use in the application, some libraries
14071 * or plugins may use it without notice. In case of doubt abstain
14072 * from calling this function or do it just before calling exit()
14073 * to avoid leak reports from valgrind !
13270 */ 14074 */
13271 14075
13272 void 14076 void
13273 xmlCleanupParser(void) { 14077 xmlCleanupParser(void) {
13274 if (!xmlParserInitialized) 14078 if (!xmlParserInitialized)
13275 return; 14079 return;
13276 14080
13277 xmlCleanupCharEncodingHandlers(); 14081 xmlCleanupCharEncodingHandlers();
13278 #ifdef LIBXML_CATALOG_ENABLED 14082 #ifdef LIBXML_CATALOG_ENABLED
13279 xmlCatalogCleanup(); 14083 xmlCatalogCleanup();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
13382 ctxt->vctxt.warning = xmlParserValidityWarning; 14186 ctxt->vctxt.warning = xmlParserValidityWarning;
13383 #endif 14187 #endif
13384 ctxt->record_info = 0; 14188 ctxt->record_info = 0;
13385 ctxt->nbChars = 0; 14189 ctxt->nbChars = 0;
13386 ctxt->checkIndex = 0; 14190 ctxt->checkIndex = 0;
13387 ctxt->inSubset = 0; 14191 ctxt->inSubset = 0;
13388 ctxt->errNo = XML_ERR_OK; 14192 ctxt->errNo = XML_ERR_OK;
13389 ctxt->depth = 0; 14193 ctxt->depth = 0;
13390 ctxt->charset = XML_CHAR_ENCODING_UTF8; 14194 ctxt->charset = XML_CHAR_ENCODING_UTF8;
13391 ctxt->catalogs = NULL; 14195 ctxt->catalogs = NULL;
14196 ctxt->nbentities = 0;
14197 ctxt->sizeentities = 0;
13392 xmlInitNodeInfoSeq(&ctxt->node_seq); 14198 xmlInitNodeInfoSeq(&ctxt->node_seq);
13393 14199
13394 if (ctxt->attsDefault != NULL) { 14200 if (ctxt->attsDefault != NULL) {
13395 xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree); 14201 xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
13396 ctxt->attsDefault = NULL; 14202 ctxt->attsDefault = NULL;
13397 } 14203 }
13398 if (ctxt->attsSpecial != NULL) { 14204 if (ctxt->attsSpecial != NULL) {
13399 xmlHashFree(ctxt->attsSpecial, NULL); 14205 xmlHashFree(ctxt->attsSpecial, NULL);
13400 ctxt->attsSpecial = NULL; 14206 ctxt->attsSpecial = NULL;
13401 } 14207 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
13493 &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer-> 14299 &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->
13494 use]; 14300 use];
13495 #ifdef DEBUG_PUSH 14301 #ifdef DEBUG_PUSH
13496 xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size); 14302 xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
13497 #endif 14303 #endif
13498 } 14304 }
13499 14305
13500 if (encoding != NULL) { 14306 if (encoding != NULL) {
13501 xmlCharEncodingHandlerPtr hdlr; 14307 xmlCharEncodingHandlerPtr hdlr;
13502 14308
14309 if (ctxt->encoding != NULL)
14310 xmlFree((xmlChar *) ctxt->encoding);
14311 ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14312
13503 hdlr = xmlFindCharEncodingHandler(encoding); 14313 hdlr = xmlFindCharEncodingHandler(encoding);
13504 if (hdlr != NULL) { 14314 if (hdlr != NULL) {
13505 xmlSwitchToEncoding(ctxt, hdlr); 14315 xmlSwitchToEncoding(ctxt, hdlr);
13506 } else { 14316 } else {
13507 xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING, 14317 xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
13508 "Unsupported encoding %s\n", BAD_CAST encoding); 14318 "Unsupported encoding %s\n", BAD_CAST encoding);
13509 } 14319 }
13510 } else if (enc != XML_CHAR_ENCODING_NONE) { 14320 } else if (enc != XML_CHAR_ENCODING_NONE) {
13511 xmlSwitchEncoding(ctxt, enc); 14321 xmlSwitchEncoding(ctxt, enc);
13512 } 14322 }
13513 14323
13514 return(0); 14324 return(0);
13515 } 14325 }
13516 14326
14327
13517 /** 14328 /**
13518 * xmlCtxtUseOptions: 14329 * xmlCtxtUseOptionsInternal:
13519 * @ctxt: an XML parser context 14330 * @ctxt: an XML parser context
13520 * @options: a combination of xmlParserOption 14331 * @options: a combination of xmlParserOption
14332 * @encoding: the user provided encoding to use
13521 * 14333 *
13522 * Applies the options to the parser context 14334 * Applies the options to the parser context
13523 * 14335 *
13524 * Returns 0 in case of success, the set of unknown or unimplemented options 14336 * Returns 0 in case of success, the set of unknown or unimplemented options
13525 * in case of error. 14337 * in case of error.
13526 */ 14338 */
13527 int 14339 static int
13528 xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options) 14340 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encodi ng)
13529 { 14341 {
13530 if (ctxt == NULL) 14342 if (ctxt == NULL)
13531 return(-1); 14343 return(-1);
14344 if (encoding != NULL) {
14345 if (ctxt->encoding != NULL)
14346 xmlFree((xmlChar *) ctxt->encoding);
14347 ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14348 }
13532 if (options & XML_PARSE_RECOVER) { 14349 if (options & XML_PARSE_RECOVER) {
13533 ctxt->recovery = 1; 14350 ctxt->recovery = 1;
13534 options -= XML_PARSE_RECOVER; 14351 options -= XML_PARSE_RECOVER;
14352 ctxt->options |= XML_PARSE_RECOVER;
13535 } else 14353 } else
13536 ctxt->recovery = 0; 14354 ctxt->recovery = 0;
13537 if (options & XML_PARSE_DTDLOAD) { 14355 if (options & XML_PARSE_DTDLOAD) {
13538 ctxt->loadsubset = XML_DETECT_IDS; 14356 ctxt->loadsubset = XML_DETECT_IDS;
13539 options -= XML_PARSE_DTDLOAD; 14357 options -= XML_PARSE_DTDLOAD;
14358 ctxt->options |= XML_PARSE_DTDLOAD;
13540 } else 14359 } else
13541 ctxt->loadsubset = 0; 14360 ctxt->loadsubset = 0;
13542 if (options & XML_PARSE_DTDATTR) { 14361 if (options & XML_PARSE_DTDATTR) {
13543 ctxt->loadsubset |= XML_COMPLETE_ATTRS; 14362 ctxt->loadsubset |= XML_COMPLETE_ATTRS;
13544 options -= XML_PARSE_DTDATTR; 14363 options -= XML_PARSE_DTDATTR;
14364 ctxt->options |= XML_PARSE_DTDATTR;
13545 } 14365 }
13546 if (options & XML_PARSE_NOENT) { 14366 if (options & XML_PARSE_NOENT) {
13547 ctxt->replaceEntities = 1; 14367 ctxt->replaceEntities = 1;
13548 /* ctxt->loadsubset |= XML_DETECT_IDS; */ 14368 /* ctxt->loadsubset |= XML_DETECT_IDS; */
13549 options -= XML_PARSE_NOENT; 14369 options -= XML_PARSE_NOENT;
14370 ctxt->options |= XML_PARSE_NOENT;
13550 } else 14371 } else
13551 ctxt->replaceEntities = 0; 14372 ctxt->replaceEntities = 0;
13552 if (options & XML_PARSE_PEDANTIC) { 14373 if (options & XML_PARSE_PEDANTIC) {
13553 ctxt->pedantic = 1; 14374 ctxt->pedantic = 1;
13554 options -= XML_PARSE_PEDANTIC; 14375 options -= XML_PARSE_PEDANTIC;
14376 ctxt->options |= XML_PARSE_PEDANTIC;
13555 } else 14377 } else
13556 ctxt->pedantic = 0; 14378 ctxt->pedantic = 0;
13557 if (options & XML_PARSE_NOBLANKS) { 14379 if (options & XML_PARSE_NOBLANKS) {
13558 ctxt->keepBlanks = 0; 14380 ctxt->keepBlanks = 0;
13559 ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace; 14381 ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
13560 options -= XML_PARSE_NOBLANKS; 14382 options -= XML_PARSE_NOBLANKS;
14383 ctxt->options |= XML_PARSE_NOBLANKS;
13561 } else 14384 } else
13562 ctxt->keepBlanks = 1; 14385 ctxt->keepBlanks = 1;
13563 if (options & XML_PARSE_DTDVALID) { 14386 if (options & XML_PARSE_DTDVALID) {
13564 ctxt->validate = 1; 14387 ctxt->validate = 1;
13565 if (options & XML_PARSE_NOWARNING) 14388 if (options & XML_PARSE_NOWARNING)
13566 ctxt->vctxt.warning = NULL; 14389 ctxt->vctxt.warning = NULL;
13567 if (options & XML_PARSE_NOERROR) 14390 if (options & XML_PARSE_NOERROR)
13568 ctxt->vctxt.error = NULL; 14391 ctxt->vctxt.error = NULL;
13569 options -= XML_PARSE_DTDVALID; 14392 options -= XML_PARSE_DTDVALID;
14393 ctxt->options |= XML_PARSE_DTDVALID;
13570 } else 14394 } else
13571 ctxt->validate = 0; 14395 ctxt->validate = 0;
13572 if (options & XML_PARSE_NOWARNING) { 14396 if (options & XML_PARSE_NOWARNING) {
13573 ctxt->sax->warning = NULL; 14397 ctxt->sax->warning = NULL;
13574 options -= XML_PARSE_NOWARNING; 14398 options -= XML_PARSE_NOWARNING;
13575 } 14399 }
13576 if (options & XML_PARSE_NOERROR) { 14400 if (options & XML_PARSE_NOERROR) {
13577 ctxt->sax->error = NULL; 14401 ctxt->sax->error = NULL;
13578 ctxt->sax->fatalError = NULL; 14402 ctxt->sax->fatalError = NULL;
13579 options -= XML_PARSE_NOERROR; 14403 options -= XML_PARSE_NOERROR;
13580 } 14404 }
13581 #ifdef LIBXML_SAX1_ENABLED 14405 #ifdef LIBXML_SAX1_ENABLED
13582 if (options & XML_PARSE_SAX1) { 14406 if (options & XML_PARSE_SAX1) {
13583 ctxt->sax->startElement = xmlSAX2StartElement; 14407 ctxt->sax->startElement = xmlSAX2StartElement;
13584 ctxt->sax->endElement = xmlSAX2EndElement; 14408 ctxt->sax->endElement = xmlSAX2EndElement;
13585 ctxt->sax->startElementNs = NULL; 14409 ctxt->sax->startElementNs = NULL;
13586 ctxt->sax->endElementNs = NULL; 14410 ctxt->sax->endElementNs = NULL;
13587 ctxt->sax->initialized = 1; 14411 ctxt->sax->initialized = 1;
13588 options -= XML_PARSE_SAX1; 14412 options -= XML_PARSE_SAX1;
14413 ctxt->options |= XML_PARSE_SAX1;
13589 } 14414 }
13590 #endif /* LIBXML_SAX1_ENABLED */ 14415 #endif /* LIBXML_SAX1_ENABLED */
13591 if (options & XML_PARSE_NODICT) { 14416 if (options & XML_PARSE_NODICT) {
13592 ctxt->dictNames = 0; 14417 ctxt->dictNames = 0;
13593 options -= XML_PARSE_NODICT; 14418 options -= XML_PARSE_NODICT;
14419 ctxt->options |= XML_PARSE_NODICT;
13594 } else { 14420 } else {
13595 ctxt->dictNames = 1; 14421 ctxt->dictNames = 1;
13596 } 14422 }
13597 if (options & XML_PARSE_NOCDATA) { 14423 if (options & XML_PARSE_NOCDATA) {
13598 ctxt->sax->cdataBlock = NULL; 14424 ctxt->sax->cdataBlock = NULL;
13599 options -= XML_PARSE_NOCDATA; 14425 options -= XML_PARSE_NOCDATA;
14426 ctxt->options |= XML_PARSE_NOCDATA;
13600 } 14427 }
13601 if (options & XML_PARSE_NSCLEAN) { 14428 if (options & XML_PARSE_NSCLEAN) {
13602 ctxt->options |= XML_PARSE_NSCLEAN; 14429 ctxt->options |= XML_PARSE_NSCLEAN;
13603 options -= XML_PARSE_NSCLEAN; 14430 options -= XML_PARSE_NSCLEAN;
13604 } 14431 }
13605 if (options & XML_PARSE_NONET) { 14432 if (options & XML_PARSE_NONET) {
13606 ctxt->options |= XML_PARSE_NONET; 14433 ctxt->options |= XML_PARSE_NONET;
13607 options -= XML_PARSE_NONET; 14434 options -= XML_PARSE_NONET;
13608 } 14435 }
13609 if (options & XML_PARSE_COMPACT) { 14436 if (options & XML_PARSE_COMPACT) {
13610 ctxt->options |= XML_PARSE_COMPACT; 14437 ctxt->options |= XML_PARSE_COMPACT;
13611 options -= XML_PARSE_COMPACT; 14438 options -= XML_PARSE_COMPACT;
13612 } 14439 }
14440 if (options & XML_PARSE_OLD10) {
14441 ctxt->options |= XML_PARSE_OLD10;
14442 options -= XML_PARSE_OLD10;
14443 }
14444 if (options & XML_PARSE_NOBASEFIX) {
14445 ctxt->options |= XML_PARSE_NOBASEFIX;
14446 options -= XML_PARSE_NOBASEFIX;
14447 }
14448 if (options & XML_PARSE_HUGE) {
14449 ctxt->options |= XML_PARSE_HUGE;
14450 options -= XML_PARSE_HUGE;
14451 }
14452 if (options & XML_PARSE_OLDSAX) {
14453 ctxt->options |= XML_PARSE_OLDSAX;
14454 options -= XML_PARSE_OLDSAX;
14455 }
13613 ctxt->linenumbers = 1; 14456 ctxt->linenumbers = 1;
13614 return (options); 14457 return (options);
13615 } 14458 }
13616 14459
13617 /** 14460 /**
14461 * xmlCtxtUseOptions:
14462 * @ctxt: an XML parser context
14463 * @options: a combination of xmlParserOption
14464 *
14465 * Applies the options to the parser context
14466 *
14467 * Returns 0 in case of success, the set of unknown or unimplemented options
14468 * in case of error.
14469 */
14470 int
14471 xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
14472 {
14473 return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
14474 }
14475
14476 /**
13618 * xmlDoRead: 14477 * xmlDoRead:
13619 * @ctxt: an XML parser context 14478 * @ctxt: an XML parser context
13620 * @URL: the base URL to use for the document 14479 * @URL: the base URL to use for the document
13621 * @encoding: the document encoding, or NULL 14480 * @encoding: the document encoding, or NULL
13622 * @options: a combination of xmlParserOption 14481 * @options: a combination of xmlParserOption
13623 * @reuse: keep the context for reuse 14482 * @reuse: keep the context for reuse
13624 * 14483 *
13625 * Common front-end for the xmlRead functions 14484 * Common front-end for the xmlRead functions
13626 * 14485 *
13627 * Returns the resulting document tree or NULL 14486 * Returns the resulting document tree or NULL
13628 */ 14487 */
13629 static xmlDocPtr 14488 static xmlDocPtr
13630 xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding, 14489 xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
13631 int options, int reuse) 14490 int options, int reuse)
13632 { 14491 {
13633 xmlDocPtr ret; 14492 xmlDocPtr ret;
13634 14493
13635 xmlCtxtUseOptions(ctxt, options); 14494 xmlCtxtUseOptionsInternal(ctxt, options, encoding);
13636 if (encoding != NULL) { 14495 if (encoding != NULL) {
13637 xmlCharEncodingHandlerPtr hdlr; 14496 xmlCharEncodingHandlerPtr hdlr;
13638 14497
13639 hdlr = xmlFindCharEncodingHandler(encoding); 14498 hdlr = xmlFindCharEncodingHandler(encoding);
13640 if (hdlr != NULL) 14499 if (hdlr != NULL)
13641 xmlSwitchToEncoding(ctxt, hdlr); 14500 xmlSwitchToEncoding(ctxt, hdlr);
13642 } 14501 }
13643 if ((URL != NULL) && (ctxt->input != NULL) && 14502 if ((URL != NULL) && (ctxt->input != NULL) &&
13644 (ctxt->input->filename == NULL)) 14503 (ctxt->input->filename == NULL))
13645 ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL); 14504 ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
14006 if (stream == NULL) { 14865 if (stream == NULL) {
14007 xmlFreeParserInputBuffer(input); 14866 xmlFreeParserInputBuffer(input);
14008 return (NULL); 14867 return (NULL);
14009 } 14868 }
14010 inputPush(ctxt, stream); 14869 inputPush(ctxt, stream);
14011 return (xmlDoRead(ctxt, URL, encoding, options, 1)); 14870 return (xmlDoRead(ctxt, URL, encoding, options, 1));
14012 } 14871 }
14013 14872
14014 #define bottom_parser 14873 #define bottom_parser
14015 #include "elfgcchack.h" 14874 #include "elfgcchack.h"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698