1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | http://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Rob Richards <rrichards@php.net> |
14 +----------------------------------------------------------------------+
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21
22 #include "php.h"
23 #include "php_ini.h"
24 #include "ext/standard/info.h"
25 #include "php_xmlreader.h"
26 #include "php_xmlreader_arginfo.h"
27 #ifdef HAVE_DOM
28 #include "ext/dom/xml_common.h"
29 #include "ext/dom/dom_ce.h"
30 #endif
31 #include <libxml/xmlreader.h>
32 #include <libxml/uri.h>
33
34 zend_class_entry *xmlreader_class_entry;
35
36 static zend_object_handlers xmlreader_object_handlers;
37
38 static HashTable xmlreader_prop_handlers;
39
40 static zend_internal_function xmlreader_open_fn;
41 static zend_internal_function xmlreader_xml_fn;
42
43 typedef int (*xmlreader_read_int_t)(xmlTextReaderPtr reader);
44 typedef unsigned char *(*xmlreader_read_char_t)(xmlTextReaderPtr reader);
45 typedef const unsigned char *(*xmlreader_read_const_char_t)(xmlTextReaderPtr reader);
46 typedef int (*xmlreader_write_t)(xmlreader_object *obj, zval *newval);
47
48 typedef unsigned char *(*xmlreader_read_one_char_t)(xmlTextReaderPtr reader, const unsigned char *);
49
50 typedef struct _xmlreader_prop_handler {
51 xmlreader_read_int_t read_int_func;
52 xmlreader_read_const_char_t read_char_func;
53 xmlreader_write_t write_func;
54 int type;
55 } xmlreader_prop_handler;
56
57 #define XMLREADER_LOAD_STRING 0
58 #define XMLREADER_LOAD_FILE 1
59
60 /* {{{ xmlreader_register_prop_handler */
xmlreader_register_prop_handler(HashTable * prop_handler,char * name,xmlreader_read_int_t read_int_func,xmlreader_read_const_char_t read_char_func,int rettype)61 static void xmlreader_register_prop_handler(HashTable *prop_handler, char *name, xmlreader_read_int_t read_int_func, xmlreader_read_const_char_t read_char_func, int rettype)
62 {
63 xmlreader_prop_handler hnd;
64 zend_string *str;
65
66 hnd.read_char_func = read_char_func;
67 hnd.read_int_func = read_int_func;
68 hnd.type = rettype;
69 str = zend_string_init_interned(name, strlen(name), 1);
70 zend_hash_add_mem(prop_handler, str, &hnd, sizeof(xmlreader_prop_handler));
71 zend_string_release_ex(str, 1);
72 }
73 /* }}} */
74
75 /* {{{ xmlreader_property_reader */
xmlreader_property_reader(xmlreader_object * obj,xmlreader_prop_handler * hnd,zval * rv)76 static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handler *hnd, zval *rv)
77 {
78 const xmlChar *retchar = NULL;
79 int retint = 0;
80
81 if (obj->ptr != NULL) {
82 if (hnd->read_char_func) {
83 retchar = hnd->read_char_func(obj->ptr);
84 } else {
85 if (hnd->read_int_func) {
86 retint = hnd->read_int_func(obj->ptr);
87 if (retint == -1) {
88 php_error_docref(NULL, E_WARNING, "Internal libxml error returned");
89 return FAILURE;
90 }
91 }
92 }
93 }
94
95 switch (hnd->type) {
96 case IS_STRING:
97 if (retchar) {
98 ZVAL_STRING(rv, (char *) retchar);
99 } else {
100 ZVAL_EMPTY_STRING(rv);
101 }
102 break;
103 /* this IS_FALSE actually means it's a BOOL type */
104 case IS_FALSE:
105 ZVAL_BOOL(rv, retint);
106 break;
107 case IS_LONG:
108 ZVAL_LONG(rv, retint);
109 break;
110 default:
111 ZVAL_NULL(rv);
112 }
113
114 return SUCCESS;
115 }
116 /* }}} */
117
118 /* {{{ xmlreader_get_property_ptr_ptr */
xmlreader_get_property_ptr_ptr(zend_object * object,zend_string * name,int type,void ** cache_slot)119 zval *xmlreader_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot)
120 {
121 xmlreader_object *obj;
122 zval *retval = NULL;
123 xmlreader_prop_handler *hnd = NULL;
124
125 obj = php_xmlreader_fetch_object(object);
126
127 if (obj->prop_handler != NULL) {
128 hnd = zend_hash_find_ptr(obj->prop_handler, name);
129 }
130
131 if (hnd == NULL) {
132 retval = zend_std_get_property_ptr_ptr(object, name, type, cache_slot);
133 }
134
135 return retval;
136 }
137 /* }}} */
138
139 /* {{{ xmlreader_read_property */
xmlreader_read_property(zend_object * object,zend_string * name,int type,void ** cache_slot,zval * rv)140 zval *xmlreader_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv)
141 {
142 xmlreader_object *obj;
143 zval *retval = NULL;
144 xmlreader_prop_handler *hnd = NULL;
145
146 obj = php_xmlreader_fetch_object(object);
147
148 if (obj->prop_handler != NULL) {
149 hnd = zend_hash_find_ptr(obj->prop_handler, name);
150 }
151
152 if (hnd != NULL) {
153 if (xmlreader_property_reader(obj, hnd, rv) == FAILURE) {
154 retval = &EG(uninitialized_zval);
155 } else {
156 retval = rv;
157 }
158 } else {
159 retval = zend_std_read_property(object, name, type, cache_slot, rv);
160 }
161
162 return retval;
163 }
164 /* }}} */
165
166 /* {{{ xmlreader_write_property */
xmlreader_write_property(zend_object * object,zend_string * name,zval * value,void ** cache_slot)167 zval *xmlreader_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
168 {
169 xmlreader_object *obj;
170 xmlreader_prop_handler *hnd = NULL;
171
172 obj = php_xmlreader_fetch_object(object);
173
174 if (obj->prop_handler != NULL) {
175 hnd = zend_hash_find_ptr(obj->prop_handler, name);
176 }
177 if (hnd != NULL) {
178 zend_throw_error(NULL, "Cannot write to read-only property");
179 } else {
180 value = zend_std_write_property(object, name, value, cache_slot);
181 }
182
183 return value;
184 }
185 /* }}} */
186
187 /* {{{ */
xmlreader_get_method(zend_object ** obj,zend_string * name,const zval * key)188 static zend_function *xmlreader_get_method(zend_object **obj, zend_string *name, const zval *key)
189 {
190 if (ZSTR_LEN(name) == sizeof("open") - 1
191 && (ZSTR_VAL(name)[0] == 'o' || ZSTR_VAL(name)[0] == 'O')
192 && (ZSTR_VAL(name)[1] == 'p' || ZSTR_VAL(name)[1] == 'P')
193 && (ZSTR_VAL(name)[2] == 'e' || ZSTR_VAL(name)[2] == 'E')
194 && (ZSTR_VAL(name)[3] == 'n' || ZSTR_VAL(name)[3] == 'N')) {
195 return (zend_function*)&xmlreader_open_fn;
196 } else if (ZSTR_LEN(name) == sizeof("xml") - 1
197 && (ZSTR_VAL(name)[0] == 'x' || ZSTR_VAL(name)[0] == 'X')
198 && (ZSTR_VAL(name)[1] == 'm' || ZSTR_VAL(name)[1] == 'M')
199 && (ZSTR_VAL(name)[2] == 'l' || ZSTR_VAL(name)[2] == 'L')) {
200 return (zend_function*)&xmlreader_xml_fn;
201 }
202 return zend_std_get_method(obj, name, key);;
203 }
204 /* }}} */
205
206 /* {{{ _xmlreader_get_valid_file_path */
207 /* _xmlreader_get_valid_file_path and _xmlreader_get_relaxNG should be made a
208 common function in libxml extension as code is common to a few xml extensions */
_xmlreader_get_valid_file_path(char * source,char * resolved_path,int resolved_path_len)209 char *_xmlreader_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len ) {
210 xmlURI *uri;
211 xmlChar *escsource;
212 char *file_dest;
213 int isFileUri = 0;
214
215 uri = xmlCreateURI();
216 escsource = xmlURIEscapeStr((xmlChar *)source, (xmlChar *)":");
217 xmlParseURIReference(uri, (const char *)escsource);
218 xmlFree(escsource);
219
220 if (uri->scheme != NULL) {
221 /* absolute file uris - libxml only supports localhost or empty host */
222 if (strncasecmp(source, "file:///",8) == 0) {
223 isFileUri = 1;
224 #ifdef PHP_WIN32
225 source += 8;
226 #else
227 source += 7;
228 #endif
229 } else if (strncasecmp(source, "file://localhost/",17) == 0) {
230 isFileUri = 1;
231 #ifdef PHP_WIN32
232 source += 17;
233 #else
234 source += 16;
235 #endif
236 }
237 }
238
239 file_dest = source;
240
241 if ((uri->scheme == NULL || isFileUri)) {
242 if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path)) {
243 xmlFreeURI(uri);
244 return NULL;
245 }
246 file_dest = resolved_path;
247 }
248
249 xmlFreeURI(uri);
250
251 return file_dest;
252 }
253 /* }}} */
254
255 #ifdef LIBXML_SCHEMAS_ENABLED
256 /* {{{ _xmlreader_get_relaxNG */
_xmlreader_get_relaxNG(char * source,size_t source_len,size_t type,xmlRelaxNGValidityErrorFunc error_func,xmlRelaxNGValidityWarningFunc warn_func)257 static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, size_t source_len, size_t type,
258 xmlRelaxNGValidityErrorFunc error_func,
259 xmlRelaxNGValidityWarningFunc warn_func)
260 {
261 char *valid_file = NULL;
262 xmlRelaxNGParserCtxtPtr parser = NULL;
263 xmlRelaxNGPtr sptr;
264 char resolved_path[MAXPATHLEN + 1];
265
266 switch (type) {
267 case XMLREADER_LOAD_FILE:
268 valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN );
269 if (!valid_file) {
270 return NULL;
271 }
272 parser = xmlRelaxNGNewParserCtxt(valid_file);
273 break;
274 case XMLREADER_LOAD_STRING:
275 parser = xmlRelaxNGNewMemParserCtxt(source, source_len);
276 /* If loading from memory, we need to set the base directory for the document
277 but it is not apparent how to do that for schema's */
278 break;
279 default:
280 return NULL;
281 }
282
283 if (parser == NULL) {
284 return NULL;
285 }
286
287 PHP_LIBXML_SANITIZE_GLOBALS(parse);
288 if (error_func || warn_func) {
289 xmlRelaxNGSetParserErrors(parser,
290 (xmlRelaxNGValidityErrorFunc) error_func,
291 (xmlRelaxNGValidityWarningFunc) warn_func,
292 parser);
293 }
294 sptr = xmlRelaxNGParse(parser);
295 xmlRelaxNGFreeParserCtxt(parser);
296 PHP_LIBXML_RESTORE_GLOBALS(parse);
297
298 return sptr;
299 }
300 /* }}} */
301 #endif
302
303 static const zend_module_dep xmlreader_deps[] = {
304 ZEND_MOD_REQUIRED("libxml")
305 ZEND_MOD_END
306 };
307
308 /* {{{ xmlreader_module_entry */
309 zend_module_entry xmlreader_module_entry = {
310 STANDARD_MODULE_HEADER_EX, NULL,
311 xmlreader_deps,
312 "xmlreader",
313 NULL,
314 PHP_MINIT(xmlreader),
315 PHP_MSHUTDOWN(xmlreader),
316 NULL,
317 NULL,
318 PHP_MINFO(xmlreader),
319 PHP_XMLREADER_VERSION,
320 STANDARD_MODULE_PROPERTIES
321 };
322 /* }}} */
323
324 #ifdef COMPILE_DL_XMLREADER
ZEND_GET_MODULE(xmlreader)325 ZEND_GET_MODULE(xmlreader)
326 #endif
327
328 /* {{{ xmlreader_objects_clone */
329 void xmlreader_objects_clone(void *object, void **object_clone)
330 {
331 /* TODO */
332 }
333 /* }}} */
334
335 /* {{{ xmlreader_free_resources */
xmlreader_free_resources(xmlreader_object * intern)336 static void xmlreader_free_resources(xmlreader_object *intern) {
337 if (intern) {
338 if (intern->input) {
339 xmlFreeParserInputBuffer(intern->input);
340 intern->input = NULL;
341 }
342
343 if (intern->ptr) {
344 xmlFreeTextReader(intern->ptr);
345 intern->ptr = NULL;
346 }
347 #ifdef LIBXML_SCHEMAS_ENABLED
348 if (intern->schema) {
349 xmlRelaxNGFree((xmlRelaxNGPtr) intern->schema);
350 intern->schema = NULL;
351 }
352 #endif
353 }
354 }
355 /* }}} */
356
357 /* {{{ xmlreader_objects_free_storage */
xmlreader_objects_free_storage(zend_object * object)358 void xmlreader_objects_free_storage(zend_object *object)
359 {
360 xmlreader_object *intern = php_xmlreader_fetch_object(object);
361
362 zend_object_std_dtor(&intern->std);
363
364 xmlreader_free_resources(intern);
365 }
366 /* }}} */
367
368 /* {{{ xmlreader_objects_new */
xmlreader_objects_new(zend_class_entry * class_type)369 zend_object *xmlreader_objects_new(zend_class_entry *class_type)
370 {
371 xmlreader_object *intern;
372
373 intern = zend_object_alloc(sizeof(xmlreader_object), class_type);
374 zend_object_std_init(&intern->std, class_type);
375 object_properties_init(&intern->std, class_type);
376 intern->prop_handler = &xmlreader_prop_handlers;
377 intern->std.handlers = &xmlreader_object_handlers;
378
379 return &intern->std;
380 }
381 /* }}} */
382
383 /* {{{ php_xmlreader_string_arg */
php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAMETERS,xmlreader_read_one_char_t internal_function)384 static void php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_one_char_t internal_function) {
385 zval *id;
386 size_t name_len = 0;
387 char *retchar = NULL;
388 xmlreader_object *intern;
389 char *name;
390
391 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
392 RETURN_THROWS();
393 }
394
395 if (!name_len) {
396 zend_argument_value_error(1, "cannot be empty");
397 RETURN_THROWS();
398 }
399
400 id = ZEND_THIS;
401
402 intern = Z_XMLREADER_P(id);
403 if (intern && intern->ptr) {
404 retchar = (char *)internal_function(intern->ptr, (const unsigned char *)name);
405 }
406 if (retchar) {
407 RETVAL_STRING(retchar);
408 xmlFree(retchar);
409 return;
410 } else {
411 RETVAL_NULL();
412 }
413 }
414 /* }}} */
415
416 /* {{{ php_xmlreader_no_arg */
php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAMETERS,xmlreader_read_int_t internal_function)417 static void php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_int_t internal_function) {
418 zval *id;
419 int retval;
420 xmlreader_object *intern;
421
422 if (zend_parse_parameters_none() == FAILURE) {
423 RETURN_THROWS();
424 }
425
426 id = ZEND_THIS;
427
428 intern = Z_XMLREADER_P(id);
429 if (intern && intern->ptr) {
430 retval = internal_function(intern->ptr);
431 if (retval == 1) {
432 RETURN_TRUE;
433 }
434 }
435
436 RETURN_FALSE;
437 }
438 /* }}} */
439
php_xmlreader_free_prop_handler(zval * el)440 static void php_xmlreader_free_prop_handler(zval *el) /* {{{ */ {
441 pefree(Z_PTR_P(el), 1);
442 } /* }}} */
443
444 /* {{{ php_xmlreader_no_arg_string */
php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAMETERS,xmlreader_read_char_t internal_function)445 static void php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_char_t internal_function) {
446 zval *id;
447 char *retchar = NULL;
448 xmlreader_object *intern;
449
450 if (zend_parse_parameters_none() == FAILURE) {
451 RETURN_THROWS();
452 }
453
454 id = ZEND_THIS;
455
456 intern = Z_XMLREADER_P(id);
457 if (intern && intern->ptr) {
458 retchar = (char *)internal_function(intern->ptr);
459 }
460 if (retchar) {
461 RETVAL_STRING(retchar);
462 xmlFree(retchar);
463 return;
464 } else {
465 RETVAL_EMPTY_STRING();
466 }
467 }
468 /* }}} */
469
470 /* {{{ php_xmlreader_set_relaxng_schema */
php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS,int type)471 static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int type) {
472 #ifdef LIBXML_SCHEMAS_ENABLED
473 zval *id;
474 size_t source_len = 0;
475 int retval = -1;
476 xmlreader_object *intern;
477 xmlRelaxNGPtr schema = NULL;
478 char *source;
479
480 if (zend_parse_parameters(ZEND_NUM_ARGS(), "p!", &source, &source_len) == FAILURE) {
481 RETURN_THROWS();
482 }
483
484 if (source != NULL && !source_len) {
485 zend_argument_value_error(1, "cannot be empty");
486 RETURN_THROWS();
487 }
488
489 id = ZEND_THIS;
490
491 intern = Z_XMLREADER_P(id);
492 if (intern && intern->ptr) {
493 if (source) {
494 schema = _xmlreader_get_relaxNG(source, source_len, type, NULL, NULL);
495 if (schema) {
496 retval = xmlTextReaderRelaxNGSetSchema(intern->ptr, schema);
497 }
498 } else {
499 /* unset the associated relaxNG context and schema if one exists */
500 retval = xmlTextReaderRelaxNGSetSchema(intern->ptr, NULL);
501 }
502
503 if (retval == 0) {
504 if (intern->schema) {
505 xmlRelaxNGFree((xmlRelaxNGPtr) intern->schema);
506 }
507
508 intern->schema = schema;
509
510 RETURN_TRUE;
511 } else {
512 php_error_docref(NULL, E_WARNING, "Schema contains errors");
513 RETURN_FALSE;
514 }
515 } else {
516 zend_throw_error(NULL, "Schema must be set prior to reading");
517 RETURN_THROWS();
518 }
519 #else
520 php_error_docref(NULL, E_WARNING, "No schema support built into libxml");
521 RETURN_FALSE;
522 #endif
523 }
524 /* }}} */
525
526 /* {{{ Closes xmlreader - current frees resources until xmlTextReaderClose is fixed in libxml */
PHP_METHOD(XMLReader,close)527 PHP_METHOD(XMLReader, close)
528 {
529 zval *id;
530 xmlreader_object *intern;
531
532 if (zend_parse_parameters_none() == FAILURE) {
533 RETURN_THROWS();
534 }
535
536 id = ZEND_THIS;
537 intern = Z_XMLREADER_P(id);
538 /* libxml is segfaulting in versions up to 2.6.8 using xmlTextReaderClose so for
539 now we will free the whole reader when close is called as it would get rebuilt on
540 a new load anyways */
541 xmlreader_free_resources(intern);
542
543 RETURN_TRUE;
544 }
545 /* }}} */
546
547 /* {{{ Get value of an attribute from current element */
PHP_METHOD(XMLReader,getAttribute)548 PHP_METHOD(XMLReader, getAttribute)
549 {
550 php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderGetAttribute);
551 }
552 /* }}} */
553
554 /* {{{ Get value of an attribute at index from current element */
PHP_METHOD(XMLReader,getAttributeNo)555 PHP_METHOD(XMLReader, getAttributeNo)
556 {
557 zval *id;
558 zend_long attr_pos;
559 char *retchar = NULL;
560 xmlreader_object *intern;
561
562 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &attr_pos) == FAILURE) {
563 RETURN_THROWS();
564 }
565
566 id = ZEND_THIS;
567
568 intern = Z_XMLREADER_P(id);
569 if (intern && intern->ptr) {
570 retchar = (char *)xmlTextReaderGetAttributeNo(intern->ptr, attr_pos);
571 }
572 if (retchar) {
573 RETVAL_STRING(retchar);
574 xmlFree(retchar);
575 }
576 }
577 /* }}} */
578
579 /* {{{ Get value of a attribute via name and namespace from current element */
PHP_METHOD(XMLReader,getAttributeNs)580 PHP_METHOD(XMLReader, getAttributeNs)
581 {
582 zval *id;
583 size_t name_len = 0, ns_uri_len = 0;
584 xmlreader_object *intern;
585 char *name, *ns_uri, *retchar = NULL;
586
587 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &name, &name_len, &ns_uri, &ns_uri_len) == FAILURE) {
588 RETURN_THROWS();
589 }
590
591 if (name_len == 0) {
592 zend_argument_value_error(1, "cannot be empty");
593 RETURN_THROWS();
594 }
595
596 if (ns_uri_len == 0) {
597 zend_argument_value_error(2, "cannot be empty");
598 RETURN_THROWS();
599 }
600
601 id = ZEND_THIS;
602
603 intern = Z_XMLREADER_P(id);
604 if (intern && intern->ptr) {
605 retchar = (char *)xmlTextReaderGetAttributeNs(intern->ptr, (xmlChar *)name, (xmlChar *)ns_uri);
606 }
607 if (retchar) {
608 RETVAL_STRING(retchar);
609 xmlFree(retchar);
610 }
611 }
612 /* }}} */
613
614 /* {{{ Indicates whether given property (one of the parser option constants) is set or not on parser */
PHP_METHOD(XMLReader,getParserProperty)615 PHP_METHOD(XMLReader, getParserProperty)
616 {
617 zval *id;
618 zend_long property;
619 xmlreader_object *intern;
620
621 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &property) == FAILURE) {
622 RETURN_THROWS();
623 }
624
625 id = ZEND_THIS;
626
627 intern = Z_XMLREADER_P(id);
628 if (!intern || !intern->ptr) {
629 zend_throw_error(NULL, "Cannot access parser properties before loading data");
630 RETURN_THROWS();
631 }
632
633 int retval = xmlTextReaderGetParserProp(intern->ptr,property);
634 if (retval == -1) {
635 zend_argument_value_error(1, "must be a valid parser property");
636 RETURN_THROWS();
637 }
638
639 RETURN_BOOL(retval);
640 }
641 /* }}} */
642
643 /* {{{ Returns boolean indicating if parsed document is valid or not.
644 Must set XMLREADER_LOADDTD or XMLREADER_VALIDATE parser option prior to the first call to read
645 or this method will always return FALSE */
PHP_METHOD(XMLReader,isValid)646 PHP_METHOD(XMLReader, isValid)
647 {
648 php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderIsValid);
649 }
650 /* }}} */
651
652 /* {{{ Return namespaceURI for associated prefix on current node */
PHP_METHOD(XMLReader,lookupNamespace)653 PHP_METHOD(XMLReader, lookupNamespace)
654 {
655 php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderLookupNamespace);
656 }
657 /* }}} */
658
659 /* {{{ Positions reader at specified attribute - Returns TRUE on success and FALSE on failure */
PHP_METHOD(XMLReader,moveToAttribute)660 PHP_METHOD(XMLReader, moveToAttribute)
661 {
662 zval *id;
663 size_t name_len = 0;
664 int retval;
665 xmlreader_object *intern;
666 char *name;
667
668 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
669 RETURN_THROWS();
670 }
671
672 if (name_len == 0) {
673 zend_argument_value_error(1, "cannot be empty");
674 RETURN_THROWS();
675 }
676
677 id = ZEND_THIS;
678
679 intern = Z_XMLREADER_P(id);
680 if (intern && intern->ptr) {
681 retval = xmlTextReaderMoveToAttribute(intern->ptr, (xmlChar *)name);
682 if (retval == 1) {
683 RETURN_TRUE;
684 }
685 }
686
687 RETURN_FALSE;
688 }
689 /* }}} */
690
691 /* {{{ Positions reader at attribute at specified index.
692 Returns TRUE on success and FALSE on failure */
PHP_METHOD(XMLReader,moveToAttributeNo)693 PHP_METHOD(XMLReader, moveToAttributeNo)
694 {
695 zval *id;
696 zend_long attr_pos;
697 int retval;
698 xmlreader_object *intern;
699
700 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &attr_pos) == FAILURE) {
701 RETURN_THROWS();
702 }
703
704 id = ZEND_THIS;
705
706 intern = Z_XMLREADER_P(id);
707 if (intern && intern->ptr) {
708 retval = xmlTextReaderMoveToAttributeNo(intern->ptr, attr_pos);
709 if (retval == 1) {
710 RETURN_TRUE;
711 }
712 }
713
714 RETURN_FALSE;
715 }
716 /* }}} */
717
718 /* {{{ Positions reader at attribute spcified by name and namespaceURI.
719 Returns TRUE on success and FALSE on failure */
PHP_METHOD(XMLReader,moveToAttributeNs)720 PHP_METHOD(XMLReader, moveToAttributeNs)
721 {
722 zval *id;
723 size_t name_len=0, ns_uri_len=0;
724 int retval;
725 xmlreader_object *intern;
726 char *name, *ns_uri;
727
728 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &name, &name_len, &ns_uri, &ns_uri_len) == FAILURE) {
729 RETURN_THROWS();
730 }
731
732 if (name_len == 0) {
733 zend_argument_value_error(1, "cannot be empty");
734 RETURN_THROWS();
735 }
736
737 if (ns_uri_len == 0) {
738 zend_argument_value_error(2, "cannot be empty");
739 RETURN_THROWS();
740 }
741
742 id = ZEND_THIS;
743
744 intern = Z_XMLREADER_P(id);
745 if (intern && intern->ptr) {
746 retval = xmlTextReaderMoveToAttributeNs(intern->ptr, (xmlChar *)name, (xmlChar *)ns_uri);
747 if (retval == 1) {
748 RETURN_TRUE;
749 }
750 }
751
752 RETURN_FALSE;
753 }
754 /* }}} */
755
756 /* {{{ Moves the position of the current instance to the node that contains the current Attribute node. */
PHP_METHOD(XMLReader,moveToElement)757 PHP_METHOD(XMLReader, moveToElement)
758 {
759 php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderMoveToElement);
760 }
761 /* }}} */
762
763 /* {{{ Moves the position of the current instance to the first attribute associated with the current node. */
PHP_METHOD(XMLReader,moveToFirstAttribute)764 PHP_METHOD(XMLReader, moveToFirstAttribute)
765 {
766 php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderMoveToFirstAttribute);
767 }
768 /* }}} */
769
770 /* {{{ Moves the position of the current instance to the next attribute associated with the current node. */
PHP_METHOD(XMLReader,moveToNextAttribute)771 PHP_METHOD(XMLReader, moveToNextAttribute)
772 {
773 php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderMoveToNextAttribute);
774 }
775 /* }}} */
776
777 /* {{{ Moves the position of the current instance to the next node in the stream. */
PHP_METHOD(XMLReader,read)778 PHP_METHOD(XMLReader, read)
779 {
780 zval *id;
781 int retval;
782 xmlreader_object *intern;
783
784 if (zend_parse_parameters_none() == FAILURE) {
785 RETURN_THROWS();
786 }
787
788 id = ZEND_THIS;
789 intern = Z_XMLREADER_P(id);
790 if (intern == NULL || intern->ptr == NULL) {
791 zend_throw_error(NULL, "Data must be loaded before reading");
792 RETURN_THROWS();
793 }
794
795 retval = xmlTextReaderRead(intern->ptr);
796 if (retval == -1) {
797 RETURN_FALSE;
798 } else {
799 RETURN_BOOL(retval);
800 }
801 }
802 /* }}} */
803
804 /* {{{ Moves the position of the current instance to the next node in the stream. */
PHP_METHOD(XMLReader,next)805 PHP_METHOD(XMLReader, next)
806 {
807 zval *id;
808 int retval;
809 size_t name_len=0;
810 xmlreader_object *intern;
811 char *name = NULL;
812
813 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!", &name, &name_len) == FAILURE) {
814 RETURN_THROWS();
815 }
816
817 id = ZEND_THIS;
818 intern = Z_XMLREADER_P(id);
819 if (intern != NULL && intern->ptr != NULL) {
820 retval = xmlTextReaderNext(intern->ptr);
821 while (name != NULL && retval == 1) {
822 if (xmlStrEqual(xmlTextReaderConstLocalName(intern->ptr), (xmlChar *)name)) {
823 RETURN_TRUE;
824 }
825 retval = xmlTextReaderNext(intern->ptr);
826 }
827 if (retval == -1) {
828 RETURN_FALSE;
829 } else {
830 RETURN_BOOL(retval);
831 }
832 }
833
834 zend_throw_error(NULL, "Data must be loaded before reading");
835 }
836 /* }}} */
837
838 /* {{{ Sets the URI that the XMLReader will parse. */
PHP_METHOD(XMLReader,open)839 PHP_METHOD(XMLReader, open)
840 {
841 zval *id;
842 size_t source_len = 0, encoding_len = 0;
843 zend_long options = 0;
844 xmlreader_object *intern = NULL;
845 char *source, *valid_file = NULL;
846 char *encoding = NULL;
847 char resolved_path[MAXPATHLEN + 1];
848 xmlTextReaderPtr reader = NULL;
849
850 if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
851 RETURN_THROWS();
852 }
853
854 id = getThis();
855 if (id != NULL) {
856 if (! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry)) {
857 id = NULL;
858 } else {
859 intern = Z_XMLREADER_P(id);
860 xmlreader_free_resources(intern);
861 }
862 }
863
864 if (!source_len) {
865 zend_argument_value_error(1, "cannot be empty");
866 RETURN_THROWS();
867 }
868
869 if (encoding && CHECK_NULL_PATH(encoding, encoding_len)) {
870 php_error_docref(NULL, E_WARNING, "Encoding must not contain NUL bytes");
871 RETURN_FALSE;
872 }
873
874 valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN );
875
876 if (valid_file) {
877 PHP_LIBXML_SANITIZE_GLOBALS(reader_for_file);
878 reader = xmlReaderForFile(valid_file, encoding, options);
879 PHP_LIBXML_RESTORE_GLOBALS(reader_for_file);
880 }
881
882 if (reader == NULL) {
883 php_error_docref(NULL, E_WARNING, "Unable to open source data");
884 RETURN_FALSE;
885 }
886
887 if (id == NULL) {
888 object_init_ex(return_value, xmlreader_class_entry);
889 intern = Z_XMLREADER_P(return_value);
890 intern->ptr = reader;
891 return;
892 }
893
894 intern->ptr = reader;
895
896 RETURN_TRUE;
897
898 }
899 /* }}} */
900
901 /* Not Yet Implemented in libxml - functions exist just not coded
902 PHP_METHOD(XMLReader, resetState)
903 {
904
905 }
906 */
907
908 /* {{{ Reads the contents of the current node, including child nodes and markup. */
PHP_METHOD(XMLReader,readInnerXml)909 PHP_METHOD(XMLReader, readInnerXml)
910 {
911 php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadInnerXml);
912 }
913 /* }}} */
914
915 /* {{{ Reads the contents of the current node, including child nodes and markup. */
PHP_METHOD(XMLReader,readOuterXml)916 PHP_METHOD(XMLReader, readOuterXml)
917 {
918 php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadOuterXml);
919 }
920 /* }}} */
921
922 /* {{{ Reads the contents of an element or a text node as a string. */
PHP_METHOD(XMLReader,readString)923 PHP_METHOD(XMLReader, readString)
924 {
925 php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadString);
926 }
927 /* }}} */
928
929 /* {{{ Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read(). */
PHP_METHOD(XMLReader,setSchema)930 PHP_METHOD(XMLReader, setSchema)
931 {
932 #ifdef LIBXML_SCHEMAS_ENABLED
933 zval *id;
934 size_t source_len = 0;
935 int retval = -1;
936 xmlreader_object *intern;
937 char *source;
938
939 if (zend_parse_parameters(ZEND_NUM_ARGS(), "p!", &source, &source_len) == FAILURE) {
940 RETURN_THROWS();
941 }
942
943 if (source != NULL && !source_len) {
944 zend_argument_value_error(1, "cannot be empty");
945 RETURN_THROWS();
946 }
947
948 id = ZEND_THIS;
949
950 intern = Z_XMLREADER_P(id);
951 if (intern && intern->ptr) {
952 PHP_LIBXML_SANITIZE_GLOBALS(schema);
953 retval = xmlTextReaderSchemaValidate(intern->ptr, source);
954 PHP_LIBXML_RESTORE_GLOBALS(schema);
955
956 if (retval == 0) {
957 RETURN_TRUE;
958 } else {
959 php_error_docref(NULL, E_WARNING, "Schema contains errors");
960 RETURN_FALSE;
961 }
962 } else {
963 zend_throw_error(NULL, "Schema must be set prior to reading");
964 RETURN_THROWS();
965 }
966 #else
967 php_error_docref(NULL, E_WARNING, "No schema support built into libxml");
968 RETURN_FALSE;
969 #endif
970 }
971 /* }}} */
972
973 /* {{{ Sets parser property (one of the parser option constants).
974 Properties must be set after open() or XML() and before the first read() is called */
PHP_METHOD(XMLReader,setParserProperty)975 PHP_METHOD(XMLReader, setParserProperty)
976 {
977 zval *id;
978 zend_long property;
979 zend_bool value;
980 xmlreader_object *intern;
981
982 if (zend_parse_parameters(ZEND_NUM_ARGS(), "lb", &property, &value) == FAILURE) {
983 RETURN_THROWS();
984 }
985
986 id = ZEND_THIS;
987
988 intern = Z_XMLREADER_P(id);
989 if (!intern || !intern->ptr) {
990 zend_throw_error(NULL, "Cannot access parser properties before loading data");
991 RETURN_THROWS();
992 }
993
994 int retval = xmlTextReaderSetParserProp(intern->ptr,property, value);
995 if (retval == -1) {
996 zend_argument_value_error(1, "must be a valid parser property");
997 RETURN_THROWS();
998 }
999
1000 RETURN_TRUE;
1001 }
1002 /* }}} */
1003
1004 /* {{{ Sets the string that the XMLReader will parse. */
PHP_METHOD(XMLReader,setRelaxNGSchema)1005 PHP_METHOD(XMLReader, setRelaxNGSchema)
1006 {
1007 php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAM_PASSTHRU, XMLREADER_LOAD_FILE);
1008 }
1009 /* }}} */
1010
1011 /* {{{ Sets the string that the XMLReader will parse. */
PHP_METHOD(XMLReader,setRelaxNGSchemaSource)1012 PHP_METHOD(XMLReader, setRelaxNGSchemaSource)
1013 {
1014 php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAM_PASSTHRU, XMLREADER_LOAD_STRING);
1015 }
1016 /* }}} */
1017
1018 /* TODO
1019 XMLPUBFUN int XMLCALL
1020 xmlTextReaderSetSchema (xmlTextReaderPtr reader,
1021 xmlSchemaPtr schema);
1022 */
1023
1024 /* {{{ Sets the string that the XMLReader will parse. */
PHP_METHOD(XMLReader,XML)1025 PHP_METHOD(XMLReader, XML)
1026 {
1027 zval *id;
1028 size_t source_len = 0, encoding_len = 0;
1029 zend_long options = 0;
1030 xmlreader_object *intern = NULL;
1031 char *source, *uri = NULL, *encoding = NULL;
1032 int resolved_path_len, ret = 0;
1033 char *directory=NULL, resolved_path[MAXPATHLEN + 1];
1034 xmlParserInputBufferPtr inputbfr;
1035 xmlTextReaderPtr reader;
1036
1037 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
1038 RETURN_THROWS();
1039 }
1040
1041 id = getThis();
1042 if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry)) {
1043 id = NULL;
1044 }
1045 if (id != NULL) {
1046 intern = Z_XMLREADER_P(id);
1047 xmlreader_free_resources(intern);
1048 }
1049
1050 if (!source_len) {
1051 zend_argument_value_error(1, "cannot be empty");
1052 RETURN_THROWS();
1053 }
1054
1055 if (encoding && CHECK_NULL_PATH(encoding, encoding_len)) {
1056 php_error_docref(NULL, E_WARNING, "Encoding must not contain NUL bytes");
1057 RETURN_FALSE;
1058 }
1059
1060 inputbfr = xmlParserInputBufferCreateMem(source, source_len, XML_CHAR_ENCODING_NONE);
1061
1062 if (inputbfr != NULL) {
1063 /* Get the URI of the current script so that we can set the base directory in libxml */
1064 #ifdef HAVE_GETCWD
1065 directory = VCWD_GETCWD(resolved_path, MAXPATHLEN);
1066 #elif defined(HAVE_GETWD)
1067 directory = VCWD_GETWD(resolved_path);
1068 #endif
1069 if (directory) {
1070 resolved_path_len = strlen(resolved_path);
1071 if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) {
1072 resolved_path[resolved_path_len] = DEFAULT_SLASH;
1073 resolved_path[++resolved_path_len] = '\0';
1074 }
1075 uri = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
1076 }
1077 PHP_LIBXML_SANITIZE_GLOBALS(text_reader);
1078 reader = xmlNewTextReader(inputbfr, uri);
1079
1080 if (reader != NULL) {
1081 ret = xmlTextReaderSetup(reader, NULL, uri, encoding, options);
1082 if (ret == 0) {
1083 if (id == NULL) {
1084 object_init_ex(return_value, xmlreader_class_entry);
1085 intern = Z_XMLREADER_P(return_value);
1086 } else {
1087 RETVAL_TRUE;
1088 }
1089 intern->input = inputbfr;
1090 intern->ptr = reader;
1091
1092 if (uri) {
1093 xmlFree(uri);
1094 }
1095
1096 PHP_LIBXML_RESTORE_GLOBALS(text_reader);
1097 return;
1098 }
1099 }
1100 PHP_LIBXML_RESTORE_GLOBALS(text_reader);
1101 }
1102
1103 if (uri) {
1104 xmlFree(uri);
1105 }
1106
1107 if (inputbfr) {
1108 xmlFreeParserInputBuffer(inputbfr);
1109 }
1110 php_error_docref(NULL, E_WARNING, "Unable to load source data");
1111 RETURN_FALSE;
1112 }
1113 /* }}} */
1114
1115 /* {{{ Moves the position of the current instance to the next node in the stream. */
PHP_METHOD(XMLReader,expand)1116 PHP_METHOD(XMLReader, expand)
1117 {
1118 #ifdef HAVE_DOM
1119 zval *id, *basenode = NULL;
1120 int ret;
1121 xmlreader_object *intern;
1122 xmlNode *node, *nodec;
1123 xmlDocPtr docp = NULL;
1124 php_libxml_node_object *domobj = NULL;
1125
1126 id = ZEND_THIS;
1127 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &basenode, dom_node_class_entry) == FAILURE) {
1128 RETURN_THROWS();
1129 }
1130
1131 if (basenode != NULL) {
1132 NODE_GET_OBJ(node, basenode, xmlNodePtr, domobj);
1133 docp = node->doc;
1134 }
1135
1136 intern = Z_XMLREADER_P(id);
1137
1138 if (intern && intern->ptr) {
1139 node = xmlTextReaderExpand(intern->ptr);
1140
1141 if (node == NULL) {
1142 php_error_docref(NULL, E_WARNING, "An Error Occurred while expanding");
1143 RETURN_FALSE;
1144 } else {
1145 nodec = xmlDocCopyNode(node, docp, 1);
1146 if (nodec == NULL) {
1147 php_error_docref(NULL, E_NOTICE, "Cannot expand this node type");
1148 RETURN_FALSE;
1149 } else {
1150 DOM_RET_OBJ(nodec, &ret, (dom_object *)domobj);
1151 }
1152 }
1153 } else {
1154 zend_throw_error(NULL, "Data must be loaded before expanding");
1155 RETURN_THROWS();
1156 }
1157 #else
1158 zval *dummy;
1159 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|z!", &dummy) == FAILURE) {
1160 RETURN_THROWS();
1161 }
1162
1163 zend_throw_error(NULL, "XMLReader::expand() requires the DOM extension to be enabled");
1164 RETURN_THROWS();
1165 #endif
1166 }
1167 /* }}} */
1168
1169 /* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(xmlreader)1170 PHP_MINIT_FUNCTION(xmlreader)
1171 {
1172
1173 zend_class_entry ce;
1174
1175 memcpy(&xmlreader_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
1176 xmlreader_object_handlers.offset = XtOffsetOf(xmlreader_object, std);
1177 xmlreader_object_handlers.dtor_obj = zend_objects_destroy_object;
1178 xmlreader_object_handlers.free_obj = xmlreader_objects_free_storage;
1179 xmlreader_object_handlers.read_property = xmlreader_read_property;
1180 xmlreader_object_handlers.write_property = xmlreader_write_property;
1181 xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr;
1182 xmlreader_object_handlers.get_method = xmlreader_get_method;
1183 xmlreader_object_handlers.clone_obj = NULL;
1184
1185 INIT_CLASS_ENTRY(ce, "XMLReader", class_XMLReader_methods);
1186 ce.create_object = xmlreader_objects_new;
1187 xmlreader_class_entry = zend_register_internal_class(&ce);
1188
1189 memcpy(&xmlreader_open_fn, zend_hash_str_find_ptr(&xmlreader_class_entry->function_table, "open", sizeof("open")-1), sizeof(zend_internal_function));
1190 xmlreader_open_fn.fn_flags &= ~ZEND_ACC_STATIC;
1191 memcpy(&xmlreader_xml_fn, zend_hash_str_find_ptr(&xmlreader_class_entry->function_table, "xml", sizeof("xml")-1), sizeof(zend_internal_function));
1192 xmlreader_xml_fn.fn_flags &= ~ZEND_ACC_STATIC;
1193
1194 zend_hash_init(&xmlreader_prop_handlers, 0, NULL, php_xmlreader_free_prop_handler, 1);
1195 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG);
1196 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", NULL, xmlTextReaderConstBaseUri, IS_STRING);
1197 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "depth", xmlTextReaderDepth, NULL, IS_LONG);
1198 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasAttributes", xmlTextReaderHasAttributes, NULL, IS_FALSE);
1199 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasValue", xmlTextReaderHasValue, NULL, IS_FALSE);
1200 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isDefault", xmlTextReaderIsDefault, NULL, IS_FALSE);
1201 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isEmptyElement", xmlTextReaderIsEmptyElement, NULL, IS_FALSE);
1202 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "localName", NULL, xmlTextReaderConstLocalName, IS_STRING);
1203 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "name", NULL, xmlTextReaderConstName, IS_STRING);
1204 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "namespaceURI", NULL, xmlTextReaderConstNamespaceUri, IS_STRING);
1205 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "nodeType", xmlTextReaderNodeType, NULL, IS_LONG);
1206 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "prefix", NULL, xmlTextReaderConstPrefix, IS_STRING);
1207 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "value", NULL, xmlTextReaderConstValue, IS_STRING);
1208 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "xmlLang", NULL, xmlTextReaderConstXmlLang, IS_STRING);
1209
1210 /* Constants for NodeType - cannot define common types to share with dom as there are differences in these types */
1211
1212 REGISTER_XMLREADER_CLASS_CONST_LONG("NONE", XML_READER_TYPE_NONE);
1213 REGISTER_XMLREADER_CLASS_CONST_LONG("ELEMENT", XML_READER_TYPE_ELEMENT);
1214 REGISTER_XMLREADER_CLASS_CONST_LONG("ATTRIBUTE", XML_READER_TYPE_ATTRIBUTE);
1215 REGISTER_XMLREADER_CLASS_CONST_LONG("TEXT", XML_READER_TYPE_TEXT);
1216 REGISTER_XMLREADER_CLASS_CONST_LONG("CDATA", XML_READER_TYPE_CDATA);
1217 REGISTER_XMLREADER_CLASS_CONST_LONG("ENTITY_REF", XML_READER_TYPE_ENTITY_REFERENCE);
1218 REGISTER_XMLREADER_CLASS_CONST_LONG("ENTITY", XML_READER_TYPE_ENTITY);
1219 REGISTER_XMLREADER_CLASS_CONST_LONG("PI", XML_READER_TYPE_PROCESSING_INSTRUCTION);
1220 REGISTER_XMLREADER_CLASS_CONST_LONG("COMMENT", XML_READER_TYPE_COMMENT);
1221 REGISTER_XMLREADER_CLASS_CONST_LONG("DOC", XML_READER_TYPE_DOCUMENT);
1222 REGISTER_XMLREADER_CLASS_CONST_LONG("DOC_TYPE", XML_READER_TYPE_DOCUMENT_TYPE);
1223 REGISTER_XMLREADER_CLASS_CONST_LONG("DOC_FRAGMENT", XML_READER_TYPE_DOCUMENT_FRAGMENT);
1224 REGISTER_XMLREADER_CLASS_CONST_LONG("NOTATION", XML_READER_TYPE_NOTATION);
1225 REGISTER_XMLREADER_CLASS_CONST_LONG("WHITESPACE", XML_READER_TYPE_WHITESPACE);
1226 REGISTER_XMLREADER_CLASS_CONST_LONG("SIGNIFICANT_WHITESPACE", XML_READER_TYPE_SIGNIFICANT_WHITESPACE);
1227 REGISTER_XMLREADER_CLASS_CONST_LONG("END_ELEMENT", XML_READER_TYPE_END_ELEMENT);
1228 REGISTER_XMLREADER_CLASS_CONST_LONG("END_ENTITY", XML_READER_TYPE_END_ENTITY);
1229 REGISTER_XMLREADER_CLASS_CONST_LONG("XML_DECLARATION", XML_READER_TYPE_XML_DECLARATION);
1230
1231 /* Constants for Parser options */
1232 REGISTER_XMLREADER_CLASS_CONST_LONG("LOADDTD", XML_PARSER_LOADDTD);
1233 REGISTER_XMLREADER_CLASS_CONST_LONG("DEFAULTATTRS", XML_PARSER_DEFAULTATTRS);
1234 REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDATE", XML_PARSER_VALIDATE);
1235 REGISTER_XMLREADER_CLASS_CONST_LONG("SUBST_ENTITIES", XML_PARSER_SUBST_ENTITIES);
1236
1237 /* Constants for Errors when loading - not yet used until we implement custom error handling
1238 REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDITY_WARNING", XML_PARSER_SEVERITY_VALIDITY_WARNING, CONST_CS | CONST_PERSISTENT);
1239 REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDITY_ERROR", XML_PARSER_SEVERITY_VALIDITY_ERROR, CONST_CS | CONST_PERSISTENT);
1240 REGISTER_XMLREADER_CLASS_CONST_LONG("WARNING", XML_PARSER_SEVERITY_WARNING, CONST_CS | CONST_PERSISTENT);
1241 REGISTER_XMLREADER_CLASS_CONST_LONG("ERROR", XML_PARSER_SEVERITY_ERROR, CONST_CS | CONST_PERSISTENT);
1242 */
1243
1244 return SUCCESS;
1245 }
1246 /* }}} */
1247
1248 /* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(xmlreader)1249 PHP_MSHUTDOWN_FUNCTION(xmlreader)
1250 {
1251 zend_hash_destroy(&xmlreader_prop_handlers);
1252 return SUCCESS;
1253 }
1254 /* }}} */
1255
1256 /* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(xmlreader)1257 PHP_MINFO_FUNCTION(xmlreader)
1258 {
1259 php_info_print_table_start();
1260 {
1261 php_info_print_table_row(2, "XMLReader", "enabled");
1262 }
1263 php_info_print_table_end();
1264 }
1265 /* }}} */
1266