23#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
28#define PHP_DOM_XPATH_QUERY 0
29#define PHP_DOM_XPATH_EVALUATE 1
35#ifdef LIBXML_XPATH_ENABLED
37void dom_xpath_objects_free_storage(
zend_object *
object)
44 xmlXPathFreeContext((xmlXPathContextPtr) intern->
dom.
ptr);
45 php_libxml_decrement_doc_ref((php_libxml_node_object *) &intern->
dom);
57static void dom_xpath_proxy_factory(xmlNodePtr node,
zval *child,
dom_object *intern, xmlXPathParserContextPtr ctxt)
66static dom_xpath_object *dom_xpath_ext_fetch_intern(xmlXPathParserContextPtr ctxt)
69 xmlGenericError(xmlGenericErrorContext,
70 "xmlExtFunctionTest: Function called from outside of PHP\n");
76 xmlGenericError(xmlGenericErrorContext,
77 "xmlExtFunctionTest: failed to get the internal object\n");
95static void dom_xpath_ext_function_string_php(xmlXPathParserContextPtr ctxt,
int nargs)
101static void dom_xpath_ext_function_object_php(xmlXPathParserContextPtr ctxt,
int nargs)
107static void dom_xpath_ext_function_trampoline(xmlXPathParserContextPtr ctxt,
int nargs)
121 bool register_node_ns =
true;
122 xmlDocPtr docp =
NULL;
131 xmlXPathContextPtr ctx = xmlXPathNewContext(docp);
138 xmlXPathContextPtr oldctx = intern->
dom.
ptr;
139 if (oldctx !=
NULL) {
140 php_libxml_decrement_doc_ref((php_libxml_node_object *) &intern->
dom);
141 xmlXPathFreeContext(oldctx);
146 xmlXPathRegisterFuncNS (ctx, (
const xmlChar *)
"functionString",
147 (
const xmlChar *)
"http://php.net/xpath",
148 dom_xpath_ext_function_string_php);
149 xmlXPathRegisterFuncNS (ctx, (
const xmlChar *)
"function",
150 (
const xmlChar *)
"http://php.net/xpath",
151 dom_xpath_ext_function_object_php);
154 ctx->userData = (
void *)intern;
157 php_libxml_increment_doc_ref((php_libxml_node_object *) &intern->
dom, docp);
175 xmlXPathContextPtr ctx = (xmlXPathContextPtr) obj->
ptr;
178 docp = (xmlDocPtr) ctx->doc;
205 php_xpath_obj_from_dom_obj(obj)->register_node_ns =
zend_is_true(newval);
214 size_t prefix_len, ns_uri_len;
215 unsigned char *
prefix, *ns_uri;
223 xmlXPathContextPtr ctxp = intern->
dom.
ptr;
229 if (xmlXPathRegisterNs(ctxp,
prefix, ns_uri) != 0) {
248 xmlNodePtr nodep =
NULL;
249 size_t expr_len, xpath_type;
260 xmlXPathContextPtr ctxp = intern->
dom.
ptr;
266 xmlDocPtr docp = ctxp->doc;
282 nodep = xmlDocGetRootElement(docp);
285 if (nodep && docp != nodep->doc) {
293 if (register_node_ns && nodep !=
NULL) {
300 ctxp->namespaces = in_scope_ns.
list;
301 ctxp->nsNr = in_scope_ns.
count;
304 xmlXPathObjectPtr xpathobjp = xmlXPathEvalExpression(BAD_CAST expr, ctxp);
307 if (register_node_ns && nodep !=
NULL) {
309 ctxp->namespaces =
NULL;
325 if (
type == PHP_DOM_XPATH_QUERY) {
326 xpath_type = XPATH_NODESET;
328 xpath_type = xpathobjp->type;
331 switch (xpath_type) {
335 xmlNodeSetPtr nodesetp;
338 if (xpathobjp->type == XPATH_NODESET &&
NULL != (nodesetp = xpathobjp->nodesetval) && nodesetp->nodeNr) {
341 for (
int i = 0; i < nodesetp->nodeNr; i++) {
342 xmlNodePtr node = nodesetp->nodeTab[i];
345 if (node->type == XML_NAMESPACE_DECL) {
349 "The namespace axis is not well-defined in the living DOM specification. "
350 "Use Dom\\Element::getInScopeNamespaces() or Dom\\Element::getDescendantNamespaces() instead.",
357 xmlNodePtr nsparent = node->_private;
358 xmlNsPtr original = (xmlNsPtr) node;
369 add_next_index_zval(&
retval, &child);
376 dom_xpath_iter(&
retval, nodeobj);
397 xmlXPathFreeObject(xpathobjp);
439 &intern->xpath_callbacks,
452 xmlXPathRegisterFuncNS((xmlXPathContextPtr) ctxt, (
const xmlChar *)
ZSTR_VAL(
name), (
const xmlChar *)
ZSTR_VAL(ns), dom_xpath_ext_function_trampoline);
482 dom_xpath_register_func_in_ctx
495 if (memchr(input,
'\'', input_len) ==
NULL) {
496 zend_string *
const output = zend_string_safe_alloc(1, input_len, 2,
false);
499 ZSTR_VAL(output)[input_len + 1] =
'\'';
500 ZSTR_VAL(output)[input_len + 2] =
'\0';
502 }
else if (memchr(input,
'"', input_len) ==
NULL) {
503 zend_string *
const output = zend_string_safe_alloc(1, input_len, 2,
false);
506 ZSTR_VAL(output)[input_len + 1] =
'"';
507 ZSTR_VAL(output)[input_len + 2] =
'\0';
512 smart_str_appendl(&output,
ZEND_STRL(
"concat("));
513 const char *
ptr = input;
514 const char *
const end = input + input_len;
516 const char *
const single_quote_ptr = memchr(
ptr,
'\'',
end -
ptr);
517 const char *
const double_quote_ptr = memchr(
ptr,
'"',
end -
ptr);
518 const size_t distance_to_single_quote = single_quote_ptr ? single_quote_ptr -
ptr :
end -
ptr;
519 const size_t distance_to_double_quote = double_quote_ptr ? double_quote_ptr -
ptr :
end -
ptr;
520 const size_t bytes_until_quote =
MAX(distance_to_single_quote, distance_to_double_quote);
521 const char quote_method = (distance_to_single_quote > distance_to_double_quote) ?
'\'' :
'"';
522 smart_str_appendc(&output, quote_method);
523 smart_str_appendl(&output,
ptr, bytes_until_quote);
524 smart_str_appendc(&output, quote_method);
525 ptr += bytes_until_quote;
526 smart_str_appendc(&output,
',');
529 ZSTR_VAL(output.s)[output.s->len - 1] =
')';
PHP_DOM_EXPORT zend_class_entry * dom_modern_node_class_entry
PHP_DOM_EXPORT zend_class_entry * dom_node_class_entry
PHP_DOM_EXPORT zend_class_entry * dom_abstract_base_document_class_entry
PHP_DOM_EXPORT zend_class_entry * dom_document_class_entry
void php_dom_throw_error_with_message(dom_exception_code error_code, const char *error_message, bool strict_error)
void php_dom_throw_error(dom_exception_code error_code, bool strict_error)
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
PHP_DOM_EXPORT php_dom_in_scope_ns php_dom_get_in_scope_ns_legacy(const xmlNode *node)
PHP_DOM_EXPORT php_dom_in_scope_ns php_dom_get_in_scope_ns(php_dom_libxml_ns_mapper *ns_mapper, const xmlNode *node, bool ignore_elements)
PHP_DOM_EXPORT void php_dom_in_scope_ns_destroy(php_dom_in_scope_ns *in_scope_ns)
PHP_DOM_EXPORT php_dom_libxml_ns_mapper * php_dom_get_ns_mapper(dom_object *object)
xmlNodePtr php_dom_create_fake_namespace_decl(xmlNodePtr nodep, xmlNsPtr original, zval *return_value, dom_object *parent_intern)
#define DOM_GET_OBJ(__ptr, __id, __prtype, __intern)
void php_dom_create_iterator(zval *return_value, dom_iterator_type iterator_type, bool modern)
unsigned const char * end
php_libxml_ref_obj * document
php_dom_xpath_callbacks xpath_callbacks
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_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)
PHP_DOM_EXPORT void php_dom_xpath_callbacks_ctor(php_dom_xpath_callbacks *registry)
@ 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)
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
#define INTERNAL_FUNCTION_PARAMETERS
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API void zend_release_fcall_info_cache(zend_fcall_info_cache *fcc)
#define Z_PARAM_PATH_STR(dest)
struct _zend_fcall_info_cache zend_fcall_info_cache
#define Z_PARAM_ARRAY_HT_OR_STR_OR_NULL(dest_ht, dest_str)
#define ZEND_PARSE_PARAMETERS_END()
#define array_init_size(arg, size)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
struct _zend_fcall_info zend_fcall_info
#define Z_PARAM_FUNC_NO_TRAMPOLINE_FREE(dest_fci, dest_fcc)
ZEND_API bool zend_is_executing(void)
ZEND_API void ZEND_FASTCALL zend_hash_real_init_packed(HashTable *ht)
#define ZVAL_EMPTY_ARRAY(z)
struct _zend_string zend_string
ZEND_API void zend_object_std_dtor(zend_object *object)
ZEND_API bool ZEND_FASTCALL zend_is_true(const zval *op)
#define ZEND_IGNORE_VALUE(x)
#define XtOffsetOf(s_type, field)
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define zend_string_equals_literal(str, literal)
#define Z_ARRVAL_P(zval_p)
struct _zend_array HashTable
ZEND_RESULT_CODE zend_result
#define ZVAL_COPY_VALUE(z, v)