OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 "<") 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 "<") 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 Loading... |
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 "<") 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 "<") 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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" |
OLD | NEW |