1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Authors: Sterling Hughes <sterling@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : #include "php.h"
20 : #if defined(HAVE_LIBXML) && (defined(HAVE_XML) || defined(HAVE_XMLRPC)) && !defined(HAVE_LIBEXPAT)
21 : #include "expat_compat.h"
22 :
23 : typedef struct _php_xml_ns {
24 : xmlNsPtr nsptr;
25 : int ref_count;
26 : void *next;
27 : void *prev;
28 : } php_xml_ns;
29 :
30 : #ifdef LIBXML_EXPAT_COMPAT
31 :
32 : #define IS_NS_DECL(__ns) \
33 : ((__ns) != NULL && strlen(__ns) == 5 && *(__ns) == 'x' && *((__ns)+1) == 'm' && \
34 : *((__ns)+2) == 'l' && *((__ns)+3) == 'n' && *((__ns)+4) == 's')
35 :
36 : static void
37 : _qualify_namespace(XML_Parser parser, const xmlChar *name, const xmlChar *URI, xmlChar **qualified)
38 20 : {
39 20 : if (URI) {
40 : /* Use libxml functions otherwise its memory deallocation is screwed up */
41 18 : *qualified = xmlStrdup(URI);
42 18 : *qualified = xmlStrncat(*qualified, parser->_ns_seperator, 1);
43 18 : *qualified = xmlStrncat(*qualified, name, xmlStrlen(name));
44 : } else {
45 2 : *qualified = xmlStrdup(name);
46 : }
47 20 : }
48 :
49 : static void
50 : _start_element_handler(void *user, const xmlChar *name, const xmlChar **attributes)
51 2152 : {
52 2152 : XML_Parser parser = (XML_Parser) user;
53 2152 : xmlChar *qualified_name = NULL;
54 :
55 2152 : if (parser->h_start_element == NULL) {
56 1 : if (parser->h_default) {
57 1 : int attno = 0;
58 :
59 1 : qualified_name = xmlStrncatNew((xmlChar *)"<", name, xmlStrlen(name));
60 1 : if (attributes) {
61 0 : while (attributes[attno] != NULL) {
62 : int att_len;
63 : char *att_string, *att_name, *att_value;
64 :
65 0 : att_name = (char *)attributes[attno++];
66 0 : att_value = (char *)attributes[attno++];
67 :
68 0 : att_len = spprintf(&att_string, 0, " %s=\"%s\"", att_name, att_value);
69 :
70 0 : qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_string, att_len);
71 0 : efree(att_string);
72 : }
73 :
74 : }
75 1 : qualified_name = xmlStrncat(qualified_name, (xmlChar *)">", 1);
76 1 : parser->h_default(parser->user, (const XML_Char *) qualified_name, xmlStrlen(qualified_name));
77 1 : xmlFree(qualified_name);
78 : }
79 1 : return;
80 : }
81 :
82 2151 : qualified_name = xmlStrdup(name);
83 :
84 2151 : parser->h_start_element(parser->user, (const XML_Char *) qualified_name, (const XML_Char **) attributes);
85 :
86 2151 : xmlFree(qualified_name);
87 : }
88 :
89 : static void
90 : _start_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)
91 16 : {
92 16 : XML_Parser parser = (XML_Parser) user;
93 16 : xmlChar *qualified_name = NULL;
94 16 : xmlChar **attrs = NULL;
95 : int i;
96 16 : int z = 0;
97 16 : int y = 0;
98 :
99 16 : if (nb_namespaces > 0 && parser->h_start_ns != NULL) {
100 3 : for (i = 0; i < nb_namespaces; i += 1) {
101 2 : parser->h_start_ns(parser->user, (const XML_Char *) namespaces[y], (const XML_Char *) namespaces[y+1]);
102 2 : y += 2;
103 : }
104 1 : y = 0;
105 : }
106 :
107 16 : if (parser->h_start_element == NULL) {
108 6 : if (parser->h_default) {
109 :
110 3 : if (prefix) {
111 2 : qualified_name = xmlStrncatNew((xmlChar *)"<", prefix, xmlStrlen(prefix));
112 2 : qualified_name = xmlStrncat(qualified_name, (xmlChar *)":", 1);
113 2 : qualified_name = xmlStrncat(qualified_name, name, xmlStrlen(name));
114 : } else {
115 1 : qualified_name = xmlStrncatNew((xmlChar *)"<", name, xmlStrlen(name));
116 : }
117 :
118 3 : if (namespaces) {
119 : int i, j;
120 3 : for (i = 0,j = 0;j < nb_namespaces;j++) {
121 : int ns_len;
122 : char *ns_string, *ns_prefix, *ns_url;
123 :
124 2 : ns_prefix = (char *) namespaces[i++];
125 2 : ns_url = (char *) namespaces[i++];
126 :
127 2 : if (ns_prefix) {
128 1 : ns_len = spprintf(&ns_string, 0, " xmlns:%s=\"%s\"", ns_prefix, ns_url);
129 : } else {
130 1 : ns_len = spprintf(&ns_string, 0, " xmlns=\"%s\"", ns_url);
131 : }
132 2 : qualified_name = xmlStrncat(qualified_name, (xmlChar *)ns_string, ns_len);
133 :
134 2 : efree(ns_string);
135 : }
136 : }
137 :
138 3 : if (attributes) {
139 5 : for (i = 0; i < nb_attributes; i += 1) {
140 : int att_len;
141 : char *att_string, *att_name, *att_value, *att_prefix, *att_valueend;
142 :
143 3 : att_name = (char *) attributes[y++];
144 3 : att_prefix = (char *)attributes[y++];
145 3 : y++;
146 3 : att_value = (char *)attributes[y++];
147 3 : att_valueend = (char *)attributes[y++];
148 :
149 3 : if (att_prefix) {
150 1 : att_len = spprintf(&att_string, 0, " %s:%s=\"", att_prefix, att_name);
151 : } else {
152 2 : att_len = spprintf(&att_string, 0, " %s=\"", att_name);
153 : }
154 :
155 3 : qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_string, att_len);
156 3 : qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_value, att_valueend - att_value);
157 3 : qualified_name = xmlStrncat(qualified_name, (xmlChar *)"\"", 1);
158 :
159 3 : efree(att_string);
160 : }
161 :
162 : }
163 3 : qualified_name = xmlStrncat(qualified_name, (xmlChar *)">", 1);
164 3 : parser->h_default(parser->user, (const XML_Char *) qualified_name, xmlStrlen(qualified_name));
165 3 : xmlFree(qualified_name);
166 : }
167 6 : return;
168 : }
169 10 : _qualify_namespace(parser, name, URI, &qualified_name);
170 :
171 10 : if (attributes != NULL) {
172 3 : xmlChar *qualified_name_attr = NULL;
173 3 : attrs = safe_emalloc((nb_attributes * 2) + 1, sizeof(int *), 0);
174 :
175 8 : for (i = 0; i < nb_attributes; i += 1) {
176 :
177 5 : if (attributes[y+1] != NULL) {
178 1 : _qualify_namespace(parser, attributes[y] , attributes[y + 2], &qualified_name_attr);
179 : } else {
180 4 : qualified_name_attr = xmlStrdup(attributes[y]);
181 : }
182 5 : attrs[z] = qualified_name_attr;
183 5 : attrs[z + 1] = xmlStrndup(attributes[y + 3] , (int) (attributes[y + 4] - attributes[y + 3]));
184 5 : z += 2;
185 5 : y += 5;
186 : }
187 :
188 3 : attrs[z] = NULL;
189 : }
190 10 : parser->h_start_element(parser->user, (const XML_Char *) qualified_name, (const XML_Char **) attrs);
191 10 : if (attrs) {
192 13 : for (i = 0; i < z; i++) {
193 10 : xmlFree(attrs[i]);
194 : }
195 3 : efree(attrs);
196 : }
197 10 : xmlFree(qualified_name);
198 : }
199 :
200 : static void
201 : _namespace_handler(XML_Parser parser, xmlNsPtr nsptr)
202 0 : {
203 0 : if (nsptr != NULL) {
204 0 : _namespace_handler(parser, nsptr->next);
205 0 : parser->h_end_ns(parser->user, nsptr->prefix);
206 : }
207 0 : }
208 :
209 : static void
210 : _end_element_handler(void *user, const xmlChar *name)
211 2148 : {
212 : xmlChar *qualified_name;
213 2148 : XML_Parser parser = (XML_Parser) user;
214 :
215 2148 : if (parser->h_end_element == NULL) {
216 1 : if (parser->h_default) {
217 : char *end_element;
218 :
219 1 : spprintf(&end_element, 0, "</%s>", (char *)name);
220 1 : parser->h_default(parser->user, (const XML_Char *) end_element, strlen(end_element));
221 1 : efree(end_element);
222 : }
223 1 : return;
224 : }
225 :
226 2147 : qualified_name = xmlStrdup(name);
227 :
228 2147 : parser->h_end_element(parser->user, (const XML_Char *) qualified_name);
229 :
230 2147 : xmlFree(qualified_name);
231 : }
232 :
233 : static void
234 : _end_element_handler_ns(void *user, const xmlChar *name, const xmlChar * prefix, const xmlChar *URI)
235 15 : {
236 : xmlChar *qualified_name;
237 15 : XML_Parser parser = (XML_Parser) user;
238 :
239 15 : if (parser->h_end_element == NULL) {
240 6 : if (parser->h_default) {
241 : char *end_element;
242 : int end_element_len;
243 :
244 3 : if (prefix) {
245 2 : end_element_len = spprintf(&end_element, 0, "</%s:%s>", (char *) prefix, (char *)name);
246 : } else {
247 1 : end_element_len = spprintf(&end_element, 0, "</%s>", (char *)name);
248 : }
249 3 : parser->h_default(parser->user, (const XML_Char *) end_element, end_element_len);
250 3 : efree(end_element);
251 : }
252 6 : return;
253 : }
254 :
255 9 : _qualify_namespace(parser, name, URI, &qualified_name);
256 :
257 9 : parser->h_end_element(parser->user, (const XML_Char *) qualified_name);
258 :
259 9 : xmlFree(qualified_name);
260 : }
261 :
262 : static void
263 : _cdata_handler(void *user, const xmlChar *cdata, int cdata_len)
264 900 : {
265 900 : XML_Parser parser = (XML_Parser) user;
266 :
267 900 : if (parser->h_cdata == NULL) {
268 150 : if (parser->h_default) {
269 5 : parser->h_default(parser->user, (const XML_Char *) cdata, cdata_len);
270 : }
271 150 : return;
272 : }
273 :
274 750 : parser->h_cdata(parser->user, (const XML_Char *) cdata, cdata_len);
275 : }
276 :
277 : static void
278 : _pi_handler(void *user, const xmlChar *target, const xmlChar *data)
279 3 : {
280 3 : XML_Parser parser = (XML_Parser) user;
281 :
282 3 : if (parser->h_pi == NULL) {
283 2 : if (parser->h_default) {
284 : char *full_pi;
285 0 : spprintf(&full_pi, 0, "<?%s %s?>", (char *)target, (char *)data);
286 0 : parser->h_default(parser->user, (const XML_Char *) full_pi, strlen(full_pi));
287 0 : efree(full_pi);
288 : }
289 2 : return;
290 : }
291 :
292 1 : parser->h_pi(parser->user, (const XML_Char *) target, (const XML_Char *) data);
293 : }
294 :
295 : static void
296 : _unparsed_entity_decl_handler(void *user,
297 : const xmlChar *name,
298 : const xmlChar *pub_id,
299 : const xmlChar *sys_id,
300 : const xmlChar *notation)
301 3 : {
302 3 : XML_Parser parser = (XML_Parser) user;
303 :
304 3 : if (parser->h_unparsed_entity_decl == NULL) {
305 0 : return;
306 : }
307 :
308 3 : parser->h_unparsed_entity_decl(parser->user, name, NULL, sys_id, pub_id, notation);
309 : }
310 :
311 : static void
312 : _notation_decl_handler(void *user, const xmlChar *notation, const xmlChar *pub_id, const xmlChar *sys_id)
313 3 : {
314 3 : XML_Parser parser = (XML_Parser) user;
315 :
316 3 : if (parser->h_notation_decl == NULL) {
317 0 : return;
318 : }
319 :
320 3 : parser->h_notation_decl(parser->user, notation, NULL, sys_id, pub_id);
321 : }
322 :
323 : static void
324 : _build_comment(const xmlChar *data, int data_len, xmlChar **comment, int *comment_len)
325 0 : {
326 0 : *comment_len = data_len + 7;
327 :
328 0 : *comment = xmlMalloc(*comment_len + 1);
329 0 : memcpy(*comment, "<!--", 4);
330 0 : memcpy(*comment + 4, data, data_len);
331 0 : memcpy(*comment + 4 + data_len, "-->", 3);
332 :
333 0 : (*comment)[*comment_len] = '\0';
334 0 : }
335 :
336 : static void
337 : _comment_handler(void *user, const xmlChar *comment)
338 15 : {
339 15 : XML_Parser parser = (XML_Parser) user;
340 :
341 15 : if (parser->h_default) {
342 : xmlChar *d_comment;
343 : int d_comment_len;
344 :
345 0 : _build_comment(comment, xmlStrlen(comment), &d_comment, &d_comment_len);
346 0 : parser->h_default(parser->user, d_comment, d_comment_len);
347 0 : xmlFree(d_comment);
348 : }
349 15 : }
350 :
351 : static void
352 : _build_entity(const xmlChar *name, int len, xmlChar **entity, int *entity_len)
353 0 : {
354 0 : *entity_len = len + 2;
355 0 : *entity = xmlMalloc(*entity_len + 1);
356 0 : (*entity)[0] = '&';
357 0 : memcpy(*entity+1, name, len);
358 0 : (*entity)[len+1] = ';';
359 0 : (*entity)[*entity_len] = '\0';
360 0 : }
361 :
362 : static void
363 : _external_entity_ref_handler(void *user, const xmlChar *names, int type, const xmlChar *sys_id, const xmlChar *pub_id, xmlChar *content)
364 0 : {
365 0 : XML_Parser parser = (XML_Parser) user;
366 :
367 0 : if (parser->h_external_entity_ref == NULL) {
368 0 : return;
369 : }
370 :
371 0 : parser->h_external_entity_ref(parser, names, "", sys_id, pub_id);
372 : }
373 :
374 : static xmlEntityPtr
375 : _get_entity(void *user, const xmlChar *name)
376 14 : {
377 14 : XML_Parser parser = (XML_Parser) user;
378 14 : xmlEntityPtr ret = NULL;
379 :
380 14 : if (parser->parser->inSubset == 0) {
381 14 : ret = xmlGetPredefinedEntity(name);
382 14 : if (ret == NULL)
383 2 : ret = xmlGetDocEntity(parser->parser->myDoc, name);
384 :
385 14 : if (ret == NULL || (parser->parser->instate != XML_PARSER_ENTITY_VALUE && parser->parser->instate != XML_PARSER_ATTRIBUTE_VALUE)) {
386 18 : if (ret == NULL || ret->etype == XML_INTERNAL_GENERAL_ENTITY || ret->etype == XML_INTERNAL_PARAMETER_ENTITY || ret->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
387 : /* Predefined entities will expand unless no cdata handler is present */
388 9 : if (parser->h_default && ! (ret && ret->etype == XML_INTERNAL_PREDEFINED_ENTITY && parser->h_cdata)) {
389 : xmlChar *entity;
390 : int len;
391 :
392 0 : _build_entity(name, xmlStrlen(name), &entity, &len);
393 0 : parser->h_default(parser->user, (const xmlChar *) entity, len);
394 0 : xmlFree(entity);
395 : } else {
396 : /* expat will not expand internal entities if default handler is present otherwise
397 : it will expand and pass them to cdata handler */
398 9 : if (parser->h_cdata && ret) {
399 6 : parser->h_cdata(parser->user, ret->content, xmlStrlen(ret->content));
400 : }
401 : }
402 : } else {
403 0 : if (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
404 0 : _external_entity_ref_handler(user, ret->name, ret->etype, ret->SystemID, ret->ExternalID, NULL);
405 : }
406 : }
407 : }
408 : }
409 :
410 14 : return ret;
411 : }
412 :
413 : static xmlSAXHandler
414 : php_xml_compat_handlers = {
415 : NULL, /* internalSubset */
416 : NULL, /* isStandalone */
417 : NULL, /* hasInternalSubset */
418 : NULL, /* hasExternalSubset */
419 : NULL, /* resolveEntity */
420 : _get_entity, /* getEntity */
421 : NULL, /* entityDecl */
422 : _notation_decl_handler,
423 : NULL, /* attributeDecl */
424 : NULL, /* elementDecl */
425 : _unparsed_entity_decl_handler, /* unparsedEntity */
426 : NULL, /* setDocumentLocator */
427 : NULL, /* startDocument */
428 : NULL, /* endDocument */
429 : _start_element_handler, /* startElement */
430 : _end_element_handler, /* endElement */
431 : NULL, /* reference */
432 : _cdata_handler,
433 : NULL, /* ignorableWhitespace */
434 : _pi_handler,
435 : _comment_handler, /* comment */
436 : NULL, /* warning */
437 : NULL, /* error */
438 : NULL, /* fatalError */
439 : NULL, /* getParameterEntity */
440 : _cdata_handler, /* cdataBlock */
441 : NULL, /* externalSubset */
442 : XML_SAX2_MAGIC,
443 : NULL,
444 : _start_element_handler_ns,
445 : _end_element_handler_ns,
446 : NULL
447 : };
448 :
449 : PHPAPI XML_Parser
450 : XML_ParserCreate(const XML_Char *encoding)
451 408 : {
452 408 : return XML_ParserCreate_MM(encoding, NULL, NULL);
453 : }
454 :
455 : PHPAPI XML_Parser
456 : XML_ParserCreateNS(const XML_Char *encoding, const XML_Char sep)
457 0 : {
458 : XML_Char tmp[2];
459 0 : tmp[0] = sep;
460 0 : tmp[1] = '\0';
461 0 : return XML_ParserCreate_MM(encoding, NULL, tmp);
462 : }
463 :
464 : PHPAPI XML_Parser
465 : XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, const XML_Char *sep)
466 564 : {
467 : XML_Parser parser;
468 :
469 564 : parser = (XML_Parser) emalloc(sizeof(struct _XML_Parser));
470 564 : memset(parser, 0, sizeof(struct _XML_Parser));
471 564 : parser->use_namespace = 0;
472 564 : parser->_ns_seperator = NULL;
473 :
474 564 : parser->parser = xmlCreatePushParserCtxt((xmlSAXHandlerPtr) &php_xml_compat_handlers, (void *) parser, NULL, 0, NULL);
475 564 : if (parser->parser == NULL) {
476 0 : efree(parser);
477 0 : return NULL;
478 : }
479 : #if LIBXML_VERSION <= 20617
480 : /* for older versions of libxml2, allow correct detection of
481 : * charset in documents with a BOM: */
482 : parser->parser->charset = XML_CHAR_ENCODING_NONE;
483 : #endif
484 :
485 : #if LIBXML_VERSION >= 20703
486 : xmlCtxtUseOptions(parser->parser, XML_PARSE_OLDSAX);
487 : #endif
488 :
489 564 : parser->parser->replaceEntities = 1;
490 564 : parser->parser->wellFormed = 0;
491 564 : if (sep != NULL) {
492 23 : parser->use_namespace = 1;
493 23 : parser->parser->sax2 = 1;
494 23 : parser->_ns_seperator = xmlStrdup(sep);
495 : } else {
496 : /* Reset flag as XML_SAX2_MAGIC is needed for xmlCreatePushParserCtxt
497 : so must be set in the handlers */
498 541 : parser->parser->sax->initialized = 1;
499 : }
500 564 : return parser;
501 : }
502 :
503 : PHPAPI void
504 : XML_SetUserData(XML_Parser parser, void *user)
505 564 : {
506 564 : parser->user = user;
507 564 : }
508 :
509 : PHPAPI void *
510 : XML_GetUserData(XML_Parser parser)
511 0 : {
512 0 : return parser->user;
513 : }
514 :
515 : PHPAPI void
516 : XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end)
517 443 : {
518 443 : parser->h_start_element = start;
519 443 : parser->h_end_element = end;
520 443 : }
521 :
522 : PHPAPI void
523 : XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler cdata)
524 415 : {
525 415 : parser->h_cdata = cdata;
526 415 : }
527 :
528 : PHPAPI void
529 : XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler pi)
530 1 : {
531 1 : parser->h_pi = pi;
532 1 : }
533 :
534 : PHPAPI void
535 : XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler comment)
536 0 : {
537 0 : parser->h_comment = comment;
538 0 : }
539 :
540 : PHPAPI void
541 : XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler d)
542 6 : {
543 6 : parser->h_default = d;
544 6 : }
545 :
546 : PHPAPI void
547 : XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler unparsed_decl)
548 1 : {
549 1 : parser->h_unparsed_entity_decl = unparsed_decl;
550 1 : }
551 :
552 : PHPAPI void
553 : XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler notation_decl)
554 1 : {
555 1 : parser->h_notation_decl = notation_decl;
556 1 : }
557 :
558 : PHPAPI void
559 : XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler ext_entity)
560 0 : {
561 0 : parser->h_external_entity_ref = ext_entity;
562 0 : }
563 :
564 : PHPAPI void
565 : XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start_ns)
566 1 : {
567 1 : parser->h_start_ns = start_ns;
568 1 : }
569 :
570 : PHPAPI void
571 : XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end_ns)
572 1 : {
573 1 : parser->h_end_ns = end_ns;
574 1 : }
575 :
576 : PHPAPI int
577 : XML_Parse(XML_Parser parser, const XML_Char *data, int data_len, int is_final)
578 3605 : {
579 : int error;
580 :
581 : /* The following is a hack to keep BC with PHP 4 while avoiding
582 : the inifite loop in libxml <= 2.6.17 which occurs when no encoding
583 : has been defined and none can be detected */
584 : #if LIBXML_VERSION <= 20617
585 : if (parser->parser->charset == XML_CHAR_ENCODING_NONE) {
586 : if (data_len >= 4 || (parser->parser->input->buf->buffer->use + data_len >= 4)) {
587 : xmlChar start[4];
588 : int char_count;
589 :
590 : char_count = parser->parser->input->buf->buffer->use;
591 : if (char_count > 4) {
592 : char_count = 4;
593 : }
594 :
595 : memcpy(start, parser->parser->input->buf->buffer->content, (size_t)char_count);
596 : memcpy(start + char_count, data, (size_t)(4 - char_count));
597 :
598 : if (xmlDetectCharEncoding(&start[0], 4) == XML_CHAR_ENCODING_NONE) {
599 : parser->parser->charset = XML_CHAR_ENCODING_UTF8;
600 : }
601 : }
602 : }
603 : #endif
604 :
605 3605 : error = xmlParseChunk(parser->parser, data, data_len, is_final);
606 3605 : if (!error) {
607 3598 : return 1;
608 7 : } else if (parser->parser->lastError.level > XML_ERR_WARNING ){
609 7 : return 0;
610 : } else {
611 0 : return 1;
612 : }
613 : }
614 :
615 : PHPAPI int
616 : XML_GetErrorCode(XML_Parser parser)
617 1 : {
618 1 : return parser->parser->errNo;
619 : }
620 :
621 : static const XML_Char *const error_mapping[] = {
622 : "No error",
623 : "No memory",
624 : "Invalid document start",
625 : "Empty document",
626 : "Not well-formed (invalid token)",
627 : "Invalid document end",
628 : "Invalid hexadecimal character reference",
629 : "Invalid decimal character reference",
630 : "Invalid character reference",
631 : "Invalid character",
632 : "XML_ERR_CHARREF_AT_EOF",
633 : "XML_ERR_CHARREF_IN_PROLOG",
634 : "XML_ERR_CHARREF_IN_EPILOG",
635 : "XML_ERR_CHARREF_IN_DTD",
636 : "XML_ERR_ENTITYREF_AT_EOF",
637 : "XML_ERR_ENTITYREF_IN_PROLOG",
638 : "XML_ERR_ENTITYREF_IN_EPILOG",
639 : "XML_ERR_ENTITYREF_IN_DTD",
640 : "PEReference at end of document",
641 : "PEReference in prolog",
642 : "PEReference in epilog",
643 : "PEReference: forbidden within markup decl in internal subset",
644 : "XML_ERR_ENTITYREF_NO_NAME",
645 : "EntityRef: expecting ';'",
646 : "PEReference: no name",
647 : "PEReference: expecting ';'",
648 : "Undeclared entity error",
649 : "Undeclared entity warning",
650 : "Unparsed Entity",
651 : "XML_ERR_ENTITY_IS_EXTERNAL",
652 : "XML_ERR_ENTITY_IS_PARAMETER",
653 : "Unknown encoding",
654 : "Unsupported encoding",
655 : "String not started expecting ' or \"",
656 : "String not closed expecting \" or '",
657 : "Namespace declaration error",
658 : "EntityValue: \" or ' expected",
659 : "EntityValue: \" or ' expected",
660 : "< in attribute",
661 : "Attribute not started",
662 : "Attribute not finished",
663 : "Attribute without value",
664 : "Attribute redefined",
665 : "SystemLiteral \" or ' expected",
666 : "SystemLiteral \" or ' expected",
667 : /* "XML_ERR_COMMENT_NOT_STARTED", <= eliminated on purpose */
668 : "Comment not finished",
669 : "Processing Instruction not started",
670 : "Processing Instruction not finished",
671 : "NOTATION: Name expected here",
672 : "'>' required to close NOTATION declaration",
673 : "'(' required to start ATTLIST enumeration",
674 : "'(' required to start ATTLIST enumeration",
675 : "MixedContentDecl : '|' or ')*' expected",
676 : "XML_ERR_MIXED_NOT_FINISHED",
677 : "ELEMENT in DTD not started",
678 : "ELEMENT in DTD not finished",
679 : "XML declaration not started",
680 : "XML declaration not finished",
681 : "XML_ERR_CONDSEC_NOT_STARTED",
682 : "XML conditional section not closed",
683 : "Content error in the external subset",
684 : "DOCTYPE not finished",
685 : "Sequence ']]>' not allowed in content",
686 : "CDATA not finished",
687 : "Reserved XML Name",
688 : "Space required",
689 : "XML_ERR_SEPARATOR_REQUIRED",
690 : "NmToken expected in ATTLIST enumeration",
691 : "XML_ERR_NAME_REQUIRED",
692 : "MixedContentDecl : '#PCDATA' expected",
693 : "SYSTEM or PUBLIC, the URI is missing",
694 : "PUBLIC, the Public Identifier is missing",
695 : "< required",
696 : "> required",
697 : "</ required",
698 : "= required",
699 : "Mismatched tag",
700 : "Tag not finished",
701 : "standalone accepts only 'yes' or 'no'",
702 : "Invalid XML encoding name",
703 : "Comment must not contain '--' (double-hyphen)",
704 : "Invalid encoding",
705 : "external parsed entities cannot be standalone",
706 : "XML conditional section '[' expected",
707 : "Entity value required",
708 : "chunk is not well balanced",
709 : "extra content at the end of well balanced chunk",
710 : "XML_ERR_ENTITY_CHAR_ERROR",
711 : "PEReferences forbidden in internal subset",
712 : "Detected an entity reference loop",
713 : "XML_ERR_ENTITY_BOUNDARY",
714 : "Invalid URI",
715 : "Fragment not allowed",
716 : "XML_WAR_CATALOG_PI",
717 : "XML_ERR_NO_DTD",
718 : "conditional section INCLUDE or IGNORE keyword expected", /* 95 */
719 : "Version in XML Declaration missing", /* 96 */
720 : "XML_WAR_UNKNOWN_VERSION", /* 97 */
721 : "XML_WAR_LANG_VALUE", /* 98 */
722 : "XML_WAR_NS_URI", /* 99 */
723 : "XML_WAR_NS_URI_RELATIVE", /* 100 */
724 : "Missing encoding in text declaration" /* 101 */
725 : };
726 :
727 : PHPAPI const XML_Char *
728 : XML_ErrorString(int code)
729 24 : {
730 24 : if (code < 0 || code >= (int)(sizeof(error_mapping) / sizeof(error_mapping[0]))) {
731 2 : return "Unknown";
732 : }
733 22 : return error_mapping[code];
734 : }
735 :
736 : PHPAPI int
737 : XML_GetCurrentLineNumber(XML_Parser parser)
738 7 : {
739 7 : return parser->parser->input->line;
740 : }
741 :
742 : PHPAPI int
743 : XML_GetCurrentColumnNumber(XML_Parser parser)
744 7 : {
745 7 : return parser->parser->input->col;
746 : }
747 :
748 : PHPAPI int
749 : XML_GetCurrentByteIndex(XML_Parser parser)
750 7 : {
751 7 : return parser->parser->input->consumed +
752 : (parser->parser->input->cur - parser->parser->input->base);
753 : }
754 :
755 : PHPAPI int
756 : XML_GetCurrentByteCount(XML_Parser parser)
757 0 : {
758 : /* WARNING: this is identical to ByteIndex; it should probably
759 : * be different */
760 0 : return parser->parser->input->consumed +
761 : (parser->parser->input->cur - parser->parser->input->base);
762 : }
763 :
764 : PHPAPI const XML_Char *XML_ExpatVersion(void)
765 0 : {
766 0 : return "1.0";
767 : }
768 :
769 : PHPAPI void
770 : XML_ParserFree(XML_Parser parser)
771 564 : {
772 564 : if (parser->use_namespace) {
773 23 : if (parser->_ns_seperator) {
774 23 : xmlFree(parser->_ns_seperator);
775 : }
776 : }
777 564 : if (parser->parser->myDoc) {
778 0 : xmlFreeDoc(parser->parser->myDoc);
779 0 : parser->parser->myDoc = NULL;
780 : }
781 564 : xmlFreeParserCtxt(parser->parser);
782 564 : efree(parser);
783 564 : }
784 :
785 : #endif /* LIBXML_EXPAT_COMPAT */
786 : #endif
787 :
788 : /**
789 : * Local Variables:
790 : * tab-width: 4
791 : * c-basic-offset: 4
792 : * indent-tabs-mode: t
793 : * End:
794 : * vim600: fdm=marker
795 : * vim: ts=4 noet sw=4
796 : */
|