18#if defined(HAVE_LIBXML) && (defined(HAVE_XML) || defined(HAVE_XMLRPC)) && !defined(HAVE_LIBEXPAT)
22#ifdef LIBXML_EXPAT_COMPAT
25qualify_namespace(XML_Parser parser,
const xmlChar *
name,
const xmlChar *URI, xmlChar **qualified)
29 *qualified = xmlStrdup(URI);
30 *qualified = xmlStrncat(*qualified, parser->_ns_separator, 1);
31 *qualified = xmlStrncat(*qualified,
name, xmlStrlen(
name));
33 *qualified = xmlStrdup(
name);
38start_element_handler(
void *user,
const xmlChar *
name,
const xmlChar **attributes)
40 XML_Parser parser = (XML_Parser) user;
41 xmlChar *qualified_name =
NULL;
43 if (parser->h_start_element ==
NULL) {
44 if (parser->h_default) {
47 qualified_name = xmlStrncatNew((xmlChar *)
"<",
name, xmlStrlen(
name));
49 while (attributes[attno] !=
NULL) {
51 char *att_string, *att_name, *att_value;
53 att_name = (
char *)attributes[attno++];
54 att_value = (
char *)attributes[attno++];
56 att_len =
spprintf(&att_string, 0,
" %s=\"%s\"", att_name, att_value);
58 qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_string, att_len);
63 qualified_name = xmlStrncat(qualified_name, (xmlChar *)
">", 1);
64 parser->h_default(parser->user, (
const XML_Char *) qualified_name, xmlStrlen(qualified_name));
65 xmlFree(qualified_name);
70 parser->h_start_element(parser->user,
name, (
const XML_Char **) attributes);
74start_element_handler_ns(
void *user,
const xmlChar *
name,
const xmlChar *
prefix,
const xmlChar *URI,
int nb_namespaces,
const xmlChar ** namespaces,
int nb_attributes,
int nb_defaulted,
const xmlChar ** attributes)
76 XML_Parser parser = (XML_Parser) user;
77 xmlChar *qualified_name =
NULL;
78 xmlChar **attrs =
NULL;
83 if (nb_namespaces > 0 && parser->h_start_ns !=
NULL) {
84 for (i = 0; i < nb_namespaces; i += 1) {
85 parser->h_start_ns(parser->user, (
const XML_Char *) namespaces[y], (
const XML_Char *) namespaces[y+1]);
91 if (parser->h_start_element ==
NULL) {
92 if (parser->h_default) {
95 qualified_name = xmlStrncatNew((xmlChar *)
"<",
prefix, xmlStrlen(
prefix));
96 qualified_name = xmlStrncat(qualified_name, (xmlChar *)
":", 1);
97 qualified_name = xmlStrncat(qualified_name,
name, xmlStrlen(
name));
99 qualified_name = xmlStrncatNew((xmlChar *)
"<",
name, xmlStrlen(
name));
104 for (i = 0,
j = 0;
j < nb_namespaces;
j++) {
106 char *ns_string, *ns_prefix, *ns_url;
108 ns_prefix = (
char *) namespaces[i++];
109 ns_url = (
char *) namespaces[i++];
112 ns_len =
spprintf(&ns_string, 0,
" xmlns:%s=\"%s\"", ns_prefix, ns_url);
114 ns_len =
spprintf(&ns_string, 0,
" xmlns=\"%s\"", ns_url);
116 qualified_name = xmlStrncat(qualified_name, (xmlChar *)ns_string, ns_len);
123 for (i = 0; i < nb_attributes; i += 1) {
125 char *att_string, *att_name, *att_value, *att_prefix, *att_valueend;
127 att_name = (
char *) attributes[y++];
128 att_prefix = (
char *)attributes[y++];
130 att_value = (
char *)attributes[y++];
131 att_valueend = (
char *)attributes[y++];
134 att_len =
spprintf(&att_string, 0,
" %s:%s=\"", att_prefix, att_name);
136 att_len =
spprintf(&att_string, 0,
" %s=\"", att_name);
139 qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_string, att_len);
140 qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_value, att_valueend - att_value);
141 qualified_name = xmlStrncat(qualified_name, (xmlChar *)
"\"", 1);
147 qualified_name = xmlStrncat(qualified_name, (xmlChar *)
">", 1);
148 parser->h_default(parser->user, (
const XML_Char *) qualified_name, xmlStrlen(qualified_name));
149 xmlFree(qualified_name);
153 qualify_namespace(parser,
name, URI, &qualified_name);
155 if (attributes !=
NULL) {
156 xmlChar *qualified_name_attr =
NULL;
157 attrs =
safe_emalloc((nb_attributes * 2) + 1,
sizeof(
int *), 0);
159 for (i = 0; i < nb_attributes; i += 1) {
161 if (attributes[y+1] !=
NULL) {
162 qualify_namespace(parser, attributes[y] , attributes[y + 2], &qualified_name_attr);
164 qualified_name_attr = xmlStrdup(attributes[y]);
166 attrs[z] = qualified_name_attr;
167 attrs[z + 1] = xmlStrndup(attributes[y + 3] , (
int) (attributes[y + 4] - attributes[y + 3]));
174 parser->h_start_element(parser->user, (
const XML_Char *) qualified_name, (
const XML_Char **) attrs);
176 for (i = 0; i < z; i++) {
181 xmlFree(qualified_name);
185end_element_handler(
void *user,
const xmlChar *
name)
187 XML_Parser parser = (XML_Parser) user;
189 if (parser->h_end_element ==
NULL) {
190 if (parser->h_default) {
194 parser->h_default(parser->user, (
const XML_Char *) end_element,
strlen(end_element));
200 parser->h_end_element(parser->user, (
const XML_Char *)
name);
204end_element_handler_ns(
void *user,
const xmlChar *
name,
const xmlChar *
prefix,
const xmlChar *URI)
206 xmlChar *qualified_name;
207 XML_Parser parser = (XML_Parser) user;
209 if (parser->h_end_element ==
NULL) {
210 if (parser->h_default) {
215 end_element_len =
spprintf(&end_element, 0,
"</%s:%s>", (
char *)
prefix, (
char *)
name);
217 end_element_len =
spprintf(&end_element, 0,
"</%s>", (
char *)
name);
219 parser->h_default(parser->user, (
const XML_Char *) end_element, end_element_len);
225 qualify_namespace(parser,
name, URI, &qualified_name);
227 parser->h_end_element(parser->user, (
const XML_Char *) qualified_name);
229 xmlFree(qualified_name);
233cdata_handler(
void *user,
const xmlChar *
cdata,
int cdata_len)
235 XML_Parser parser = (XML_Parser) user;
237 if (parser->h_cdata ==
NULL) {
238 if (parser->h_default) {
239 parser->h_default(parser->user, (
const XML_Char *)
cdata, cdata_len);
244 parser->h_cdata(parser->user, (
const XML_Char *)
cdata, cdata_len);
248pi_handler(
void *user,
const xmlChar *target,
const xmlChar *
data)
250 XML_Parser parser = (XML_Parser) user;
252 if (parser->h_pi ==
NULL) {
253 if (parser->h_default) {
255 spprintf(&full_pi, 0,
"<?%s %s?>", (
char *)target, (
char *)
data);
256 parser->h_default(parser->user, (
const XML_Char *) full_pi,
strlen(full_pi));
262 parser->h_pi(parser->user, (
const XML_Char *) target, (
const XML_Char *)
data);
266unparsed_entity_decl_handler(
void *user,
268 const xmlChar *pub_id,
269 const xmlChar *sys_id,
270 const xmlChar *notation)
272 XML_Parser parser = (XML_Parser) user;
274 if (parser->h_unparsed_entity_decl ==
NULL) {
278 parser->h_unparsed_entity_decl(parser->user,
name,
NULL, sys_id, pub_id, notation);
282notation_decl_handler(
void *user,
const xmlChar *notation,
const xmlChar *pub_id,
const xmlChar *sys_id)
284 XML_Parser parser = (XML_Parser) user;
286 if (parser->h_notation_decl ==
NULL) {
290 parser->h_notation_decl(parser->user, notation,
NULL, sys_id, pub_id);
294build_comment(
const xmlChar *
data,
size_t data_len, xmlChar **comment,
size_t *comment_len)
296 *comment_len = data_len + 7;
298 *comment = xmlMalloc(*comment_len + 1);
299 memcpy(*comment,
"<!--", 4);
301 memcpy(*comment + 4 + data_len,
"-->", 3);
303 (*comment)[*comment_len] =
'\0';
307comment_handler(
void *user,
const xmlChar *comment)
309 XML_Parser parser = (XML_Parser) user;
311 if (parser->h_default) {
313 size_t d_comment_len;
315 build_comment(comment, (
size_t) xmlStrlen(comment), &d_comment, &d_comment_len);
316 parser->h_default(parser->user, d_comment, d_comment_len);
322build_entity(
const xmlChar *
name,
size_t len, xmlChar **entity,
size_t *entity_len)
324 *entity_len =
len + 2;
325 *entity = xmlMalloc(*entity_len + 1);
328 (*entity)[
len+1] =
';';
329 (*entity)[*entity_len] =
'\0';
333external_entity_ref_handler(
void *user,
const xmlChar *names,
const xmlChar *sys_id,
const xmlChar *pub_id)
335 XML_Parser parser = (XML_Parser) user;
337 if (parser->h_external_entity_ref ==
NULL) {
341 if (!parser->h_external_entity_ref(parser, names, (XML_Char *)
"", sys_id, pub_id)) {
342 xmlStopParser(parser->parser);
348get_entity(
void *user,
const xmlChar *
name)
350 XML_Parser parser = (XML_Parser) user;
353 if (parser->parser->inSubset == 0) {
354 ret = xmlGetPredefinedEntity(
name);
356 ret = xmlGetDocEntity(parser->parser->myDoc,
name);
358 if (
ret ==
NULL || parser->parser->instate == XML_PARSER_CONTENT) {
359 if (
ret ==
NULL ||
ret->etype == XML_INTERNAL_GENERAL_ENTITY ||
ret->etype == XML_INTERNAL_PARAMETER_ENTITY ||
ret->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
361 if (parser->h_default && ! (
ret &&
ret->etype == XML_INTERNAL_PREDEFINED_ENTITY && parser->h_cdata)) {
365 build_entity(
name, (
size_t) xmlStrlen(
name), &entity, &
len);
366 parser->h_default(parser->user, (
const xmlChar *) entity,
len);
371 if (parser->h_cdata &&
ret) {
372 parser->h_cdata(parser->user,
ret->content, xmlStrlen(
ret->content));
376 if (
ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
377 external_entity_ref_handler(user,
ret->name,
ret->SystemID,
ret->ExternalID);
386static const xmlSAXHandler
387php_xml_compat_handlers = {
395 notation_decl_handler,
398 unparsed_entity_decl_handler,
402 start_element_handler,
417 start_element_handler_ns,
418 end_element_handler_ns,
423XML_ParserCreate(
const XML_Char *
encoding)
429XML_ParserCreateNS(
const XML_Char *
encoding,
const XML_Char sep)
438XML_ParserCreate_MM(
const XML_Char *
encoding,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *sep)
442 parser =
emalloc(
sizeof(
struct XML_Parser_Struct));
443 memset(parser, 0,
sizeof(
struct XML_Parser_Struct));
444 parser->use_namespace = 0;
445 parser->_ns_separator =
NULL;
447 parser->parser = xmlCreatePushParserCtxt((xmlSAXHandlerPtr) &php_xml_compat_handlers, (
void *) parser,
NULL, 0,
NULL);
448 if (parser->parser ==
NULL) {
453 php_libxml_sanitize_parse_ctxt_options(parser->parser);
454 xmlCtxtUseOptions(parser->parser, XML_PARSE_OLDSAX | XML_PARSE_NOENT);
456 parser->parser->wellFormed = 0;
459 ZEND_ASSERT(parser->parser->sax->initialized == XML_SAX2_MAGIC);
460 parser->use_namespace = 1;
461 parser->_ns_separator = xmlStrdup(sep);
465 parser->parser->sax->initialized = 1;
471XML_SetUserData(XML_Parser parser,
void *user)
477XML_GetUserData(XML_Parser parser)
483XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler
start, XML_EndElementHandler
end)
485 parser->h_start_element =
start;
486 parser->h_end_element =
end;
490XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler
cdata)
492 parser->h_cdata =
cdata;
496XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler
pi)
502XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler comment)
504 parser->h_comment = comment;
508XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler d)
510 parser->h_default = d;
514XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler unparsed_decl)
516 parser->h_unparsed_entity_decl = unparsed_decl;
520XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler notation_decl)
522 parser->h_notation_decl = notation_decl;
526XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler ext_entity)
528 parser->h_external_entity_ref = ext_entity;
532XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start_ns)
534 parser->h_start_ns = start_ns;
538XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end_ns)
540 parser->h_end_ns = end_ns;
544XML_Parse(XML_Parser parser,
const XML_Char *
data,
int data_len,
int is_final)
546 int error = xmlParseChunk(parser->parser, (
char *)
data, data_len, is_final);
549 const xmlError *error_data = xmlCtxtGetLastError(parser->parser);
550 return !error_data || error_data->level <= XML_ERR_WARNING;
557XML_GetErrorCode(XML_Parser parser)
559 return parser->parser->errNo;
562static const XML_Char *
const error_mapping[] = {
563 (
const XML_Char *)
"No error",
564 (
const XML_Char *)
"No memory",
565 (
const XML_Char *)
"Invalid document start",
566 (
const XML_Char *)
"Empty document",
567 (
const XML_Char *)
"Not well-formed (invalid token)",
568 (
const XML_Char *)
"Invalid document end",
569 (
const XML_Char *)
"Invalid hexadecimal character reference",
570 (
const XML_Char *)
"Invalid decimal character reference",
571 (
const XML_Char *)
"Invalid character reference",
572 (
const XML_Char *)
"Invalid character",
573 (
const XML_Char *)
"XML_ERR_CHARREF_AT_EOF",
574 (
const XML_Char *)
"XML_ERR_CHARREF_IN_PROLOG",
575 (
const XML_Char *)
"XML_ERR_CHARREF_IN_EPILOG",
576 (
const XML_Char *)
"XML_ERR_CHARREF_IN_DTD",
577 (
const XML_Char *)
"XML_ERR_ENTITYREF_AT_EOF",
578 (
const XML_Char *)
"XML_ERR_ENTITYREF_IN_PROLOG",
579 (
const XML_Char *)
"XML_ERR_ENTITYREF_IN_EPILOG",
580 (
const XML_Char *)
"XML_ERR_ENTITYREF_IN_DTD",
581 (
const XML_Char *)
"PEReference at end of document",
582 (
const XML_Char *)
"PEReference in prolog",
583 (
const XML_Char *)
"PEReference in epilog",
584 (
const XML_Char *)
"PEReference: forbidden within markup decl in internal subset",
585 (
const XML_Char *)
"XML_ERR_ENTITYREF_NO_NAME",
586 (
const XML_Char *)
"EntityRef: expecting ';'",
587 (
const XML_Char *)
"PEReference: no name",
588 (
const XML_Char *)
"PEReference: expecting ';'",
589 (
const XML_Char *)
"Undeclared entity error",
590 (
const XML_Char *)
"Undeclared entity warning",
591 (
const XML_Char *)
"Unparsed Entity",
592 (
const XML_Char *)
"XML_ERR_ENTITY_IS_EXTERNAL",
593 (
const XML_Char *)
"XML_ERR_ENTITY_IS_PARAMETER",
594 (
const XML_Char *)
"Unknown encoding",
595 (
const XML_Char *)
"Unsupported encoding",
596 (
const XML_Char *)
"String not started expecting ' or \"",
597 (
const XML_Char *)
"String not closed expecting \" or '",
598 (
const XML_Char *)
"Namespace declaration error",
599 (
const XML_Char *)
"EntityValue: \" or ' expected",
600 (
const XML_Char *)
"EntityValue: \" or ' expected",
601 (
const XML_Char *)
"< in attribute",
602 (
const XML_Char *)
"Attribute not started",
603 (
const XML_Char *)
"Attribute not finished",
604 (
const XML_Char *)
"Attribute without value",
605 (
const XML_Char *)
"Attribute redefined",
606 (
const XML_Char *)
"SystemLiteral \" or ' expected",
607 (
const XML_Char *)
"SystemLiteral \" or ' expected",
609 (
const XML_Char *)
"Comment not finished",
610 (
const XML_Char *)
"Processing Instruction not started",
611 (
const XML_Char *)
"Processing Instruction not finished",
612 (
const XML_Char *)
"NOTATION: Name expected here",
613 (
const XML_Char *)
"'>' required to close NOTATION declaration",
614 (
const XML_Char *)
"'(' required to start ATTLIST enumeration",
615 (
const XML_Char *)
"'(' required to start ATTLIST enumeration",
616 (
const XML_Char *)
"MixedContentDecl : '|' or ')*' expected",
617 (
const XML_Char *)
"XML_ERR_MIXED_NOT_FINISHED",
618 (
const XML_Char *)
"ELEMENT in DTD not started",
619 (
const XML_Char *)
"ELEMENT in DTD not finished",
620 (
const XML_Char *)
"XML declaration not started",
621 (
const XML_Char *)
"XML declaration not finished",
622 (
const XML_Char *)
"XML_ERR_CONDSEC_NOT_STARTED",
623 (
const XML_Char *)
"XML conditional section not closed",
624 (
const XML_Char *)
"Content error in the external subset",
625 (
const XML_Char *)
"DOCTYPE not finished",
626 (
const XML_Char *)
"Sequence ']]>' not allowed in content",
627 (
const XML_Char *)
"CDATA not finished",
628 (
const XML_Char *)
"Reserved XML Name",
629 (
const XML_Char *)
"Space required",
630 (
const XML_Char *)
"XML_ERR_SEPARATOR_REQUIRED",
631 (
const XML_Char *)
"NmToken expected in ATTLIST enumeration",
632 (
const XML_Char *)
"XML_ERR_NAME_REQUIRED",
633 (
const XML_Char *)
"MixedContentDecl : '#PCDATA' expected",
634 (
const XML_Char *)
"SYSTEM or PUBLIC, the URI is missing",
635 (
const XML_Char *)
"PUBLIC, the Public Identifier is missing",
636 (
const XML_Char *)
"< required",
637 (
const XML_Char *)
"> required",
638 (
const XML_Char *)
"</ required",
639 (
const XML_Char *)
"= required",
640 (
const XML_Char *)
"Mismatched tag",
641 (
const XML_Char *)
"Tag not finished",
642 (
const XML_Char *)
"standalone accepts only 'yes' or 'no'",
643 (
const XML_Char *)
"Invalid XML encoding name",
644 (
const XML_Char *)
"Comment must not contain '--' (double-hyphen)",
645 (
const XML_Char *)
"Invalid encoding",
646 (
const XML_Char *)
"external parsed entities cannot be standalone",
647 (
const XML_Char *)
"XML conditional section '[' expected",
648 (
const XML_Char *)
"Entity value required",
649 (
const XML_Char *)
"chunk is not well balanced",
650 (
const XML_Char *)
"extra content at the end of well balanced chunk",
651 (
const XML_Char *)
"XML_ERR_ENTITY_CHAR_ERROR",
652 (
const XML_Char *)
"PEReferences forbidden in internal subset",
653 (
const XML_Char *)
"Detected an entity reference loop",
654 (
const XML_Char *)
"XML_ERR_ENTITY_BOUNDARY",
655 (
const XML_Char *)
"Invalid URI",
656 (
const XML_Char *)
"Fragment not allowed",
657 (
const XML_Char *)
"XML_WAR_CATALOG_PI",
658 (
const XML_Char *)
"XML_ERR_NO_DTD",
659 (
const XML_Char *)
"conditional section INCLUDE or IGNORE keyword expected",
660 (
const XML_Char *)
"Version in XML Declaration missing",
661 (
const XML_Char *)
"XML_WAR_UNKNOWN_VERSION",
662 (
const XML_Char *)
"XML_WAR_LANG_VALUE",
663 (
const XML_Char *)
"XML_WAR_NS_URI",
664 (
const XML_Char *)
"XML_WAR_NS_URI_RELATIVE",
665 (
const XML_Char *)
"Missing encoding in text declaration"
669XML_ErrorString(
int code)
671 if (code < 0 || code >= (
int)(
sizeof(error_mapping) /
sizeof(error_mapping[0]))) {
672 return (
const XML_Char *)
"Unknown";
674 return error_mapping[code];
678XML_GetCurrentLineNumber(XML_Parser parser)
680 return parser->parser->input->line;
684XML_GetCurrentColumnNumber(XML_Parser parser)
686 return parser->parser->input->col;
690XML_GetCurrentByteIndex(XML_Parser parser)
692 return parser->parser->input->consumed +
693 (parser->parser->input->cur - parser->parser->input->base);
697XML_GetCurrentByteCount(XML_Parser parser)
701 return (
int) XML_GetCurrentByteIndex(parser);
706 return (
const XML_Char *)
"1.0";
710XML_ParserFree(XML_Parser parser)
712 if (parser->use_namespace) {
713 if (parser->_ns_separator) {
714 xmlFree(parser->_ns_separator);
717 if (parser->parser->myDoc) {
718 xmlFreeDoc(parser->parser->myDoc);
719 parser->parser->myDoc =
NULL;
721 xmlFreeParserCtxt(parser->parser);
memset(ptr, 0, type->size)
unsigned const char * end
xmlCharEncodingHandlerPtr encoding
const XML_ERROR_EXTERNAL_ENTITY_HANDLING
#define safe_emalloc(nmemb, size, offset)