24#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
28#include <libxml/parserInternals.h>
30static void xpath_callbacks_entry_dtor(
zval *
zv)
66 for (uint32_t i = 0; i <
num_args; i++) {
67 xmlXPathObjectPtr obj = valuePop(ctxt);
68 xmlXPathFreeObject(obj);
79 php_dom_xpath_callback_ns_dtor(
registry->php_ns);
85 php_dom_xpath_callback_ns_dtor(ns);
99 zend_get_gc_buffer_add_fcc(gc_buffer, entry);
106 php_dom_xpath_callback_ns_get_gc(
registry->php_ns, gc_buffer);
111 php_dom_xpath_callback_ns_get_gc(ns, gc_buffer);
121 zend_get_gc_buffer_use(gc_buffer, table,
n);
123 if (
object->properties ==
NULL &&
object->ce->default_properties_count == 0) {
140 if (zend_str_has_nul_byte(
name)) {
146 if (xmlValidateNCName(BAD_CAST
ZSTR_VAL(
name), 0) != 0) {
156 if (!php_dom_xpath_is_callback_name_valid(
name, name_validation)) {
175 register_func(ctxt,
namespace,
name);
181static zend_result php_dom_xpath_callback_ns_update_method_handler(
183 xmlXPathContextPtr ctxt,
191 zval *entry, registered_value;
205 zend_fcc_addref(fcc);
210 if (str && php_dom_xpath_is_callback_name_valid_and_throw(str, name_validation,
true)) {
213 register_func(ctxt,
namespace, str);
222 if (!php_dom_xpath_is_callback_name_valid_and_throw(
key, name_validation,
true)) {
229 register_func(ctxt,
namespace,
key);
235 if (!php_dom_xpath_is_callback_name_valid(
name, name_validation)) {
249 zend_fcc_addref(fcc);
253 register_func(ctxt,
namespace,
name);
268 php_dom_xpath_callback_ns_ctor(
registry->php_ns);
277 if (
namespace ==
NULL) {
279 php_dom_xpath_callback_ns_ctor(
namespace);
280 zend_hash_add_new_ptr(
registry->namespaces, ns,
namespace);
289 return php_dom_xpath_callback_ns_update_method_handler(
namespace, ctxt, ns,
name, callable_ht, name_validation, register_func);
294 if (!php_dom_xpath_is_callback_name_valid_and_throw(
name, name_validation,
false)) {
300 zend_fcc_dup(allocated_fcc, fcc);
302 zval registered_value;
303 ZVAL_PTR(®istered_value, allocated_fcc);
307 register_func(ctxt, ns,
name);
317 if (param_count == 0) {
324 for (
zval *param = params + param_count - 1; param >= params; param--) {
325 xmlXPathObjectPtr obj = valuePop(ctxt);
339 char *str = (
char *)xmlXPathCastToString(obj);
343 if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
346 for (
int j = 0;
j < obj->nodesetval->nodeNr;
j++) {
347 xmlNodePtr node = obj->nodesetval->nodeTab[
j];
349 if (
UNEXPECTED(node->type == XML_NAMESPACE_DECL)) {
350 xmlNodePtr nsparent = node->_private;
351 xmlNsPtr original = (xmlNsPtr) node;
360 proxy_factory(node, &child, intern, ctxt);
370 char *str = (
char *)xmlXPathCastToString(obj);
376 xmlXPathFreeObject(obj);
382static void php_dom_xpath_callback_cleanup_args(
zval *params, uint32_t param_count)
385 for (uint32_t i = 0; i < param_count; i++) {
394 zval callback_retval;
403 fci.
size =
sizeof(fci);
405 fci.
retval = &callback_retval;
421 zend_call_known_fcc(
Z_PTR_P(fcc_wrapper), &callback_retval, param_count, params,
NULL);
430 && (instanceof_function(
Z_OBJCE(callback_retval), dom_get_node_ce(php_dom_follow_spec_node((
const xmlNode *) ctxt->context->doc))))) {
440 valuePush(ctxt, xmlXPathNewNodeSet(nodep));
442 valuePush(ctxt, xmlXPathNewBoolean(
Z_TYPE(callback_retval) ==
IS_TRUE));
444 zend_type_error(
"Only objects that are instances of DOM nodes can be converted to an XPath expression");
448 zend_string *str = zval_get_string(&callback_retval);
449 valuePush(ctxt, xmlXPathNewString(BAD_CAST
ZSTR_VAL(str)));
467 uint32_t param_count =
num_args - 1;
468 zval *params = php_dom_xpath_callback_fetch_args(ctxt, param_count, evaluation_mode, intern, proxy_factory);
471 xmlXPathObjectPtr obj = valuePop(ctxt);
477 const char *function_name = (
const char *) obj->stringval;
478 size_t function_name_length =
strlen(function_name);
480 result = php_dom_xpath_callback_dispatch(xpath_callbacks, xpath_callbacks->
php_ns, ctxt, params, param_count, function_name, function_name_length);
483 xmlXPathFreeObject(obj);
484 php_dom_xpath_callback_cleanup_args(params, param_count);
488 valuePush(ctxt, xmlXPathNewString((
const xmlChar *)
""));
497 zval *params = php_dom_xpath_callback_fetch_args(ctxt, param_count, evaluation_mode, intern, proxy_factory);
499 const char *
namespace = (const char *) ctxt->context->functionURI;
507 const char *function_name = (
const char *) ctxt->context->function;
508 size_t function_name_length =
strlen(function_name);
510 zend_result result = php_dom_xpath_callback_dispatch(xpath_callbacks, ns, ctxt, params, param_count, function_name, function_name_length);
512 php_dom_xpath_callback_cleanup_args(params, param_count);
515 valuePush(ctxt, xmlXPathNewString((
const xmlChar *)
""));
sizeof(Countable|array $value, int $mode=COUNT_NORMAL)
xmlNodePtr php_dom_create_fake_namespace_decl(xmlNodePtr nodep, xmlNsPtr original, zval *return_value, dom_object *parent_intern)
unsigned char key[REFLECTION_KEY_LEN]
php_dom_register_functions_mode mode
php_dom_xpath_callback_ns * php_ns
PHP_DOM_EXPORT xmlNodePtr dom_object_get_node(dom_object *obj)
struct _dom_object dom_object
PHP_DOM_EXPORT bool php_dom_create_object(xmlNodePtr obj, zval *return_value, dom_object *domobj)
PHP_DOM_EXPORT void php_dom_xpath_callbacks_clean_argument_stack(xmlXPathParserContextPtr ctxt, uint32_t num_args)
PHP_DOM_EXPORT zend_result php_dom_xpath_callbacks_update_method_handler(php_dom_xpath_callbacks *registry, xmlXPathContextPtr ctxt, zend_string *ns, zend_string *name, const HashTable *callable_ht, php_dom_xpath_callback_name_validation name_validation, php_dom_xpath_callbacks_register_func_ctx register_func)
@ PHP_DOM_REG_FUNC_MODE_SET
@ PHP_DOM_REG_FUNC_MODE_ALL
@ PHP_DOM_REG_FUNC_MODE_NONE
PHP_DOM_EXPORT zend_result php_dom_xpath_callbacks_call_custom_ns(php_dom_xpath_callbacks *xpath_callbacks, xmlXPathParserContextPtr ctxt, int num_args, php_dom_xpath_nodeset_evaluation_mode evaluation_mode, dom_object *intern, php_dom_xpath_callbacks_proxy_factory proxy_factory)
PHP_DOM_EXPORT void php_dom_xpath_callbacks_dtor(php_dom_xpath_callbacks *registry)
PHP_DOM_EXPORT zend_result php_dom_xpath_callbacks_call_php_ns(php_dom_xpath_callbacks *xpath_callbacks, xmlXPathParserContextPtr ctxt, int num_args, php_dom_xpath_nodeset_evaluation_mode evaluation_mode, dom_object *intern, php_dom_xpath_callbacks_proxy_factory proxy_factory)
void(* php_dom_xpath_callbacks_register_func_ctx)(void *ctxt, const zend_string *ns, const zend_string *name)
void(* php_dom_xpath_callbacks_proxy_factory)(xmlNodePtr node, zval *proxy, dom_object *intern, xmlXPathParserContextPtr ctxt)
PHP_DOM_EXPORT void php_dom_xpath_callbacks_ctor(php_dom_xpath_callbacks *registry)
PHP_DOM_EXPORT void php_dom_xpath_callbacks_clean_node_list(php_dom_xpath_callbacks *registry)
php_dom_xpath_callback_name_validation
@ PHP_DOM_XPATH_CALLBACK_NAME_VALIDATE_NCNAME
@ PHP_DOM_XPATH_CALLBACK_NAME_VALIDATE_NULLS
php_dom_xpath_nodeset_evaluation_mode
@ PHP_DOM_XPATH_EVALUATE_NODESET_TO_STRING
@ PHP_DOM_XPATH_EVALUATE_NODESET_TO_NODESET
PHP_DOM_EXPORT HashTable * php_dom_xpath_callbacks_get_gc_for_whole_object(php_dom_xpath_callbacks *registry, zend_object *object, zval **table, int *n)
PHP_DOM_EXPORT zend_result php_dom_xpath_callbacks_update_single_method_handler(php_dom_xpath_callbacks *registry, xmlXPathContextPtr ctxt, zend_string *ns, zend_string *name, const zend_fcall_info_cache *fcc, php_dom_xpath_callback_name_validation name_validation, php_dom_xpath_callbacks_register_func_ctx register_func)
PHP_DOM_EXPORT void php_dom_xpath_callbacks_get_gc(php_dom_xpath_callbacks *registry, zend_get_gc_buffer *gc_buffer)
PHP_DOM_EXPORT void php_dom_xpath_callbacks_delayed_lib_registration(const php_dom_xpath_callbacks *registry, void *ctxt, php_dom_xpath_callbacks_register_func_ctx register_func)
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
ZEND_API ZEND_COLD void zend_type_error(const char *format,...)
ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format,...)
struct _zend_fcall_info_cache zend_fcall_info_cache
#define ZVAL_STRING(z, s)
#define array_init_size(arg, size)
struct _zend_fcall_info zend_fcall_info
#define ZVAL_STRINGL(z, s, l)
ZEND_API zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
#define FREE_HASHTABLE(ht)
#define safe_emalloc(nmemb, size, offset)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API zend_get_gc_buffer * zend_get_gc_buffer_create(void)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API void ZEND_FASTCALL zend_hash_real_init_packed(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *str, size_t len)
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert_new(HashTable *ht, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_update(HashTable *ht, zend_string *key, zval *pData)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
#define zend_new_array(size)
#define ZEND_HASH_FOREACH_STR_KEY_VAL(ht, _key, _val)
#define ZEND_HASH_MAP_FOREACH_STR_KEY(ht, _key)
#define ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(ht, _key, _ptr)
#define ZEND_HASH_FOREACH_END()
#define ZVAL_EMPTY_ARRAY(z)
struct _zend_string zend_string
ZEND_API HashTable * zend_std_get_properties(zend_object *zobj)
ZEND_API HashTable * zend_std_get_gc(zend_object *zobj, zval **table, int *n)
#define UNEXPECTED(condition)
struct _zend_object zend_object
#define Z_ARRVAL_P(zval_p)
struct _zend_array HashTable
#define ZVAL_DOUBLE(z, d)
ZEND_RESULT_CODE zend_result
ZEND_API void zval_ptr_dtor(zval *zval_ptr)