22#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
32#define DECLARE_NS_TOKEN(name, uri) \
33 static const struct { \
34 char val[sizeof(uri)]; \
36 } decl_##name = { uri, 0.0 }; \
37 PHP_DOM_EXPORT const php_dom_ns_magic_token *(name) = (const php_dom_ns_magic_token *) &decl_##name;
45static void php_dom_libxml_ns_mapper_prefix_map_element_dtor(
zval *
zv)
58 zend_hash_init(prefix_map, 0,
NULL, php_dom_libxml_ns_mapper_prefix_map_element_dtor,
false);
60 ZVAL_ARR(&zv_prefix_map, prefix_map);
80 zend_string *uri_str = zend_string_init(uri, length,
false);
82 (*ptr)->_private = (
void *) token;
102 xmlNsPtr ns =
emalloc(
sizeof(*ns));
103 memset(ns, 0,
sizeof(*ns));
128 HashTable *prefix_map = php_dom_libxml_ns_mapper_ensure_prefix_map(mapper, &uri);
129 xmlNsPtr found = zend_hash_find_ptr(prefix_map,
prefix);
134 xmlNsPtr ns = dom_create_owned_ns(
prefix, uri);
146 if (prefix_len == 0) {
150 zend_string *prefix_str = zend_string_init((
const char *)
prefix, prefix_len,
false);
157static xmlNsPtr php_dom_libxml_ns_mapper_get_ns_raw_strings_ex(
php_dom_libxml_ns_mapper *mapper,
const char *
prefix,
size_t prefix_len,
const char *uri,
size_t uri_len)
160 zend_string *uri_str = zend_string_init(uri, uri_len,
false);
180 return php_dom_libxml_ns_mapper_get_ns_raw_strings(mapper,
prefix, uri);
183static xmlNsPtr php_dom_libxml_ns_mapper_store_and_normalize_parsed_ns(
php_dom_libxml_ns_mapper *mapper, xmlNsPtr ns)
187 zend_string *href_str = zend_string_init((
const char *) ns->href, xmlStrlen(ns->href),
false);
189 HashTable *prefix_map = php_dom_libxml_ns_mapper_ensure_prefix_map(mapper, &href_str);
192 const char *
prefix = (
const char *) ns->prefix;
198 prefix_len = xmlStrlen(ns->prefix);
201 zval *
zv = zend_hash_str_find_ptr(prefix_map,
prefix, prefix_len);
218 xmlNsPtr last_mapped_src, last_mapped_dst;
220} dom_libxml_reconcile_ctx;
224 return &php_dom_get_private_data(
object)->ns_mapper;
231 if (ns->prefix !=
NULL) {
232 xmlns_ns = php_dom_libxml_ns_mapper_get_ns_raw_strings(mapper,
"xmlns",
DOM_XMLNS_NS_URI);
236 name = BAD_CAST
"xmlns";
241 return xmlSetNsProp(node, xmlns_ns,
name, ns->href);
246 if (node->nsDef ==
NULL) {
252 xmlAttrPtr
attr = node->properties;
253 node->properties =
NULL;
255 xmlNsPtr ns = node->nsDef;
256 xmlAttrPtr last_added =
NULL;
259 php_dom_libxml_ns_mapper_store_and_normalize_parsed_ns(mapper, ns);
260 xmlNsPtr
next = ns->next;
262 php_libxml_set_old_ns(node->doc, ns);
264 }
while (ns !=
NULL);
266 if (last_added !=
NULL) {
269 last_added->next =
attr;
270 attr->prev = last_added;
274 node->properties =
attr;
284 if (ns->_private == magic_token) {
286 }
else if (ns->_private !=
NULL && ((uintptr_t) ns->_private & 1) == 0) {
291 if (xmlStrEqual(ns->href, BAD_CAST magic_token)) {
292 if (ns->_private ==
NULL) {
294 ns->_private = (
void *) magic_token;
304 xmlNsPtr ns = nodep->ns;
322 if (attrp->ns !=
NULL) {
324 xmlNodePtr nodep = attrp->parent;
325 xmlNsPtr matching_ns = xmlSearchNs(nodep->doc, nodep, attrp->ns->prefix);
326 if (matching_ns && xmlStrEqual(matching_ns->href, attrp->ns->href)) {
328 attrp->ns = matching_ns;
330 if (attrp->ns->prefix !=
NULL) {
333 xmlReconciliateNs(nodep->doc, nodep);
339static zend_always_inline void php_dom_libxml_reconcile_modern_single_node(dom_libxml_reconcile_ctx *ctx, xmlNodePtr node)
343 if (node->ns == ctx->last_mapped_src) {
344 node->ns = ctx->last_mapped_dst;
349 xmlNsPtr new_ns = zend_hash_index_find_ptr(&ctx->old_ns_to_new_ns_ptr, dom_mangle_pointer_for_key(node->ns));
350 if (new_ns ==
NULL) {
352 const char *
prefix = (
const char *) node->ns->prefix;
353 const char *href = (
const char *) node->ns->href;
355 zend_hash_index_add_new_ptr(&ctx->old_ns_to_new_ns_ptr, dom_mangle_pointer_for_key(node->ns), new_ns);
356 ctx->last_mapped_src = node->ns;
357 ctx->last_mapped_dst = new_ns;
359 }
else if (node->ns != new_ns) {
369 return node->children ==
NULL && node->properties ==
NULL && node->ns == node->nsDef;
372static zend_always_inline void php_dom_libxml_reconcile_modern_single_element_node(dom_libxml_reconcile_ctx *ctx, xmlNodePtr node)
379 if (node->ns !=
NULL) {
380 php_dom_libxml_reconcile_modern_single_node(ctx, node);
385 php_dom_libxml_reconcile_modern_single_node(ctx, (xmlNodePtr)
attr);
393 if (node->ns !=
NULL) {
399 if (node->type !=
XML_ELEMENT_NODE || dom_libxml_reconcile_fast_element_skip(node)) {
403 dom_libxml_reconcile_ctx ctx;
405 ctx.last_mapped_src =
NULL;
406 ctx.last_mapped_dst =
NULL;
407 ctx.ns_mapper = ns_mapper;
409 php_dom_libxml_reconcile_modern_single_element_node(&ctx, node);
411 xmlNodePtr base = node;
412 node = node->children;
413 while (node !=
NULL) {
417 php_dom_libxml_reconcile_modern_single_element_node(&ctx, node);
420 node = php_dom_next_in_tree_order(node, base);
440 for (
const xmlNode *cur = node; cur !=
NULL; cur = cur->parent) {
443 if (!ignore_elements && cur->ns !=
NULL && cur->ns->prefix !=
NULL) {
444 const char *
prefix = (
const char *) cur->ns->prefix;
454 const char *
prefix = (
const char *)
attr->name;
455 xmlNsPtr ns = php_dom_libxml_ns_mapper_get_ns_raw_strings(ns_mapper,
prefix, (
const char *)
attr->children->content);
462 in_scope_ns.
count = zend_hash_num_elements(&tmp_prefix_to_ns_table);
468 in_scope_ns.
list[index++] = ns;
482 in_scope_ns.
list = xmlGetNsList(node->doc, node);
483 in_scope_ns.
count = 0;
500 xmlFree(in_scope_ns->
list);
memset(ptr, 0, type->size)
#define DOM_Z_IS_OWNED(z)
#define DOM_Z_UNOWNED(z, v)
#define DOM_Z_OWNED(z, v)
PHP_DOM_EXPORT php_dom_in_scope_ns php_dom_get_in_scope_ns_legacy(const xmlNode *node)
PHP_DOM_EXPORT const php_dom_ns_magic_token * php_dom_ns_is_html_magic_token
PHP_DOM_EXPORT xmlNsPtr php_dom_libxml_ns_mapper_get_ns_raw_prefix_string(php_dom_libxml_ns_mapper *mapper, const xmlChar *prefix, size_t prefix_len, zend_string *uri)
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 const php_dom_ns_magic_token * php_dom_ns_is_xmlns_magic_token
PHP_DOM_EXPORT xmlNsPtr php_dom_libxml_ns_mapper_ensure_html_ns(php_dom_libxml_ns_mapper *mapper)
PHP_DOM_EXPORT bool php_dom_ns_is_fast_ex(xmlNsPtr ns, const php_dom_ns_magic_token *magic_token)
PHP_DOM_EXPORT void php_dom_in_scope_ns_destroy(php_dom_in_scope_ns *in_scope_ns)
PHP_DOM_EXPORT const php_dom_ns_magic_token * php_dom_ns_is_xlink_magic_token
struct php_dom_ns_magic_token php_dom_ns_magic_token
PHP_DOM_EXPORT xmlNsPtr php_dom_libxml_ns_mapper_ensure_prefixless_xmlns_ns(php_dom_libxml_ns_mapper *mapper)
PHP_DOM_EXPORT bool php_dom_ns_is_fast(const xmlNode *nodep, const php_dom_ns_magic_token *magic_token)
PHP_DOM_EXPORT bool php_dom_ns_is_html_and_document_is_html(const xmlNode *nodep)
PHP_DOM_EXPORT void php_dom_libxml_reconcile_modern(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr node)
PHP_DOM_EXPORT void php_dom_reconcile_attribute_namespace_after_insertion(xmlAttrPtr attrp)
PHP_DOM_EXPORT xmlNsPtr php_dom_libxml_ns_mapper_get_ns(php_dom_libxml_ns_mapper *mapper, zend_string *prefix, zend_string *uri)
PHP_DOM_EXPORT void php_dom_ns_compat_mark_attribute_list(php_dom_libxml_ns_mapper *mapper, xmlNodePtr node)
PHP_DOM_EXPORT const php_dom_ns_magic_token * php_dom_ns_is_svg_magic_token
#define DOM_MATHML_NS_URI
PHP_DOM_EXPORT const php_dom_ns_magic_token * php_dom_ns_is_mathml_magic_token
PHP_DOM_EXPORT php_dom_libxml_ns_mapper * php_dom_get_ns_mapper(dom_object *object)
PHP_DOM_EXPORT xmlNsPtr php_dom_libxml_ns_mapper_get_ns_raw_strings_nullsafe(php_dom_libxml_ns_mapper *mapper, const char *prefix, const char *uri)
PHP_DOM_EXPORT const php_dom_ns_magic_token * php_dom_ns_is_xml_magic_token
PHP_DOM_EXPORT xmlAttrPtr php_dom_ns_compat_mark_attribute(php_dom_libxml_ns_mapper *mapper, xmlNodePtr node, xmlNsPtr ns)
const XML_HTML_DOCUMENT_NODE
const XML_LOCAL_NAMESPACE
HashTable uri_to_prefix_map
xmlNsPtr prefixless_xmlns_ns
struct _dom_object dom_object
#define safe_emalloc(nmemb, size, offset)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_add_new(HashTable *ht, zend_string *key, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_add_new(HashTable *ht, const char *str, size_t len, zval *pData)
ZEND_API void ZEND_FASTCALL zend_hash_real_init_mixed(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
#define ZEND_HASH_FOREACH_END()
struct _zend_string zend_string
#define EXPECTED(condition)
#define zend_always_inline
#define XtOffsetOf(s_type, field)
ZEND_API zend_string * zend_empty_string
#define Z_ARRVAL_P(zval_p)
struct _zend_array HashTable