22#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
29#include <libxml/xmlsave.h>
37static zend_result dom_inner_html_write_string(
void *application_data,
const char *
buf)
40 smart_str_appends(output,
buf);
44static zend_result dom_inner_html_write_string_len(
void *application_data,
const char *
buf,
size_t len)
47 smart_str_appendl(output,
buf,
len);
65 const xmlDoc *context_document = node->doc;
85 xmlSaveCtxtPtr ctxt = xmlSaveToIO(dom_write_smart_str,
NULL, &str,
"UTF-8", XML_SAVE_AS_XML);
87 xmlCharEncodingHandlerPtr
handler = xmlFindCharEncodingHandler(
"UTF-8");
88 xmlOutputBufferPtr
out = xmlOutputBufferCreateIO(dom_write_smart_str,
NULL, &str,
handler);
92 xmlNodePtr child = node->children;
101 (
void) xmlSaveClose(ctxt);
105 smart_str_free_ex(&str,
false);
137 while (buf_ref < buf_end) {
138 if (decode.
u.
utf_8.
need == 0 && *buf_ref < 0x80) {
156 last_output = buf_ref;
160 if (buf_ref != last_output) {
173 switch (quirks_mode) {
182static xmlNodePtr dom_html_fragment_parsing_algorithm(
dom_object *obj, xmlNodePtr context_node,
const zend_string *input, php_libxml_quirks_mode quirks_mode)
196 if (context_node->ns ==
NULL || context_node->ns->href ==
NULL) {
200 ns_uri = context_node->ns->href;
201 ns_uri_len = xmlStrlen(ns_uri);
206 lxb_dom_node_t *node = dom_html_fragment_lexbor_parse(document, element, input);
207 xmlNodePtr fragment =
NULL;
223static void dom_xml_parser_tag_name(
const xmlNode *context_node, xmlParserCtxtPtr parser)
225 if (context_node->ns !=
NULL && context_node->ns->prefix !=
NULL) {
226 xmlParseChunk(parser, (
const char *) context_node->ns->prefix, xmlStrlen(context_node->ns->prefix), 0);
227 xmlParseChunk(parser,
":", 1, 0);
230 xmlParseChunk(parser, (
const char *) context_node->name, xmlStrlen(context_node->name), 0);
235 xmlParseChunk(parser,
"<", 1, 0);
236 dom_xml_parser_tag_name(context_node, parser);
241 for (
size_t i = 0; i < in_scope_ns.
count; i++) {
242 const xmlNs *ns = in_scope_ns.
list[i];
243 xmlParseChunk(parser,
" xmlns:", 7, 0);
245 xmlParseChunk(parser, (
const char *) ns->prefix, xmlStrlen(ns->prefix), 0);
246 xmlParseChunk(parser,
"=\"", 2, 0);
247 xmlParseChunk(parser, (
const char *) ns->href, xmlStrlen(ns->href), 0);
248 xmlParseChunk(parser,
"\"", 1, 0);
253 if (default_ns !=
NULL) {
254 xmlParseChunk(parser,
" xmlns=\"", 8, 0);
255 xmlParseChunk(parser, default_ns,
strlen(default_ns), 0);
256 xmlParseChunk(parser,
"\"", 1, 0);
259 xmlParseChunk(parser,
">", 1, 0);
263 xmlParseChunk(parser,
"</", 2, 0);
264 dom_xml_parser_tag_name(context_node, parser);
265 xmlParseChunk(parser,
">", 1, 1);
269static xmlNodePtr dom_xml_fragment_parsing_algorithm(
dom_object *obj,
const xmlNode *context_node,
const zend_string *input)
272 xmlParserCtxtPtr parser = xmlCreatePushParserCtxt(
NULL,
NULL,
NULL, 0,
NULL);
280 xmlDictFree(parser->dict);
281 if (context_node->doc->dict ==
NULL) {
282 context_node->doc->dict = xmlDictCreate();
283 xmlDictSetLimit(context_node->doc->dict, XML_MAX_DICTIONARY_LIMIT);
285 parser->dict = context_node->doc->dict;
287 php_libxml_sanitize_parse_ctxt_options(parser);
288 xmlCtxtUseOptions(parser, XML_PARSE_IGNORE_ENC | XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
290 xmlCharEncodingHandlerPtr
encoding = xmlFindCharEncodingHandler(
"UTF-8");
294 dom_xml_fragment_parsing_algorithm_parse(ns_mapper, context_node, input, parser);
297 if (!parser->wellFormed || !parser->nsWellFormed) {
299 xmlFreeDoc(parser->myDoc);
300 xmlFreeParserCtxt(parser);
305 xmlDocPtr doc = parser->myDoc;
306 xmlFreeParserCtxt(parser);
312 xmlNodePtr document_element = doc->children;
313 if (document_element ==
NULL || document_element->next !=
NULL) {
320 xmlNodePtr fragment = xmlNewDocFragment(context_node->doc);
322 xmlNodePtr child = document_element->children;
325 xmlSetTreeDoc(document_element, context_node->doc);
326 xmlAddChildList(fragment, child);
328 document_element->children =
NULL;
329 document_element->last =
NULL;
345 fragment = dom_xml_fragment_parsing_algorithm(obj, context_node,
Z_STR_P(newval));
347 fragment = dom_html_fragment_parsing_algorithm(obj, context_node,
Z_STR_P(newval), obj->
document->quirks_mode);
350 if (fragment ==
NULL) {
356 if (context_node ==
NULL) {
357 xmlFreeNode(fragment);
363 php_libxml_invalidate_node_list_cache(obj->
document);
lxb_codepoint_t lxb_encoding_decode_utf_8_single(lxb_encoding_decode_t *ctx, const lxb_char_t **data, const lxb_char_t *end)
struct lxb_dom_node lxb_dom_node_t
struct lxb_dom_element lxb_dom_element_t
@ LXB_DOM_DOCUMENT_CMODE_QUIRKS
@ LXB_DOM_DOCUMENT_CMODE_LIMITED_QUIRKS
@ LXB_DOM_DOCUMENT_CMODE_NO_QUIRKS
zend_result dom_element_inner_html_read(dom_object *obj, zval *retval)
zend_result dom_element_inner_html_write(dom_object *obj, zval *newval)
#define DOM_PROP_NODE(type, name, obj)
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)
#define LXB_ENCODING_REPLACEMENT_BYTES
@ LXB_ENCODING_REPLACEMENT_SIZE
@ LXB_ENCODING_MAX_CODEPOINT
struct lxb_encoding_data lxb_encoding_data_t
lxb_inline const lxb_encoding_data_t * lxb_encoding_data(lxb_encoding_t encoding)
lxb_inline lxb_status_t lxb_encoding_decode_init_single(lxb_encoding_decode_t *decode, const lxb_encoding_data_t *encoding_data)
zend_ffi_ctype_name_buf buf
lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert_fragment(lxb_dom_node_t *start_node, xmlDocPtr lxml_doc, xmlNodePtr *fragment_out, bool compact_text_nodes, bool create_default_ns, php_dom_private_data *private_data)
lexbor_libxml2_bridge_status
@ LEXBOR_LIBXML2_BRIDGE_STATUS_OK
zend_result dom_html5_serialize(dom_html5_serialize_context *ctx, const xmlNode *node)
struct lxb_html_document lxb_html_document_t
lxb_dom_element_t * lxb_dom_element_interface_create(lxb_dom_document_t *document)
lxb_html_document_t * lxb_html_document_create(void)
lxb_status_t lxb_html_document_parse_fragment_chunk(lxb_html_document_t *document, const lxb_char_t *html, size_t size)
lxb_status_t lxb_html_document_parse_fragment_chunk_begin(lxb_html_document_t *document, lxb_dom_element_t *element)
lxb_html_document_t * lxb_html_document_destroy(lxb_html_document_t *document)
lxb_dom_node_t * lxb_html_document_parse_fragment_chunk_end(lxb_html_document_t *document)
PHP_DOM_EXPORT const php_dom_ns_magic_token * php_dom_ns_is_html_magic_token
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 bool php_dom_ns_is_fast(const xmlNode *nodep, const php_dom_ns_magic_token *magic_token)
PHP_DOM_EXPORT php_dom_libxml_ns_mapper * php_dom_get_ns_mapper(dom_object *object)
const lxb_ns_data_t * lxb_ns_data_by_link(lexbor_hash_t *hash, const lxb_char_t *link, size_t length)
bool php_dom_pre_insert(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePtr parent, xmlNodePtr insertion_point)
const char * dom_locate_a_namespace(const xmlNode *node, const zend_string *prefix)
void dom_mark_namespaces_as_attributes_too(php_dom_libxml_ns_mapper *ns_mapper, xmlDocPtr doc)
void dom_remove_all_children(xmlNodePtr nodep)
const XML_HTML_DOCUMENT_NODE
xmlCharEncodingHandlerPtr encoding
xmlNodePtr php_dom_ensure_templated_content(php_dom_private_data *private_data, xmlNodePtr template_node)
php_libxml_ref_obj * document
zend_result(* write_string_len)(void *application_data, const char *buf, size_t len)
php_dom_private_data * private_data
zend_result(* write_string)(void *application_data, const char *buf)
lxb_dom_document_cmode_t compat_mode
lxb_dom_node_t * last_child
lxb_encoding_ctx_utf_8_t utf_8
union lxb_encoding_decode_t::@302274252113053227061303304053361346350151303155 u
lxb_dom_document_t dom_document
const lxb_tag_data_t * lxb_tag_data_by_name(lexbor_hash_t *hash, const lxb_char_t *name, size_t len)
unsigned int lxb_status_t
struct _dom_object dom_object
int dom_xml_serialize(xmlSaveCtxtPtr ctx, xmlOutputBufferPtr out, xmlNodePtr node, bool format, bool require_well_formed, php_dom_private_data *private_data)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
struct _zend_string zend_string
#define EXPECTED(condition)
#define EMPTY_SWITCH_DEFAULT_CASE()
#define UNEXPECTED(condition)
#define ZSTR_IS_VALID_UTF8(s)
ZEND_RESULT_CODE zend_result
fbc internal_function handler(call, ret)