php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
xml.c
Go to the documentation of this file.
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 | https://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 | Authors: Stig Sæther Bakken <ssb@php.net> |
14 | Thies C. Arntzen <thies@thieso.net> |
15 | Sterling Hughes <sterling@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
22
23#include "php.h"
24
25#include "zend_variables.h"
26#include "zend_attributes.h"
27#include "ext/standard/info.h"
28#include "ext/standard/html.h" /* For php_next_utf8_char() */
29
30#ifdef HAVE_XML
31
32#include "php_xml.h"
33#ifdef LIBXML_EXPAT_COMPAT
35#endif
36
37#include "xml_arginfo.h"
38
39/* Short-term TODO list:
40 * - Implement XML_ExternalEntityParserCreate()
41 * - XML_SetCommentHandler
42 * - XML_SetCdataSectionHandler
43 * - XML_SetParamEntityParsing
44 */
45
46/* Long-term TODO list:
47 * - Fix the expat library so you can install your own memory manager
48 * functions
49 */
50
51/* Known bugs:
52 * - Weird things happen with <![CDATA[]]> sections.
53 */
54
56 XML_Char *default_encoding;
58
60
61#define XML(v) ZEND_MODULE_GLOBALS_ACCESSOR(xml, v)
62
63typedef struct {
64 XML_Parser parser;
65 XML_Char *target_encoding;
66
67 /* Reference to the object itself, for convenience.
68 * It is not owned, do not release it. */
69 zval index;
70
72 zend_fcall_info_cache startElementHandler;
73 zend_fcall_info_cache endElementHandler;
74 zend_fcall_info_cache characterDataHandler;
75 zend_fcall_info_cache processingInstructionHandler;
76 zend_fcall_info_cache defaultHandler;
77 zend_fcall_info_cache unparsedEntityDeclHandler;
78 zend_fcall_info_cache notationDeclHandler;
79 zend_fcall_info_cache externalEntityRefHandler;
80 zend_fcall_info_cache startNamespaceDeclHandler;
81 zend_fcall_info_cache endNamespaceDeclHandler;
82 zval data;
83 zval info;
84
85 int level;
86 int toffset;
87 int curtag;
88 zend_long ctag_index;
89 char **ltags;
90 bool lastwasopen;
91 bool skipwhite;
92 bool isparsing;
93 bool parsehuge;
94 bool case_folding;
95
96 XML_Char *baseURI;
97
98 zend_object std;
99} xml_parser;
100
101
102typedef struct {
103 XML_Char *name;
104 char (*decoding_function)(unsigned short);
105 unsigned short (*encoding_function)(unsigned char);
106} xml_encoding;
107
108/* {{{ dynamically loadable module stuff */
109#ifdef COMPILE_DL_XML
110#ifdef ZTS
112#endif
114#endif /* COMPILE_DL_XML */
115/* }}} */
116
117#define XML_MAXLEVEL 255 /* XXX this should be dynamic */
118
119#define SKIP_TAGSTART(str) ((str) + (parser->toffset > strlen(str) ? strlen(str) : parser->toffset))
120
121static zend_class_entry *xml_parser_ce;
122static zend_object_handlers xml_parser_object_handlers;
123
124/* {{{ function prototypes */
127static PHP_GINIT_FUNCTION(xml);
128
129static zend_object *xml_parser_create_object(zend_class_entry *class_type);
130static void xml_parser_free_obj(zend_object *object);
131static HashTable *xml_parser_get_gc(zend_object *object, zval **table, int *n);
132static zend_function *xml_parser_get_constructor(zend_object *object);
133
134static zend_string *xml_utf8_decode(const XML_Char *, size_t, const XML_Char *);
135inline static unsigned short xml_encode_iso_8859_1(unsigned char);
136inline static char xml_decode_iso_8859_1(unsigned short);
137inline static unsigned short xml_encode_us_ascii(unsigned char);
138inline static char xml_decode_us_ascii(unsigned short);
139static void xml_xmlchar_zval(const XML_Char *, int, const XML_Char *, zval *);
140static int xml_xmlcharlen(const XML_Char *);
141static void xml_add_to_info(xml_parser *parser, const char *name);
142inline static zend_string *xml_decode_tag(xml_parser *parser, const XML_Char *tag);
143
144void xml_startElementHandler(void *, const XML_Char *, const XML_Char **);
145void xml_endElementHandler(void *, const XML_Char *);
146void xml_characterDataHandler(void *, const XML_Char *, int);
147void xml_processingInstructionHandler(void *, const XML_Char *, const XML_Char *);
148void xml_defaultHandler(void *, const XML_Char *, int);
149void xml_unparsedEntityDeclHandler(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
150void xml_notationDeclHandler(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
151int xml_externalEntityRefHandler(XML_Parser, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
152
153void xml_startNamespaceDeclHandler(void *, const XML_Char *, const XML_Char *);
154void xml_endNamespaceDeclHandler(void *, const XML_Char *);
155/* }}} */
156
157#ifdef LIBXML_EXPAT_COMPAT
158static const zend_module_dep xml_deps[] = {
159 ZEND_MOD_REQUIRED("libxml")
161};
162#endif
163
164zend_module_entry xml_module_entry = {
165#ifdef LIBXML_EXPAT_COMPAT
167 xml_deps,
168#else
170#endif
171 "xml", /* extension name */
172 ext_functions, /* extension function list */
173 PHP_MINIT(xml), /* extension-wide startup function */
174 NULL, /* extension-wide shutdown function */
175 NULL, /* per-request startup function */
176 NULL, /* per-request shutdown function */
177 PHP_MINFO(xml), /* information function */
178 PHP_XML_VERSION,
179 PHP_MODULE_GLOBALS(xml), /* globals descriptor */
180 PHP_GINIT(xml), /* globals ctor */
181 NULL, /* globals dtor */
182 NULL, /* post deactivate */
184};
185
186/* All the encoding functions are set to NULL right now, since all
187 * the encoding is currently done internally by expat/xmltok.
188 */
189static const xml_encoding xml_encodings[] = {
190 { (XML_Char *)"ISO-8859-1", xml_decode_iso_8859_1, xml_encode_iso_8859_1 },
191 { (XML_Char *)"US-ASCII", xml_decode_us_ascii, xml_encode_us_ascii },
192 { (XML_Char *)"UTF-8", NULL, NULL },
193 { (XML_Char *)NULL, NULL, NULL }
194};
195
196static XML_Memory_Handling_Suite php_xml_mem_hdlrs;
197
198/* }}} */
199
200/* {{{ startup, shutdown and info functions */
202{
203#if defined(COMPILE_DL_XML) && defined(ZTS)
205#endif
206 xml_globals->default_encoding = (XML_Char*)"UTF-8";
207}
208
209static void *php_xml_malloc_wrapper(size_t sz)
210{
211 return emalloc(sz);
212}
213
214static void *php_xml_realloc_wrapper(void *ptr, size_t sz)
215{
216 return erealloc(ptr, sz);
217}
218
219static void php_xml_free_wrapper(void *ptr)
220{
221 if (ptr != NULL) {
222 efree(ptr);
223 }
224}
225
227{
228 xml_parser_ce = register_class_XMLParser();
229 xml_parser_ce->create_object = xml_parser_create_object;
230 xml_parser_ce->default_object_handlers = &xml_parser_object_handlers;
231
232 memcpy(&xml_parser_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
233 xml_parser_object_handlers.offset = XtOffsetOf(xml_parser, std);
234 xml_parser_object_handlers.free_obj = xml_parser_free_obj;
235 xml_parser_object_handlers.get_gc = xml_parser_get_gc;
236 xml_parser_object_handlers.get_constructor = xml_parser_get_constructor;
237 xml_parser_object_handlers.clone_obj = NULL;
238 xml_parser_object_handlers.compare = zend_objects_not_comparable;
239
240 register_xml_symbols(module_number);
241
242 /* this object should not be pre-initialised at compile time,
243 as the order of members may vary */
244
245 php_xml_mem_hdlrs.malloc_fcn = php_xml_malloc_wrapper;
246 php_xml_mem_hdlrs.realloc_fcn = php_xml_realloc_wrapper;
247 php_xml_mem_hdlrs.free_fcn = php_xml_free_wrapper;
248
249 return SUCCESS;
250}
251
253{
255 php_info_print_table_row(2, "XML Support", "active");
256 php_info_print_table_row(2, "XML Namespace Support", "active");
257#if defined(LIBXML_DOTTED_VERSION) && defined(LIBXML_EXPAT_COMPAT)
258 php_info_print_table_row(2, "libxml2 Version", LIBXML_DOTTED_VERSION);
259#else
260 php_info_print_table_row(2, "EXPAT Version", XML_ExpatVersion());
261#endif
263}
264/* }}} */
265
266/* {{{ extension-internal functions */
267
268static int xml_parse_helper(xml_parser *parser, const char *data, size_t data_len, bool is_final)
269{
270 ZEND_ASSERT(!parser->isparsing);
271
272 /* libxml2 specific options */
273#ifdef LIBXML_EXPAT_COMPAT
274 /* TODO: In libxml2 2.14.0 change this to the new options API so we don't rely on deprecated APIs. */
275 ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations")
276 /* See xmlInitSAXParserCtxt() and xmlCtxtUseOptions() */
277 if (parser->parsehuge) {
278 parser->parser->parser->options |= XML_PARSE_HUGE;
279 xmlDictSetLimit(parser->parser->parser->dict, 0);
280 } else {
281 parser->parser->parser->options &= ~XML_PARSE_HUGE;
282 xmlDictSetLimit(parser->parser->parser->dict, XML_MAX_DICTIONARY_LIMIT);
283 }
285#endif
286
287 parser->isparsing = 1;
288 int ret = XML_Parse(parser->parser, (const XML_Char *) data, data_len, is_final);
289 parser->isparsing = 0;
290 return ret;
291}
292
293static void xml_xmlchar_zval(const XML_Char *s, int len, const XML_Char *encoding, zval *ret)
294{
295 if (s == NULL) {
297 return;
298 }
299 if (len == 0) {
300 len = xml_xmlcharlen(s);
301 }
302 ZVAL_STR(ret, xml_utf8_decode(s, len, encoding));
303}
304/* }}} */
305
306static inline xml_parser *xml_parser_from_obj(zend_object *obj) {
307 return (xml_parser *)((char *)(obj) - XtOffsetOf(xml_parser, std));
308}
309
310#define Z_XMLPARSER_P(zv) xml_parser_from_obj(Z_OBJ_P(zv))
311
312static zend_object *xml_parser_create_object(zend_class_entry *class_type) {
313 xml_parser *intern = zend_object_alloc(sizeof(xml_parser), class_type);
314 memset(intern, 0, sizeof(xml_parser) - sizeof(zend_object));
315
316 zend_object_std_init(&intern->std, class_type);
317 object_properties_init(&intern->std, class_type);
318
319 return &intern->std;
320}
321
322static void xml_parser_free_ltags(xml_parser *parser)
323{
324 if (parser->ltags) {
325 int inx;
326 for (inx = 0; ((inx < parser->level) && (inx < XML_MAXLEVEL)); inx++)
327 efree(parser->ltags[ inx ]);
328 efree(parser->ltags);
329 }
330}
331
332static void xml_parser_free_obj(zend_object *object)
333{
334 xml_parser *parser = xml_parser_from_obj(object);
335
336 zval_ptr_dtor(&parser->info);
337 zval_ptr_dtor(&parser->data);
338 if (parser->parser) {
339 XML_ParserFree(parser->parser);
340 }
341 xml_parser_free_ltags(parser);
342 if (ZEND_FCC_INITIALIZED(parser->startElementHandler)) {
343 zend_fcc_dtor(&parser->startElementHandler);
344 parser->startElementHandler.function_handler = NULL;
345 }
346 if (ZEND_FCC_INITIALIZED(parser->endElementHandler)) {
347 zend_fcc_dtor(&parser->endElementHandler);
348 parser->endElementHandler.function_handler = NULL;
349 }
350 if (ZEND_FCC_INITIALIZED(parser->characterDataHandler)) {
351 zend_fcc_dtor(&parser->characterDataHandler);
352 parser->characterDataHandler.function_handler = NULL;
353 }
354 if (ZEND_FCC_INITIALIZED(parser->processingInstructionHandler)) {
355 zend_fcc_dtor(&parser->processingInstructionHandler);
356 parser->processingInstructionHandler.function_handler = NULL;
357 }
358 if (ZEND_FCC_INITIALIZED(parser->defaultHandler)) {
359 zend_fcc_dtor(&parser->defaultHandler);
360 parser->defaultHandler.function_handler = NULL;
361 }
362 if (ZEND_FCC_INITIALIZED(parser->unparsedEntityDeclHandler)) {
363 zend_fcc_dtor(&parser->unparsedEntityDeclHandler);
364 parser->unparsedEntityDeclHandler.function_handler = NULL;
365 }
366 if (ZEND_FCC_INITIALIZED(parser->notationDeclHandler)) {
367 zend_fcc_dtor(&parser->notationDeclHandler);
368 parser->notationDeclHandler.function_handler = NULL;
369 }
370 if (ZEND_FCC_INITIALIZED(parser->externalEntityRefHandler)) {
371 zend_fcc_dtor(&parser->externalEntityRefHandler);
372 parser->externalEntityRefHandler.function_handler = NULL;
373 }
374 if (ZEND_FCC_INITIALIZED(parser->startNamespaceDeclHandler)) {
375 zend_fcc_dtor(&parser->startNamespaceDeclHandler);
376 parser->startNamespaceDeclHandler.function_handler = NULL;
377 }
378 if (ZEND_FCC_INITIALIZED(parser->endNamespaceDeclHandler)) {
379 zend_fcc_dtor(&parser->endNamespaceDeclHandler);
380 parser->endNamespaceDeclHandler.function_handler = NULL;
381 }
382 if (parser->baseURI) {
383 efree(parser->baseURI);
384 }
385 if (parser->object) {
386 OBJ_RELEASE(parser->object);
387 }
388
389 zend_object_std_dtor(&parser->std);
390}
391
392static HashTable *xml_parser_get_gc(zend_object *object, zval **table, int *n)
393{
394 xml_parser *parser = xml_parser_from_obj(object);
395
397 if (parser->object) {
398 zend_get_gc_buffer_add_obj(gc_buffer, parser->object);
399 }
400 if (ZEND_FCC_INITIALIZED(parser->startElementHandler)) {
401 zend_get_gc_buffer_add_fcc(gc_buffer, &parser->startElementHandler);
402 }
403 if (ZEND_FCC_INITIALIZED(parser->endElementHandler)) {
404 zend_get_gc_buffer_add_fcc(gc_buffer, &parser->endElementHandler);
405 }
406 if (ZEND_FCC_INITIALIZED(parser->characterDataHandler)) {
407 zend_get_gc_buffer_add_fcc(gc_buffer, &parser->characterDataHandler);
408 }
409 if (ZEND_FCC_INITIALIZED(parser->processingInstructionHandler)) {
410 zend_get_gc_buffer_add_fcc(gc_buffer, &parser->processingInstructionHandler);
411 }
412 if (ZEND_FCC_INITIALIZED(parser->defaultHandler)) {
413 zend_get_gc_buffer_add_fcc(gc_buffer, &parser->defaultHandler);
414 }
415 if (ZEND_FCC_INITIALIZED(parser->unparsedEntityDeclHandler)) {
416 zend_get_gc_buffer_add_fcc(gc_buffer, &parser->unparsedEntityDeclHandler);
417 }
418 if (ZEND_FCC_INITIALIZED(parser->notationDeclHandler)) {
419 zend_get_gc_buffer_add_fcc(gc_buffer, &parser->notationDeclHandler);
420 }
421 if (ZEND_FCC_INITIALIZED(parser->externalEntityRefHandler)) {
422 zend_get_gc_buffer_add_fcc(gc_buffer, &parser->externalEntityRefHandler);
423 }
424 if (ZEND_FCC_INITIALIZED(parser->startNamespaceDeclHandler)) {
425 zend_get_gc_buffer_add_fcc(gc_buffer, &parser->startNamespaceDeclHandler);
426 }
427 if (ZEND_FCC_INITIALIZED(parser->endNamespaceDeclHandler)) {
428 zend_get_gc_buffer_add_fcc(gc_buffer, &parser->endNamespaceDeclHandler);
429 }
430 zend_get_gc_buffer_add_zval(gc_buffer, &parser->data);
431 zend_get_gc_buffer_add_zval(gc_buffer, &parser->info);
432
433 zend_get_gc_buffer_use(gc_buffer, table, n);
434
435 return zend_std_get_properties(object);
436}
437
438static zend_function *xml_parser_get_constructor(zend_object *object) {
439 zend_throw_error(NULL, "Cannot directly construct XMLParser, use xml_parser_create() or xml_parser_create_ns() instead");
440 return NULL;
441}
442
443/* This is always called to simplify the mess to deal with BC breaks, but only set a new handler if it is initialized */
444static void xml_set_handler(zend_fcall_info_cache *const parser_handler, const zend_fcall_info_cache *const fn)
445{
446 /* If we have already a handler, release it */
447 if (ZEND_FCC_INITIALIZED(*parser_handler)) {
448 zend_fcc_dtor(parser_handler);
449 parser_handler->function_handler = NULL;
450 }
451
452 if (ZEND_FCC_INITIALIZED(*fn)) {
453 zend_fcc_dup(parser_handler, fn);
454 }
455}
456
457/* {{{ xml_encode_iso_8859_1() */
458inline static unsigned short xml_encode_iso_8859_1(unsigned char c)
459{
460 return (unsigned short)c;
461}
462/* }}} */
463
464/* {{{ xml_decode_iso_8859_1() */
465inline static char xml_decode_iso_8859_1(unsigned short c)
466{
467 return (char)(c > 0xff ? '?' : c);
468}
469/* }}} */
470
471/* {{{ xml_encode_us_ascii() */
472inline static unsigned short xml_encode_us_ascii(unsigned char c)
473{
474 return (unsigned short)c;
475}
476/* }}} */
477
478/* {{{ xml_decode_us_ascii() */
479inline static char xml_decode_us_ascii(unsigned short c)
480{
481 return (char)(c > 0x7f ? '?' : c);
482}
483/* }}} */
484
485/* {{{ xml_get_encoding() */
486static const xml_encoding *xml_get_encoding(const XML_Char *name)
487{
488 const xml_encoding *enc = &xml_encodings[0];
489
490 while (enc && enc->name) {
491 if (strcasecmp((char *)name, (char *)enc->name) == 0) {
492 return enc;
493 }
494 enc++;
495 }
496 return NULL;
497}
498/* }}} */
499
500/* {{{ xml_utf8_decode() */
501static zend_string *xml_utf8_decode(const XML_Char *s, size_t len, const XML_Char *encoding)
502{
503 size_t pos = 0;
504 unsigned int c;
505 char (*decoder)(unsigned short) = NULL;
506 const xml_encoding *enc = xml_get_encoding(encoding);
507 zend_string *str;
508
509 if (enc) {
510 decoder = enc->decoding_function;
511 }
512
513 if (decoder == NULL) {
514 /* If the target encoding was unknown, or no decoder function
515 * was specified, return the UTF-8-encoded data as-is.
516 */
517 str = zend_string_init((char *)s, len, 0);
518 return str;
519 }
520
521 str = zend_string_alloc(len, 0);
522 ZSTR_LEN(str) = 0;
523 while (pos < len) {
525 c = php_next_utf8_char((const unsigned char*)s, len, &pos, &status);
526
527 if (status == FAILURE || c > 0xFFU) {
528 c = '?';
529 }
530
531 ZSTR_VAL(str)[ZSTR_LEN(str)++] = decoder(c);
532 }
533 ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0';
534 if (ZSTR_LEN(str) < len) {
535 str = zend_string_truncate(str, ZSTR_LEN(str), 0);
536 }
537
538 return str;
539}
540/* }}} */
541
542/* {{{ xml_xmlcharlen() */
543static int xml_xmlcharlen(const XML_Char *s)
544{
545 int len = 0;
546
547 while (*s) {
548 len++;
549 s++;
550 }
551 return len;
552}
553/* }}} */
554
555/* {{{ xml_add_to_info() */
556static void xml_add_to_info(xml_parser *parser, const char *name)
557{
558 zval *element;
559
560 if (Z_ISUNDEF(parser->info) || UNEXPECTED(Z_TYPE_P(Z_REFVAL(parser->info)) != IS_ARRAY)) {
561 return;
562 }
563
564 SEPARATE_ARRAY(Z_REFVAL(parser->info));
565 zend_array *arr = Z_ARRVAL_P(Z_REFVAL(parser->info));
566
567 size_t name_len = strlen(name);
568 if ((element = zend_hash_str_find(arr, name, name_len)) == NULL) {
569 zval values;
570 array_init(&values);
571 element = zend_hash_str_update(arr, name, name_len, &values);
572 }
573
574 add_next_index_long(element, parser->curtag);
575
576 parser->curtag++;
577}
578/* }}} */
579
580/* {{{ xml_decode_tag() */
581static zend_string *xml_decode_tag(xml_parser *parser, const XML_Char *tag)
582{
583 zend_string *str;
584
585 str = xml_utf8_decode(tag, xml_xmlcharlen(tag), parser->target_encoding);
586
587 if (parser->case_folding) {
589 }
590
591 return str;
592}
593/* }}} */
594
595static zval *xml_get_separated_data(xml_parser *parser)
596{
597 if (EXPECTED(Z_TYPE_P(Z_REFVAL(parser->data)) == IS_ARRAY)) {
598 SEPARATE_ARRAY(Z_REFVAL(parser->data));
599 return Z_REFVAL(parser->data);
600 }
601 return NULL;
602}
603
604static zval *xml_get_ctag(xml_parser *parser)
605{
606 zval *data = xml_get_separated_data(parser);
607 if (EXPECTED(data)) {
608 zval *zv = zend_hash_index_find_deref(Z_ARRVAL_P(data), parser->ctag_index);
609 if (EXPECTED(zv && Z_TYPE_P(zv) == IS_ARRAY)) {
611 return zv;
612 }
613 }
614 return NULL;
615}
616
617/* {{{ xml_startElementHandler() */
618void xml_startElementHandler(void *userData, const XML_Char *name, const XML_Char **attributes)
619{
620 xml_parser *parser = (xml_parser *)userData;
621 const char **attrs = (const char **) attributes;
622 zend_string *att, *tag_name, *val;
623
624 if (!parser) {
625 return;
626 }
627
628 parser->level++;
629
630 tag_name = xml_decode_tag(parser, name);
631
632 if (ZEND_FCC_INITIALIZED(parser->startElementHandler)) {
633 zval args[3];
634 ZVAL_COPY(&args[0], &parser->index);
635 ZVAL_STRING(&args[1], SKIP_TAGSTART(ZSTR_VAL(tag_name)));
636 array_init(&args[2]);
637
638 while (attributes && *attributes) {
639 zval tmp;
640
641 att = xml_decode_tag(parser, attributes[0]);
642 val = xml_utf8_decode(attributes[1], strlen((char *)attributes[1]), parser->target_encoding);
643
644 ZVAL_STR(&tmp, val);
645 zend_symtable_update(Z_ARRVAL(args[2]), att, &tmp);
646
647 attributes += 2;
648
650 }
651
652 zend_call_known_fcc(&parser->startElementHandler, /* retval */ NULL, /* param_count */ 3, args, /* named_params */ NULL);
653 zval_ptr_dtor(&args[0]);
654 zval_ptr_dtor(&args[1]);
655 zval_ptr_dtor(&args[2]);
656 }
657
658 if (!Z_ISUNDEF(parser->data) && !EG(exception)) {
659 if (parser->level <= XML_MAXLEVEL) {
660 zval tag, atr;
661 int atcnt = 0;
662
663 array_init(&tag);
664 array_init(&atr);
665
666 char *skipped_tag_name = SKIP_TAGSTART(ZSTR_VAL(tag_name));
667
668 xml_add_to_info(parser, skipped_tag_name);
669
670 add_assoc_string(&tag, "tag", skipped_tag_name);
671 add_assoc_string(&tag, "type", "open");
672 add_assoc_long(&tag, "level", parser->level);
673
674 parser->ltags[parser->level-1] = estrdup(ZSTR_VAL(tag_name));
675 parser->lastwasopen = 1;
676
677 attributes = (const XML_Char **) attrs;
678
679 while (attributes && *attributes) {
680 zval tmp;
681
682 att = xml_decode_tag(parser, attributes[0]);
683 val = xml_utf8_decode(attributes[1], strlen((char *)attributes[1]), parser->target_encoding);
684
685 ZVAL_STR(&tmp, val);
686 zend_symtable_update(Z_ARRVAL(atr), att, &tmp);
687
688 atcnt++;
689 attributes += 2;
690
692 }
693
694 if (atcnt) {
695 zend_hash_str_add(Z_ARRVAL(tag), "attributes", sizeof("attributes") - 1, &atr);
696 } else {
697 zval_ptr_dtor(&atr);
698 }
699
700 zval *data = xml_get_separated_data(parser);
701 if (EXPECTED(data)) {
702 /* Note: due to array resizes or user interference,
703 * we have to store an index instead of a zval into the array's memory. */
704 zend_array *arr = Z_ARRVAL_P(data);
705 if (EXPECTED(zend_hash_next_index_insert(arr, &tag))) {
706 parser->ctag_index = arr->nNextFreeElement - 1;
707 } else {
708 zval_ptr_dtor(&tag);
709 }
710 } else {
711 zval_ptr_dtor(&tag);
712 }
713 } else if (parser->level == (XML_MAXLEVEL + 1)) {
714 php_error_docref(NULL, E_WARNING, "Maximum depth exceeded - Results truncated");
715 }
716 }
717
718 zend_string_release_ex(tag_name, 0);
719}
720/* }}} */
721
722/* {{{ xml_endElementHandler() */
723void xml_endElementHandler(void *userData, const XML_Char *name)
724{
725 xml_parser *parser = (xml_parser *)userData;
726
727 if (!parser) {
728 return;
729 }
730
731 zend_string *tag_name = xml_decode_tag(parser, name);
732
733 if (ZEND_FCC_INITIALIZED(parser->endElementHandler)) {
734 zval args[2];
735 ZVAL_COPY(&args[0], &parser->index);
736 ZVAL_STRING(&args[1], SKIP_TAGSTART(ZSTR_VAL(tag_name)));
737
738 zend_call_known_fcc(&parser->endElementHandler, /* retval */ NULL, /* param_count */ 2, args, /* named_params */ NULL);
739 zval_ptr_dtor(&args[0]);
740 zval_ptr_dtor(&args[1]);
741 }
742
743 if (!Z_ISUNDEF(parser->data) && !EG(exception)) {
744 zval tag;
745
746 if (parser->lastwasopen) {
747 zval *zv = xml_get_ctag(parser);
748 if (EXPECTED(zv)) {
749 add_assoc_string(zv, "type", "complete");
750 }
751 } else {
752 char *skipped_tag_name = SKIP_TAGSTART(ZSTR_VAL(tag_name));
753
754 xml_add_to_info(parser, skipped_tag_name);
755
756 zval *data = xml_get_separated_data(parser);
757 if (EXPECTED(data)) {
758 array_init(&tag);
759 add_assoc_string(&tag, "tag", skipped_tag_name);
760 add_assoc_string(&tag, "type", "close");
761 add_assoc_long(&tag, "level", parser->level);
763 }
764 }
765
766 parser->lastwasopen = 0;
767 }
768
769 zend_string_release_ex(tag_name, 0);
770
771 if ((parser->ltags) && (parser->level <= XML_MAXLEVEL)) {
772 efree(parser->ltags[parser->level-1]);
773 }
774
775 parser->level--;
776}
777/* }}} */
778
779/* {{{ xml_characterDataHandler() */
780void xml_characterDataHandler(void *userData, const XML_Char *s, int len)
781{
782 xml_parser *parser = (xml_parser *)userData;
783
784 if (!parser) {
785 return;
786 }
787
788 if (ZEND_FCC_INITIALIZED(parser->characterDataHandler)) {
789 zval args[2];
790 ZVAL_COPY(&args[0], &parser->index);
791 xml_xmlchar_zval(s, len, parser->target_encoding, &args[1]);
792
793 zend_call_known_fcc(&parser->characterDataHandler, /* retval */ NULL, /* param_count */ 2, args, /* named_params */ NULL);
794 zval_ptr_dtor(&args[0]);
795 zval_ptr_dtor(&args[1]);
796 }
797
798 if (Z_ISUNDEF(parser->data) || EG(exception)) {
799 return;
800 }
801
802 bool doprint = 0;
803 zend_string *decoded_value;
804 decoded_value = xml_utf8_decode(s, len, parser->target_encoding);
805 if (parser->skipwhite) {
806 for (size_t i = 0; i < ZSTR_LEN(decoded_value); i++) {
807 switch (ZSTR_VAL(decoded_value)[i]) {
808 case ' ':
809 case '\t':
810 case '\n':
811 continue;
812 default:
813 doprint = 1;
814 break;
815 }
816 if (doprint) {
817 break;
818 }
819 }
820 }
821 if (parser->lastwasopen) {
822 zval *ctag = xml_get_ctag(parser);
823 if (UNEXPECTED(!ctag)) {
824 zend_string_release_ex(decoded_value, false);
825 return;
826 }
827
828 zval *myval;
829 /* check if the current tag already has a value - if yes append to that! */
830 if ((myval = zend_hash_find(Z_ARRVAL_P(ctag), ZSTR_KNOWN(ZEND_STR_VALUE))) && Z_TYPE_P(myval) == IS_STRING) {
831 size_t newlen = Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value);
832 Z_STR_P(myval) = zend_string_extend(Z_STR_P(myval), newlen, 0);
833 strncpy(Z_STRVAL_P(myval) + Z_STRLEN_P(myval) - ZSTR_LEN(decoded_value),
834 ZSTR_VAL(decoded_value), ZSTR_LEN(decoded_value) + 1);
835 zend_string_release_ex(decoded_value, 0);
836 } else {
837 if (doprint || (! parser->skipwhite)) {
838 add_assoc_str(ctag, "value", decoded_value);
839 } else {
840 zend_string_release_ex(decoded_value, 0);
841 }
842 }
843 } else {
844 zval tag;
845 zval *curtag, *mytype, *myval;
846
847 zval *data = xml_get_separated_data(parser);
848 if (UNEXPECTED(!data)) {
849 zend_string_release_ex(decoded_value, false);
850 return;
851 }
852
854 if (EXPECTED(Z_TYPE_P(curtag) == IS_ARRAY) && (mytype = zend_hash_str_find(Z_ARRVAL_P(curtag),"type", sizeof("type") - 1))) {
855 if (EXPECTED(Z_TYPE_P(mytype) == IS_STRING) && zend_string_equals_literal(Z_STR_P(mytype), "cdata")) {
856 SEPARATE_ARRAY(curtag);
857 if ((myval = zend_hash_find(Z_ARRVAL_P(curtag), ZSTR_KNOWN(ZEND_STR_VALUE)))) {
858 size_t newlen = Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value);
859 Z_STR_P(myval) = zend_string_extend(Z_STR_P(myval), newlen, 0);
860 strncpy(Z_STRVAL_P(myval) + Z_STRLEN_P(myval) - ZSTR_LEN(decoded_value),
861 ZSTR_VAL(decoded_value), ZSTR_LEN(decoded_value) + 1);
862 zend_string_release_ex(decoded_value, 0);
863 return;
864 }
865 }
866 }
867 break;
869 if (parser->level <= XML_MAXLEVEL && parser->level > 0 && (doprint || (! parser->skipwhite))) {
870 array_init(&tag);
871 xml_add_to_info(parser,SKIP_TAGSTART(parser->ltags[parser->level-1]));
872 add_assoc_string(&tag, "tag", SKIP_TAGSTART(parser->ltags[parser->level-1]));
873 add_assoc_str(&tag, "value", decoded_value);
874 add_assoc_string(&tag, "type", "cdata");
875 add_assoc_long(&tag, "level", parser->level);
877 } else if (parser->level == (XML_MAXLEVEL + 1)) {
878 php_error_docref(NULL, E_WARNING, "Maximum depth exceeded - Results truncated");
879 } else {
880 zend_string_release_ex(decoded_value, 0);
881 }
882 }
883}
884/* }}} */
885
886/* {{{ xml_processingInstructionHandler() */
887void xml_processingInstructionHandler(void *userData, const XML_Char *target, const XML_Char *data)
888{
889 xml_parser *parser = (xml_parser *)userData;
890
891 if (!parser || !ZEND_FCC_INITIALIZED(parser->processingInstructionHandler)) {
892 return;
893 }
894
895 zval args[3];
896
897 ZVAL_COPY(&args[0], &parser->index);
898 xml_xmlchar_zval(target, 0, parser->target_encoding, &args[1]);
899 xml_xmlchar_zval(data, 0, parser->target_encoding, &args[2]);
900
901 zend_call_known_fcc(&parser->processingInstructionHandler, /* retval */ NULL, /* param_count */ 3, args, /* named_params */ NULL);
902 zval_ptr_dtor(&args[0]);
903 zval_ptr_dtor(&args[1]);
904 zval_ptr_dtor(&args[2]);
905}
906/* }}} */
907
908/* {{{ xml_defaultHandler() */
909void xml_defaultHandler(void *userData, const XML_Char *s, int len)
910{
911 xml_parser *parser = (xml_parser *)userData;
912
913 if (!parser || !ZEND_FCC_INITIALIZED(parser->defaultHandler)) {
914 return;
915 }
916
917 zval args[2];
918
919 ZVAL_COPY(&args[0], &parser->index);
920 xml_xmlchar_zval(s, len, parser->target_encoding, &args[1]);
921
922 zend_call_known_fcc(&parser->defaultHandler, /* retval */ NULL, /* param_count */ 2, args, /* named_params */ NULL);
923 zval_ptr_dtor(&args[0]);
924 zval_ptr_dtor(&args[1]);
925}
926/* }}} */
927
928/* {{{ xml_unparsedEntityDeclHandler() */
929void xml_unparsedEntityDeclHandler(void *userData,
930 const XML_Char *entityName, const XML_Char *base, const XML_Char *systemId,
931 const XML_Char *publicId, const XML_Char *notationName)
932{
933 xml_parser *parser = (xml_parser *)userData;
934
935 if (!parser || !ZEND_FCC_INITIALIZED(parser->unparsedEntityDeclHandler)) {
936 return;
937 }
938
939 zval args[6];
940
941 ZVAL_COPY(&args[0], &parser->index);
942 xml_xmlchar_zval(entityName, 0, parser->target_encoding, &args[1]);
943 xml_xmlchar_zval(base, 0, parser->target_encoding, &args[2]);
944 xml_xmlchar_zval(systemId, 0, parser->target_encoding, &args[3]);
945 xml_xmlchar_zval(publicId, 0, parser->target_encoding, &args[4]);
946 xml_xmlchar_zval(notationName, 0, parser->target_encoding, &args[5]);
947
948 zend_call_known_fcc(&parser->unparsedEntityDeclHandler, /* retval */ NULL, /* param_count */ 6, args, /* named_params */ NULL);
949 zval_ptr_dtor(&args[0]);
950 zval_ptr_dtor(&args[1]);
951 zval_ptr_dtor(&args[2]);
952 zval_ptr_dtor(&args[3]);
953 zval_ptr_dtor(&args[4]);
954 zval_ptr_dtor(&args[5]);
955}
956/* }}} */
957
958/* {{{ xml_notationDeclHandler() */
959void xml_notationDeclHandler(void *userData, const XML_Char *notationName,
960 const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId)
961{
962 xml_parser *parser = (xml_parser *)userData;
963
964 if (!parser || !ZEND_FCC_INITIALIZED(parser->notationDeclHandler)) {
965 return;
966 }
967
968 zval args[5];
969
970 ZVAL_COPY(&args[0], &parser->index);
971 xml_xmlchar_zval(notationName, 0, parser->target_encoding, &args[1]);
972 xml_xmlchar_zval(base, 0, parser->target_encoding, &args[2]);
973 xml_xmlchar_zval(systemId, 0, parser->target_encoding, &args[3]);
974 xml_xmlchar_zval(publicId, 0, parser->target_encoding, &args[4]);
975
976 zend_call_known_fcc(&parser->notationDeclHandler, /* retval */ NULL, /* param_count */ 5, args, /* named_params */ NULL);
977 zval_ptr_dtor(&args[0]);
978 zval_ptr_dtor(&args[1]);
979 zval_ptr_dtor(&args[2]);
980 zval_ptr_dtor(&args[3]);
981 zval_ptr_dtor(&args[4]);
982}
983/* }}} */
984
985/* {{{ xml_externalEntityRefHandler() */
986int xml_externalEntityRefHandler(XML_Parser userData, const XML_Char *openEntityNames,
987 const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId)
988{
989 xml_parser *parser = XML_GetUserData(userData);
990
991 if (!parser || !ZEND_FCC_INITIALIZED(parser->externalEntityRefHandler)) {
992 return 0;
993 }
994
995 int ret = 0; /* abort if no handler is set (should be configurable?) */
996 zval args[5];
997 zval retval;
998
999 ZVAL_COPY(&args[0], &parser->index);
1000 xml_xmlchar_zval(openEntityNames, 0, parser->target_encoding, &args[1]);
1001 xml_xmlchar_zval(base, 0, parser->target_encoding, &args[2]);
1002 xml_xmlchar_zval(systemId, 0, parser->target_encoding, &args[3]);
1003 xml_xmlchar_zval(publicId, 0, parser->target_encoding, &args[4]);
1004
1005 zend_call_known_fcc(&parser->externalEntityRefHandler, /* retval */ &retval, /* param_count */ 5, args, /* named_params */ NULL);
1006 zval_ptr_dtor(&args[0]);
1007 zval_ptr_dtor(&args[1]);
1008 zval_ptr_dtor(&args[2]);
1009 zval_ptr_dtor(&args[3]);
1010 zval_ptr_dtor(&args[4]);
1011
1012 /* TODO Better handling from callable return value */
1013 if (!Z_ISUNDEF(retval)) {
1015 ret = Z_LVAL(retval);
1016 } else {
1017 ret = 0;
1018 }
1019 return ret;
1020}
1021/* }}} */
1022
1023/* {{{ xml_startNamespaceDeclHandler() */
1024void xml_startNamespaceDeclHandler(void *userData,const XML_Char *prefix, const XML_Char *uri)
1025{
1026 xml_parser *parser = (xml_parser *)userData;
1027
1028 if (!parser || !ZEND_FCC_INITIALIZED(parser->startNamespaceDeclHandler)) {
1029 return;
1030 }
1031
1032 zval args[3];
1033
1034 ZVAL_COPY(&args[0], &parser->index);
1035 xml_xmlchar_zval(prefix, 0, parser->target_encoding, &args[1]);
1036 xml_xmlchar_zval(uri, 0, parser->target_encoding, &args[2]);
1037
1038 zend_call_known_fcc(&parser->startNamespaceDeclHandler, /* retval */ NULL, /* param_count */ 3, args, /* named_params */ NULL);
1039 zval_ptr_dtor(&args[0]);
1040 zval_ptr_dtor(&args[1]);
1041 zval_ptr_dtor(&args[2]);
1042}
1043/* }}} */
1044
1045/* {{{ xml_endNamespaceDeclHandler() */
1046void xml_endNamespaceDeclHandler(void *userData, const XML_Char *prefix)
1047{
1048 xml_parser *parser = (xml_parser *)userData;
1049
1050 if (!parser || !ZEND_FCC_INITIALIZED(parser->endNamespaceDeclHandler)) {
1051 return;
1052 }
1053
1054 zval args[2];
1055
1056 ZVAL_COPY(&args[0], &parser->index);
1057 xml_xmlchar_zval(prefix, 0, parser->target_encoding, &args[1]);
1058
1059 zend_call_known_fcc(&parser->endNamespaceDeclHandler, /* retval */ NULL, /* param_count */ 2, args, /* named_params */ NULL);
1060 zval_ptr_dtor(&args[0]);
1061 zval_ptr_dtor(&args[1]);
1062}
1063/* }}} */
1064
1065/************************* EXTENSION FUNCTIONS *************************/
1066
1067static void php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAMETERS, int ns_support) /* {{{ */
1068{
1069 xml_parser *parser;
1070 int auto_detect = 0;
1071
1072 zend_string *encoding_param = NULL;
1073
1074 char *ns_param = NULL;
1075 size_t ns_param_len = 0;
1076
1077 XML_Char *encoding;
1078
1079 if (zend_parse_parameters(ZEND_NUM_ARGS(), (ns_support ? "|S!s": "|S!"), &encoding_param, &ns_param, &ns_param_len) == FAILURE) {
1080 RETURN_THROWS();
1081 }
1082
1083 if (encoding_param != NULL) {
1084 /* The supported encoding types are hardcoded here because
1085 * we are limited to the encodings supported by expat/xmltok.
1086 */
1087 if (ZSTR_LEN(encoding_param) == 0) {
1088 encoding = XML(default_encoding);
1089 auto_detect = 1;
1090 } else if (zend_string_equals_literal_ci(encoding_param, "ISO-8859-1")) {
1091 encoding = (XML_Char*)"ISO-8859-1";
1092 } else if (zend_string_equals_literal_ci(encoding_param, "UTF-8")) {
1093 encoding = (XML_Char*)"UTF-8";
1094 } else if (zend_string_equals_literal_ci(encoding_param, "US-ASCII")) {
1095 encoding = (XML_Char*)"US-ASCII";
1096 } else {
1097 zend_argument_value_error(1, "is not a supported source encoding");
1098 RETURN_THROWS();
1099 }
1100 } else {
1101 encoding = XML(default_encoding);
1102 }
1103
1104 if (ns_support && ns_param == NULL){
1105 ns_param = ":";
1106 }
1107
1108 object_init_ex(return_value, xml_parser_ce);
1109 parser = Z_XMLPARSER_P(return_value);
1110 parser->parser = XML_ParserCreate_MM((auto_detect ? NULL : encoding),
1111 &php_xml_mem_hdlrs, (XML_Char*)ns_param);
1112
1113 parser->target_encoding = encoding;
1114 parser->case_folding = 1;
1115 parser->isparsing = 0;
1116 parser->parsehuge = false; /* It's the default for BC & DoS protection */
1117
1118 XML_SetUserData(parser->parser, parser);
1119 ZVAL_COPY_VALUE(&parser->index, return_value);
1120}
1121/* }}} */
1122
1123/* {{{ Create an XML parser */
1125{
1126 php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1127}
1128/* }}} */
1129
1130/* {{{ Create an XML parser */
1132{
1133 php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1134}
1135/* }}} */
1136
1137static bool php_xml_check_string_method_arg(
1138 unsigned int arg_num,
1139 zend_object *object,
1140 zend_string *method_name,
1141 zend_fcall_info_cache *const parser_handler_fcc
1142) {
1143 if (ZSTR_LEN(method_name) == 0) {
1144 ZEND_ASSERT(arg_num != 0);
1145 /* Unset handler */
1146 return true;
1147 }
1148
1149 if (!object) {
1150 ZEND_ASSERT(arg_num != 0);
1151 zend_argument_value_error(arg_num, "an object must be set via xml_set_object() to be able to lookup method");
1152 return false;
1153 }
1154
1155 zend_class_entry *ce = object->ce;
1156 zend_function *method_ptr = zend_hash_find_ptr_lc(&ce->function_table, method_name);
1157 if (!method_ptr) {
1158 if (arg_num) {
1159 zend_argument_value_error(arg_num, "method %s::%s() does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(method_name));
1160 }
1161 return false;
1162 }
1163
1164 parser_handler_fcc->function_handler = method_ptr;
1165 /* We set the calling scope to NULL to be able to differentiate a "method" set from a proper callable */
1166 parser_handler_fcc->calling_scope = NULL;
1167 parser_handler_fcc->called_scope = ce;
1168 parser_handler_fcc->object = object;
1169
1170 return true;
1171}
1172
1173#define PHP_XML_CHECK_NEW_THIS_METHODS(parser_to_check, new_this_obj, fcc_field, handler_set_method) \
1174 if ( \
1175 ZEND_FCC_INITIALIZED(parser_to_check->fcc_field) \
1176 && parser_to_check->fcc_field.object == parser_to_check->object \
1177 && parser_to_check->fcc_field.calling_scope == NULL \
1178 ) { \
1179 zend_string *method_name = zend_string_copy(parser_to_check->fcc_field.function_handler->common.function_name); \
1180 zend_fcc_dtor(&parser_to_check->fcc_field); \
1181 bool status = php_xml_check_string_method_arg(0, new_this_obj, method_name, &parser_to_check->fcc_field); \
1182 if (status == false) { \
1183 zend_argument_value_error(2, "cannot safely swap to object of class %s as method \"%s\" does not exist, which was set via " handler_set_method, \
1184 ZSTR_VAL(new_this_obj->ce->name), ZSTR_VAL(method_name)); \
1185 zend_string_release(method_name); \
1186 RETURN_THROWS(); \
1187 } \
1188 zend_string_release(method_name); \
1189 zend_fcc_addref(&parser_to_check->fcc_field); \
1190 }
1191
1192
1193/* {{{ Set up object which should be used for callbacks */
1195{
1196 xml_parser *parser;
1197 zval *pind, *mythis;
1198 zend_object *new_this;
1199
1200 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oo", &pind, xml_parser_ce, &mythis) == FAILURE) {
1201 RETURN_THROWS();
1202 }
1203
1204 parser = Z_XMLPARSER_P(pind);
1205 new_this = Z_OBJ_P(mythis);
1206
1207 if (parser->object) {
1208 PHP_XML_CHECK_NEW_THIS_METHODS(parser, new_this, startElementHandler, "xml_set_element_handler()");
1209 PHP_XML_CHECK_NEW_THIS_METHODS(parser, new_this, endElementHandler, "xml_set_element_handler()");
1210 PHP_XML_CHECK_NEW_THIS_METHODS(parser, new_this, characterDataHandler, "xml_set_character_data_handler()");
1211 PHP_XML_CHECK_NEW_THIS_METHODS(parser, new_this, processingInstructionHandler, "xml_set_processing_instruction_handler()");
1212 PHP_XML_CHECK_NEW_THIS_METHODS(parser, new_this, defaultHandler, "xml_set_default_handler()");
1213 PHP_XML_CHECK_NEW_THIS_METHODS(parser, new_this, unparsedEntityDeclHandler, "xml_set_unparsed_entity_decl_handler()");
1214 PHP_XML_CHECK_NEW_THIS_METHODS(parser, new_this, notationDeclHandler, "xml_set_notation_decl_handler()");
1215 PHP_XML_CHECK_NEW_THIS_METHODS(parser, new_this, externalEntityRefHandler, "xml_set_external_entity_ref_handler()");
1216 PHP_XML_CHECK_NEW_THIS_METHODS(parser, new_this, startNamespaceDeclHandler, "xml_set_start_namespace_decl_handler()");
1217 PHP_XML_CHECK_NEW_THIS_METHODS(parser, new_this, endNamespaceDeclHandler, "xml_set_end_namespace_decl_handler()");
1218
1219 OBJ_RELEASE(parser->object);
1220 }
1221
1222 parser->object = new_this;
1223 GC_ADDREF(parser->object);
1224
1226}
1227/* }}} */
1228
1229/* {{{ Set up start and end element handlers */
1231{
1232 xml_parser *parser;
1233 zval *pind;
1234 zend_fcall_info start_fci = {0};
1235 zend_fcall_info_cache start_fcc = {0};
1236 zend_fcall_info end_fci = {0};
1237 zend_fcall_info_cache end_fcc = {0};
1238 zend_string *start_method_name = NULL;
1239 zend_string *end_method_name = NULL;
1240
1241 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OF!F!", &pind, xml_parser_ce, &start_fci, &start_fcc, &end_fci, &end_fcc) == SUCCESS) {
1242 parser = Z_XMLPARSER_P(pind);
1243 goto set_handlers;
1244 }
1247
1248 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OF!S", &pind, xml_parser_ce, &start_fci, &start_fcc, &end_method_name) == SUCCESS) {
1249 parser = Z_XMLPARSER_P(pind);
1250
1251 php_error_docref(NULL, E_DEPRECATED, "Passing non-callable strings is deprecated since 8.4");
1252 if (UNEXPECTED(EG(exception))) {
1255 RETURN_THROWS();
1256 }
1257
1258 bool status = php_xml_check_string_method_arg(3, parser->object, end_method_name, &end_fcc);
1259 if (status == false) {
1262 RETURN_THROWS();
1263 }
1264 } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OSF!", &pind, xml_parser_ce, &start_method_name, &end_fci, &end_fcc) == SUCCESS) {
1265 parser = Z_XMLPARSER_P(pind);
1266
1267 php_error_docref(NULL, E_DEPRECATED, "Passing non-callable strings is deprecated since 8.4");
1268 if (UNEXPECTED(EG(exception))) {
1271 RETURN_THROWS();
1272 }
1273
1274 bool status = php_xml_check_string_method_arg(2, parser->object, start_method_name, &start_fcc);
1275 if (status == false) {
1278 RETURN_THROWS();
1279 }
1280 } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OSS", &pind, xml_parser_ce, &start_method_name, &end_method_name) == SUCCESS) {
1283
1284 php_error_docref(NULL, E_DEPRECATED, "Passing non-callable strings is deprecated since 8.4");
1285 if (UNEXPECTED(EG(exception))) {
1286 RETURN_THROWS();
1287 }
1288
1289 parser = Z_XMLPARSER_P(pind);
1290
1291 bool status = php_xml_check_string_method_arg(2, parser->object, start_method_name, &start_fcc);
1292 if (status == false) {
1293 RETURN_THROWS();
1294 }
1295 status = php_xml_check_string_method_arg(3, parser->object, end_method_name, &end_fcc);
1296 if (status == false) {
1297 RETURN_THROWS();
1298 }
1299 } else {
1300 zval *dummy_start;
1301 zval *dummy_end;
1302
1305 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ozz", &pind, xml_parser_ce, &dummy_start, &dummy_end) == FAILURE) {
1306 RETURN_THROWS();
1307 } else {
1308 switch (Z_TYPE_P(dummy_start)) {
1309 case IS_NULL:
1310 case IS_STRING:
1311 break;
1312 default:
1313 zend_argument_type_error(2, "must be of type callable|string|null");
1314 RETURN_THROWS();
1315 }
1316 zend_argument_type_error(3, "must be of type callable|string|null");
1317 RETURN_THROWS();
1318 }
1319 }
1320
1321 set_handlers:
1322 xml_set_handler(&parser->startElementHandler, &start_fcc);
1323 xml_set_handler(&parser->endElementHandler, &end_fcc);
1324 XML_SetElementHandler(parser->parser, xml_startElementHandler, xml_endElementHandler);
1325
1327}
1328/* }}} */
1329
1330static void php_xml_set_handler_parse_callable(
1332 xml_parser **const parser,
1333 zend_fcall_info_cache *const parser_handler_fcc
1334) {
1335 zval *pind;
1336 zend_fcall_info handler_fci = {0};
1337 zend_fcall_info_cache handler_fcc = {0};
1338 zend_string *method_name = NULL;
1339
1340 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OF!", &pind, xml_parser_ce, &handler_fci, &handler_fcc) == SUCCESS) {
1341 *parser = Z_XMLPARSER_P(pind);
1342 if (!ZEND_FCI_INITIALIZED(handler_fci)) {
1343 /* Free handler, so just return and an uninitialized FCC communicates this */
1344 return;
1345 }
1346 memcpy(parser_handler_fcc, &handler_fcc, sizeof(zend_fcall_info_cache));
1347 } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OS", &pind, xml_parser_ce, &method_name) == SUCCESS) {
1348 *parser = Z_XMLPARSER_P(pind);
1349 php_error_docref(NULL, E_DEPRECATED, "Passing non-callable strings is deprecated since 8.4");
1350 if (UNEXPECTED(EG(exception))) {
1351 RETURN_THROWS();
1352 }
1353 bool status = php_xml_check_string_method_arg(2, (*parser)->object, method_name, parser_handler_fcc);
1354 if (status == false) {
1355 RETURN_THROWS();
1356 }
1357 } else {
1358 zval *dummy;
1359 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz", &pind, xml_parser_ce, &dummy) == FAILURE) {
1360 RETURN_THROWS();
1361 }
1362 zend_argument_type_error(2, "must be of type callable|string|null");
1363 RETURN_THROWS();
1364 }
1365}
1366
1367#define XML_SET_HANDLER_PHP_FUNCTION(function_name, parser_handler_name, parse_function, c_function) \
1368 PHP_FUNCTION(function_name) \
1369 { \
1370 xml_parser *parser = NULL; \
1371 zend_fcall_info_cache handler_fcc = {0}; \
1372 php_xml_set_handler_parse_callable(INTERNAL_FUNCTION_PARAM_PASSTHRU, &parser, &handler_fcc); \
1373 if (EG(exception)) { return; } \
1374 ZEND_ASSERT(parser); \
1375 xml_set_handler(&parser->parser_handler_name, &handler_fcc); \
1376 parse_function(parser->parser, c_function); \
1377 RETURN_TRUE; \
1378 }
1379
1380XML_SET_HANDLER_PHP_FUNCTION(xml_set_character_data_handler, characterDataHandler, XML_SetCharacterDataHandler, xml_characterDataHandler);
1381XML_SET_HANDLER_PHP_FUNCTION(xml_set_processing_instruction_handler, processingInstructionHandler, XML_SetProcessingInstructionHandler, xml_processingInstructionHandler);
1382XML_SET_HANDLER_PHP_FUNCTION(xml_set_default_handler, defaultHandler, XML_SetDefaultHandler, xml_defaultHandler);
1383XML_SET_HANDLER_PHP_FUNCTION(xml_set_unparsed_entity_decl_handler, unparsedEntityDeclHandler, XML_SetUnparsedEntityDeclHandler, xml_unparsedEntityDeclHandler);
1384XML_SET_HANDLER_PHP_FUNCTION(xml_set_notation_decl_handler, notationDeclHandler, XML_SetNotationDeclHandler, xml_notationDeclHandler);
1385XML_SET_HANDLER_PHP_FUNCTION(xml_set_external_entity_ref_handler, externalEntityRefHandler, XML_SetExternalEntityRefHandler, xml_externalEntityRefHandler);
1386XML_SET_HANDLER_PHP_FUNCTION(xml_set_start_namespace_decl_handler, startNamespaceDeclHandler, XML_SetStartNamespaceDeclHandler, xml_startNamespaceDeclHandler);
1387XML_SET_HANDLER_PHP_FUNCTION(xml_set_end_namespace_decl_handler, endNamespaceDeclHandler, XML_SetEndNamespaceDeclHandler, xml_endNamespaceDeclHandler);
1388
1389/* {{{ Start parsing an XML document */
1391{
1392 xml_parser *parser;
1393 zval *pind;
1394 char *data;
1395 size_t data_len;
1396 bool isFinal = 0;
1397
1398 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|b", &pind, xml_parser_ce, &data, &data_len, &isFinal) == FAILURE) {
1399 RETURN_THROWS();
1400 }
1401
1402 parser = Z_XMLPARSER_P(pind);
1403 if (parser->isparsing) {
1404 zend_throw_error(NULL, "Parser must not be called recursively");
1405 RETURN_THROWS();
1406 }
1407 RETURN_LONG(xml_parse_helper(parser, data, data_len, isFinal));
1408}
1409
1410/* }}} */
1411
1412/* {{{ Parsing a XML document */
1414{
1415 xml_parser *parser;
1416 zval *pind, *xdata, *info = NULL;
1417 char *data;
1418 size_t data_len;
1419
1420 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osz|z", &pind, xml_parser_ce, &data, &data_len, &xdata, &info) == FAILURE) {
1421 RETURN_THROWS();
1422 }
1423
1424 parser = Z_XMLPARSER_P(pind);
1425
1426 if (parser->isparsing) {
1427 php_error_docref(NULL, E_WARNING, "Parser must not be called recursively");
1429 }
1430
1431 if (info) {
1432 if (!zend_try_array_init(info)) {
1433 RETURN_THROWS();
1434 }
1435 }
1436
1437 if (!zend_try_array_init(xdata)) {
1438 RETURN_THROWS();
1439 }
1440
1441 zval_ptr_dtor(&parser->data);
1442 ZVAL_COPY(&parser->data, xdata);
1443
1444 if (info) {
1445 zval_ptr_dtor(&parser->info);
1446 ZVAL_COPY(&parser->info, info);
1447 }
1448
1449 parser->level = 0;
1450 xml_parser_free_ltags(parser);
1451 parser->ltags = safe_emalloc(XML_MAXLEVEL, sizeof(char *), 0);
1452 memset(parser->ltags, 0, XML_MAXLEVEL * sizeof(char *));
1453
1454 XML_SetElementHandler(parser->parser, xml_startElementHandler, xml_endElementHandler);
1455 XML_SetCharacterDataHandler(parser->parser, xml_characterDataHandler);
1456
1457 RETURN_LONG(xml_parse_helper(parser, data, data_len, true));
1458}
1459/* }}} */
1460
1461/* {{{ Get XML parser error code */
1463{
1464 xml_parser *parser;
1465 zval *pind;
1466
1467 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pind, xml_parser_ce) == FAILURE) {
1468 RETURN_THROWS();
1469 }
1470
1471 parser = Z_XMLPARSER_P(pind);
1472 RETURN_LONG((zend_long)XML_GetErrorCode(parser->parser));
1473}
1474/* }}} */
1475
1476/* {{{ Get XML parser error string */
1478{
1479 zend_long code;
1480 char *str;
1481
1482 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &code) == FAILURE) {
1483 RETURN_THROWS();
1484 }
1485
1486 str = (char *)XML_ErrorString((int)code);
1487 if (str) {
1488 RETVAL_STRING(str);
1489 }
1490}
1491/* }}} */
1492
1493/* {{{ Get current line number for an XML parser */
1495{
1496 xml_parser *parser;
1497 zval *pind;
1498
1499 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pind, xml_parser_ce) == FAILURE) {
1500 RETURN_THROWS();
1501 }
1502
1503 parser = Z_XMLPARSER_P(pind);
1504 RETVAL_LONG(XML_GetCurrentLineNumber(parser->parser));
1505}
1506/* }}} */
1507
1508/* {{{ Get current column number for an XML parser */
1510{
1511 xml_parser *parser;
1512 zval *pind;
1513
1514 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pind, xml_parser_ce) == FAILURE) {
1515 RETURN_THROWS();
1516 }
1517
1518 parser = Z_XMLPARSER_P(pind);
1519 RETVAL_LONG(XML_GetCurrentColumnNumber(parser->parser));
1520}
1521/* }}} */
1522
1523/* {{{ Get current byte index for an XML parser */
1525{
1526 xml_parser *parser;
1527 zval *pind;
1528
1529 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pind, xml_parser_ce) == FAILURE) {
1530 RETURN_THROWS();
1531 }
1532
1533 parser = Z_XMLPARSER_P(pind);
1534 RETVAL_LONG(XML_GetCurrentByteIndex(parser->parser));
1535}
1536/* }}} */
1537
1538/* {{{ Free an XML parser */
1540{
1541 zval *pind;
1542 xml_parser *parser;
1543
1544 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pind, xml_parser_ce) == FAILURE) {
1545 RETURN_THROWS();
1546 }
1547
1548 parser = Z_XMLPARSER_P(pind);
1549 if (parser->isparsing == 1) {
1550 php_error_docref(NULL, E_WARNING, "Parser cannot be freed while it is parsing");
1552 }
1553
1555}
1556/* }}} */
1557
1558/* {{{ Set options in an XML parser */
1560{
1561 xml_parser *parser;
1562 zval *pind;
1563 zend_long opt;
1564 zval *value;
1565
1566 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olz", &pind, xml_parser_ce, &opt, &value) == FAILURE) {
1567 RETURN_THROWS();
1568 }
1569
1570 if (Z_TYPE_P(value) != IS_FALSE && Z_TYPE_P(value) != IS_TRUE &&
1573 "Argument #3 ($value) must be of type string|int|bool, %s given", zend_zval_type_name(value));
1574 }
1575
1576 parser = Z_XMLPARSER_P(pind);
1577 switch (opt) {
1578 /* Boolean option */
1580 parser->case_folding = zend_is_true(value);
1581 break;
1582 /* Boolean option */
1584 parser->skipwhite = zend_is_true(value);
1585 break;
1586 /* Boolean option */
1588 /* Prevent wreaking havock to the parser internals during parsing */
1589 if (UNEXPECTED(parser->isparsing)) {
1590 zend_throw_error(NULL, "Cannot change option XML_OPTION_PARSE_HUGE while parsing");
1591 RETURN_THROWS();
1592 }
1593 parser->parsehuge = zend_is_true(value);
1594 break;
1595 /* Integer option */
1597 /* The tag start offset is stored in an int */
1598 /* TODO Improve handling of values? */
1599 zend_long value_long = zval_get_long(value);
1600 if (value_long < 0 || value_long > INT_MAX) {
1601 /* TODO Promote to ValueError in PHP 9.0 */
1602 php_error_docref(NULL, E_WARNING, "Argument #3 ($value) must be between 0 and %d"
1603 " for option XML_OPTION_SKIP_TAGSTART", INT_MAX);
1605 }
1606 parser->toffset = (int) value_long;
1607 break;
1608 }
1609 /* String option */
1611 const xml_encoding *enc;
1612 if (!try_convert_to_string(value)) {
1613 RETURN_THROWS();
1614 }
1615
1616 enc = xml_get_encoding((XML_Char*)Z_STRVAL_P(value));
1617 if (enc == NULL) {
1618 zend_argument_value_error(3, "is not a supported target encoding");
1619 RETURN_THROWS();
1620 }
1621
1622 parser->target_encoding = enc->name;
1623 break;
1624 }
1625 default:
1626 zend_argument_value_error(2, "must be a XML_OPTION_* constant");
1627 RETURN_THROWS();
1628 break;
1629 }
1630
1632}
1633/* }}} */
1634
1635/* {{{ Get options from an XML parser */
1637{
1638 xml_parser *parser;
1639 zval *pind;
1640 zend_long opt;
1641
1642 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pind, xml_parser_ce, &opt) == FAILURE) {
1643 RETURN_THROWS();
1644 }
1645
1646 parser = Z_XMLPARSER_P(pind);
1647 switch (opt) {
1649 RETURN_BOOL(parser->case_folding);
1650 break;
1652 RETURN_LONG(parser->toffset);
1653 break;
1655 RETURN_BOOL(parser->skipwhite);
1656 break;
1658 RETURN_BOOL(parser->parsehuge);
1659 break;
1661 RETURN_STRING((char *)parser->target_encoding);
1662 break;
1663 default:
1664 zend_argument_value_error(2, "must be a XML_OPTION_* constant");
1665 RETURN_THROWS();
1666 }
1667}
1668/* }}} */
1669
1670#endif
size_t len
Definition apprentice.c:174
bool exception
Definition assert.c:30
char s[4]
Definition cdf.c:77
DNS_STATUS status
Definition dns_win32.c:49
zval * zv
Definition ffi.c:3975
zend_long n
Definition ffi.c:4979
void * ptr
Definition ffi.c:3814
memcpy(ptr1, ptr2, size)
memset(ptr, 0, type->size)
zval * val
Definition ffi.c:4262
#define NULL
Definition gdcache.h:45
#define prefix
#define SUCCESS
Definition hash_sha3.c:261
PHPAPI unsigned int php_next_utf8_char(const unsigned char *str, size_t str_len, size_t *cursor, zend_result *status)
Definition html.c:351
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
const LIBXML_DOTTED_VERSION
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
Definition main.c:1173
text application xhtml xml
Definition mbstring.c:951
php_info_print_table_start()
Definition info.c:1064
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
Definition info.c:1074
#define PHP_GINIT
Definition php.h:397
#define PHP_FUNCTION
Definition php.h:364
#define PHP_MINFO
Definition php.h:396
#define PHP_MINIT_FUNCTION
Definition php.h:400
#define PHP_MINFO_FUNCTION
Definition php.h:404
#define PHP_GINIT_FUNCTION
Definition php.h:405
#define INT_MAX
Definition php.h:237
#define PHP_MINIT
Definition php.h:392
#define PHP_MODULE_GLOBALS
Definition php.h:408
unsigned const char * pos
Definition php_ffi.h:52
xmlCharEncodingHandlerPtr encoding
Definition php_soap.h:170
#define zend_hash_str_add(...)
Definition phpdbg.h:77
zend_constant * data
zend_long nNextFreeElement
Definition zend_types.h:410
zend_string * name
Definition zend.h:149
HashTable function_table
Definition zend.h:163
zend_class_entry * calling_scope
Definition zend_API.h:61
zend_function * function_handler
Definition zend_API.h:60
zend_class_entry * called_scope
Definition zend_API.h:62
zend_object * object
Definition zend_API.h:63
zend_object_compare_t compare
zend_object_free_obj_t free_obj
zend_object_get_gc_t get_gc
zend_object_get_constructor_t get_constructor
zend_object_clone_obj_t clone_obj
@ PHP_XML_OPTION_CASE_FOLDING
Definition php_xml.h:43
@ PHP_XML_OPTION_PARSE_HUGE
Definition php_xml.h:47
@ PHP_XML_OPTION_SKIP_WHITE
Definition php_xml.h:46
@ PHP_XML_OPTION_SKIP_TAGSTART
Definition php_xml.h:45
@ PHP_XML_OPTION_TARGET_ENCODING
Definition php_xml.h:44
xml_get_error_code(XMLParser $parser)
Definition xml.stub.php:181
xml_parser_free(XMLParser $parser)
Definition xml.stub.php:192
xml_set_start_namespace_decl_handler(XMLParser $parser, callable|string|null $handler)
Definition xml.stub.php:169
xml_get_current_line_number(XMLParser $parser)
Definition xml.stub.php:186
xml_set_external_entity_ref_handler(XMLParser $parser, callable|string|null $handler)
Definition xml.stub.php:167
xml_set_object(XMLParser $parser, object $object)
Definition xml.stub.php:153
xml_parser_create(?string $encoding=null)
Definition xml.stub.php:148
xml_set_notation_decl_handler(XMLParser $parser, callable|string|null $handler)
Definition xml.stub.php:165
xml_parser_set_option(XMLParser $parser, int $option, $value)
Definition xml.stub.php:195
xml_set_default_handler(XMLParser $parser, callable|string|null $handler)
Definition xml.stub.php:161
xml_set_element_handler(XMLParser $parser, callable|string|null $start_handler, callable|string|null $end_handler)
Definition xml.stub.php:155
xml_set_end_namespace_decl_handler(XMLParser $parser, callable|string|null $handler)
Definition xml.stub.php:171
xml_get_current_byte_index(XMLParser $parser)
Definition xml.stub.php:190
xml_set_character_data_handler(XMLParser $parser, callable|string|null $handler)
Definition xml.stub.php:157
xml_set_processing_instruction_handler(XMLParser $parser, callable|string|null $handler)
Definition xml.stub.php:159
xml_parse_into_struct(XMLParser $parser, string $data, &$values, &$index=null)
Definition xml.stub.php:179
xml_parser_create_ns(?string $encoding=null, string $separator=":")
Definition xml.stub.php:150
xml_get_current_column_number(XMLParser $parser)
Definition xml.stub.php:188
xml_parse(XMLParser $parser, string $data, bool $is_final=false)
Definition xml.stub.php:173
xml_parser_get_option(XMLParser $parser, int $option)
Definition xml.stub.php:198
xml_error_string(int $error_code)
Definition xml.stub.php:184
xml_set_unparsed_entity_decl_handler(XMLParser $parser, callable|string|null $handler)
Definition xml.stub.php:163
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
Definition zend.c:1772
#define ZEND_TSRMLS_CACHE_UPDATE()
Definition zend.h:69
#define INTERNAL_FUNCTION_PARAMETERS
Definition zend.h:49
#define ZEND_TSRMLS_CACHE_DEFINE()
Definition zend.h:68
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
Definition zend.h:50
ZEND_API zend_result add_next_index_long(zval *arg, zend_long n)
Definition zend_API.c:2132
ZEND_API const char * zend_zval_type_name(const zval *arg)
Definition zend_API.c:167
ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *class_type)
Definition zend_API.c:1849
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
Definition zend_API.c:1300
ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type)
Definition zend_API.c:1688
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
ZEND_API void zend_release_fcall_info_cache(zend_fcall_info_cache *fcc)
Definition zend_API.c:3845
ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:423
ZEND_API zend_result zend_parse_parameters_ex(int flags, uint32_t num_args, const char *type_spec,...)
Definition zend_API.c:1287
#define ZEND_NUM_ARGS()
Definition zend_API.h:530
struct _zend_fcall_info_cache zend_fcall_info_cache
#define RETURN_STRING(s)
Definition zend_API.h:1043
#define ZEND_PARSE_PARAMS_QUIET
Definition zend_API.h:361
#define RETURN_FALSE
Definition zend_API.h:1058
#define RETVAL_STRING(s)
Definition zend_API.h:1017
#define ZVAL_STRING(z, s)
Definition zend_API.h:956
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
Definition zend_API.h:268
#define ZEND_GET_MODULE(name)
Definition zend_API.h:241
#define ZEND_FCI_INITIALIZED(fci)
Definition zend_API.h:340
#define ZEND_END_MODULE_GLOBALS(module_name)
Definition zend_API.h:248
#define RETURN_LONG(l)
Definition zend_API.h:1037
#define RETURN_BOOL(b)
Definition zend_API.h:1035
struct _zend_fcall_info zend_fcall_info
#define RETURN_THROWS()
Definition zend_API.h:1060
#define ZEND_FCC_INITIALIZED(fcc)
Definition zend_API.h:341
#define RETVAL_LONG(l)
Definition zend_API.h:1011
#define RETURN_TRUE
Definition zend_API.h:1059
#define ZEND_BEGIN_MODULE_GLOBALS(module_name)
Definition zend_API.h:246
#define array_init(arg)
Definition zend_API.h:537
#define efree(ptr)
Definition zend_alloc.h:155
#define estrdup(s)
Definition zend_alloc.h:164
#define erealloc(ptr, size)
Definition zend_alloc.h:159
#define safe_emalloc(nmemb, size, offset)
Definition zend_alloc.h:154
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
strlen(string $string)
zend_string_release_ex(func->internal_function.function_name, 0)
zval * args
#define strcasecmp(s1, s2)
#define E_WARNING
Definition zend_errors.h:24
#define E_DEPRECATED
Definition zend_errors.h:37
union _zend_function zend_function
ZEND_API zend_get_gc_buffer * zend_get_gc_buffer_create(void)
Definition zend_gc.c:2130
#define EG(v)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *str, size_t len)
Definition zend_hash.c:2689
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert(HashTable *ht, zval *pData)
Definition zend_hash.c:1224
ZEND_API zval *ZEND_FASTCALL zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData)
Definition zend_hash.c:1031
ZEND_API void * zend_hash_find_ptr_lc(const HashTable *ht, zend_string *key)
Definition zend_hash.c:104
ZEND_API zval *ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key)
Definition zend_hash.c:2668
#define ZEND_HASH_REVERSE_FOREACH_VAL(ht, _val)
Definition zend_hash.h:1106
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
int32_t zend_long
Definition zend_long.h:42
struct _zend_string zend_string
#define STANDARD_MODULE_HEADER
#define ZEND_MOD_END
struct _zend_module_dep zend_module_dep
struct _zend_module_entry zend_module_entry
#define ZEND_MOD_REQUIRED(name)
#define STANDARD_MODULE_PROPERTIES_EX
#define STANDARD_MODULE_HEADER_EX
ZEND_API int zend_objects_not_comparable(zval *o1, zval *o2)
ZEND_API HashTable * zend_std_get_properties(zend_object *zobj)
ZEND_API const zend_object_handlers std_object_handlers
ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce)
ZEND_API void zend_object_std_dtor(zend_object *object)
#define OBJ_RELEASE(obj)
ZEND_API void ZEND_FASTCALL zend_str_toupper(char *str, size_t length)
ZEND_API bool ZEND_FASTCALL zend_is_true(const zval *op)
ZEND_API void ZEND_FASTCALL convert_to_long(zval *op)
#define EXPECTED(condition)
#define ZEND_DIAGNOSTIC_IGNORED_END
#define XtOffsetOf(s_type, field)
#define ZEND_ASSERT(c)
#define ZEND_DIAGNOSTIC_IGNORED_START(warning)
#define UNEXPECTED(condition)
struct _zend_array zend_array
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_KNOWN(idx)
#define zend_string_equals_literal(str, literal)
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define zend_string_equals_literal_ci(str, c)
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define IS_TRUE
Definition zend_types.h:603
#define ZVAL_STR(z, s)
#define ZVAL_FALSE(z)
#define IS_FALSE
Definition zend_types.h:602
#define Z_STRVAL_P(zval_p)
Definition zend_types.h:975
#define Z_ARRVAL_P(zval_p)
Definition zend_types.h:987
#define IS_STRING
Definition zend_types.h:606
struct _zend_array HashTable
Definition zend_types.h:386
#define Z_OBJ_P(zval_p)
Definition zend_types.h:990
#define IS_ARRAY
Definition zend_types.h:607
#define Z_ISUNDEF(zval)
Definition zend_types.h:956
#define Z_STR_P(zval_p)
Definition zend_types.h:972
#define GC_ADDREF(p)
Definition zend_types.h:709
#define Z_REFVAL(zval)
#define Z_STRLEN_P(zval_p)
Definition zend_types.h:978
#define IS_NULL
Definition zend_types.h:601
@ FAILURE
Definition zend_types.h:61
#define IS_LONG
Definition zend_types.h:604
#define ZVAL_COPY(z, v)
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
struct _zend_object_handlers zend_object_handlers
Definition zend_types.h:88
#define SEPARATE_ARRAY(zv)
#define Z_ARRVAL(zval)
Definition zend_types.h:986
#define ZVAL_COPY_VALUE(z, v)
#define Z_LVAL(zval)
Definition zend_types.h:965
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zval retval
zval * return_value
uint32_t arg_num
zend_string * name
object
zval * ret
value