diff --git a/NEWS b/NEWS
index 0e4a16cf6e8a6..0694dc8543309 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,7 @@ PHP NEWS
. Handle OOM more consistently. (nielsdos)
. Implemented "Improve callbacks in ext/dom and ext/xsl" RFC. (nielsdos)
. Added DOMXPath::quote() static method. (divinity76)
+ . Implemented opt-in ext/dom spec compliance RFC. (nielsdos)
- Fileinfo:
. Update to libmagic 5.45. (nielsdos)
diff --git a/UPGRADING b/UPGRADING
index 3b080ac78444d..00ba1c2885bcb 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -179,14 +179,6 @@ PHP 8.4 UPGRADE NOTES
. Added constant DOMNode::DOCUMENT_POSITION_CONTAINS.
. Added constant DOMNode::DOCUMENT_POSITION_CONTAINED_BY.
. Added constant DOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC.
- . Implemented DOM HTML5 parsing and serialization.
- RFC: https://wiki.php.net/rfc/domdocument_html5_parser.
- This RFC adds the new DOM namespace along with class and constant aliases.
- There are two new classes to handle HTML and XML documents:
- DOM\HTMLDocument and DOM\XMLDocument.
- These classes provide a cleaner API to handle HTML and XML documents.
- Furthermore, the DOM\HTMLDocument class implements spec-compliant HTML5
- parsing and serialization.
. It is now possible to pass any callable to registerPhpFunctions().
RFC: https://wiki.php.net/rfc/improve_callbacks_dom_and_xsl
@@ -436,6 +428,22 @@ PHP 8.4 UPGRADE NOTES
7. New Classes and Interfaces
========================================
+- DOM:
+ . Implemented DOM HTML5 parsing and serialization.
+ RFC: https://wiki.php.net/rfc/domdocument_html5_parser.
+ This RFC adds the new DOM namespace along with new classes and
+ constant aliases.
+ There are two new classes to handle HTML and XML documents:
+ DOM\HTMLDocument and DOM\XMLDocument.
+ These classes provide a cleaner API to handle HTML and XML documents.
+ Furthermore, the DOM\HTMLDocument class implements spec-compliant HTML5
+ parsing and serialization.
+ . Implemented opt-in ext/dom spec compliance RFC.
+ This adds new classes in the DOM namespace that correspond to modern
+ equivalents to the old DOM classes in the global namespaces.
+ The new classes follow the DOM living spec.
+ RFC: https://wiki.php.net/rfc/opt_in_dom_spec_compliance
+
========================================
8. Removed Extensions and SAPIs
========================================
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index 217d86809ad46..c0fa021120cc3 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -140,6 +140,7 @@ PHP 8.4 INTERNALS UPGRADE NOTES
- The macros DOM_NO_ARGS() and DOM_NOT_IMPLEMENTED() have been removed.
- New public APIs are available to handle callbacks from XPath, see
xpath_callbacks.h.
+ - Added public APIs to manipulate namespace data, see namespace_compat.h.
b. ext/random
- The macro RAND_RANGE_BADSCALING() has been removed. The implementation
@@ -173,6 +174,8 @@ PHP 8.4 INTERNALS UPGRADE NOTES
- Added php_libxml_pretend_ctx_error_ex() to emit errors as if they had come
from libxml.
- Removed the "properties" HashTable field from php_libxml_node_object.
+ - Added a way to attached private data to a php_libxml_ref_obj.
+ - Added a way to fix a class type onto php_libxml_ref_obj.
e. ext/date
- Added the php_format_date_ex() API to format instances of php_date_obj.
diff --git a/ext/dom/attr.c b/ext/dom/attr.c
index cb1129c3940f0..3f5783defd148 100644
--- a/ext/dom/attr.c
+++ b/ext/dom/attr.c
@@ -72,20 +72,24 @@ PHP_METHOD(DOMAttr, __construct)
/* {{{ name string
readonly=yes
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1112119403
+Modern spec URL: https://dom.spec.whatwg.org/#dom-attr-name
Since:
*/
zend_result dom_attr_name_read(dom_object *obj, zval *retval)
{
- xmlAttrPtr attrp;
-
- attrp = (xmlAttrPtr) dom_object_get_node(obj);
+ xmlAttrPtr attrp = (xmlAttrPtr) dom_object_get_node(obj);
if (attrp == NULL) {
php_dom_throw_error(INVALID_STATE_ERR, 1);
return FAILURE;
}
- ZVAL_STRING(retval, (char *) attrp->name);
+ if (php_dom_follow_spec_intern(obj)) {
+ zend_string *str = dom_node_get_node_name_attribute_or_element((xmlNodePtr) attrp, false);
+ ZVAL_NEW_STR(retval, str);
+ } else {
+ ZVAL_STRING(retval, (char *) attrp->name);
+ }
return SUCCESS;
}
@@ -99,7 +103,7 @@ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-86
*/
zend_result dom_attr_specified_read(dom_object *obj, zval *retval)
{
- /* TODO */
+ /* From spec: "useless; always returns true" */
ZVAL_TRUE(retval);
return SUCCESS;
}
@@ -147,7 +151,13 @@ zend_result dom_attr_value_write(dom_object *obj, zval *newval)
zend_string *str = Z_STR_P(newval);
dom_remove_all_children((xmlNodePtr) attrp);
- xmlNodeSetContentLen((xmlNodePtr) attrp, (xmlChar *) ZSTR_VAL(str), ZSTR_LEN(str));
+
+ if (php_dom_follow_spec_intern(obj)) {
+ xmlNodePtr node = xmlNewDocTextLen(attrp->doc, BAD_CAST ZSTR_VAL(str), ZSTR_LEN(str));
+ xmlAddChild((xmlNodePtr) attrp, node);
+ } else {
+ xmlNodeSetContentLen((xmlNodePtr) attrp, BAD_CAST ZSTR_VAL(str), ZSTR_LEN(str));
+ }
return SUCCESS;
}
diff --git a/ext/dom/characterdata.c b/ext/dom/characterdata.c
index 36298f526830f..f54e042aa7d25 100644
--- a/ext/dom/characterdata.c
+++ b/ext/dom/characterdata.c
@@ -30,6 +30,24 @@
* Since:
*/
+/* For some peculiar reason, many of these methods operate on unsigned numbers.
+ * Unfortunately, "old DOM" doesn't, so we have to conditionally convert...
+ * And the reason we're using "unsigned int" instead of "unsigned zend_long" is because libxml2 internally works with ints. */
+static bool dom_convert_number_unsigned(dom_object *intern, zend_long input, unsigned int *output)
+{
+ if (input < 0) {
+ if (php_dom_follow_spec_intern(intern)) {
+ *output = (unsigned int) input;
+ } else {
+ php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
+ return false;
+ }
+ } else {
+ *output = input;
+ }
+ return true;
+}
+
/* {{{ data string
readonly=no
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-72AB8359
@@ -96,20 +114,22 @@ zend_result dom_characterdata_length_read(dom_object *obj, zval *retval)
/* }}} */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF
+Modern spec URL: https://dom.spec.whatwg.org/#dom-characterdata-substringdata
Since:
*/
PHP_METHOD(DOMCharacterData, substringData)
{
- zval *id;
- xmlChar *cur;
- xmlChar *substring;
- xmlNodePtr node;
- zend_long offset, count;
- int length;
- dom_object *intern;
+ zval *id;
+ xmlChar *cur;
+ xmlChar *substring;
+ xmlNodePtr node;
+ zend_long offset_input, count_input;
+ unsigned int count, offset;
+ int length;
+ dom_object *intern;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &offset, &count) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &offset_input, &count_input) == FAILURE) {
RETURN_THROWS();
}
@@ -117,12 +137,21 @@ PHP_METHOD(DOMCharacterData, substringData)
cur = node->content;
if (cur == NULL) {
- RETURN_FALSE;
+ /* TODO: is this even possible? */
+ cur = BAD_CAST "";
}
length = xmlUTF8Strlen(cur);
+ if (ZEND_LONG_INT_OVFL(offset_input) || ZEND_LONG_INT_OVFL(count_input)) {
+ php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
+ RETURN_FALSE;
+ }
- if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
+ if (!dom_convert_number_unsigned(intern, offset_input, &offset) || !dom_convert_number_unsigned(intern, count_input, &count)) {
+ RETURN_FALSE;
+ }
+
+ if (offset > length) {
php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
RETURN_FALSE;
}
@@ -143,9 +172,10 @@ PHP_METHOD(DOMCharacterData, substringData)
/* }}} end dom_characterdata_substring_data */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F
+Modern spec URL: https://dom.spec.whatwg.org/#dom-characterdata-appenddata
Since:
*/
-PHP_METHOD(DOMCharacterData, appendData)
+static void dom_character_data_append_data(INTERNAL_FUNCTION_PARAMETERS, bool return_true)
{
zval *id;
xmlNode *nodep;
@@ -160,26 +190,40 @@ PHP_METHOD(DOMCharacterData, appendData)
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
xmlTextConcat(nodep, (xmlChar *) arg, arg_len);
- RETURN_TRUE;
+ if (return_true) {
+ RETURN_TRUE;
+ }
+}
+
+PHP_METHOD(DOMCharacterData, appendData)
+{
+ dom_character_data_append_data(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
+
+PHP_METHOD(DOM_CharacterData, appendData)
+{
+ dom_character_data_append_data(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
}
/* }}} end dom_characterdata_append_data */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F
+Modern spec URL: https://dom.spec.whatwg.org/#dom-characterdata-insertdata
Since:
*/
-PHP_METHOD(DOMCharacterData, insertData)
+static void dom_character_data_insert_data(INTERNAL_FUNCTION_PARAMETERS, bool return_true)
{
zval *id;
xmlChar *cur, *first, *second;
xmlNodePtr node;
char *arg;
- zend_long offset;
+ zend_long offset_input;
+ unsigned int offset;
int length;
size_t arg_len;
dom_object *intern;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &offset, &arg, &arg_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &offset_input, &arg, &arg_len) == FAILURE) {
RETURN_THROWS();
}
@@ -187,12 +231,22 @@ PHP_METHOD(DOMCharacterData, insertData)
cur = node->content;
if (cur == NULL) {
- RETURN_FALSE;
+ /* TODO: is this even possible? */
+ cur = BAD_CAST "";
}
length = xmlUTF8Strlen(cur);
- if (offset < 0 || ZEND_LONG_INT_OVFL(offset) || offset > length) {
+ if (ZEND_LONG_INT_OVFL(offset_input)) {
+ php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
+ RETURN_FALSE;
+ }
+
+ if (!dom_convert_number_unsigned(intern, offset_input, &offset)) {
+ RETURN_FALSE;
+ }
+
+ if (offset > length) {
php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
RETURN_FALSE;
}
@@ -207,24 +261,38 @@ PHP_METHOD(DOMCharacterData, insertData)
xmlFree(first);
xmlFree(second);
- RETURN_TRUE;
+ if (return_true) {
+ RETURN_TRUE;
+ }
+}
+
+PHP_METHOD(DOMCharacterData, insertData)
+{
+ dom_character_data_insert_data(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
+
+PHP_METHOD(DOM_CharacterData, insertData)
+{
+ dom_character_data_insert_data(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
}
/* }}} end dom_characterdata_insert_data */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781
+Modern spec URL: https://dom.spec.whatwg.org/#dom-characterdata-deletedata
Since:
*/
-PHP_METHOD(DOMCharacterData, deleteData)
+static void dom_character_data_delete_data(INTERNAL_FUNCTION_PARAMETERS, bool return_true)
{
zval *id;
xmlChar *cur, *substring, *second;
xmlNodePtr node;
- zend_long offset, count;
+ zend_long offset, count_input;
+ unsigned int count;
int length;
dom_object *intern;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &offset, &count) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &offset, &count_input) == FAILURE) {
RETURN_THROWS();
}
@@ -232,16 +300,21 @@ PHP_METHOD(DOMCharacterData, deleteData)
cur = node->content;
if (cur == NULL) {
- RETURN_FALSE;
+ /* TODO: is this even possible? */
+ cur = BAD_CAST "";
}
length = xmlUTF8Strlen(cur);
- if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
+ if (offset < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count_input) || offset > length) {
php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
RETURN_FALSE;
}
+ if (!dom_convert_number_unsigned(intern, count_input, &count)) {
+ RETURN_FALSE;
+ }
+
if (offset > 0) {
substring = xmlUTF8Strsub(cur, 0, (int)offset);
} else {
@@ -260,26 +333,40 @@ PHP_METHOD(DOMCharacterData, deleteData)
xmlFree(second);
xmlFree(substring);
- RETURN_TRUE;
+ if (return_true) {
+ RETURN_TRUE;
+ }
+}
+
+PHP_METHOD(DOMCharacterData, deleteData)
+{
+ dom_character_data_delete_data(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
+
+PHP_METHOD(DOM_CharacterData, deleteData)
+{
+ dom_character_data_delete_data(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
}
/* }}} end dom_characterdata_delete_data */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB
+Modern spec URL: https://dom.spec.whatwg.org/#dom-characterdata-replacedata
Since:
*/
-PHP_METHOD(DOMCharacterData, replaceData)
+static void dom_character_data_replace_data(INTERNAL_FUNCTION_PARAMETERS, bool return_true)
{
zval *id;
xmlChar *cur, *substring, *second = NULL;
xmlNodePtr node;
char *arg;
- zend_long offset, count;
+ zend_long offset, count_input;
+ unsigned int count;
int length;
size_t arg_len;
dom_object *intern;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "lls", &offset, &count, &arg, &arg_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "lls", &offset, &count_input, &arg, &arg_len) == FAILURE) {
RETURN_THROWS();
}
@@ -287,16 +374,21 @@ PHP_METHOD(DOMCharacterData, replaceData)
cur = node->content;
if (cur == NULL) {
- RETURN_FALSE;
+ /* TODO: is this even possible? */
+ cur = BAD_CAST "";
}
length = xmlUTF8Strlen(cur);
- if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
+ if (offset < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count_input) || offset > length) {
php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
RETURN_FALSE;
}
+ if (!dom_convert_number_unsigned(intern, count_input, &count)) {
+ RETURN_FALSE;
+ }
+
if (offset > 0) {
substring = xmlUTF8Strsub(cur, 0, (int)offset);
} else {
@@ -321,7 +413,19 @@ PHP_METHOD(DOMCharacterData, replaceData)
}
xmlFree(substring);
- RETURN_TRUE;
+ if (return_true) {
+ RETURN_TRUE;
+ }
+}
+
+PHP_METHOD(DOMCharacterData, replaceData)
+{
+ dom_character_data_replace_data(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
+
+PHP_METHOD(DOM_CharacterData, replaceData)
+{
+ dom_character_data_replace_data(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
}
/* }}} end dom_characterdata_replace_data */
diff --git a/ext/dom/config.m4 b/ext/dom/config.m4
index c0736861460da..b3a92287b3f1c 100644
--- a/ext/dom/config.m4
+++ b/ext/dom/config.m4
@@ -26,7 +26,7 @@ if test "$PHP_DOM" != "no"; then
$LEXBOR_DIR/ns/ns.c \
$LEXBOR_DIR/tag/tag.c"
PHP_NEW_EXTENSION(dom, [php_dom.c attr.c document.c \
- xml_document.c html_document.c html5_serializer.c html5_parser.c namespace_compat.c \
+ xml_document.c html_document.c xml_serializer.c html5_serializer.c html5_parser.c namespace_compat.c \
domexception.c parentnode.c \
processinginstruction.c cdatasection.c \
documentfragment.c domimplementation.c \
@@ -49,7 +49,7 @@ if test "$PHP_DOM" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/$LEXBOR_DIR/ns)
PHP_ADD_BUILD_DIR($ext_builddir/$LEXBOR_DIR/tag)
PHP_SUBST(DOM_SHARED_LIBADD)
- PHP_INSTALL_HEADERS([ext/dom], [xml_common.h xpath_callbacks.h])
+ PHP_INSTALL_HEADERS([ext/dom], [xml_common.h xpath_callbacks.h namespace_compat.h])
PHP_ADD_EXTENSION_DEP(dom, libxml)
])
fi
diff --git a/ext/dom/config.w32 b/ext/dom/config.w32
index bb0101b960b2f..a70d226d0fa31 100644
--- a/ext/dom/config.w32
+++ b/ext/dom/config.w32
@@ -8,7 +8,7 @@ if (PHP_DOM == "yes") {
CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_DOM", PHP_PHP_BUILD + "\\include\\libxml2")
) {
EXTENSION("dom", "php_dom.c attr.c document.c \
- xml_document.c html_document.c html5_serializer.c html5_parser.c namespace_compat.c \
+ xml_document.c html_document.c xml_serializer.c html5_serializer.c html5_parser.c namespace_compat.c \
domexception.c parentnode.c processinginstruction.c \
cdatasection.c documentfragment.c domimplementation.c element.c \
node.c characterdata.c documenttype.c \
@@ -41,7 +41,7 @@ if (PHP_DOM == "yes") {
WARNING("dom support can't be enabled, libxml is not found")
}
}
- PHP_INSTALL_HEADERS("ext/dom", "xml_common.h xpath_callbacks.h");
+ PHP_INSTALL_HEADERS("ext/dom", "xml_common.h xpath_callbacks.h namespace_compat.h");
} else {
WARNING("dom support can't be enabled, libxml is not enabled")
PHP_DOM = "no"
diff --git a/ext/dom/document.c b/ext/dom/document.c
index 6268f9b687594..8dba522eb9d03 100644
--- a/ext/dom/document.c
+++ b/ext/dom/document.c
@@ -22,19 +22,15 @@
#include "php.h"
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
#include "php_dom.h"
+#include "namespace_compat.h"
+#include "xml_serializer.h"
+#include "internal_helpers.h"
#include
-#include
#ifdef LIBXML_SCHEMAS_ENABLED
#include
#include
#endif
-typedef struct _idsIterator idsIterator;
-struct _idsIterator {
- xmlChar *elementId;
- xmlNode *element;
-};
-
/*
* class DOMDocument extends DOMNode
*
@@ -76,10 +72,9 @@ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-
*/
zend_result dom_document_implementation_read(dom_object *obj, zval *retval)
{
- php_dom_create_implementation(retval);
+ php_dom_create_implementation(retval, false);
return SUCCESS;
}
-
/* }}} */
/* {{{ documentElement DOMElement
@@ -253,6 +248,14 @@ zend_result dom_document_version_write(dom_object *obj, zval *newval)
return FAILURE;
}
+ if (php_dom_follow_spec_intern(obj)) {
+ if (!zend_string_equals_literal(str, "1.0") && !zend_string_equals_literal(str, "1.1")) {
+ zend_value_error("Invalid XML version");
+ zend_string_release_ex(str, 0);
+ return FAILURE;
+ }
+ }
+
if (docp->version != NULL) {
xmlFree((xmlChar *) docp->version );
}
@@ -434,7 +437,11 @@ zend_result dom_document_document_uri_read(dom_object *obj, zval *retval)
if (url != NULL) {
ZVAL_STRING(retval, url);
} else {
- ZVAL_NULL(retval);
+ if (php_dom_follow_spec_intern(obj)) {
+ ZVAL_STRING(retval, "about:blank");
+ } else {
+ ZVAL_NULL(retval);
+ }
}
return SUCCESS;
@@ -481,31 +488,69 @@ zend_result dom_document_config_read(dom_object *obj, zval *retval)
/* }}} */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547
+Modern spec URL: https://dom.spec.whatwg.org/#dom-document-createelement
Since:
*/
+PHP_METHOD(DOMDocument, createElement)
+{
+ xmlDocPtr docp;
+ dom_object *intern;
+ int ret;
+ size_t value_len;
+ char *value = NULL;
+ zend_string *name;
+
+ ZEND_PARSE_PARAMETERS_START(1, 2)
+ Z_PARAM_STR(name)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_STRING(value, value_len)
+ ZEND_PARSE_PARAMETERS_END();
+
+ DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);
+
+ if (xmlValidateName(BAD_CAST ZSTR_VAL(name), 0) != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document));
+ RETURN_FALSE;
+ }
+
+ xmlNodePtr node = xmlNewDocNode(docp, NULL, BAD_CAST ZSTR_VAL(name), BAD_CAST value);
+
+ if (!node) {
+ php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
+ RETURN_THROWS();
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+
PHP_METHOD(DOM_Document, createElement)
{
- zval *id;
xmlNode *node;
xmlDocPtr docp;
dom_object *intern;
int ret;
- size_t name_len, value_len;
- char *name, *value = NULL;
+ zend_string *name;
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", &name, &name_len, &value, &value_len) == FAILURE) {
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_STR(name)
+ ZEND_PARSE_PARAMETERS_END();
+
+ DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);
+
+ if (xmlValidateName(BAD_CAST ZSTR_VAL(name), 0) != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, /* strict */ true);
RETURN_THROWS();
}
- DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
-
- if (xmlValidateName((xmlChar *) name, 0) != 0) {
- php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document));
- RETURN_FALSE;
+ if (docp->type == XML_HTML_DOCUMENT_NODE) {
+ php_dom_libxml_ns_mapper *ns_mapper = php_dom_get_ns_mapper(intern);
+ char *lower = zend_str_tolower_dup_ex(ZSTR_VAL(name), ZSTR_LEN(name));
+ node = xmlNewDocRawNode(docp, php_dom_libxml_ns_mapper_ensure_html_ns(ns_mapper), BAD_CAST (lower ? lower : ZSTR_VAL(name)), NULL);
+ efree(lower);
+ } else {
+ node = xmlNewDocNode(docp, NULL, BAD_CAST ZSTR_VAL(name), NULL);
}
- node = xmlNewDocNode(docp, NULL, (xmlChar *) name, (xmlChar *) value);
if (!node) {
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
RETURN_THROWS();
@@ -518,7 +563,7 @@ PHP_METHOD(DOM_Document, createElement)
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5
Since:
*/
-PHP_METHOD(DOM_Document, createDocumentFragment)
+PHP_METHOD(DOMDocument, createDocumentFragment)
{
zval *id;
xmlNode *node;
@@ -546,7 +591,7 @@ PHP_METHOD(DOM_Document, createDocumentFragment)
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127
Since:
*/
-PHP_METHOD(DOM_Document, createTextNode)
+PHP_METHOD(DOMDocument, createTextNode)
{
zval *id;
xmlNode *node;
@@ -576,7 +621,7 @@ PHP_METHOD(DOM_Document, createTextNode)
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328
Since:
*/
-PHP_METHOD(DOM_Document, createComment)
+PHP_METHOD(DOMDocument, createComment)
{
zval *id;
xmlNode *node;
@@ -604,9 +649,10 @@ PHP_METHOD(DOM_Document, createComment)
/* }}} end dom_document_create_comment */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8
+Modern spec URL: https://dom.spec.whatwg.org/#dom-document-createcdatasection
Since:
*/
-PHP_METHOD(DOM_Document, createCDATASection)
+PHP_METHOD(DOMDocument, createCDATASection)
{
zval *id;
xmlNode *node;
@@ -623,6 +669,18 @@ PHP_METHOD(DOM_Document, createCDATASection)
DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+ if (php_dom_follow_spec_intern(intern)) {
+ if (docp->type == XML_HTML_DOCUMENT_NODE) {
+ php_dom_throw_error_with_message(NOT_SUPPORTED_ERR, "This operation is not supported for HTML documents", /* strict */ true);
+ RETURN_THROWS();
+ }
+
+ if (zend_memnstr(value, "]]>", strlen("]]>"), value + value_len) != NULL) {
+ php_dom_throw_error_with_message(INVALID_CHARACTER_ERR, "Invalid character sequence \"]]>\" in CDATA section", /* strict */ true);
+ RETURN_THROWS();
+ }
+ }
+
node = xmlNewCDataBlock(docp, (xmlChar *) value, value_len);
if (!node) {
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
@@ -634,11 +692,11 @@ PHP_METHOD(DOM_Document, createCDATASection)
/* }}} end dom_document_create_cdatasection */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439
+Modern spec URL: https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
Since:
*/
-PHP_METHOD(DOM_Document, createProcessingInstruction)
+static void dom_document_create_processing_instruction(INTERNAL_FUNCTION_PARAMETERS, bool modern)
{
- zval *id;
xmlNode *node;
xmlDocPtr docp;
int ret;
@@ -646,56 +704,77 @@ PHP_METHOD(DOM_Document, createProcessingInstruction)
dom_object *intern;
char *name, *value = NULL;
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", &name, &name_len, &value, &value_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), modern ? "ss" : "s|s", &name, &name_len, &value, &value_len) != SUCCESS) {
RETURN_THROWS();
}
- DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+ DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);
if (xmlValidateName((xmlChar *) name, 0) != 0) {
php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document));
RETURN_FALSE;
}
- node = xmlNewPI((xmlChar *) name, (xmlChar *) value);
+ if (modern) {
+ if (value != NULL && zend_memnstr(value, "?>", strlen("?>"), value + value_len) != NULL) {
+ php_dom_throw_error_with_message(INVALID_CHARACTER_ERR, "Invalid character sequence \"?>\" in processing instruction", /* strict */ true);
+ RETURN_THROWS();
+ }
+ }
+
+ node = xmlNewDocPI(docp, (xmlChar *) name, (xmlChar *) value);
if (!node) {
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
RETURN_THROWS();
}
- node->doc = docp;
-
DOM_RET_OBJ(node, &ret, intern);
}
+
+PHP_METHOD(DOMDocument, createProcessingInstruction)
+{
+ dom_document_create_processing_instruction(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+PHP_METHOD(DOM_Document, createProcessingInstruction)
+{
+ dom_document_create_processing_instruction(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
/* }}} end dom_document_create_processing_instruction */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198
+Modern spec URL: https://dom.spec.whatwg.org/#dom-document-createattribute
Since:
*/
-PHP_METHOD(DOM_Document, createAttribute)
+PHP_METHOD(DOMDocument, createAttribute)
{
zval *id;
xmlAttrPtr node;
xmlDocPtr docp;
int ret;
- size_t name_len;
dom_object *intern;
- char *name;
+ zend_string *name;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
- RETURN_THROWS();
- }
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_PATH_STR(name)
+ ZEND_PARSE_PARAMETERS_END();
DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
- if (xmlValidateName((xmlChar *) name, 0) != 0) {
+ if (xmlValidateName(BAD_CAST ZSTR_VAL(name), 0) != 0) {
php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document));
RETURN_FALSE;
}
- node = xmlNewDocProp(docp, (xmlChar *) name, NULL);
+ if (docp->type == XML_HTML_DOCUMENT_NODE && php_dom_follow_spec_intern(intern)) {
+ char *lower = zend_str_tolower_dup_ex(ZSTR_VAL(name), ZSTR_LEN(name));
+ node = xmlNewDocProp(docp, BAD_CAST (lower ? lower : ZSTR_VAL(name)), NULL);
+ efree(lower);
+ } else {
+ node = xmlNewDocProp(docp, BAD_CAST ZSTR_VAL(name), NULL);
+ }
+
if (!node) {
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
RETURN_THROWS();
@@ -741,31 +820,11 @@ PHP_METHOD(DOMDocument, createEntityReference)
}
/* }}} end dom_document_create_entity_reference */
-/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094
-Since:
-*/
-PHP_METHOD(DOM_Document, getElementsByTagName)
-{
- size_t name_len;
- dom_object *intern, *namednode;
- char *name;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
- RETURN_THROWS();
- }
-
- DOM_GET_THIS_INTERN(intern);
-
- php_dom_create_iterator(return_value, DOM_NODELIST);
- namednode = Z_DOMOBJ_P(return_value);
- dom_namednode_iter(intern, 0, namednode, NULL, name, name_len, NULL, 0);
-}
-/* }}} end dom_document_get_elements_by_tag_name */
-
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode
+Modern spec URL: https://dom.spec.whatwg.org/#dom-document-importnode
Since: DOM Level 2
*/
-PHP_METHOD(DOM_Document, importNode)
+PHP_METHOD(DOMDocument, importNode)
{
zval *node;
xmlDocPtr docp;
@@ -782,8 +841,7 @@ PHP_METHOD(DOM_Document, importNode)
DOM_GET_OBJ(nodep, node, xmlNodePtr, nodeobj);
- if (nodep->type == XML_HTML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_NODE
- || nodep->type == XML_DOCUMENT_TYPE_NODE) {
+ if (nodep->type == XML_HTML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_NODE) {
php_error_docref(NULL, E_WARNING, "Cannot import: Node Type Not Supported");
RETURN_FALSE;
}
@@ -791,12 +849,12 @@ PHP_METHOD(DOM_Document, importNode)
if (nodep->doc == docp) {
retnodep = nodep;
} else {
- retnodep = dom_clone_node(nodep, docp, intern, recursive);
+ retnodep = dom_clone_node(NULL, nodep, docp, recursive);
if (!retnodep) {
RETURN_FALSE;
}
- if ((retnodep->type == XML_ATTRIBUTE_NODE) && (nodep->ns != NULL)) {
+ if (retnodep->type == XML_ATTRIBUTE_NODE && nodep->ns != NULL && retnodep->ns == NULL) {
xmlNsPtr nsptr = NULL;
xmlNodePtr root = xmlDocGetRootElement(docp);
@@ -809,50 +867,93 @@ PHP_METHOD(DOM_Document, importNode)
}
}
- php_libxml_invalidate_node_list_cache(intern->document);
+ DOM_RET_OBJ(retnodep, &ret, intern);
+}
- DOM_RET_OBJ((xmlNodePtr) retnodep, &ret, intern);
+static void dom_modern_document_import_node(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *node_ce)
+{
+ zval *node;
+ xmlDocPtr docp;
+ xmlNodePtr nodep, retnodep;
+ dom_object *intern, *nodeobj;
+ int ret;
+ bool recursive = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|b", &node, node_ce, &recursive) != SUCCESS) {
+ RETURN_THROWS();
+ }
+
+ DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);
+
+ DOM_GET_OBJ(nodep, node, xmlNodePtr, nodeobj);
+
+ if (nodep->type == XML_HTML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_NODE) {
+ php_dom_throw_error(NOT_SUPPORTED_ERR, /* strict */ true);
+ RETURN_THROWS();
+ }
+
+ if (nodep->doc == docp) {
+ retnodep = nodep;
+ } else {
+ retnodep = dom_clone_node(php_dom_get_ns_mapper(intern), nodep, docp, recursive);
+ if (!retnodep) {
+ php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
+ RETURN_THROWS();
+ }
+ }
+
+ DOM_RET_OBJ(retnodep, &ret, intern);
+}
+
+PHP_METHOD(DOM_Document, importNode)
+{
+ dom_modern_document_import_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_modern_node_class_entry);
}
/* }}} end dom_document_import_node */
+PHP_METHOD(DOM_Document, importLegacyNode)
+{
+ dom_modern_document_import_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_node_class_entry);
+}
+
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS
+Modern spec URL: https://dom.spec.whatwg.org/#internal-createelementns-steps
Since: DOM Level 2
*/
-PHP_METHOD(DOM_Document, createElementNS)
+PHP_METHOD(DOMDocument, createElementNS)
{
- zval *id;
xmlDocPtr docp;
xmlNodePtr nodep = NULL;
int ret;
- size_t uri_len = 0, name_len = 0, value_len = 0;
- char *uri, *name, *value = NULL;
- char *localname = NULL, *prefix = NULL;
+ size_t value_len = 0;
+ char *value = NULL;
int errorcode;
dom_object *intern;
+ zend_string *name = NULL, *uri;
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!s|s", &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S!S|s", &uri, &name, &value, &value_len) == FAILURE) {
RETURN_THROWS();
}
- DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+ DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);
- errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+ char *localname = NULL, *prefix = NULL;
+ errorcode = dom_check_qname(ZSTR_VAL(name), &localname, &prefix, uri ? ZSTR_LEN(uri) : 0, ZSTR_LEN(name));
if (errorcode == 0) {
- if (xmlValidateName((xmlChar *) localname, 0) == 0) {
- nodep = xmlNewDocNode(docp, NULL, (xmlChar *) localname, (xmlChar *) value);
+ if (xmlValidateName(BAD_CAST localname, 0) == 0) {
+ nodep = xmlNewDocNode(docp, NULL, BAD_CAST localname, BAD_CAST value);
if (UNEXPECTED(nodep == NULL)) {
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
RETURN_THROWS();
}
if (uri != NULL) {
- xmlNsPtr nsptr = xmlSearchNsByHref(nodep->doc, nodep, (xmlChar *) uri);
+ xmlNsPtr nsptr = xmlSearchNsByHref(nodep->doc, nodep, BAD_CAST ZSTR_VAL(uri));
if (nsptr == NULL) {
- nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
+ nsptr = dom_get_ns(nodep, ZSTR_VAL(uri), &errorcode, prefix);
}
- xmlSetNs(nodep, nsptr);
+ nodep->ns = nsptr;
}
} else {
errorcode = INVALID_CHARACTER_ERR;
@@ -860,9 +961,7 @@ PHP_METHOD(DOM_Document, createElementNS)
}
xmlFree(localname);
- if (prefix != NULL) {
- xmlFree(prefix);
- }
+ xmlFree(prefix);
if (errorcode != 0) {
xmlFreeNode(nodep);
@@ -872,12 +971,46 @@ PHP_METHOD(DOM_Document, createElementNS)
DOM_RET_OBJ(nodep, &ret, intern);
}
+
+PHP_METHOD(DOM_Document, createElementNS)
+{
+ xmlDocPtr docp;
+ int ret;
+ dom_object *intern;
+ zend_string *name = NULL, *uri;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S!S", &uri, &name) == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);
+
+ xmlChar *localname = NULL, *prefix = NULL;
+ int errorcode = dom_validate_and_extract(uri, name, &localname, &prefix);
+
+ if (errorcode == 0) {
+ php_dom_libxml_ns_mapper *ns_mapper = php_dom_get_ns_mapper(intern);
+ xmlNsPtr ns = php_dom_libxml_ns_mapper_get_ns_raw_prefix_string(ns_mapper, prefix, xmlStrlen(prefix), uri);
+ xmlNodePtr nodep = xmlNewDocNode(docp, ns, localname, NULL);
+ if (UNEXPECTED(nodep == NULL)) {
+ php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
+ } else {
+ DOM_RET_OBJ(nodep, &ret, intern);
+ }
+ } else {
+ php_dom_throw_error(errorcode, dom_get_strict_error(intern->document));
+ }
+
+ xmlFree(localname);
+ xmlFree(prefix);
+}
/* }}} end dom_document_create_element_ns */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS
+Modern spec URL: https://dom.spec.whatwg.org/#dom-document-createattributens
Since: DOM Level 2
*/
-PHP_METHOD(DOM_Document, createAttributeNS)
+PHP_METHOD(DOMDocument, createAttributeNS)
{
zval *id;
xmlDocPtr docp;
@@ -885,7 +1018,7 @@ PHP_METHOD(DOM_Document, createAttributeNS)
xmlNsPtr nsptr;
int ret;
zend_string *name, *uri;
- char *localname = NULL, *prefix = NULL;
+ xmlChar *localname = NULL, *prefix = NULL;
dom_object *intern;
int errorcode;
@@ -896,60 +1029,45 @@ PHP_METHOD(DOM_Document, createAttributeNS)
DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
- if (UNEXPECTED(uri == NULL)) {
- uri = zend_empty_string;
- }
- size_t uri_len = ZSTR_LEN(uri);
-
root = xmlDocGetRootElement(docp);
- if (root != NULL) {
- errorcode = dom_check_qname(ZSTR_VAL(name), &localname, &prefix, uri_len, ZSTR_LEN(name));
+ if (root != NULL || php_dom_follow_spec_intern(intern)) {
+ errorcode = dom_validate_and_extract(uri, name, &localname, &prefix);
if (UNEXPECTED(errorcode != 0)) {
- goto error;
- }
- if (UNEXPECTED(xmlValidateName((xmlChar *) localname, 0) != 0)) {
- errorcode = INVALID_CHARACTER_ERR;
- goto error;
- }
- /* If prefix is "xml" and namespace is not the XML namespace, then throw a "NamespaceError" DOMException. */
- if (UNEXPECTED(!zend_string_equals_literal(uri, "http://www.w3.org/XML/1998/namespace") && xmlStrEqual(BAD_CAST prefix, BAD_CAST "xml"))) {
- errorcode = NAMESPACE_ERR;
- goto error;
- }
- /* If either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace, then throw a "NamespaceError" DOMException. */
- if (UNEXPECTED((zend_string_equals_literal(name, "xmlns") || xmlStrEqual(BAD_CAST prefix, BAD_CAST "xmlns")) && !zend_string_equals_literal(uri, "http://www.w3.org/2000/xmlns/"))) {
- errorcode = NAMESPACE_ERR;
- goto error;
- }
- /* If namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns", then throw a "NamespaceError" DOMException. */
- if (UNEXPECTED(zend_string_equals_literal(uri, "http://www.w3.org/2000/xmlns/") && !zend_string_equals_literal(name, "xmlns") && !xmlStrEqual(BAD_CAST prefix, BAD_CAST "xmlns"))) {
- errorcode = NAMESPACE_ERR;
+ if (!php_dom_follow_spec_intern(intern)) {
+ /* legacy behaviour */
+ errorcode = NAMESPACE_ERR;
+ }
goto error;
}
- nodep = (xmlNodePtr) xmlNewDocProp(docp, (xmlChar *) localname, NULL);
+ nodep = (xmlNodePtr) xmlNewDocProp(docp, localname, NULL);
if (UNEXPECTED(nodep == NULL)) {
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
RETURN_THROWS();
}
- if (uri_len > 0) {
- nsptr = xmlSearchNsByHref(docp, root, BAD_CAST ZSTR_VAL(uri));
-
- if (zend_string_equals_literal(name, "xmlns") || xmlStrEqual(BAD_CAST prefix, BAD_CAST "xml")) {
- if (nsptr == NULL) {
- nsptr = xmlNewNs(NULL, BAD_CAST ZSTR_VAL(uri), BAD_CAST prefix);
- php_libxml_set_old_ns(docp, nsptr);
- }
+ if (uri != NULL && ZSTR_LEN(uri) > 0) {
+ if (php_dom_follow_spec_intern(intern)) {
+ php_dom_libxml_ns_mapper *ns_mapper = php_dom_get_ns_mapper(intern);
+ nsptr = php_dom_libxml_ns_mapper_get_ns_raw_prefix_string(ns_mapper, prefix, xmlStrlen(prefix), uri);
} else {
- if (nsptr == NULL || nsptr->prefix == NULL) {
- nsptr = dom_get_ns_unchecked(root, ZSTR_VAL(uri), prefix ? prefix : "default");
- if (UNEXPECTED(nsptr == NULL)) {
- errorcode = NAMESPACE_ERR;
+ nsptr = xmlSearchNsByHref(docp, root, BAD_CAST ZSTR_VAL(uri));
+
+ if (zend_string_equals_literal(name, "xmlns") || xmlStrEqual(BAD_CAST prefix, BAD_CAST "xml")) {
+ if (nsptr == NULL) {
+ nsptr = xmlNewNs(NULL, BAD_CAST ZSTR_VAL(uri), BAD_CAST prefix);
+ php_libxml_set_old_ns(docp, nsptr);
+ }
+ } else {
+ if (nsptr == NULL || nsptr->prefix == NULL) {
+ nsptr = dom_get_ns_unchecked(root, ZSTR_VAL(uri), prefix ? (char *) prefix : "default");
+ if (UNEXPECTED(nsptr == NULL)) {
+ errorcode = NAMESPACE_ERR;
+ }
}
}
}
- xmlSetNs(nodep, nsptr);
+ nodep->ns = nsptr;
}
} else {
php_error_docref(NULL, E_WARNING, "Document Missing Root Element");
@@ -958,9 +1076,7 @@ PHP_METHOD(DOM_Document, createAttributeNS)
error:
xmlFree(localname);
- if (prefix != NULL) {
- xmlFree(prefix);
- }
+ xmlFree(prefix);
if (errorcode != 0) {
xmlFreeProp((xmlAttrPtr) nodep);
@@ -972,31 +1088,10 @@ PHP_METHOD(DOM_Document, createAttributeNS)
}
/* }}} end dom_document_create_attribute_ns */
-/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS
-Since: DOM Level 2
-*/
-PHP_METHOD(DOM_Document, getElementsByTagNameNS)
-{
- size_t uri_len, name_len;
- dom_object *intern, *namednode;
- char *uri, *name;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!s", &uri, &uri_len, &name, &name_len) == FAILURE) {
- RETURN_THROWS();
- }
-
- DOM_GET_THIS_INTERN(intern);
-
- php_dom_create_iterator(return_value, DOM_NODELIST);
- namednode = Z_DOMOBJ_P(return_value);
- dom_namednode_iter(intern, 0, namednode, NULL, name, name_len, uri ? uri : "", uri_len);
-}
-/* }}} end dom_document_get_elements_by_tag_name_ns */
-
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId
Since: DOM Level 2
*/
-PHP_METHOD(DOM_Document, getElementById)
+PHP_METHOD(DOMDocument, getElementById)
{
zval *id;
xmlDocPtr docp;
@@ -1061,17 +1156,65 @@ static void php_dom_transfer_document_ref(xmlNodePtr node, php_libxml_ref_obj *n
}
}
+/* Workaround for bug that was fixed in https://github.com/GNOME/libxml2/commit/4bc3ebf3eaba352fbbce2ef70ad00a3c7752478a */
+#if LIBXML_VERSION < 21000
+static xmlChar *libxml_copy_dicted_string(xmlDictPtr src_dict, xmlDictPtr dst_dict, xmlChar *str)
+{
+ if (str == NULL) {
+ return NULL;
+ }
+ if (xmlDictOwns(src_dict, str) == 1) {
+ if (dst_dict == NULL) {
+ return xmlStrdup(str);
+ }
+ return BAD_CAST xmlDictLookup(dst_dict, str, -1);
+ }
+ return str;
+}
+
+static void libxml_fixup_name_and_content(xmlDocPtr src_doc, xmlDocPtr dst_doc, xmlNodePtr node)
+{
+ if (src_doc != NULL && dst_doc != src_doc && src_doc->dict != NULL) {
+ node->name = libxml_copy_dicted_string(src_doc->dict, dst_doc->dict, BAD_CAST node->name);
+ node->content = libxml_copy_dicted_string(src_doc->dict, NULL, node->content);
+ }
+}
+
+static void libxml_fixup_name_and_content_element(xmlDocPtr src_doc, xmlDocPtr dst_doc, xmlNodePtr node)
+{
+ libxml_fixup_name_and_content(src_doc, dst_doc, node);
+ for (xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
+ libxml_fixup_name_and_content(src_doc, dst_doc, (xmlNodePtr) attr);
+ }
+
+ for (xmlNodePtr child = node->children; child != NULL; child = child->next) {
+ libxml_fixup_name_and_content_element(src_doc, dst_doc, child);
+ }
+}
+#endif
+
bool php_dom_adopt_node(xmlNodePtr nodep, dom_object *dom_object_new_document, xmlDocPtr new_document)
{
- php_libxml_invalidate_node_list_cache_from_doc(nodep->doc);
+ xmlDocPtr original_document = nodep->doc;
+ php_libxml_invalidate_node_list_cache_from_doc(original_document);
if (nodep->doc != new_document) {
php_libxml_invalidate_node_list_cache(dom_object_new_document->document);
/* Note for ATTRIBUTE_NODE: specified is always true in ext/dom,
* and since this unlink it; the owner element will be unset (i.e. parentNode). */
- int ret = xmlDOMWrapAdoptNode(NULL, nodep->doc, nodep, new_document, NULL, /* options, unused */ 0);
- if (UNEXPECTED(ret != 0)) {
- return false;
+ if (php_dom_follow_spec_intern(dom_object_new_document)) {
+ xmlUnlinkNode(nodep);
+ xmlSetTreeDoc(nodep, new_document);
+ php_dom_libxml_ns_mapper *ns_mapper = php_dom_get_ns_mapper(dom_object_new_document);
+ php_dom_libxml_reconcile_modern(ns_mapper, nodep);
+#if LIBXML_VERSION < 21000
+ libxml_fixup_name_and_content_element(original_document, new_document, nodep);
+#endif
+ } else {
+ int ret = xmlDOMWrapAdoptNode(NULL, original_document, nodep, new_document, NULL, /* options, unused */ 0);
+ if (UNEXPECTED(ret != 0)) {
+ return false;
+ }
}
php_dom_transfer_document_ref(nodep, dom_object_new_document->document);
@@ -1085,10 +1228,10 @@ bool php_dom_adopt_node(xmlNodePtr nodep, dom_object *dom_object_new_document, x
Since: DOM Level 3
Modern spec URL: https://dom.spec.whatwg.org/#dom-document-adoptnode
*/
-PHP_METHOD(DOM_Document, adoptNode)
+static void dom_document_adopt_node(INTERNAL_FUNCTION_PARAMETERS, bool modern)
{
zval *node_zval;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node_zval, dom_node_class_entry) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node_zval, dom_get_node_ce(modern)) == FAILURE) {
RETURN_THROWS();
}
@@ -1112,17 +1255,31 @@ PHP_METHOD(DOM_Document, adoptNode)
DOM_GET_OBJ(new_document, new_document_zval, xmlDocPtr, dom_object_new_document);
if (!php_dom_adopt_node(nodep, dom_object_new_document, new_document)) {
+ if (modern) {
+ php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
+ RETURN_THROWS();
+ }
RETURN_FALSE;
}
RETURN_OBJ_COPY(&dom_object_nodep->std);
}
+
+PHP_METHOD(DOMDocument, adoptNode)
+{
+ dom_document_adopt_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+PHP_METHOD(DOM_Document, adoptNode)
+{
+ dom_document_adopt_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
/* }}} end dom_document_adopt_node */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument
Since: DOM Level 3
*/
-PHP_METHOD(DOM_Document, normalizeDocument)
+PHP_METHOD(DOMDocument, normalizeDocument)
{
zval *id;
xmlDocPtr docp;
@@ -1135,9 +1292,7 @@ PHP_METHOD(DOM_Document, normalizeDocument)
DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
- php_libxml_invalidate_node_list_cache(intern->document);
-
- dom_normalize((xmlNodePtr) docp);
+ php_dom_normalize_legacy((xmlNodePtr) docp);
}
/* }}} end dom_document_normalize_document */
@@ -1274,7 +1429,6 @@ xmlDocPtr dom_document_parser(zval *id, dom_load_mode mode, const char *source,
if (file_dest) {
ctxt = xmlCreateFileParserCtxt(file_dest);
}
-
} else {
ctxt = xmlCreateMemoryParserCtxt(source, source_len);
}
@@ -1350,7 +1504,7 @@ xmlDocPtr dom_document_parser(zval *id, dom_load_mode mode, const char *source,
ret->URL = xmlStrdup((xmlChar *) ctxt->directory);
}
} else {
- ret = NULL;
+ ret = DOM_DOCUMENT_MALFORMED;
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
}
@@ -1369,13 +1523,13 @@ static void php_dom_finish_loading_document(zval *this, zval *return_value, xmlD
dom_object *intern = Z_DOMOBJ_P(this);
size_t old_modification_nr = 0;
if (intern != NULL) {
- bool is_modern_api_class = false;
+ php_libxml_class_type class_type = PHP_LIBXML_CLASS_LEGACY;
xmlDocPtr docp = (xmlDocPtr) dom_object_get_node(intern);
dom_doc_propsptr doc_prop = NULL;
if (docp != NULL) {
const php_libxml_ref_obj *doc_ptr = intern->document;
ZEND_ASSERT(doc_ptr != NULL); /* Must exist, we have a document */
- is_modern_api_class = doc_ptr->is_modern_api_class;
+ class_type = doc_ptr->class_type;
old_modification_nr = doc_ptr->cache_tag.modification_nr;
php_libxml_decrement_node_ptr((php_libxml_node_object *) intern);
doc_prop = intern->document->doc_props;
@@ -1390,7 +1544,7 @@ static void php_dom_finish_loading_document(zval *this, zval *return_value, xmlD
RETURN_FALSE;
}
intern->document->doc_props = doc_prop;
- intern->document->is_modern_api_class = is_modern_api_class;
+ intern->document->class_type = class_type;
}
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern);
@@ -1427,6 +1581,9 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode)
}
xmlDocPtr newdoc = dom_document_parser(ZEND_THIS, mode, source, source_len, options, NULL);
+ if (newdoc == DOM_DOCUMENT_MALFORMED) {
+ newdoc = NULL;
+ }
php_dom_finish_loading_document(ZEND_THIS, return_value, newdoc);
}
@@ -1493,9 +1650,9 @@ PHP_METHOD(DOMDocument, save)
/* {{{ URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML
Since: DOM Level 3
*/
-PHP_METHOD(DOMDocument, saveXML)
+static void dom_document_save_xml(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *node_ce)
{
- zval *id, *nodep = NULL;
+ zval *nodep = NULL;
xmlDoc *docp;
xmlNode *node;
xmlBufferPtr buf;
@@ -1504,16 +1661,16 @@ PHP_METHOD(DOMDocument, saveXML)
int size, format, old_xml_save_no_empty_tags;
zend_long options = 0;
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!l", &nodep, dom_node_class_entry, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!l", &nodep, node_ce, &options) != SUCCESS) {
RETURN_THROWS();
}
- DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+ DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);
libxml_doc_props const* doc_props = dom_get_doc_props_read_only(intern->document);
format = doc_props->formatoutput;
+ int status = -1;
if (nodep != NULL) {
/* Dump contents of Node */
DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
@@ -1530,7 +1687,22 @@ PHP_METHOD(DOMDocument, saveXML)
/* Save libxml2 global, override its vaule, and restore after saving. */
old_xml_save_no_empty_tags = xmlSaveNoEmptyTags;
xmlSaveNoEmptyTags = (options & LIBXML_SAVE_NOEMPTYTAG) ? 1 : 0;
- xmlNodeDump(buf, docp, node, 0, format);
+ if (php_dom_follow_spec_intern(intern)) {
+ xmlSaveCtxtPtr ctxt = xmlSaveToBuffer(buf, (const char *) docp->encoding, XML_SAVE_AS_XML);
+ if (EXPECTED(ctxt != NULL)) {
+ xmlCharEncodingHandlerPtr handler = xmlFindCharEncodingHandler((const char *) docp->encoding);
+ xmlOutputBufferPtr out = xmlOutputBufferCreateBuffer(buf, handler);
+ if (EXPECTED(out != NULL)) {
+ status = dom_xml_serialize(ctxt, out, node, format);
+ status |= xmlOutputBufferFlush(out);
+ status |= xmlOutputBufferClose(out);
+ }
+ (void) xmlSaveClose(ctxt);
+ xmlCharEncCloseFunc(handler);
+ }
+ } else {
+ status = xmlNodeDump(buf, docp, node, 0, format);
+ }
xmlSaveNoEmptyTags = old_xml_save_no_empty_tags;
} else {
buf = xmlBufferCreate();
@@ -1557,15 +1729,26 @@ PHP_METHOD(DOMDocument, saveXML)
php_error_docref(NULL, E_WARNING, "Could not create save context");
RETURN_FALSE;
}
- if (UNEXPECTED(xmlSaveDoc(ctxt, docp) < 0)) {
- (void) xmlSaveClose(ctxt);
- xmlBufferFree(buf);
- php_error_docref(NULL, E_WARNING, "Could not save document");
- RETURN_FALSE;
+ if (php_dom_follow_spec_intern(intern)) {
+ xmlCharEncodingHandlerPtr handler = xmlFindCharEncodingHandler((const char *) docp->encoding);
+ xmlOutputBufferPtr out = xmlOutputBufferCreateBuffer(buf, handler);
+ if (EXPECTED(out != NULL)) {
+ status = dom_xml_serialize(ctxt, out, (xmlNodePtr) docp, format);
+ status |= xmlOutputBufferFlush(out);
+ status |= xmlOutputBufferClose(out);
+ } else {
+ xmlCharEncCloseFunc(handler);
+ }
+ } else {
+ status = xmlSaveDoc(ctxt, docp);
}
- (void) xmlSaveFlush(ctxt);
(void) xmlSaveClose(ctxt);
}
+ if (UNEXPECTED(status < 0)) {
+ xmlBufferFree(buf);
+ php_error_docref(NULL, E_WARNING, "Could not save document");
+ RETURN_FALSE;
+ }
mem = xmlBufferContent(buf);
if (!mem) {
xmlBufferFree(buf);
@@ -1575,6 +1758,16 @@ PHP_METHOD(DOMDocument, saveXML)
RETVAL_STRINGL((const char *) mem, size);
xmlBufferFree(buf);
}
+
+PHP_METHOD(DOMDocument, saveXML)
+{
+ dom_document_save_xml(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_node_class_entry);
+}
+
+PHP_METHOD(DOM_XMLDocument, saveXML)
+{
+ dom_document_save_xml(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_modern_node_class_entry);
+}
/* }}} end dom_document_savexml */
static xmlNodePtr php_dom_free_xinclude_node(xmlNodePtr cur) /* {{{ */
@@ -1800,14 +1993,14 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type
/* }}} */
/* {{{ */
-PHP_METHOD(DOM_Document, schemaValidate)
+PHP_METHOD(DOMDocument, schemaValidate)
{
_dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
}
/* }}} end dom_document_schema_validate_file */
/* {{{ */
-PHP_METHOD(DOM_Document, schemaValidateSource)
+PHP_METHOD(DOMDocument, schemaValidateSource)
{
_dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
}
@@ -1897,14 +2090,14 @@ static void _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int typ
/* }}} */
/* {{{ */
-PHP_METHOD(DOM_Document, relaxNGValidate)
+PHP_METHOD(DOMDocument, relaxNGValidate)
{
_dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
}
/* }}} end dom_document_relaxNG_validate_file */
/* {{{ */
-PHP_METHOD(DOM_Document, relaxNGValidateSource)
+PHP_METHOD(DOMDocument, relaxNGValidateSource)
{
_dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
}
@@ -2110,9 +2303,9 @@ PHP_METHOD(DOMDocument, saveHTML)
#endif /* defined(LIBXML_HTML_ENABLED) */
/* {{{ Register extended class used to create base node type */
-PHP_METHOD(DOM_Document, registerNodeClass)
+static void dom_document_register_node_class(INTERNAL_FUNCTION_PARAMETERS, bool modern)
{
- zend_class_entry *basece = dom_node_class_entry, *ce = NULL;
+ zend_class_entry *basece = dom_get_node_ce(modern), *ce = NULL;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "CC!", &basece, &ce) == FAILURE) {
@@ -2131,17 +2324,31 @@ PHP_METHOD(DOM_Document, registerNodeClass)
}
DOM_GET_THIS_INTERN(intern);
dom_set_doc_classmap(intern->document, basece, ce);
- RETURN_TRUE;
+ if (!modern) {
+ RETVAL_TRUE;
+ }
+ return;
}
zend_argument_error(NULL, 2, "must be a class name derived from %s or null, %s given", ZSTR_VAL(basece->name), ZSTR_VAL(ce->name));
+ RETURN_THROWS();
+}
+
+PHP_METHOD(DOMDocument, registerNodeClass)
+{
+ dom_document_register_node_class(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+PHP_METHOD(DOM_Document, registerNodeClass)
+{
+ dom_document_register_node_class(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
}
/* }}} */
/* {{{ URL: https://dom.spec.whatwg.org/#dom-parentnode-replacechildren
Since:
*/
-PHP_METHOD(DOM_Document, replaceChildren)
+PHP_METHOD(DOMDocument, replaceChildren)
{
uint32_t argc = 0;
zval *args;
diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c
index 5e23d57be8ab3..36e168524383c 100644
--- a/ext/dom/documenttype.c
+++ b/ext/dom/documenttype.c
@@ -60,7 +60,7 @@ zend_result dom_documenttype_entities_read(dom_object *obj, zval *retval)
return FAILURE;
}
- php_dom_create_iterator(retval, DOM_NAMEDNODEMAP);
+ php_dom_create_iterator(retval, DOM_DTD_NAMEDNODEMAP, php_dom_follow_spec_intern(obj));
entityht = (xmlHashTable *) doctypep->entities;
@@ -88,7 +88,7 @@ zend_result dom_documenttype_notations_read(dom_object *obj, zval *retval)
return FAILURE;
}
- php_dom_create_iterator(retval, DOM_NAMEDNODEMAP);
+ php_dom_create_iterator(retval, DOM_DTD_NAMEDNODEMAP, php_dom_follow_spec_intern(obj));
notationht = (xmlHashTable *) doctypep->notations;
@@ -184,7 +184,7 @@ zend_result dom_documenttype_internal_subset_read(dom_object *obj, zval *retval)
}
if (ret_buf.s) {
- ZVAL_STR(retval, smart_str_extract(&ret_buf));
+ ZVAL_NEW_STR(retval, smart_str_extract(&ret_buf));
return SUCCESS;
}
}
diff --git a/ext/dom/dom_ce.h b/ext/dom/dom_ce.h
index 5b661b2abbb94..847688ca9092f 100644
--- a/ext/dom/dom_ce.h
+++ b/ext/dom/dom_ce.h
@@ -19,28 +19,51 @@
#define DOM_CE_H
extern PHP_DOM_EXPORT zend_class_entry *dom_node_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_node_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_domexception_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_parentnode_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_parentnode_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_childnode_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_childnode_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_domimplementation_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_domimplementation_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_documentfragment_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_documentfragment_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_document_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_html_document_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_xml_document_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_nodelist_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_nodelist_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_namednodemap_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_namednodemap_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_dtd_namednodemap_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_html_collection_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_characterdata_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_characterdata_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_attr_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_attr_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_element_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_element_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_text_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_text_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_comment_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_comment_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_cdatasection_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_cdatasection_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_documenttype_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_documenttype_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_notation_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_notation_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_entity_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_entity_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_entityreference_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_entityreference_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_processinginstruction_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_processinginstruction_class_entry;
extern PHP_DOM_EXPORT zend_class_entry *dom_abstract_base_document_class_entry;
#ifdef LIBXML_XPATH_ENABLED
extern PHP_DOM_EXPORT zend_class_entry *dom_xpath_class_entry;
+extern PHP_DOM_EXPORT zend_class_entry *dom_modern_xpath_class_entry;
#endif
extern PHP_DOM_EXPORT zend_class_entry *dom_namespace_node_class_entry;
diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c
index bb151c198953c..29a567d78474d 100644
--- a/ext/dom/dom_iterators.c
+++ b/ext/dom/dom_iterators.c
@@ -230,7 +230,7 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter) /* {{{ */
curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
}
curnode = dom_get_elements_by_tag_name_ns_raw(
- basenode, curnode, (char *) objmap->ns, (char *) objmap->local, &previndex, iter->index);
+ basenode, curnode, objmap->ns, objmap->local, objmap->local_lower, &previndex, iter->index);
}
}
} else {
@@ -316,7 +316,7 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i
nodep = nodep->children;
}
curnode = dom_get_elements_by_tag_name_ns_raw(
- basep, nodep, (char *) objmap->ns, (char *) objmap->local, &curindex, 0);
+ basep, nodep, objmap->ns, objmap->local, objmap->local_lower, &curindex, 0);
}
}
} else {
diff --git a/ext/dom/dom_properties.h b/ext/dom/dom_properties.h
index 349b604dddcc7..03525707b9701 100644
--- a/ext/dom/dom_properties.h
+++ b/ext/dom/dom_properties.h
@@ -34,6 +34,7 @@ zend_result dom_characterdata_length_read(dom_object *obj, zval *retval);
/* document properties */
zend_result dom_document_doctype_read(dom_object *obj, zval *retval);
zend_result dom_document_implementation_read(dom_object *obj, zval *retval);
+zend_result dom_modern_document_implementation_read(dom_object *obj, zval *retval);
zend_result dom_document_document_element_read(dom_object *obj, zval *retval);
zend_result dom_document_actual_encoding_read(dom_object *obj, zval *retval);
zend_result dom_document_actual_encoding_write(dom_object *obj, zval *newval);
@@ -115,6 +116,7 @@ zend_result dom_node_is_connected_read(dom_object *obj, zval *retval);
zend_result dom_node_owner_document_read(dom_object *obj, zval *retval);
zend_result dom_node_namespace_uri_read(dom_object *obj, zval *retval);
zend_result dom_node_prefix_read(dom_object *obj, zval *retval);
+zend_result dom_modern_node_prefix_read(dom_object *obj, zval *retval);
zend_result dom_node_prefix_write(dom_object *obj, zval *newval);
zend_result dom_node_local_name_read(dom_object *obj, zval *retval);
zend_result dom_node_base_uri_read(dom_object *obj, zval *retval);
diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c
index d771eccad8684..5dad65aef8935 100644
--- a/ext/dom/domimplementation.c
+++ b/ext/dom/domimplementation.c
@@ -22,6 +22,7 @@
#include "php.h"
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
#include "php_dom.h"
+#include "namespace_compat.h"
/*
* class DOMImplementation
@@ -46,6 +47,7 @@ PHP_METHOD(DOMImplementation, hasFeature)
/* }}} end dom_domimplementation_has_feature */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocType
+Modern URL: https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
Since: DOM Level 2
*/
PHP_METHOD(DOMImplementation, createDocumentType)
@@ -91,10 +93,6 @@ PHP_METHOD(DOMImplementation, createDocumentType)
localname = xmlStrdup((xmlChar *) name);
}
- /* TODO: Test that localname has no invalid chars
- php_dom_throw_error(INVALID_CHARACTER_ERR,);
- */
-
if (uri) {
xmlFreeURI(uri);
}
@@ -109,6 +107,41 @@ PHP_METHOD(DOMImplementation, createDocumentType)
DOM_RET_OBJ((xmlNodePtr) doctype, &ret, NULL);
}
+
+PHP_METHOD(DOM_Implementation, createDocumentType)
+{
+ size_t name_len, publicid_len = 0, systemid_len = 0;
+ const char *name, *publicid = NULL, *systemid = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppp", &name, &name_len, &publicid, &publicid_len, &systemid, &systemid_len) != SUCCESS) {
+ RETURN_THROWS();
+ }
+
+ /* 1. Validate qualifiedName. */
+ if (xmlValidateQName(BAD_CAST name, 0) != 0) {
+ php_dom_throw_error(NAMESPACE_ERR, true);
+ RETURN_THROWS();
+ }
+
+ /* 2. Return a new doctype, with qualifiedName as its name, publicId as its public ID, and systemId as its system ID ... */
+ xmlDtdPtr doctype = xmlCreateIntSubset(
+ NULL,
+ BAD_CAST name,
+ publicid_len ? BAD_CAST publicid : NULL,
+ systemid_len ? BAD_CAST systemid : NULL
+ );
+ if (UNEXPECTED(doctype == NULL)) {
+ php_dom_throw_error(INVALID_STATE_ERR, true);
+ RETURN_THROWS();
+ }
+
+ php_dom_instantiate_object_helper(
+ return_value,
+ dom_modern_documenttype_class_entry,
+ (xmlNodePtr) doctype,
+ NULL
+ );
+}
/* }}} end dom_domimplementation_create_document_type */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument
@@ -216,8 +249,170 @@ PHP_METHOD(DOMImplementation, createDocument)
php_libxml_increment_doc_ref((php_libxml_node_object *)doctobj, docp);
}
}
+
+PHP_METHOD(DOM_Implementation, createDocument)
+{
+ zval *dtd = NULL;
+ xmlDtdPtr doctype = NULL;
+ zend_string *uri = NULL, *qualified_name = zend_empty_string;
+ dom_object *doctobj;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "P!P|O!", &uri, &qualified_name, &dtd, dom_modern_documenttype_class_entry) != SUCCESS) {
+ RETURN_THROWS();
+ }
+
+ if (dtd != NULL) {
+ DOM_GET_OBJ(doctype, dtd, xmlDtdPtr, doctobj);
+ }
+
+ xmlDocPtr document = NULL;
+ xmlChar *localname = NULL, *prefix = NULL;
+ php_dom_libxml_ns_mapper *ns_mapper = php_dom_libxml_ns_mapper_create();
+
+ /* 1. Let document be a new XMLDocument. */
+ document = xmlNewDoc(BAD_CAST "1.0");
+ if (UNEXPECTED(document == NULL)) {
+ goto oom;
+ }
+ document->encoding = xmlStrdup(BAD_CAST "UTF-8");
+
+ /* 2. Let element be null. */
+ xmlNodePtr element = NULL;
+
+ /* 3. If qualifiedName is not the empty string, then set element to the result of running the internal createElementNS steps. */
+ if (ZSTR_LEN(qualified_name) != 0) {
+ int errorcode = dom_validate_and_extract(uri, qualified_name, &localname, &prefix);
+
+ if (EXPECTED(errorcode == 0)) {
+ xmlNsPtr ns = php_dom_libxml_ns_mapper_get_ns_raw_prefix_string(ns_mapper, prefix, xmlStrlen(prefix), uri);
+ element = xmlNewDocNode(document, ns, localname, NULL);
+ if (UNEXPECTED(element == NULL)) {
+ goto oom;
+ }
+ xmlFree(localname);
+ xmlFree(prefix);
+ localname = NULL;
+ prefix = NULL;
+ } else {
+ php_dom_throw_error(errorcode, /* strict */ true);
+ goto error;
+ }
+ }
+
+ /* 8. Return document.
+ * => This is done here already to gain access to the dom_object */
+ dom_object *intern = php_dom_instantiate_object_helper(
+ return_value,
+ dom_xml_document_class_entry,
+ (xmlNodePtr) document,
+ NULL
+ );
+ intern->document->class_type = PHP_LIBXML_CLASS_MODERN;
+ intern->document->private_data = php_dom_libxml_ns_mapper_header(ns_mapper);
+
+ /* 4. If doctype is non-null, append doctype to document. */
+ if (doctype != NULL) {
+ php_dom_adopt_node((xmlNodePtr) doctype, intern, document);
+ xmlAddChild((xmlNodePtr) document, (xmlNodePtr) doctype);
+ doctype->doc = document;
+ document->intSubset = (xmlDtdPtr) doctype;
+ ZEND_ASSERT(doctype->parent == document);
+ }
+
+ /* 5. If element is non-null, append element to document. */
+ if (element != NULL) {
+ xmlAddChild((xmlNodePtr) document, element);
+ }
+
+ /* 6. document’s origin is this’s associated document’s origin.
+ * => We don't store the origin in ext/dom. */
+
+ /* 7. document’s content type is determined by namespace:
+ * => We don't store the content type in ext/dom. */
+
+ return;
+
+oom:
+ php_dom_throw_error(INVALID_STATE_ERR, true);
+error:
+ xmlFree(localname);
+ xmlFree(prefix);
+ xmlFreeDoc(document);
+ php_dom_libxml_ns_mapper_destroy(ns_mapper);
+ RETURN_THROWS();
+}
/* }}} end dom_domimplementation_create_document */
+/* {{{ URL: https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument */
+PHP_METHOD(DOM_Implementation, createHTMLDocument)
+{
+ const char *title = NULL;
+ size_t title_len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p!", &title, &title_len) != SUCCESS) {
+ RETURN_THROWS();
+ }
+
+ /* 1. Let doc be a new document that is an HTML document. */
+ xmlDocPtr doc = php_dom_create_html_doc();
+ if (UNEXPECTED(doc == NULL)) {
+ php_dom_throw_error(INVALID_STATE_ERR, true);
+ RETURN_THROWS();
+ }
+ doc->encoding = xmlStrdup(BAD_CAST "UTF-8");
+
+ /* 2. Set doc’s content type to "text/html".
+ * => We don't store the content type in ext/dom. */
+
+ /* 3. Append a new doctype, with "html" as its name and with its node document set to doc, to doc. */
+ xmlDtdPtr dtd = xmlCreateIntSubset(doc, BAD_CAST "html", NULL, NULL);
+
+ php_dom_libxml_ns_mapper *ns_mapper = php_dom_libxml_ns_mapper_create();
+ xmlNsPtr html_ns = php_dom_libxml_ns_mapper_ensure_html_ns(ns_mapper);
+
+ /* 4. Append the result of creating an element given doc, html, and the HTML namespace, to doc. */
+ xmlNodePtr html_element = xmlNewDocRawNode(doc, html_ns, BAD_CAST "html", NULL);
+ xmlAddChild((xmlNodePtr) doc, html_element);
+
+ /* 5. Append the result of creating an element given doc, head, and the HTML namespace, to the html element created earlier. */
+ xmlNodePtr head_element = xmlNewDocRawNode(doc, html_ns, BAD_CAST "head", NULL);
+ xmlAddChild(html_element, head_element);
+
+ /* 6. If title is given: */
+ xmlNodePtr title_element = NULL;
+ if (title != NULL) {
+ /* 6.1. Append the result of creating an element given doc, title, and the HTML namespace, to the head element created earlier. */
+ /* 6.2. Append the result of creating a text node given doc and title, to the title element created earlier. */
+ title_element = xmlNewDocRawNode(doc, html_ns, BAD_CAST "title", BAD_CAST title);
+ xmlAddChild(head_element, title_element);
+ }
+
+ /* 7. Append the result of creating an element given doc, body, and the HTML namespace, to the html element created earlier. */
+ xmlNodePtr body_element = xmlNewDocRawNode(doc, html_ns, BAD_CAST "body", NULL);
+ xmlAddChild(html_element, body_element);
+
+ /* 8. doc’s origin is this’s associated document’s origin.
+ * => We don't store the origin in ext/dom. */
+
+ if (UNEXPECTED(dtd == NULL || html_element == NULL || head_element == NULL || (title != NULL && title_element == NULL) || body_element == NULL)) {
+ php_dom_throw_error(INVALID_STATE_ERR, true);
+ xmlFreeDoc(doc);
+ php_dom_libxml_ns_mapper_destroy(ns_mapper);
+ RETURN_THROWS();
+ }
+
+ /* 9. Return doc. */
+ dom_object *intern = php_dom_instantiate_object_helper(
+ return_value,
+ dom_html_document_class_entry,
+ (xmlNodePtr) doc,
+ NULL
+ );
+ intern->document->class_type = PHP_LIBXML_CLASS_MODERN;
+ intern->document->private_data = php_dom_libxml_ns_mapper_header(ns_mapper);
+}
+/* }}} */
+
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementation3-getFeature
Since: DOM Level 3
*/
diff --git a/ext/dom/element.c b/ext/dom/element.c
index 5061af68e272a..3b81d8141138e 100644
--- a/ext/dom/element.c
+++ b/ext/dom/element.c
@@ -22,6 +22,8 @@
#include "php.h"
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
#include "php_dom.h"
+#include "namespace_compat.h"
+#include "internal_helpers.h"
/*
* class DOMElement extends DOMNode
@@ -106,31 +108,22 @@ PHP_METHOD(DOMElement, __construct)
/* {{{ tagName string
readonly=yes
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-104682815
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-tagname
Since:
*/
zend_result dom_element_tag_name_read(dom_object *obj, zval *retval)
{
- xmlNodePtr nodep;
- xmlNsPtr ns;
- xmlChar *qname;
-
- nodep = dom_object_get_node(obj);
+ xmlNodePtr nodep = dom_object_get_node(obj);
if (nodep == NULL) {
php_dom_throw_error(INVALID_STATE_ERR, 1);
return FAILURE;
}
- ns = nodep->ns;
- if (ns != NULL && ns->prefix) {
- qname = xmlStrdup(ns->prefix);
- qname = xmlStrcat(qname, (xmlChar *)":");
- qname = xmlStrcat(qname, nodep->name);
- ZVAL_STRING(retval, (char *)qname);
- xmlFree(qname);
- } else {
- ZVAL_STRING(retval, (char *) nodep->name);
- }
+ bool uppercase = php_dom_follow_spec_intern(obj) && php_dom_ns_is_html_and_document_is_html(nodep);
+
+ zend_string *result = dom_node_get_node_name_attribute_or_element((const xmlNode *) nodep, uppercase);
+ ZVAL_NEW_STR(retval, result);
return SUCCESS;
}
@@ -226,49 +219,53 @@ zend_result dom_element_schema_type_info_read(dom_object *obj, zval *retval)
/* }}} */
/* Note: the object returned is not necessarily a node, but can be an attribute or a namespace declaration. */
-static xmlNodePtr dom_get_dom1_attribute(xmlNodePtr elem, xmlChar *name) /* {{{ */
+static xmlNodePtr dom_get_attribute_or_nsdecl(dom_object *intern, xmlNodePtr elem, const xmlChar *name, size_t name_len) /* {{{ */
{
- int len;
- const xmlChar *nqname;
-
- nqname = xmlSplitQName3(name, &len);
- if (nqname != NULL) {
- xmlNsPtr ns;
- if (strncmp((const char *) name, "xmlns:", len + 1) == 0) {
- ns = elem->nsDef;
- while (ns) {
- if (xmlStrEqual(ns->prefix, nqname)) {
- break;
+ if (!php_dom_follow_spec_intern(intern)) {
+ int len;
+ const xmlChar *nqname = xmlSplitQName3(name, &len);
+
+ if (nqname != NULL) {
+ xmlNsPtr ns;
+ if (strncmp((const char *) name, "xmlns:", len + 1) == 0) {
+ ns = elem->nsDef;
+ while (ns) {
+ if (xmlStrEqual(ns->prefix, nqname)) {
+ break;
+ }
+ ns = ns->next;
}
- ns = ns->next;
+ return (xmlNodePtr)ns;
}
- return (xmlNodePtr)ns;
- }
- xmlChar *prefix = xmlStrndup(name, len);
- ns = xmlSearchNs(elem->doc, elem, prefix);
- if (prefix != NULL) {
- xmlFree(prefix);
- }
- if (ns != NULL) {
- return (xmlNodePtr)xmlHasNsProp(elem, nqname, ns->href);
- }
- } else {
- if (xmlStrEqual(name, (xmlChar *)"xmlns")) {
- xmlNsPtr nsPtr = elem->nsDef;
- while (nsPtr) {
- if (nsPtr->prefix == NULL) {
- return (xmlNodePtr)nsPtr;
+ xmlChar *prefix = xmlStrndup(name, len);
+ ns = xmlSearchNs(elem->doc, elem, prefix);
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ }
+ if (ns != NULL) {
+ return (xmlNodePtr)xmlHasNsProp(elem, nqname, ns->href);
+ }
+ } else {
+ if (xmlStrEqual(name, (xmlChar *)"xmlns")) {
+ xmlNsPtr nsPtr = elem->nsDef;
+ while (nsPtr) {
+ if (nsPtr->prefix == NULL) {
+ return (xmlNodePtr)nsPtr;
+ }
+ nsPtr = nsPtr->next;
}
- nsPtr = nsPtr->next;
+ return NULL;
}
- return NULL;
}
+ return (xmlNodePtr) xmlHasNsProp(elem, name, NULL);
+ } else {
+ return (xmlNodePtr) php_dom_get_attribute_node(elem, name, name_len);
}
- return (xmlNodePtr)xmlHasNsProp(elem, name, NULL);
}
/* }}} */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-666EE0F9
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-getattribute
Since:
*/
PHP_METHOD(DOMElement, getAttribute)
@@ -280,7 +277,7 @@ PHP_METHOD(DOMElement, getAttribute)
dom_object *intern;
xmlNodePtr attr;
size_t name_len;
- bool should_free;
+ bool should_free = false;
id = ZEND_THIS;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
@@ -289,7 +286,7 @@ PHP_METHOD(DOMElement, getAttribute)
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
+ attr = dom_get_attribute_or_nsdecl(intern, nodep, BAD_CAST name, name_len);
if (attr) {
switch (attr->type) {
case XML_ATTRIBUTE_NODE:
@@ -307,6 +304,9 @@ PHP_METHOD(DOMElement, getAttribute)
}
if (value == NULL) {
+ if (php_dom_follow_spec_intern(intern)) {
+ RETURN_NULL();
+ }
RETURN_EMPTY_STRING();
} else {
RETVAL_STRING((char *)value);
@@ -324,27 +324,29 @@ PHP_METHOD(DOMElement, getAttributeNames)
{
zval *id;
xmlNode *nodep;
- dom_object *unused_intern;
+ dom_object *intern;
zval tmp;
if (zend_parse_parameters_none() == FAILURE) {
RETURN_THROWS();
}
- DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, unused_intern);
+ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
array_init(return_value);
HashTable *ht = Z_ARRVAL_P(return_value);
zend_hash_real_init_packed(ht);
- for (xmlNsPtr nsptr = nodep->nsDef; nsptr; nsptr = nsptr->next) {
- const char *prefix = (const char *) nsptr->prefix;
- ZVAL_STR(&tmp, dom_node_concatenated_name_helper(strlen(prefix), prefix, strlen("xmlns"), (const char *) "xmlns"));
- zend_hash_next_index_insert(ht, &tmp);
+ if (!php_dom_follow_spec_intern(intern)) {
+ for (xmlNsPtr nsptr = nodep->nsDef; nsptr; nsptr = nsptr->next) {
+ const char *prefix = (const char *) nsptr->prefix;
+ ZVAL_NEW_STR(&tmp, dom_node_concatenated_name_helper(strlen(prefix), prefix, strlen("xmlns"), (const char *) "xmlns"));
+ zend_hash_next_index_insert(ht, &tmp);
+ }
}
for (xmlAttrPtr attr = nodep->properties; attr; attr = attr->next) {
- ZVAL_STR(&tmp, dom_node_get_node_name_attribute_or_element((const xmlNode *) attr));
+ ZVAL_NEW_STR(&tmp, dom_node_get_node_name_attribute_or_element((const xmlNode *) attr, false));
zend_hash_next_index_insert(ht, &tmp);
}
}
@@ -360,6 +362,7 @@ static xmlNodePtr dom_create_attribute(xmlNodePtr nodep, const char *name, const
}
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68F082
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-setattribute
Since:
*/
PHP_METHOD(DOMElement, setAttribute)
@@ -390,31 +393,52 @@ PHP_METHOD(DOMElement, setAttribute)
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
- if (attr != NULL) {
- switch (attr->type) {
- case XML_ATTRIBUTE_NODE:
- node_list_unlink(attr->children);
- break;
- case XML_NAMESPACE_DECL:
- RETURN_FALSE;
- default:
- break;
+ if (php_dom_follow_spec_intern(intern)) {
+ xmlChar *name_processed = BAD_CAST name;
+ if (php_dom_ns_is_html_and_document_is_html(nodep)) {
+ char *lowercase_copy = zend_str_tolower_dup_ex(name, name_len);
+ if (lowercase_copy != NULL) {
+ name_processed = BAD_CAST lowercase_copy;
+ }
}
- }
+ /* Can't use xmlSetNsProp unconditionally here because that doesn't take into account the qualified name matching... */
+ attr = (xmlNodePtr) php_dom_get_attribute_node(nodep, BAD_CAST name, name_len);
+ if (attr != NULL) {
+ dom_remove_all_children(attr);
+ xmlNodePtr node = xmlNewDocText(attr->doc, BAD_CAST value);
+ xmlAddChild(attr, node);
+ } else {
+ attr = (xmlNodePtr) xmlSetNsProp(nodep, NULL, name_processed, BAD_CAST value);
+ }
- attr = dom_create_attribute(nodep, name, value);
- if (!attr) {
- zend_argument_value_error(1, "must be a valid XML attribute");
- RETURN_THROWS();
- }
- if (attr->type == XML_NAMESPACE_DECL) {
- RETURN_TRUE;
- }
+ if (name_processed != BAD_CAST name) {
+ efree(name_processed);
+ }
+ } else {
+ attr = dom_get_attribute_or_nsdecl(intern, nodep, BAD_CAST name, name_len);
+ if (attr != NULL) {
+ switch (attr->type) {
+ case XML_ATTRIBUTE_NODE:
+ node_list_unlink(attr->children);
+ break;
+ case XML_NAMESPACE_DECL:
+ RETURN_FALSE;
+ EMPTY_SWITCH_DEFAULT_CASE();
+ }
+ }
- DOM_RET_OBJ(attr, &ret, intern);
+ attr = dom_create_attribute(nodep, name, value);
+ if (!attr) {
+ zend_argument_value_error(1, "must be a valid XML attribute");
+ RETURN_THROWS();
+ }
+ if (attr->type == XML_NAMESPACE_DECL) {
+ RETURN_TRUE;
+ }
+ DOM_RET_OBJ(attr, &ret, intern);
+ }
}
/* }}} end dom_element_set_attribute */
@@ -533,33 +557,52 @@ static bool dom_remove_attribute(xmlNodePtr thisp, xmlNodePtr attrp)
}
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D6AC0F9
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-removeattribute
Since:
*/
PHP_METHOD(DOMElement, removeAttribute)
{
- zval *id;
xmlNodePtr nodep, attrp;
dom_object *intern;
size_t name_len;
char *name;
- id = ZEND_THIS;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
RETURN_THROWS();
}
- DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+ DOM_GET_OBJ(nodep, ZEND_THIS, xmlNodePtr, intern);
- attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name);
+ attrp = dom_get_attribute_or_nsdecl(intern, nodep, BAD_CAST name, name_len);
if (attrp == NULL) {
RETURN_FALSE;
}
RETURN_BOOL(dom_remove_attribute(nodep, attrp));
}
+
+PHP_METHOD(DOM_Element, removeAttribute)
+{
+ xmlNodePtr nodep, attrp;
+ dom_object *intern;
+ size_t name_len;
+ char *name;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ DOM_GET_OBJ(nodep, ZEND_THIS, xmlNodePtr, intern);
+
+ attrp = dom_get_attribute_or_nsdecl(intern, nodep, BAD_CAST name, name_len);
+ if (attrp != NULL) {
+ dom_remove_attribute(nodep, attrp);
+ }
+}
/* }}} end dom_element_remove_attribute */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-217A91B8
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-getattributenode
Since:
*/
PHP_METHOD(DOMElement, getAttributeNode)
@@ -578,8 +621,11 @@ PHP_METHOD(DOMElement, getAttributeNode)
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name);
+ attrp = dom_get_attribute_or_nsdecl(intern, nodep, BAD_CAST name, name_len);
if (attrp == NULL) {
+ if (php_dom_follow_spec_intern(intern)) {
+ RETURN_NULL();
+ }
RETURN_FALSE;
}
@@ -594,34 +640,50 @@ PHP_METHOD(DOMElement, getAttributeNode)
}
/* }}} end dom_element_get_attribute_node */
-/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-887236154
-Since:
-*/
-PHP_METHOD(DOMElement, setAttributeNode)
+static void dom_element_set_attribute_node_common(INTERNAL_FUNCTION_PARAMETERS, bool use_ns, bool modern)
{
zval *id, *node;
xmlNode *nodep;
+ xmlNs *nsp;
xmlAttr *attrp, *existattrp = NULL;
dom_object *intern, *attrobj, *oldobj;
int ret;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node, dom_attr_class_entry) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node, dom_get_node_ce(modern)) == FAILURE) {
RETURN_THROWS();
}
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
-
DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
+ /* ZPP Guarantees that a DOMAttr class is given, as it is converted to a xmlAttr
+ * to pass to libxml (see http://www.xmlsoft.org/html/libxml-tree.html#xmlAttr)
+ * if it is not of type XML_ATTRIBUTE_NODE it indicates a bug somewhere */
ZEND_ASSERT(attrp->type == XML_ATTRIBUTE_NODE);
- if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) {
- php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document));
- RETURN_FALSE;
+ if (modern) {
+ if (attrp->parent != NULL && attrp->parent != nodep) {
+ php_dom_throw_error(INUSE_ATTRIBUTE_ERR, /* strict */ true);
+ RETURN_THROWS();
+ }
+ if (attrp->doc != NULL && attrp->doc != nodep->doc) {
+ php_dom_adopt_node((xmlNodePtr) attrp, intern, nodep->doc);
+ }
+ } else {
+ if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document));
+ RETURN_FALSE;
+ }
+ }
+
+ nsp = attrp->ns;
+ if (use_ns && nsp != NULL) {
+ existattrp = xmlHasNsProp(nodep, attrp->name, nsp->href);
+ } else {
+ existattrp = xmlHasProp(nodep, attrp->name);
}
- existattrp = xmlHasProp(nodep, attrp->name);
if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) {
if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL &&
((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
@@ -641,35 +703,44 @@ PHP_METHOD(DOMElement, setAttributeNode)
}
xmlAddChild(nodep, (xmlNodePtr) attrp);
- php_dom_reconcile_attribute_namespace_after_insertion(attrp);
+ if (!modern) {
+ php_dom_reconcile_attribute_namespace_after_insertion(attrp);
+ }
/* Returns old property if removed otherwise NULL */
if (existattrp != NULL) {
DOM_RET_OBJ((xmlNodePtr) existattrp, &ret, intern);
} else {
- RETVAL_NULL();
+ RETURN_NULL();
}
+}
+/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-887236154
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-setattributenode
+Since:
+*/
+PHP_METHOD(DOMElement, setAttributeNode)
+{
+ dom_element_set_attribute_node_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* use_ns */ false, /* modern */ false);
}
/* }}} end dom_element_set_attribute_node */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D589198
Since:
*/
-PHP_METHOD(DOMElement, removeAttributeNode)
+static void dom_element_remove_attribute_node(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *node_ce)
{
- zval *id, *node;
+ zval *node;
xmlNode *nodep;
xmlAttr *attrp;
dom_object *intern, *attrobj;
int ret;
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node, dom_attr_class_entry) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node, node_ce) == FAILURE) {
RETURN_THROWS();
}
- DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+ DOM_GET_OBJ(nodep, ZEND_THIS, xmlNodePtr, intern);
DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
@@ -683,14 +754,24 @@ PHP_METHOD(DOMElement, removeAttributeNode)
xmlUnlinkNode((xmlNodePtr) attrp);
DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern);
+}
+PHP_METHOD(DOMElement, removeAttributeNode)
+{
+ dom_element_remove_attribute_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_node_class_entry);
+}
+
+PHP_METHOD(DOM_Element, removeAttributeNode)
+{
+ dom_element_remove_attribute_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_modern_node_class_entry);
}
/* }}} end dom_element_remove_attribute_node */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1938918D
+Modern spec URL: https://dom.spec.whatwg.org/#concept-getelementsbytagname
Since:
*/
-PHP_METHOD(DOMElement, getElementsByTagName)
+static void dom_element_get_elements_by_tag_name(INTERNAL_FUNCTION_PARAMETERS, bool modern)
{
size_t name_len;
dom_object *intern, *namednode;
@@ -702,24 +783,64 @@ PHP_METHOD(DOMElement, getElementsByTagName)
DOM_GET_THIS_INTERN(intern);
- php_dom_create_iterator(return_value, DOM_NODELIST);
+ if (modern) {
+ php_dom_create_iterator(return_value, DOM_HTMLCOLLECTION, true);
+ } else {
+ php_dom_create_iterator(return_value, DOM_NODELIST, false);
+ }
namednode = Z_DOMOBJ_P(return_value);
dom_namednode_iter(intern, 0, namednode, NULL, name, name_len, NULL, 0);
}
+
+PHP_METHOD(DOMElement, getElementsByTagName)
+{
+ dom_element_get_elements_by_tag_name(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+PHP_METHOD(DOM_Element, getElementsByTagName)
+{
+ dom_element_get_elements_by_tag_name(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
/* }}} end dom_element_get_elements_by_tag_name */
+/* should_free_result must be initialized to false */
+static const xmlChar *dom_get_attribute_ns(dom_object *intern, xmlNodePtr elemp, const char *uri, size_t uri_len, const char *name, bool *should_free_result)
+{
+ bool follow_spec = php_dom_follow_spec_intern(intern);
+ if (follow_spec && uri_len == 0) {
+ uri = NULL;
+ }
+
+ xmlChar *strattr = xmlGetNsProp(elemp, (xmlChar *) name, (xmlChar *) uri);
+
+ if (strattr != NULL) {
+ *should_free_result = true;
+ return strattr;
+ } else {
+ if (!follow_spec && xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
+ xmlNsPtr nsptr = dom_get_nsdecl(elemp, (xmlChar *)name);
+ if (nsptr != NULL) {
+ return nsptr->href;
+ } else {
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+ }
+}
+
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAttrNS
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-getattributens
Since: DOM Level 2
*/
PHP_METHOD(DOMElement, getAttributeNS)
{
zval *id;
xmlNodePtr elemp;
- xmlNsPtr nsptr;
dom_object *intern;
size_t uri_len = 0, name_len = 0;
char *uri, *name;
- xmlChar *strattr;
id = ZEND_THIS;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!s", &uri, &uri_len, &name, &name_len) == FAILURE) {
@@ -728,57 +849,37 @@ PHP_METHOD(DOMElement, getAttributeNS)
DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
- strattr = xmlGetNsProp(elemp, (xmlChar *) name, (xmlChar *) uri);
-
- if (strattr != NULL) {
- RETVAL_STRING((char *)strattr);
- xmlFree(strattr);
+ bool should_free_result = false;
+ const xmlChar *result = dom_get_attribute_ns(intern, elemp, uri, uri_len, name, &should_free_result);
+ if (result == NULL) {
+ if (php_dom_follow_spec_intern(intern)) {
+ RETURN_NULL();
+ }
+ RETURN_EMPTY_STRING();
} else {
- if (xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
- nsptr = dom_get_nsdecl(elemp, (xmlChar *)name);
- if (nsptr != NULL) {
- RETVAL_STRING((char *) nsptr->href);
- } else {
- RETVAL_EMPTY_STRING();
- }
- } else {
- RETVAL_EMPTY_STRING();
+ RETVAL_STRING((const char *) result);
+ if (should_free_result) {
+ xmlFree(BAD_CAST result);
}
}
-
}
/* }}} end dom_element_get_attribute_ns */
-/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS
-Since: DOM Level 2
-*/
-PHP_METHOD(DOMElement, setAttributeNS)
+static void dom_set_attribute_ns_legacy(dom_object *intern, xmlNodePtr elemp, char *uri, size_t uri_len, char *name, size_t name_len, const char *value)
{
- zval *id;
- xmlNodePtr elemp, nodep = NULL;
- xmlNsPtr nsptr;
- xmlAttr *attr;
- size_t uri_len = 0, name_len = 0, value_len = 0;
- char *uri, *name, *value;
- char *localname = NULL, *prefix = NULL;
- dom_object *intern;
- int errorcode = 0, stricterror, is_xmlns = 0, name_valid;
-
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!ss", &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) {
- RETURN_THROWS();
- }
-
if (name_len == 0) {
zend_argument_value_error(2, "cannot be empty");
- RETURN_THROWS();
+ return;
}
- DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
-
- stricterror = dom_get_strict_error(intern->document);
+ xmlNodePtr nodep = NULL;
+ xmlNsPtr nsptr;
+ xmlAttr *attr;
+ char *localname = NULL, *prefix = NULL;
+ int is_xmlns = 0, name_valid;
+ int stricterror = dom_get_strict_error(intern->document);
- errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+ int errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
if (errorcode == 0) {
if (uri_len > 0) {
@@ -858,8 +959,54 @@ PHP_METHOD(DOMElement, setAttributeNS)
if (errorcode != 0) {
php_dom_throw_error(errorcode, stricterror);
}
+}
- RETURN_NULL();
+/* https://dom.spec.whatwg.org/#dom-element-setattributens */
+static void dom_set_attribute_ns_modern(dom_object *intern, xmlNodePtr elemp, zend_string *uri, const zend_string *name, const char *value)
+{
+ xmlChar *localname = NULL, *prefix = NULL;
+ int errorcode = dom_validate_and_extract(uri, name, &localname, &prefix);
+
+ if (errorcode == 0) {
+ php_dom_libxml_ns_mapper *ns_mapper = php_dom_get_ns_mapper(intern);
+ xmlNsPtr ns = php_dom_libxml_ns_mapper_get_ns_raw_prefix_string(ns_mapper, prefix, xmlStrlen(prefix), uri);
+ if (UNEXPECTED(xmlSetNsProp(elemp, ns, localname, BAD_CAST value) == NULL)) {
+ php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
+ }
+ } else {
+ php_dom_throw_error(errorcode, /* strict */ true);
+ }
+
+ xmlFree(localname);
+ xmlFree(prefix);
+}
+
+/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-setattributens
+Since: DOM Level 2
+*/
+PHP_METHOD(DOMElement, setAttributeNS)
+{
+ zval *id;
+ xmlNodePtr elemp;
+ size_t value_len = 0;
+ char *value;
+ zend_string *uri;
+ zend_string *name = NULL;
+ dom_object *intern;
+
+ id = ZEND_THIS;
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S!Ss", &uri, &name, &value, &value_len) == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
+
+ if (php_dom_follow_spec_intern(intern)) {
+ dom_set_attribute_ns_modern(intern, elemp, uri, name, value);
+ } else {
+ dom_set_attribute_ns_legacy(intern, elemp, uri ? ZSTR_VAL(uri) : NULL, uri ? ZSTR_LEN(uri) : 0, ZSTR_VAL(name), ZSTR_LEN(name), value);
+ }
}
/* }}} end dom_element_set_attribute_ns */
@@ -895,18 +1042,7 @@ static void dom_remove_eliminated_ns(xmlNodePtr node, xmlNsPtr eliminatedNs)
}
}
- if (node->next) {
- node = node->next;
- } else {
- /* Go upwards, until we find a parent node with a next sibling, or until we hit the base. */
- do {
- node = node->parent;
- if (node == base) {
- return;
- }
- } while (node->next == NULL);
- node = node->next;
- }
+ node = php_dom_next_in_tree_order(node, base);
}
}
@@ -941,6 +1077,7 @@ static void dom_eliminate_ns(xmlNodePtr nodep, xmlNsPtr nsptr)
}
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElRemAtNS
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-removeattributens
Since: DOM Level 2
*/
PHP_METHOD(DOMElement, removeAttributeNS)
@@ -960,14 +1097,21 @@ PHP_METHOD(DOMElement, removeAttributeNS)
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- attrp = xmlHasNsProp(nodep, (xmlChar *)name, (xmlChar *)uri);
+ bool follow_spec = php_dom_follow_spec_intern(intern);
+ if (follow_spec && uri_len == 0) {
+ uri = NULL;
+ }
- nsptr = dom_get_nsdecl(nodep, (xmlChar *)name);
- if (nsptr != NULL) {
- if (xmlStrEqual((xmlChar *)uri, nsptr->href)) {
- dom_eliminate_ns(nodep, nsptr);
- } else {
- RETURN_NULL();
+ attrp = xmlHasNsProp(nodep, BAD_CAST name, BAD_CAST uri);
+
+ if (!follow_spec) {
+ nsptr = dom_get_nsdecl(nodep, BAD_CAST name);
+ if (nsptr != NULL) {
+ if (xmlStrEqual(BAD_CAST uri, nsptr->href)) {
+ dom_eliminate_ns(nodep, nsptr);
+ } else {
+ return;
+ }
}
}
@@ -980,12 +1124,11 @@ PHP_METHOD(DOMElement, removeAttributeNS)
xmlUnlinkNode((xmlNodePtr) attrp);
}
}
-
- RETURN_NULL();
}
/* }}} end dom_element_remove_attribute_ns */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAtNodeNS
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-getattributenodens
Since: DOM Level 2
*/
PHP_METHOD(DOMElement, getAttributeNodeNS)
@@ -1005,12 +1148,17 @@ PHP_METHOD(DOMElement, getAttributeNodeNS)
DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
- attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
+ bool follow_spec = php_dom_follow_spec_intern(intern);
+ if (follow_spec && uri_len == 0) {
+ uri = NULL;
+ }
+
+ attrp = xmlHasNsProp(elemp, BAD_CAST name, BAD_CAST uri);
if (attrp == NULL) {
- if (xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
+ if (!follow_spec && xmlStrEqual(BAD_CAST uri, DOM_XMLNS_NAMESPACE)) {
xmlNsPtr nsptr;
- nsptr = dom_get_nsdecl(elemp, (xmlChar *)name);
+ nsptr = dom_get_nsdecl(elemp, BAD_CAST name);
if (nsptr != NULL) {
/* Keep parent alive, because we're a fake child. */
GC_ADDREF(&intern->std);
@@ -1019,7 +1167,7 @@ PHP_METHOD(DOMElement, getAttributeNodeNS)
RETURN_NULL();
}
} else {
- RETURN_NULL();
+ RETURN_NULL();
}
} else {
DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern);
@@ -1029,77 +1177,25 @@ PHP_METHOD(DOMElement, getAttributeNodeNS)
/* }}} end dom_element_get_attribute_node_ns */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAtNodeNS
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-setattributenodens
Since: DOM Level 2
*/
PHP_METHOD(DOMElement, setAttributeNodeNS)
{
- zval *id, *node;
- xmlNode *nodep;
- xmlNs *nsp;
- xmlAttr *attrp, *existattrp = NULL;
- dom_object *intern, *attrobj, *oldobj;
- int ret;
-
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node, dom_attr_class_entry) == FAILURE) {
- RETURN_THROWS();
- }
-
- DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
-
- /* ZPP Guarantees that a DOMAttr class is given, as it is converted to a xmlAttr
- * to pass to libxml (see http://www.xmlsoft.org/html/libxml-tree.html#xmlAttr)
- * if it is not of type XML_ATTRIBUTE_NODE it indicates a bug somewhere */
- ZEND_ASSERT(attrp->type == XML_ATTRIBUTE_NODE);
-
- if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) {
- php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document));
- RETURN_FALSE;
- }
-
- nsp = attrp->ns;
- if (nsp != NULL) {
- existattrp = xmlHasNsProp(nodep, attrp->name, nsp->href);
- } else {
- existattrp = xmlHasProp(nodep, attrp->name);
- }
-
- if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) {
- if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL &&
- ((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
- {
- RETURN_NULL();
- }
- xmlUnlinkNode((xmlNodePtr) existattrp);
- }
-
- if (attrp->parent != NULL) {
- xmlUnlinkNode((xmlNodePtr) attrp);
- }
-
- if (attrp->doc == NULL && nodep->doc != NULL) {
- attrobj->document = intern->document;
- php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL);
- }
-
- xmlAddChild(nodep, (xmlNodePtr) attrp);
- php_dom_reconcile_attribute_namespace_after_insertion(attrp);
-
- /* Returns old property if removed otherwise NULL */
- if (existattrp != NULL) {
- DOM_RET_OBJ((xmlNodePtr) existattrp, &ret, intern);
- } else {
- RETVAL_NULL();
- }
+ dom_element_set_attribute_node_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* use_ns */ true, /* modern */ false);
+}
+PHP_METHOD(DOM_Element, setAttributeNodeNS)
+{
+ dom_element_set_attribute_node_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* use_ns */ true, /* modern */ true);
}
/* }}} end dom_element_set_attribute_node_ns */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C90942
+Modern spec URL: https://dom.spec.whatwg.org/#concept-getelementsbytagnamens
Since: DOM Level 2
*/
-PHP_METHOD(DOMElement, getElementsByTagNameNS)
+static void dom_element_get_elements_by_tag_name_ns(INTERNAL_FUNCTION_PARAMETERS, bool modern)
{
size_t uri_len, name_len;
dom_object *intern, *namednode;
@@ -1111,14 +1207,28 @@ PHP_METHOD(DOMElement, getElementsByTagNameNS)
DOM_GET_THIS_INTERN(intern);
- php_dom_create_iterator(return_value, DOM_NODELIST);
+ if (modern) {
+ php_dom_create_iterator(return_value, DOM_HTMLCOLLECTION, true);
+ } else {
+ php_dom_create_iterator(return_value, DOM_NODELIST, false);
+ }
namednode = Z_DOMOBJ_P(return_value);
dom_namednode_iter(intern, 0, namednode, NULL, name, name_len, uri ? uri : "", uri_len);
+}
+PHP_METHOD(DOMElement, getElementsByTagNameNS)
+{
+ dom_element_get_elements_by_tag_name_ns(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+PHP_METHOD(DOM_Element, getElementsByTagNameNS)
+{
+ dom_element_get_elements_by_tag_name_ns(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
}
/* }}} end dom_element_get_elements_by_tag_name_ns */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttr
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-hasattribute
Since: DOM Level 2
*/
PHP_METHOD(DOMElement, hasAttribute)
@@ -1137,7 +1247,7 @@ PHP_METHOD(DOMElement, hasAttribute)
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
+ attr = dom_get_attribute_or_nsdecl(intern, nodep, BAD_CAST name, name_len);
if (attr == NULL) {
RETURN_FALSE;
} else {
@@ -1147,17 +1257,16 @@ PHP_METHOD(DOMElement, hasAttribute)
/* }}} end dom_element_has_attribute */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttrNS
+Modern spec URL: https://dom.spec.whatwg.org/#dom-element-hasattributens
Since: DOM Level 2
*/
PHP_METHOD(DOMElement, hasAttributeNS)
{
zval *id;
xmlNodePtr elemp;
- xmlNs *nsp;
dom_object *intern;
size_t uri_len, name_len;
char *uri, *name;
- xmlChar *value;
id = ZEND_THIS;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!s", &uri, &uri_len, &name, &name_len) == FAILURE) {
@@ -1166,21 +1275,16 @@ PHP_METHOD(DOMElement, hasAttributeNS)
DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
- value = xmlGetNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
-
- if (value != NULL) {
- xmlFree(value);
- RETURN_TRUE;
+ bool should_free_result = false;
+ const xmlChar *result = dom_get_attribute_ns(intern, elemp, uri, uri_len, name, &should_free_result);
+ if (result == NULL) {
+ RETURN_FALSE;
} else {
- if (xmlStrEqual((xmlChar *)uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
- nsp = dom_get_nsdecl(elemp, (xmlChar *)name);
- if (nsp != NULL) {
- RETURN_TRUE;
- }
+ if (should_free_result) {
+ xmlFree(BAD_CAST result);
}
+ RETURN_TRUE;
}
-
- RETURN_FALSE;
}
/* }}} end dom_element_has_attribute_ns */
@@ -1266,7 +1370,7 @@ PHP_METHOD(DOMElement, setIdAttributeNS)
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNode
Since: DOM Level 3
*/
-PHP_METHOD(DOMElement, setIdAttributeNode)
+static void dom_element_set_id_attribute_node(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *attr_ce)
{
zval *id, *node;
xmlNode *nodep;
@@ -1275,7 +1379,7 @@ PHP_METHOD(DOMElement, setIdAttributeNode)
bool is_id;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ob", &node, dom_attr_class_entry, &is_id) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ob", &node, attr_ce, &is_id) != SUCCESS) {
RETURN_THROWS();
}
@@ -1290,6 +1394,16 @@ PHP_METHOD(DOMElement, setIdAttributeNode)
RETURN_NULL();
}
+
+PHP_METHOD(DOMElement, setIdAttributeNode)
+{
+ dom_element_set_id_attribute_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_attr_class_entry);
+}
+
+PHP_METHOD(DOM_Element, setIdAttributeNode)
+{
+ dom_element_set_id_attribute_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_modern_attr_class_entry);
+}
/* }}} end dom_element_set_id_attribute_node */
/* {{{ URL:
@@ -1415,7 +1529,9 @@ PHP_METHOD(DOMElement, replaceChildren)
}
/* }}} */
-#define INSERT_ADJACENT_RES_FAILED ((void*) -1)
+#define INSERT_ADJACENT_RES_ADOPT_FAILED ((void*) -1)
+#define INSERT_ADJACENT_RES_SYNTAX_FAILED INSERT_ADJACENT_RES_ADOPT_FAILED
+#define INSERT_ADJACENT_RES_PRE_INSERT_FAILED ((void*) -2)
static xmlNodePtr dom_insert_adjacent(const zend_string *where, xmlNodePtr thisp, dom_object *this_intern, xmlNodePtr otherp)
{
@@ -1423,60 +1539,47 @@ static xmlNodePtr dom_insert_adjacent(const zend_string *where, xmlNodePtr thisp
if (thisp->parent == NULL) {
return NULL;
}
- if (dom_hierarchy(thisp->parent, otherp) == FAILURE) {
- php_dom_throw_error(HIERARCHY_REQUEST_ERR, dom_get_strict_error(this_intern->document));
- return INSERT_ADJACENT_RES_FAILED;
- }
if (!php_dom_adopt_node(otherp, this_intern, thisp->doc)) {
- return INSERT_ADJACENT_RES_FAILED;
+ return INSERT_ADJACENT_RES_ADOPT_FAILED;
}
- otherp = xmlAddPrevSibling(thisp, otherp);
- } else if (zend_string_equals_literal_ci(where, "afterbegin")) {
- if (dom_hierarchy(thisp, otherp) == FAILURE) {
- php_dom_throw_error(HIERARCHY_REQUEST_ERR, dom_get_strict_error(this_intern->document));
- return INSERT_ADJACENT_RES_FAILED;
+ if (!php_dom_pre_insert(this_intern->document, otherp, thisp->parent, thisp)) {
+ return INSERT_ADJACENT_RES_PRE_INSERT_FAILED;
}
+ } else if (zend_string_equals_literal_ci(where, "afterbegin")) {
if (!php_dom_adopt_node(otherp, this_intern, thisp->doc)) {
- return INSERT_ADJACENT_RES_FAILED;
+ return INSERT_ADJACENT_RES_ADOPT_FAILED;
}
- if (thisp->children == NULL) {
- otherp = xmlAddChild(thisp, otherp);
- } else {
- otherp = xmlAddPrevSibling(thisp->children, otherp);
+ if (!php_dom_pre_insert(this_intern->document, otherp, thisp, thisp->children)) {
+ return INSERT_ADJACENT_RES_PRE_INSERT_FAILED;
}
} else if (zend_string_equals_literal_ci(where, "beforeend")) {
- if (dom_hierarchy(thisp, otherp) == FAILURE) {
- php_dom_throw_error(HIERARCHY_REQUEST_ERR, dom_get_strict_error(this_intern->document));
- return INSERT_ADJACENT_RES_FAILED;
- }
if (!php_dom_adopt_node(otherp, this_intern, thisp->doc)) {
- return INSERT_ADJACENT_RES_FAILED;
+ return INSERT_ADJACENT_RES_ADOPT_FAILED;
+ }
+ if (!php_dom_pre_insert(this_intern->document, otherp, thisp, NULL)) {
+ return INSERT_ADJACENT_RES_PRE_INSERT_FAILED;
}
- otherp = xmlAddChild(thisp, otherp);
} else if (zend_string_equals_literal_ci(where, "afterend")) {
if (thisp->parent == NULL) {
return NULL;
}
- if (dom_hierarchy(thisp->parent, otherp) == FAILURE) {
- php_dom_throw_error(HIERARCHY_REQUEST_ERR, dom_get_strict_error(this_intern->document));
- return INSERT_ADJACENT_RES_FAILED;
- }
if (!php_dom_adopt_node(otherp, this_intern, thisp->doc)) {
- return INSERT_ADJACENT_RES_FAILED;
+ return INSERT_ADJACENT_RES_ADOPT_FAILED;
+ }
+ if (!php_dom_pre_insert(this_intern->document, otherp, thisp->parent, thisp->next)) {
+ return INSERT_ADJACENT_RES_PRE_INSERT_FAILED;
}
- otherp = xmlAddNextSibling(thisp, otherp);
} else {
php_dom_throw_error(SYNTAX_ERR, dom_get_strict_error(this_intern->document));
- return INSERT_ADJACENT_RES_FAILED;
+ return INSERT_ADJACENT_RES_SYNTAX_FAILED;
}
- dom_reconcile_ns(thisp->doc, otherp);
return otherp;
}
/* {{{ URL: https://dom.spec.whatwg.org/#dom-element-insertadjacentelement
Since:
*/
-PHP_METHOD(DOMElement, insertAdjacentElement)
+static void dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *element_ce)
{
zend_string *where;
zval *element_zval, *id;
@@ -1484,7 +1587,7 @@ PHP_METHOD(DOMElement, insertAdjacentElement)
dom_object *this_intern, *other_intern;
int ret;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "SO", &where, &element_zval, dom_element_class_entry) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "SO", &where, &element_zval, element_ce) != SUCCESS) {
RETURN_THROWS();
}
@@ -1494,12 +1597,22 @@ PHP_METHOD(DOMElement, insertAdjacentElement)
xmlNodePtr result = dom_insert_adjacent(where, thisp, this_intern, otherp);
if (result == NULL) {
RETURN_NULL();
- } else if (result != INSERT_ADJACENT_RES_FAILED) {
+ } else if (result != INSERT_ADJACENT_RES_ADOPT_FAILED && result != INSERT_ADJACENT_RES_PRE_INSERT_FAILED) {
DOM_RET_OBJ(otherp, &ret, other_intern);
} else {
RETURN_THROWS();
}
}
+
+PHP_METHOD(DOMElement, insertAdjacentElement)
+{
+ dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_element_class_entry);
+}
+
+PHP_METHOD(DOM_Element, insertAdjacentElement)
+{
+ dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_modern_element_class_entry);
+}
/* }}} end DOMElement::insertAdjacentElement */
/* {{{ URL: https://dom.spec.whatwg.org/#dom-element-insertadjacenttext
@@ -1525,11 +1638,12 @@ PHP_METHOD(DOMElement, insertAdjacentText)
xmlNodePtr otherp = xmlNewDocTextLen(thisp->doc, (const xmlChar *) ZSTR_VAL(data), ZSTR_LEN(data));
xmlNodePtr result = dom_insert_adjacent(where, thisp, this_intern, otherp);
- if (result == NULL || result == INSERT_ADJACENT_RES_FAILED) {
+ if (result == NULL || result == INSERT_ADJACENT_RES_ADOPT_FAILED) {
xmlFreeNode(otherp);
}
}
/* }}} end DOMElement::insertAdjacentText */
+
/* {{{ URL: https://dom.spec.whatwg.org/#dom-element-toggleattribute
Since:
*/
@@ -1555,8 +1669,11 @@ PHP_METHOD(DOMElement, toggleAttribute)
RETURN_THROWS();
}
+ bool follow_spec = php_dom_follow_spec_intern(intern);
+
/* Step 2 */
- if (thisp->doc != NULL && thisp->doc->type == XML_HTML_DOCUMENT_NODE && (thisp->ns == NULL || xmlStrEqual(thisp->ns->href, (const xmlChar *) "http://www.w3.org/1999/xhtml"))) {
+ if (thisp->doc != NULL && thisp->doc->type == XML_HTML_DOCUMENT_NODE
+ && ((!follow_spec && thisp->ns == NULL) || (thisp->ns != NULL && xmlStrEqual(thisp->ns->href, BAD_CAST DOM_XHTML_NS_URI)))) {
qname_tmp = zend_str_tolower_dup_ex(qname, qname_length);
if (qname_tmp != NULL) {
qname = qname_tmp;
@@ -1564,22 +1681,26 @@ PHP_METHOD(DOMElement, toggleAttribute)
}
/* Step 3 */
- xmlNodePtr attribute = dom_get_dom1_attribute(thisp, (xmlChar *) qname);
+ xmlNodePtr attribute = dom_get_attribute_or_nsdecl(intern, thisp, BAD_CAST qname, qname_length);
/* Step 4 */
if (attribute == NULL) {
/* Step 4.1 */
if (force_is_null || force) {
- /* The behaviour for namespaces isn't defined by spec, but this is based on observing browers behaviour.
- * It follows the same rules when you'd manually add an attribute using the other APIs. */
- int len;
- const xmlChar *split = xmlSplitQName3((const xmlChar *) qname, &len);
- if (split == NULL || strncmp(qname, "xmlns:", len + 1) != 0) {
- /* unqualified name, or qualified name with no xml namespace declaration */
- dom_create_attribute(thisp, qname, "");
+ if (follow_spec) {
+ xmlSetNsProp(thisp, NULL, BAD_CAST qname, NULL);
} else {
- /* qualified name with xml namespace declaration */
- xmlNewNs(thisp, (const xmlChar *) "", (const xmlChar *) (qname + len + 1));
+ /* The behaviour for namespaces isn't defined by spec, but this is based on observing browers behaviour.
+ * It follows the same rules when you'd manually add an attribute using the other APIs. */
+ int len;
+ const xmlChar *split = xmlSplitQName3((const xmlChar *) qname, &len);
+ if (split == NULL || strncmp(qname, "xmlns:", len + 1 /* +1 for matching ':' too */) != 0) {
+ /* unqualified name, or qualified name with no xml namespace declaration */
+ dom_create_attribute(thisp, qname, "");
+ } else {
+ /* qualified name with xml namespace declaration */
+ xmlNewNs(thisp, (const xmlChar *) "", (const xmlChar *) (qname + len + 1));
+ }
}
retval = true;
goto out;
diff --git a/ext/dom/html5_parser.c b/ext/dom/html5_parser.c
index 6a262318a89eb..c30d8ee86a082 100644
--- a/ext/dom/html5_parser.c
+++ b/ext/dom/html5_parser.c
@@ -20,11 +20,10 @@
#include "php.h"
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
+#include "php_dom.h"
#include "html5_parser.h"
-#include "namespace_compat.h"
#include
#include
-#include
#include
#include
#include
@@ -63,14 +62,14 @@ static unsigned short sanitize_line_nr(size_t line)
return (unsigned short) line;
}
-static const xmlChar *get_libxml_namespace_href(uintptr_t lexbor_namespace)
+static const php_dom_ns_magic_token *get_libxml_namespace_href(uintptr_t lexbor_namespace)
{
if (lexbor_namespace == LXB_NS_SVG) {
- return (const xmlChar *) DOM_SVG_NS_URI;
+ return php_dom_ns_is_svg_magic_token;
} else if (lexbor_namespace == LXB_NS_MATH) {
- return (const xmlChar *) DOM_MATHML_NS_URI;
+ return php_dom_ns_is_mathml_magic_token;
} else {
- return (const xmlChar *) DOM_XHTML_NS_URI;
+ return php_dom_ns_is_html_magic_token;
}
}
@@ -98,11 +97,16 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert(
lxb_dom_node_t *start_node,
xmlDocPtr lxml_doc,
bool compact_text_nodes,
- bool create_default_ns
+ bool create_default_ns,
+ php_dom_libxml_ns_mapper *ns_mapper
)
{
lexbor_libxml2_bridge_status retval = LEXBOR_LIBXML2_BRIDGE_STATUS_OK;
+ xmlNsPtr html_ns = php_dom_libxml_ns_mapper_ensure_html_ns(ns_mapper);
+ xmlNsPtr xlink_ns = NULL;
+ xmlNsPtr prefixed_xmlns_ns = NULL;
+
lexbor_array_obj_t work_list;
lexbor_array_obj_init(&work_list, WORK_LIST_INIT_SIZE, sizeof(work_list_item));
@@ -135,7 +139,17 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert(
uintptr_t entering_namespace = element->node.ns;
xmlNsPtr current_lxml_ns = current_stack_item->lxml_ns;
if (create_default_ns && UNEXPECTED(entering_namespace != current_stack_item->current_active_namespace)) {
- current_lxml_ns = xmlNewNs(lxml_element, get_libxml_namespace_href(entering_namespace), NULL);
+ if (entering_namespace == LXB_NS_HTML) {
+ current_lxml_ns = html_ns;
+ } else {
+ const php_dom_ns_magic_token *magic_token = get_libxml_namespace_href(entering_namespace);
+ zend_string *uri = zend_string_init((char *) magic_token, strlen((char *) magic_token), false);
+ current_lxml_ns = php_dom_libxml_ns_mapper_get_ns(ns_mapper, NULL, uri);
+ zend_string_release_ex(uri, false);
+ if (EXPECTED(current_lxml_ns != NULL)) {
+ current_lxml_ns->_private = (void *) magic_token;
+ }
+ }
}
/* Instead of xmlSetNs() because we know the arguments are valid. Prevents overhead. */
lxml_element->ns = current_lxml_ns;
@@ -181,6 +195,25 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert(
}
lxml_attr->children = lxml_attr->last = lxml_text;
+ lxml_text->parent = (xmlNodePtr) lxml_attr;
+
+ if (attr->node.ns == LXB_NS_XMLNS) {
+ if (strcmp((const char *) local_name, "xmlns") != 0) {
+ if (prefixed_xmlns_ns == NULL) {
+ prefixed_xmlns_ns = php_dom_libxml_ns_mapper_get_ns_raw_strings_nullsafe(ns_mapper, "xmlns", DOM_XMLNS_NS_URI);
+ }
+ lxml_attr->ns = prefixed_xmlns_ns;
+ } else {
+ lxml_attr->ns = php_dom_libxml_ns_mapper_ensure_prefixless_xmlns_ns(ns_mapper);
+ }
+ lxml_attr->ns->_private = (void *) php_dom_ns_is_xmlns_magic_token;
+ } else if (attr->node.ns == LXB_NS_XLINK) {
+ if (xlink_ns == NULL) {
+ xlink_ns = php_dom_libxml_ns_mapper_get_ns_raw_strings_nullsafe(ns_mapper, "xlink", DOM_XLINK_NS_URI);
+ xlink_ns->_private = (void *) php_dom_ns_is_xlink_magic_token;
+ }
+ lxml_attr->ns = xlink_ns;
+ }
if (last_added_attr == NULL) {
lxml_element->properties = lxml_attr;
@@ -270,29 +303,20 @@ lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert_document(
lxb_html_document_t *document,
xmlDocPtr *doc_out,
bool compact_text_nodes,
- bool create_default_ns
+ bool create_default_ns,
+ php_dom_libxml_ns_mapper *ns_mapper
)
{
-#ifdef LIBXML_HTML_ENABLED
- xmlDocPtr lxml_doc = htmlNewDocNoDtD(NULL, NULL);
+ xmlDocPtr lxml_doc = php_dom_create_html_doc();
if (UNEXPECTED(!lxml_doc)) {
return LEXBOR_LIBXML2_BRIDGE_STATUS_OOM;
}
-#else
- /* If HTML support is not enabled, then htmlNewDocNoDtD() is not available.
- * This code mimics the behaviour. */
- xmlDocPtr lxml_doc = xmlNewDoc((const xmlChar *) "1.0");
- if (UNEXPECTED(!lxml_doc)) {
- return LEXBOR_LIBXML2_BRIDGE_STATUS_OOM;
- }
- lxml_doc->type = XML_HTML_DOCUMENT_NODE;
-#endif
- lxml_doc->dict = xmlDictCreate();
lexbor_libxml2_bridge_status status = lexbor_libxml2_bridge_convert(
lxb_dom_interface_node(document)->last_child,
lxml_doc,
compact_text_nodes,
- create_default_ns
+ create_default_ns,
+ ns_mapper
);
if (status != LEXBOR_LIBXML2_BRIDGE_STATUS_OK) {
xmlFreeDoc(lxml_doc);
diff --git a/ext/dom/html5_parser.h b/ext/dom/html5_parser.h
index 4ed6dc2ed03db..bffa6b0c8aaab 100644
--- a/ext/dom/html5_parser.h
+++ b/ext/dom/html5_parser.h
@@ -17,6 +17,7 @@
#ifndef HTML5_PARSER_H
#define HTML5_PARSER_H
+#include "namespace_compat.h"
#include
#include
#include
@@ -68,7 +69,8 @@ lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert_document(
lxb_html_document_t *document,
xmlDocPtr *doc_out,
bool compact_text_nodes,
- bool create_default_ns
+ bool create_default_ns,
+ php_dom_libxml_ns_mapper *ns_mapper
);
void lexbor_libxml2_bridge_report_errors(
const lexbor_libxml2_bridge_parse_context *ctx,
diff --git a/ext/dom/html5_serializer.c b/ext/dom/html5_serializer.c
index f61254257abb5..3503bb3afc3f5 100644
--- a/ext/dom/html5_serializer.c
+++ b/ext/dom/html5_serializer.c
@@ -23,24 +23,14 @@
#include "php_dom.h"
#include "html5_serializer.h"
#include "namespace_compat.h"
+#include "serialize_common.h"
#include
-#define TRY(x) do { if (UNEXPECTED((x) != SUCCESS)) { return FAILURE; } } while (0)
-
-static bool dom_is_ns(const xmlNode *node, const char *uri)
-{
- return node->ns != NULL && strcmp((const char *) node->ns->href, uri) == 0;
-}
+/* This file implements the HTML 5 serialization algorithm.
+ * https://html.spec.whatwg.org/multipage/parsing.html#serialising-html-fragments (Date 2023-12-14)
+ */
-static bool dom_is_html_ns(const xmlNode *node)
-{
- return node->ns == NULL || dom_is_ns(node, DOM_XHTML_NS_URI);
-}
-
-static bool dom_local_name_compare_ex(const xmlNode *node, const char *tag, size_t tag_length, size_t name_length)
-{
- return name_length == tag_length && zend_binary_strcmp((const char *) node->name, name_length, tag, tag_length) == 0;
-}
+#define TRY(x) do { if (UNEXPECTED((x) != SUCCESS)) { return FAILURE; } } while (0)
static zend_result dom_html5_serialize_doctype(dom_html5_serialize_context *ctx, const xmlDtd *dtd)
{
@@ -61,10 +51,19 @@ static zend_result dom_html5_serialize_processing_instruction(dom_html5_serializ
TRY(ctx->write_string_len(ctx->application_data, "", strlen("")));
TRY(ctx->write_string(ctx->application_data, (const char *) node->name));
TRY(ctx->write_string_len(ctx->application_data, " ", strlen(" ")));
- TRY(ctx->write_string(ctx->application_data, (const char *) node->content));
+ if (node->content) {
+ TRY(ctx->write_string(ctx->application_data, (const char *) node->content));
+ }
return ctx->write_string_len(ctx->application_data, ">", strlen(">"));
}
+static zend_result dom_html5_serialize_entity_ref(dom_html5_serialize_context *ctx, const xmlNode *node)
+{
+ TRY(ctx->write_string_len(ctx->application_data, "&", strlen("&")));
+ TRY(ctx->write_string(ctx->application_data, (const char *) node->name));
+ return ctx->write_string_len(ctx->application_data, ";", strlen(";"));
+}
+
/* https://html.spec.whatwg.org/multipage/parsing.html#escapingString */
static zend_result dom_html5_escape_string(dom_html5_serialize_context *ctx, const char *content, bool attribute_mode)
{
@@ -132,7 +131,7 @@ static zend_result dom_html5_escape_string(dom_html5_serialize_context *ctx, con
static zend_result dom_html5_serialize_text_node(dom_html5_serialize_context *ctx, const xmlNode *node)
{
- if (node->parent->type == XML_ELEMENT_NODE && dom_is_html_ns(node->parent)) {
+ if (node->parent->type == XML_ELEMENT_NODE && php_dom_ns_is_fast(node->parent, php_dom_ns_is_html_magic_token)) {
const xmlNode *parent = node->parent;
size_t name_length = strlen((const char *) parent->name);
/* Spec tells us to only emit noscript content as-is if scripting is enabled.
@@ -156,7 +155,7 @@ static zend_result dom_html5_serialize_element_tag_name(dom_html5_serialize_cont
{
/* Note: it is not the serializer's responsibility to care about uppercase/lowercase (see createElement() note) */
if (node->ns != NULL && node->ns->prefix != NULL
- && !(dom_is_html_ns(node) || dom_is_ns(node, DOM_MATHML_NS_URI) || dom_is_ns(node, DOM_SVG_NS_URI))) {
+ && !(php_dom_ns_is_fast(node, php_dom_ns_is_html_magic_token) || php_dom_ns_is_fast(node, php_dom_ns_is_mathml_magic_token) || php_dom_ns_is_fast(node, php_dom_ns_is_svg_magic_token))) {
TRY(ctx->write_string(ctx->application_data, (const char *) node->ns->prefix));
TRY(ctx->write_string_len(ctx->application_data, ":", strlen(":")));
}
@@ -170,32 +169,15 @@ static zend_result dom_html5_serialize_element_start(dom_html5_serialize_context
/* We don't support the "is" value during element creation, so no handling here. */
- /* Some namespace declarations are also attributes (see https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token) */
- for (const xmlNs *ns = node->nsDef; ns != NULL; ns = ns->next) {
- if (!dom_ns_is_also_an_attribute(ns)) {
- continue;
- }
-
- if (ns->prefix != NULL) {
- TRY(ctx->write_string_len(ctx->application_data, " xmlns:", strlen(" xmlns:")));
- TRY(ctx->write_string(ctx->application_data, (const char *) ns->prefix));
- TRY(ctx->write_string_len(ctx->application_data, "=\"", strlen("=\"")));
- } else {
- TRY(ctx->write_string_len(ctx->application_data, " xmlns=\"", strlen(" xmlns=\"")));
- }
- TRY(ctx->write_string(ctx->application_data, (const char *) ns->href));
- TRY(ctx->write_string_len(ctx->application_data, "\"", strlen("\"")));
- }
-
for (const xmlAttr *attr = node->properties; attr; attr = attr->next) {
TRY(ctx->write_string_len(ctx->application_data, " ", strlen(" ")));
if (attr->ns == NULL) {
TRY(ctx->write_string(ctx->application_data, (const char *) attr->name));
} else {
- if (dom_is_ns((const xmlNode *) attr, DOM_XML_NS_URI)) {
+ if (php_dom_ns_is_fast((const xmlNode *) attr, php_dom_ns_is_xml_magic_token)) {
TRY(ctx->write_string_len(ctx->application_data, "xml:", strlen("xml:")));
TRY(ctx->write_string(ctx->application_data, (const char *) attr->name));
- } else if (dom_is_ns((const xmlNode *) attr, DOM_XMLNS_NS_URI)) {
+ } else if (php_dom_ns_is_fast((const xmlNode *) attr, php_dom_ns_is_xmlns_magic_token)) {
/* Compatibility for real attributes */
if (strcmp((const char *) attr->name, "xmlns") == 0) {
TRY(ctx->write_string_len(ctx->application_data, "xmlns", strlen("xmlns")));
@@ -203,7 +185,7 @@ static zend_result dom_html5_serialize_element_start(dom_html5_serialize_context
TRY(ctx->write_string_len(ctx->application_data, "xmlns:", strlen("xmlns:")));
TRY(ctx->write_string(ctx->application_data, (const char *) attr->name));
}
- } else if (dom_is_ns((const xmlNode *) attr, DOM_XLINK_NS_URI)) {
+ } else if (php_dom_ns_is_fast((const xmlNode *) attr, php_dom_ns_is_xlink_magic_token)) {
TRY(ctx->write_string_len(ctx->application_data, "xlink:", strlen("xlink:")));
TRY(ctx->write_string(ctx->application_data, (const char *) attr->name));
} else if (attr->ns->prefix == NULL) {
@@ -233,7 +215,7 @@ static zend_result dom_html5_serialize_element_start(dom_html5_serialize_context
* https://html.spec.whatwg.org/multipage/parsing.html#serializes-as-void */
static bool dom_html5_serializes_as_void(const xmlNode *node)
{
- if (dom_is_html_ns(node)) {
+ if (php_dom_ns_is_fast(node, php_dom_ns_is_html_magic_token)) {
size_t name_length = strlen((const char *) node->name);
if (/* These are the void elements from https://html.spec.whatwg.org/multipage/syntax.html#void-elements */
dom_local_name_compare_ex(node, "area", strlen("area"), name_length)
@@ -311,6 +293,12 @@ static zend_result dom_html5_serialize_node(dom_html5_serialize_context *ctx, co
break;
}
+ /* Only exists for compatibility with XML and old DOM. */
+ case XML_ENTITY_REF_NODE: {
+ TRY(dom_html5_serialize_entity_ref(ctx, node));
+ break;
+ }
+
default:
break;
}
@@ -335,8 +323,7 @@ static zend_result dom_html5_serialize_node(dom_html5_serialize_context *ctx, co
return SUCCESS;
}
-/* https://html.spec.whatwg.org/multipage/parsing.html#serialising-html-fragments (Date 2023-10-18)
- * Note: this serializes the _children_, excluding the node itself! */
+/* Note: this serializes the _children_, excluding the node itself! */
zend_result dom_html5_serialize(dom_html5_serialize_context *ctx, const xmlNode *node)
{
/* Step 1. Note that this algorithm serializes children. Only elements, documents, and fragments can have children. */
@@ -357,4 +344,22 @@ zend_result dom_html5_serialize(dom_html5_serialize_context *ctx, const xmlNode
return dom_html5_serialize_node(ctx, node->children, node);
}
+/* Variant on the above that is equivalent to the "outer HTML". */
+zend_result dom_html5_serialize_outer(dom_html5_serialize_context *ctx, const xmlNode *node)
+{
+ if (node->type == XML_DOCUMENT_NODE || node->type == XML_HTML_DOCUMENT_NODE || node->type == XML_DOCUMENT_FRAG_NODE) {
+ node = node->children;
+ if (!node) {
+ return SUCCESS;
+ }
+ return dom_html5_serialize_node(ctx, node, node->parent);
+ } else {
+ xmlNodePtr old_next = node->next;
+ ((xmlNodePtr) node)->next = NULL;
+ zend_result result = dom_html5_serialize_node(ctx, node, node->parent);
+ ((xmlNodePtr) node)->next = old_next;
+ return result;
+ }
+}
+
#endif /* HAVE_LIBXML && HAVE_DOM */
diff --git a/ext/dom/html5_serializer.h b/ext/dom/html5_serializer.h
index a7eb4ee9be0c1..8ddedd48495ab 100644
--- a/ext/dom/html5_serializer.h
+++ b/ext/dom/html5_serializer.h
@@ -27,5 +27,6 @@ typedef struct {
} dom_html5_serialize_context;
zend_result dom_html5_serialize(dom_html5_serialize_context *ctx, const xmlNode *node);
+zend_result dom_html5_serialize_outer(dom_html5_serialize_context *ctx, const xmlNode *node);
#endif
diff --git a/ext/dom/html_document.c b/ext/dom/html_document.c
index f684f449f6f65..c14ada84aefc4 100644
--- a/ext/dom/html_document.c
+++ b/ext/dom/html_document.c
@@ -78,6 +78,28 @@ typedef struct _dom_decoding_encoding_ctx {
lxb_codepoint_t codepoints[4096];
} dom_decoding_encoding_ctx;
+/* https://dom.spec.whatwg.org/#dom-document-implementation */
+zend_result dom_modern_document_implementation_read(dom_object *obj, zval *retval)
+{
+ const uint32_t PROP_INDEX = 14;
+
+#if ZEND_DEBUG
+ zend_string *implementation_str = ZSTR_INIT_LITERAL("implementation", false);
+ const zend_property_info *prop_info = zend_get_property_info(dom_abstract_base_document_class_entry, implementation_str, 0);
+ zend_string_release_ex(implementation_str, false);
+ ZEND_ASSERT(OBJ_PROP_TO_NUM(prop_info->offset) == PROP_INDEX);
+#endif
+
+ zval *cached_implementation = OBJ_PROP_NUM(&obj->std, PROP_INDEX);
+ if (Z_ISUNDEF_P(cached_implementation)) {
+ php_dom_create_implementation(cached_implementation, true);
+ }
+
+ ZVAL_OBJ_COPY(retval, Z_OBJ_P(cached_implementation));
+
+ return SUCCESS;
+}
+
static void dom_decoding_encoding_ctx_init(dom_decoding_encoding_ctx *ctx)
{
ctx->encode_data = lxb_encoding_data(LXB_ENCODING_UTF_8);
@@ -279,7 +301,7 @@ static void dom_lexbor_libxml2_bridge_tree_error_reporter(
return;
}
- if (UNEXPECTED(len <= 1)) {
+ if (len <= 1) {
/* Possible with EOF, or single-character tokens, don't use a range in the error display in this case */
php_libxml_pretend_ctx_error_ex(
application_data->input_name,
@@ -350,23 +372,7 @@ static void dom_post_process_html5_loading(
dom_place_remove_element_and_hoist_children(html_node, "body");
}
if (!observations->has_explicit_html_tag) {
- /* The HTML node has a single namespace declaration, that we must preserve after removing the node.
- * However, it's possible the namespace is NULL if DOM\HTML_NO_DEFAULT_NS was set. */
- if (!(options & DOM_HTML_NO_DEFAULT_NS)) {
- php_libxml_set_old_ns(lxml_doc, html_node->nsDef);
- html_node->nsDef = NULL;
- }
dom_place_remove_element_and_hoist_children((xmlNodePtr) lxml_doc, "html");
- if (!(options & DOM_HTML_NO_DEFAULT_NS) && EXPECTED(lxml_doc->children != NULL)) {
- xmlNodePtr node = lxml_doc->children;
- while (node) {
- /* Fine to use the DOM wrap reconciliation here because it's the "modern" world of DOM,
- * and no user manipulation happened yet. */
- xmlDOMWrapCtxt dummy_ctxt = {0};
- xmlDOMWrapReconcileNamespaces(&dummy_ctxt, node, /* options */ 0);
- node = node->next;
- }
- }
}
}
}
@@ -719,19 +725,11 @@ PHP_METHOD(DOM_HTMLDocument, createEmpty)
zend_argument_value_error(1, "must be a valid document encoding");
RETURN_THROWS();
}
-
-#ifdef LIBXML_HTML_ENABLED
- xmlDocPtr lxml_doc = htmlNewDocNoDtD(NULL, NULL);
- if (UNEXPECTED(lxml_doc == NULL)) {
- goto oom;
- }
-#else
- xmlDocPtr lxml_doc = xmlNewDoc((const xmlChar *) "1.0");
+
+ xmlDocPtr lxml_doc = php_dom_create_html_doc();
if (UNEXPECTED(lxml_doc == NULL)) {
goto oom;
}
- lxml_doc->type = XML_HTML_DOCUMENT_NODE;
-#endif
lxml_doc->encoding = xmlStrdup((const xmlChar *) encoding);
@@ -741,7 +739,8 @@ PHP_METHOD(DOM_HTMLDocument, createEmpty)
(xmlNodePtr) lxml_doc,
NULL
);
- intern->document->is_modern_api_class = true;
+ intern->document->class_type = PHP_LIBXML_CLASS_MODERN;
+ intern->document->private_data = php_dom_libxml_ns_mapper_header(php_dom_libxml_ns_mapper_create());
return;
oom:
@@ -852,15 +851,19 @@ PHP_METHOD(DOM_HTMLDocument, createFromString)
goto fail_oom;
}
+ php_dom_libxml_ns_mapper *ns_mapper = php_dom_libxml_ns_mapper_create();
+
xmlDocPtr lxml_doc;
lexbor_libxml2_bridge_status bridge_status = lexbor_libxml2_bridge_convert_document(
document,
&lxml_doc,
options & XML_PARSE_COMPACT,
- !(options & DOM_HTML_NO_DEFAULT_NS)
+ !(options & DOM_HTML_NO_DEFAULT_NS),
+ ns_mapper
);
lexbor_libxml2_bridge_copy_observations(parser->tree, &ctx.observations);
if (UNEXPECTED(bridge_status != LEXBOR_LIBXML2_BRIDGE_STATUS_OK)) {
+ php_dom_libxml_ns_mapper_destroy(ns_mapper);
php_libxml_ctx_error(
NULL,
"%s in %s",
@@ -886,7 +889,8 @@ PHP_METHOD(DOM_HTMLDocument, createFromString)
(xmlNodePtr) lxml_doc,
NULL
);
- intern->document->is_modern_api_class = true;
+ intern->document->class_type = PHP_LIBXML_CLASS_MODERN;
+ intern->document->private_data = php_dom_libxml_ns_mapper_header(ns_mapper);
return;
fail_oom:
@@ -898,6 +902,7 @@ PHP_METHOD(DOM_HTMLDocument, createFromString)
PHP_METHOD(DOM_HTMLDocument, createFromFile)
{
const char *filename, *override_encoding = NULL;
+ php_dom_libxml_ns_mapper *ns_mapper = NULL;
size_t filename_len, override_encoding_len;
zend_long options = 0;
php_stream *stream = NULL;
@@ -958,7 +963,8 @@ PHP_METHOD(DOM_HTMLDocument, createFromFile)
dom_setup_parser_encoding_manually((const lxb_char_t *) buf, encoding_data, &decoding_encoding_ctx, &application_data);
}
- stream = php_stream_open_wrapper_ex(filename, "rb", REPORT_ERRORS, /* opened_path */ NULL, php_libxml_get_stream_context());
+ zend_string *opened_path = NULL;
+ stream = php_stream_open_wrapper_ex(filename, "rb", REPORT_ERRORS, &opened_path, php_libxml_get_stream_context());
if (!stream) {
if (!EG(exception)) {
zend_throw_exception_ex(NULL, 0, "Cannot open file '%s'", filename);
@@ -1035,19 +1041,21 @@ PHP_METHOD(DOM_HTMLDocument, createFromFile)
goto fail_oom;
}
+ ns_mapper = php_dom_libxml_ns_mapper_create();
+
xmlDocPtr lxml_doc;
lexbor_libxml2_bridge_status bridge_status = lexbor_libxml2_bridge_convert_document(
document,
&lxml_doc,
options & XML_PARSE_COMPACT,
- !(options & DOM_HTML_NO_DEFAULT_NS)
+ !(options & DOM_HTML_NO_DEFAULT_NS),
+ ns_mapper
);
lexbor_libxml2_bridge_copy_observations(parser->tree, &ctx.observations);
if (UNEXPECTED(bridge_status != LEXBOR_LIBXML2_BRIDGE_STATUS_OK)) {
php_libxml_ctx_error(NULL, "%s in %s", dom_lexbor_libxml2_bridge_status_code_to_string(bridge_status), filename);
- lxb_html_document_destroy(document);
- php_stream_close(stream);
- RETURN_FALSE;
+ RETVAL_FALSE;
+ goto fail_general;
}
lxb_html_document_destroy(document);
@@ -1059,8 +1067,8 @@ PHP_METHOD(DOM_HTMLDocument, createFromFile)
lxml_doc->encoding = xmlStrdup((const xmlChar *) "UTF-8");
}
- if (stream->wrapper == &php_plain_files_wrapper) {
- xmlChar *converted = xmlPathToURI((const xmlChar *) filename);
+ if (stream->wrapper == &php_plain_files_wrapper && opened_path != NULL) {
+ xmlChar *converted = xmlPathToURI((const xmlChar *) ZSTR_VAL(opened_path));
if (UNEXPECTED(!converted)) {
goto fail_oom;
}
@@ -1080,12 +1088,18 @@ PHP_METHOD(DOM_HTMLDocument, createFromFile)
xmlFree(converted);
lxml_doc->URL = new_buffer;
} else {
+#if PHP_WIN32
+ converted = php_dom_libxml_fix_file_path(converted);
+#endif
lxml_doc->URL = converted;
}
} else {
lxml_doc->URL = xmlStrdup((const xmlChar *) filename);
}
+ if (opened_path != NULL) {
+ zend_string_release_ex(opened_path, false);
+ }
php_stream_close(stream);
stream = NULL;
@@ -1095,16 +1109,21 @@ PHP_METHOD(DOM_HTMLDocument, createFromFile)
(xmlNodePtr) lxml_doc,
NULL
);
- intern->document->is_modern_api_class = true;
+ intern->document->class_type = PHP_LIBXML_CLASS_MODERN;
+ intern->document->private_data = php_dom_libxml_ns_mapper_header(ns_mapper);
return;
fail_oom:
php_dom_throw_error(INVALID_STATE_ERR, 1);
+fail_general:
+ if (ns_mapper != NULL) {
+ php_dom_libxml_ns_mapper_destroy(ns_mapper);
+ }
lxb_html_document_destroy(document);
- if (stream) {
- php_stream_close(stream);
+ php_stream_close(stream);
+ if (opened_path != NULL) {
+ zend_string_release_ex(opened_path, false);
}
- RETURN_THROWS();
}
static zend_result dom_write_output_smart_str(void *ctx, const char *buf, size_t size)
@@ -1189,7 +1208,7 @@ static zend_result dom_common_save(dom_output_ctx *output_ctx, const xmlDoc *doc
ctx.write_string_len = dom_saveHTML_write_string_len;
ctx.write_string = dom_saveHTML_write_string;
ctx.application_data = output_ctx;
- if (UNEXPECTED(dom_html5_serialize(&ctx, node) != SUCCESS)) {
+ if (UNEXPECTED(dom_html5_serialize_outer(&ctx, node) != SUCCESS)) {
return FAILURE;
}
@@ -1265,7 +1284,7 @@ PHP_METHOD(DOM_HTMLDocument, saveHTML)
const xmlNode *node;
dom_object *intern, *nodeobj;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &nodep, dom_node_class_entry) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &nodep, dom_modern_node_class_entry) == FAILURE) {
RETURN_THROWS();
}
@@ -1292,12 +1311,6 @@ PHP_METHOD(DOM_HTMLDocument, saveHTML)
RETURN_STR(smart_str_extract(&buf));
}
-PHP_METHOD(DOM_HTMLDocument, __construct)
-{
- /* Private constructor cannot be called. */
- ZEND_UNREACHABLE();
-}
-
zend_result dom_html_document_encoding_write(dom_object *obj, zval *newval)
{
xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
diff --git a/ext/dom/internal_helpers.h b/ext/dom/internal_helpers.h
new file mode 100644
index 0000000000000..0f67550898ab4
--- /dev/null
+++ b/ext/dom/internal_helpers.h
@@ -0,0 +1,66 @@
+/*
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | https://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Niels Dossche |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef DOM_INTERNAL_HELPERS
+#define DOM_INTERNAL_HELPERS
+
+/* We're using the type flags of the zval to store an extra flag. */
+#define DOM_Z_OWNED(z, v) ZVAL_PTR(z, (void *) v)
+#define DOM_Z_UNOWNED(z, v) ZVAL_INDIRECT(z, (void *) v)
+#define DOM_Z_IS_OWNED(z) (Z_TYPE_P(z) == IS_PTR)
+
+#ifdef DOM_CE_H
+
+#define DOM_DEF_GET_CE_FUNC(name) \
+static zend_always_inline zend_class_entry *dom_get_##name##_ce(bool modern) \
+{ \
+ return modern ? dom_modern_##name##_class_entry : dom_##name##_class_entry; \
+}
+
+static zend_always_inline zend_class_entry *dom_get_html_document_ce(bool modern)
+{
+ return modern ? dom_html_document_class_entry : dom_document_class_entry;
+}
+
+static zend_always_inline zend_class_entry *dom_get_xml_document_ce(bool modern)
+{
+ return modern ? dom_xml_document_class_entry : dom_document_class_entry;
+}
+
+static zend_always_inline zend_class_entry *dom_get_dtd_namednodemap_ce(bool modern)
+{
+ return modern ? dom_modern_dtd_namednodemap_class_entry : dom_namednodemap_class_entry;
+}
+
+DOM_DEF_GET_CE_FUNC(node)
+DOM_DEF_GET_CE_FUNC(documenttype)
+DOM_DEF_GET_CE_FUNC(element)
+DOM_DEF_GET_CE_FUNC(attr)
+DOM_DEF_GET_CE_FUNC(entity)
+DOM_DEF_GET_CE_FUNC(entityreference)
+DOM_DEF_GET_CE_FUNC(processinginstruction)
+DOM_DEF_GET_CE_FUNC(comment)
+DOM_DEF_GET_CE_FUNC(text)
+DOM_DEF_GET_CE_FUNC(cdatasection)
+DOM_DEF_GET_CE_FUNC(notation)
+DOM_DEF_GET_CE_FUNC(documentfragment)
+DOM_DEF_GET_CE_FUNC(namednodemap)
+DOM_DEF_GET_CE_FUNC(nodelist)
+DOM_DEF_GET_CE_FUNC(domimplementation)
+
+#endif
+
+#endif
diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c
index 32d10a1bc0dee..02966036b93bf 100644
--- a/ext/dom/namednodemap.c
+++ b/ext/dom/namednodemap.c
@@ -71,7 +71,7 @@ zend_result dom_namednodemap_length_read(dom_object *obj, zval *retval)
/* }}} */
-xmlNodePtr php_dom_named_node_map_get_named_item(dom_nnodemap_object *objmap, const char *named, bool may_transform)
+xmlNodePtr php_dom_named_node_map_get_named_item(dom_nnodemap_object *objmap, const zend_string *named, bool may_transform)
{
xmlNodePtr itemnode = NULL;
if (objmap != NULL) {
@@ -79,9 +79,9 @@ xmlNodePtr php_dom_named_node_map_get_named_item(dom_nnodemap_object *objmap, co
objmap->nodetype == XML_ENTITY_NODE) {
if (objmap->ht) {
if (objmap->nodetype == XML_ENTITY_NODE) {
- itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, (const xmlChar *) named);
+ itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, BAD_CAST ZSTR_VAL(named));
} else {
- xmlNotationPtr notep = xmlHashLookup(objmap->ht, (const xmlChar *) named);
+ xmlNotationPtr notep = xmlHashLookup(objmap->ht, BAD_CAST ZSTR_VAL(named));
if (notep) {
if (may_transform) {
itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
@@ -94,14 +94,18 @@ xmlNodePtr php_dom_named_node_map_get_named_item(dom_nnodemap_object *objmap, co
} else {
xmlNodePtr nodep = dom_object_get_node(objmap->baseobj);
if (nodep) {
- itemnode = (xmlNodePtr)xmlHasProp(nodep, (const xmlChar *) named);
+ if (php_dom_follow_spec_intern(objmap->baseobj)) {
+ itemnode = (xmlNodePtr) php_dom_get_attribute_node(nodep, BAD_CAST ZSTR_VAL(named), ZSTR_LEN(named));
+ } else {
+ itemnode = (xmlNodePtr) xmlHasProp(nodep, BAD_CAST ZSTR_VAL(named));
+ }
}
}
}
return itemnode;
}
-void php_dom_named_node_map_get_named_item_into_zval(dom_nnodemap_object *objmap, const char *named, zval *return_value)
+void php_dom_named_node_map_get_named_item_into_zval(dom_nnodemap_object *objmap, const zend_string *named, zval *return_value)
{
int ret;
xmlNodePtr itemnode = php_dom_named_node_map_get_named_item(objmap, named, true);
@@ -117,10 +121,9 @@ void php_dom_named_node_map_get_named_item_into_zval(dom_nnodemap_object *objmap
*/
PHP_METHOD(DOMNamedNodeMap, getNamedItem)
{
- size_t namedlen;
- char *named;
+ zend_string *named;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &named, &namedlen) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &named) == FAILURE) {
RETURN_THROWS();
}
@@ -221,9 +224,9 @@ PHP_METHOD(DOMNamedNodeMap, getNamedItemNS)
objmap->nodetype == XML_ENTITY_NODE) {
if (objmap->ht) {
if (objmap->nodetype == XML_ENTITY_NODE) {
- itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, (xmlChar *) named);
+ itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, BAD_CAST named);
} else {
- notep = (xmlNotation *)xmlHashLookup(objmap->ht, (xmlChar *) named);
+ notep = (xmlNotation *)xmlHashLookup(objmap->ht, BAD_CAST named);
if (notep) {
itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
}
@@ -232,7 +235,7 @@ PHP_METHOD(DOMNamedNodeMap, getNamedItemNS)
} else {
nodep = dom_object_get_node(objmap->baseobj);
if (nodep) {
- itemnode = (xmlNodePtr)xmlHasNsProp(nodep, (xmlChar *) named, (xmlChar *) uri);
+ itemnode = (xmlNodePtr)xmlHasNsProp(nodep, BAD_CAST named, BAD_CAST uri);
}
}
}
diff --git a/ext/dom/namespace_compat.c b/ext/dom/namespace_compat.c
index efd51cd6545d6..29378b583372e 100644
--- a/ext/dom/namespace_compat.c
+++ b/ext/dom/namespace_compat.c
@@ -22,33 +22,515 @@
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
#include "php_dom.h"
#include "namespace_compat.h"
+#include "internal_helpers.h"
-bool dom_ns_is_also_an_attribute(const xmlNs *ns) {
- return ns->_private != NULL;
+PHP_DOM_EXPORT const php_dom_ns_magic_token *php_dom_ns_is_html_magic_token = (const php_dom_ns_magic_token *) DOM_XHTML_NS_URI;
+PHP_DOM_EXPORT const php_dom_ns_magic_token *php_dom_ns_is_mathml_magic_token = (const php_dom_ns_magic_token *) DOM_MATHML_NS_URI;
+PHP_DOM_EXPORT const php_dom_ns_magic_token *php_dom_ns_is_svg_magic_token = (const php_dom_ns_magic_token *) DOM_SVG_NS_URI;
+PHP_DOM_EXPORT const php_dom_ns_magic_token *php_dom_ns_is_xlink_magic_token = (const php_dom_ns_magic_token *) DOM_XLINK_NS_URI;
+PHP_DOM_EXPORT const php_dom_ns_magic_token *php_dom_ns_is_xml_magic_token = (const php_dom_ns_magic_token *) DOM_XML_NS_URI;
+PHP_DOM_EXPORT const php_dom_ns_magic_token *php_dom_ns_is_xmlns_magic_token = (const php_dom_ns_magic_token *) DOM_XMLNS_NS_URI;
+
+struct _php_dom_libxml_ns_mapper {
+ php_libxml_private_data_header header;
+ /* This is used almost all the time for HTML documents, so it makes sense to cache this. */
+ xmlNsPtr html_ns;
+ /* Used for every prefixless namespace declaration in XML, so also very common. */
+ xmlNsPtr prefixless_xmlns_ns;
+ HashTable uri_to_prefix_map;
+};
+
+static void php_dom_libxml_ns_mapper_prefix_map_element_dtor(zval *zv)
+{
+ if (DOM_Z_IS_OWNED(zv)) {
+ efree(Z_PTR_P(zv));
+ }
+}
+
+static HashTable *php_dom_libxml_ns_mapper_ensure_prefix_map(php_dom_libxml_ns_mapper *mapper, zend_string **uri)
+{
+ zval *zv = zend_hash_find(&mapper->uri_to_prefix_map, *uri);
+ HashTable *prefix_map;
+ if (zv == NULL) {
+ prefix_map = emalloc(sizeof(HashTable));
+ zend_hash_init(prefix_map, 0, NULL, php_dom_libxml_ns_mapper_prefix_map_element_dtor, false);
+ zval zv;
+ ZVAL_ARR(&zv, prefix_map);
+ zend_hash_add_new(&mapper->uri_to_prefix_map, *uri, &zv);
+ } else {
+ /* cast to Bucket* only works if this holds, I would prefer a static assert but we're stuck at C99. */
+ ZEND_ASSERT(XtOffsetOf(Bucket, val) == 0);
+ ZEND_ASSERT(Z_TYPE_P(zv) == IS_ARRAY);
+ Bucket *bucket = (Bucket *) zv;
+ /* Make sure we take the value from the key string that lives long enough. */
+ *uri = bucket->key;
+ prefix_map = Z_ARRVAL_P(zv);
+ }
+ return prefix_map;
+}
+
+static void php_dom_libxml_ns_mapper_header_destroy(php_libxml_private_data_header *header)
+{
+ php_dom_libxml_ns_mapper_destroy((php_dom_libxml_ns_mapper *) header);
+}
+
+PHP_DOM_EXPORT php_dom_libxml_ns_mapper *php_dom_libxml_ns_mapper_create(void)
+{
+ php_dom_libxml_ns_mapper *mapper = emalloc(sizeof(*mapper));
+ mapper->header.dtor = php_dom_libxml_ns_mapper_header_destroy;
+ mapper->html_ns = NULL;
+ mapper->prefixless_xmlns_ns = NULL;
+ zend_hash_init(&mapper->uri_to_prefix_map, 0, NULL, ZVAL_PTR_DTOR, false);
+ return mapper;
+}
+
+void php_dom_libxml_ns_mapper_destroy(php_dom_libxml_ns_mapper *mapper)
+{
+ zend_hash_destroy(&mapper->uri_to_prefix_map);
+ efree(mapper);
+}
+
+static xmlNsPtr php_dom_libxml_ns_mapper_ensure_cached_ns(php_dom_libxml_ns_mapper *mapper, xmlNsPtr *ptr, const char *uri, size_t length, const php_dom_ns_magic_token *token)
+{
+ if (EXPECTED(*ptr != NULL)) {
+ return *ptr;
+ }
+
+ zend_string *uri_str = zend_string_init(uri, length, false);
+ *ptr = php_dom_libxml_ns_mapper_get_ns(mapper, NULL, uri_str);
+ (*ptr)->_private = (void *) token;
+ zend_string_release_ex(uri_str, false);
+ return *ptr;
}
-void dom_ns_compat_mark_attribute(xmlNsPtr ns) {
- ns->_private = (void *) 1;
+PHP_DOM_EXPORT xmlNsPtr php_dom_libxml_ns_mapper_ensure_html_ns(php_dom_libxml_ns_mapper *mapper)
+{
+ return php_dom_libxml_ns_mapper_ensure_cached_ns(mapper, &mapper->html_ns, DOM_XHTML_NS_URI, sizeof(DOM_XHTML_NS_URI) - 1, php_dom_ns_is_html_magic_token);
}
-void dom_ns_compat_mark_attribute_list(xmlNsPtr ns) {
- while (ns != NULL) {
- dom_ns_compat_mark_attribute(ns);
- ns = ns->next;
- }
+PHP_DOM_EXPORT xmlNsPtr php_dom_libxml_ns_mapper_ensure_prefixless_xmlns_ns(php_dom_libxml_ns_mapper *mapper)
+{
+ return php_dom_libxml_ns_mapper_ensure_cached_ns(mapper, &mapper->prefixless_xmlns_ns, DOM_XMLNS_NS_URI, sizeof(DOM_XMLNS_NS_URI) - 1, php_dom_ns_is_xmlns_magic_token);
+}
+
+static xmlNsPtr dom_create_owned_ns(zend_string *prefix, zend_string *uri)
+{
+ ZEND_ASSERT(prefix != NULL);
+ ZEND_ASSERT(uri != NULL);
+
+ xmlNsPtr ns = emalloc(sizeof(*ns));
+ memset(ns, 0, sizeof(*ns));
+ ns->type = XML_LOCAL_NAMESPACE;
+ /* These two strings are kept alive because they're the hash table keys that lead to this entry. */
+ ns->prefix = ZSTR_LEN(prefix) == 0 ? NULL : BAD_CAST ZSTR_VAL(prefix);
+ ns->href = BAD_CAST ZSTR_VAL(uri);
+ /* Note ns->context is unused in libxml2 at the moment, and if it were used it would be for
+ * LIBXML_NAMESPACE_DICT which is opt-in anyway. */
+
+ return ns;
+}
+
+PHP_DOM_EXPORT xmlNsPtr php_dom_libxml_ns_mapper_get_ns(php_dom_libxml_ns_mapper *mapper, zend_string *prefix, zend_string *uri)
+{
+ if (uri == NULL) {
+ uri = zend_empty_string;
+ }
+
+ if (prefix == NULL) {
+ prefix = zend_empty_string;
+ }
+
+ if (ZSTR_LEN(prefix) == 0 && ZSTR_LEN(uri) == 0) {
+ return NULL;
+ }
+
+ HashTable *prefix_map = php_dom_libxml_ns_mapper_ensure_prefix_map(mapper, &uri);
+ xmlNsPtr found = zend_hash_find_ptr(prefix_map, prefix);
+ if (found != NULL) {
+ return found;
+ }
+
+ xmlNsPtr ns = dom_create_owned_ns(prefix, uri);
+
+ zval new_zv;
+ DOM_Z_OWNED(&new_zv, ns);
+ zend_hash_add_new(prefix_map, prefix, &new_zv);
+
+ return ns;
+}
+
+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)
+{
+ xmlNsPtr ns;
+ if (prefix_len == 0) {
+ /* Fast path */
+ ns = php_dom_libxml_ns_mapper_get_ns(mapper, zend_empty_string, uri);
+ } else {
+ zend_string *prefix_str = zend_string_init((const char *) prefix, prefix_len, false);
+ ns = php_dom_libxml_ns_mapper_get_ns(mapper, prefix_str, uri);
+ zend_string_release_ex(prefix_str, false);
+ }
+ return ns;
+}
+
+static 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)
+{
+ zend_string *prefix_str = zend_string_init(prefix, prefix_len, false);
+ zend_string *uri_str = zend_string_init(uri, uri_len, false);
+ xmlNsPtr ns = php_dom_libxml_ns_mapper_get_ns(mapper, prefix_str, uri_str);
+ zend_string_release_ex(prefix_str, false);
+ zend_string_release_ex(uri_str, false);
+ return ns;
+}
+
+static zend_always_inline xmlNsPtr php_dom_libxml_ns_mapper_get_ns_raw_strings(php_dom_libxml_ns_mapper *mapper, const char *prefix, const char *uri)
+{
+ return php_dom_libxml_ns_mapper_get_ns_raw_strings_ex(mapper, prefix, strlen(prefix), uri, strlen(uri));
+}
+
+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)
+{
+ if (prefix == NULL) {
+ prefix = "";
+ }
+ if (uri == NULL) {
+ uri = "";
+ }
+ return php_dom_libxml_ns_mapper_get_ns_raw_strings(mapper, prefix, uri);
+}
+
+static xmlNsPtr php_dom_libxml_ns_mapper_store_and_normalize_parsed_ns(php_dom_libxml_ns_mapper *mapper, xmlNsPtr ns)
+{
+ ZEND_ASSERT(ns != NULL);
+
+ zend_string *href_str = zend_string_init((const char *) ns->href, xmlStrlen(ns->href), false);
+ zend_string *href_str_orig = href_str;
+ HashTable *prefix_map = php_dom_libxml_ns_mapper_ensure_prefix_map(mapper, &href_str);
+ zend_string_release_ex(href_str_orig, false);
+
+ const char *prefix = (const char *) ns->prefix;
+ size_t prefix_len;
+ if (prefix == NULL) {
+ prefix = "";
+ prefix_len = 0;
+ } else {
+ prefix_len = xmlStrlen(ns->prefix);
+ }
+
+ zval *zv = zend_hash_str_find_ptr(prefix_map, prefix, prefix_len);
+ if (zv != NULL) {
+ return Z_PTR_P(zv);
+ }
+
+ zval new_zv;
+ DOM_Z_UNOWNED(&new_zv, ns);
+ zend_hash_str_add_new(prefix_map, prefix, prefix_len, &new_zv);
+
+ return ns;
+}
+
+PHP_DOM_EXPORT php_libxml_private_data_header *php_dom_libxml_ns_mapper_header(php_dom_libxml_ns_mapper *mapper)
+{
+ return mapper == NULL ? NULL : &mapper->header;
+}
+
+typedef struct {
+ /* Fast lookup for created mappings. */
+ HashTable old_ns_to_new_ns_ptr;
+ /* It is common that the last created mapping will be used for a while,
+ * cache it too to bypass the hash table. */
+ xmlNsPtr last_mapped_src, last_mapped_dst;
+ php_dom_libxml_ns_mapper *ns_mapper;
+} dom_libxml_reconcile_ctx;
+
+PHP_DOM_EXPORT xmlAttrPtr php_dom_ns_compat_mark_attribute(php_dom_libxml_ns_mapper *mapper, xmlNodePtr node, xmlNsPtr ns)
+{
+ xmlNsPtr xmlns_ns;
+ const xmlChar *name;
+ if (ns->prefix != NULL) {
+ xmlns_ns = php_dom_libxml_ns_mapper_get_ns_raw_strings(mapper, "xmlns", DOM_XMLNS_NS_URI);
+ name = ns->prefix;
+ } else {
+ xmlns_ns = php_dom_libxml_ns_mapper_ensure_prefixless_xmlns_ns(mapper);
+ name = BAD_CAST "xmlns";
+ }
+
+ ZEND_ASSERT(xmlns_ns != NULL);
+
+ return xmlSetNsProp(node, xmlns_ns, name, ns->href);
+}
+
+PHP_DOM_EXPORT void php_dom_ns_compat_mark_attribute_list(php_dom_libxml_ns_mapper *mapper, xmlNodePtr node)
+{
+ if (node->nsDef == NULL) {
+ return;
+ }
+
+ /* We want to prepend at the front, but in order of the namespace definitions.
+ * So temporarily unlink the existing properties and add them again at the end. */
+ xmlAttrPtr attr = node->properties;
+ node->properties = NULL;
+
+ xmlNsPtr ns = node->nsDef;
+ xmlAttrPtr last_added = NULL;
+ do {
+ last_added = php_dom_ns_compat_mark_attribute(mapper, node, ns);
+ php_dom_libxml_ns_mapper_store_and_normalize_parsed_ns(mapper, ns);
+ xmlNsPtr next = ns->next;
+ ns->next = NULL;
+ php_libxml_set_old_ns(node->doc, ns);
+ ns = next;
+ } while (ns != NULL);
+
+ if (last_added != NULL) {
+ /* node->properties now points to the first namespace declaration attribute. */
+ if (attr != NULL) {
+ last_added->next = attr;
+ attr->prev = last_added;
+ }
+ } else {
+ /* Nothing added, so nothing changed. Only really possible on OOM. */
+ node->properties = attr;
+ }
+
+ node->nsDef = NULL;
+}
+
+PHP_DOM_EXPORT bool php_dom_ns_is_fast_ex(xmlNsPtr ns, const php_dom_ns_magic_token *magic_token)
+{
+ ZEND_ASSERT(ns != NULL);
+ /* cached for fast checking */
+ if (ns->_private == magic_token) {
+ return true;
+ } else if (ns->_private != NULL) {
+ /* Other token stored */
+ return false;
+ }
+ /* Slow path */
+ if (xmlStrEqual(ns->href, BAD_CAST magic_token)) {
+ ns->_private = (void *) magic_token;
+ return true;
+ }
+ return false;
+}
+
+PHP_DOM_EXPORT bool php_dom_ns_is_fast(const xmlNode *nodep, const php_dom_ns_magic_token *magic_token)
+{
+ ZEND_ASSERT(nodep != NULL);
+ xmlNsPtr ns = nodep->ns;
+ if (ns != NULL) {
+ return php_dom_ns_is_fast_ex(ns, magic_token);
+ }
+ return false;
+}
+
+PHP_DOM_EXPORT bool php_dom_ns_is_html_and_document_is_html(const xmlNode *nodep)
+{
+ ZEND_ASSERT(nodep != NULL);
+ return nodep->doc && nodep->doc->type == XML_HTML_DOCUMENT_NODE && php_dom_ns_is_fast(nodep, php_dom_ns_is_html_magic_token);
+}
+
+/* will rename prefixes if there is a declaration with the same prefix but different uri. */
+PHP_DOM_EXPORT void php_dom_reconcile_attribute_namespace_after_insertion(xmlAttrPtr attrp)
+{
+ ZEND_ASSERT(attrp != NULL);
+
+ if (attrp->ns != NULL) {
+ /* Try to link to an existing namespace. If that won't work, reconcile. */
+ xmlNodePtr nodep = attrp->parent;
+ xmlNsPtr matching_ns = xmlSearchNs(nodep->doc, nodep, attrp->ns->prefix);
+ if (matching_ns && xmlStrEqual(matching_ns->href, attrp->ns->href)) {
+ /* Doesn't leak because this doesn't define the declaration. */
+ attrp->ns = matching_ns;
+ } else {
+ if (attrp->ns->prefix != NULL) {
+ /* Note: explicitly use the legacy reconciliation as it mostly (i.e. as good as it gets for legacy DOM)
+ * does the right thing for attributes. */
+ xmlReconciliateNs(nodep->doc, nodep);
+ }
+ }
+ }
+}
+
+static zend_always_inline zend_long dom_mangle_pointer_for_key(void *ptr)
+{
+ zend_ulong value = (zend_ulong) (uintptr_t) ptr;
+ /* Shift 3/4 for better hash distribution because the low 3/4 bits are always 0. */
+#if SIZEOF_ZEND_LONG == 8
+ return value >> 4;
+#else
+ return value >> 3;
+#endif
+}
+
+static zend_always_inline void php_dom_libxml_reconcile_modern_single_node(dom_libxml_reconcile_ctx *ctx, xmlNodePtr ns_holder, xmlNodePtr node)
+{
+ ZEND_ASSERT(node->ns != NULL);
+
+ if (node->ns == ctx->last_mapped_src) {
+ node->ns = ctx->last_mapped_dst;
+ return;
+ }
+
+ /* If the namespace is the same as in the map, we're good. */
+ xmlNsPtr new_ns = zend_hash_index_find_ptr(&ctx->old_ns_to_new_ns_ptr, dom_mangle_pointer_for_key(node->ns));
+ if (new_ns == NULL) {
+ /* We have to create an alternative declaration, and we'll add it to the map. */
+ const char *prefix = (const char *) node->ns->prefix;
+ const char *href = (const char *) node->ns->href;
+ new_ns = php_dom_libxml_ns_mapper_get_ns_raw_strings_nullsafe(ctx->ns_mapper, prefix, href);
+ zend_hash_index_add_new_ptr(&ctx->old_ns_to_new_ns_ptr, dom_mangle_pointer_for_key(node->ns), new_ns);
+ ctx->last_mapped_src = node->ns;
+ ctx->last_mapped_dst = new_ns;
+ node->ns = new_ns;
+ } else if (node->ns != new_ns) {
+ /* The namespace is different, so we have to replace it. */
+ node->ns = new_ns;
+ }
+}
+
+static zend_always_inline bool dom_libxml_reconcile_fast_element_skip(xmlNodePtr node)
+{
+ /* Fast path: this is a lone element and the namespace is defined by the node (or the namespace is NULL). */
+ ZEND_ASSERT(node->type == XML_ELEMENT_NODE);
+ return node->children == NULL && node->properties == NULL && node->ns == node->nsDef;
+}
+
+static zend_always_inline void php_dom_libxml_reconcile_modern_single_element_node(dom_libxml_reconcile_ctx *ctx, xmlNodePtr node)
+{
+ ZEND_ASSERT(node->type == XML_ELEMENT_NODE);
+
+ /* Since this is modern DOM, the declarations are not on the node and thus there's nothing to add from nsDef. */
+ ZEND_ASSERT(node->nsDef == NULL);
+
+ if (node->ns != NULL) {
+ php_dom_libxml_reconcile_modern_single_node(ctx, node, node);
+ }
+
+ for (xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
+ if (attr->ns != NULL) {
+ php_dom_libxml_reconcile_modern_single_node(ctx, node, (xmlNodePtr) attr);
+ }
+ }
+}
+
+PHP_DOM_EXPORT void php_dom_libxml_reconcile_modern(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr node)
+{
+ if (node->type == XML_ATTRIBUTE_NODE) {
+ if (node->ns != NULL) {
+ node->ns = php_dom_libxml_ns_mapper_get_ns_raw_strings_nullsafe(ns_mapper, (const char *) node->ns->prefix, (const char *) node->ns->href);
+ }
+ return;
+ }
+
+ if (node->type != XML_ELEMENT_NODE || dom_libxml_reconcile_fast_element_skip(node)) {
+ return;
+ }
+
+ dom_libxml_reconcile_ctx ctx;
+ zend_hash_init(&ctx.old_ns_to_new_ns_ptr, 0, NULL, NULL, 0);
+ ctx.last_mapped_src = NULL;
+ ctx.last_mapped_dst = NULL;
+ ctx.ns_mapper = ns_mapper;
+
+ php_dom_libxml_reconcile_modern_single_element_node(&ctx, node);
+
+ xmlNodePtr base = node;
+ node = node->children;
+ while (node != NULL) {
+ ZEND_ASSERT(node != base);
+
+ if (node->type == XML_ELEMENT_NODE) {
+ php_dom_libxml_reconcile_modern_single_element_node(&ctx, node);
+
+ if (node->children) {
+ node = node->children;
+ continue;
+ }
+ }
+
+ node = php_dom_next_in_tree_order(node, base);
+ }
+
+ zend_hash_destroy(&ctx.old_ns_to_new_ns_ptr);
+}
+
+PHP_DOM_EXPORT php_dom_in_scope_ns php_dom_get_in_scope_ns(php_dom_libxml_ns_mapper *ns_mapper, const xmlNode *node)
+{
+ ZEND_ASSERT(node != NULL);
+
+ php_dom_in_scope_ns in_scope_ns;
+ in_scope_ns.origin_is_ns_compat = true;
+
+ /* libxml fetches all nsDef items from bottom to top - left to right, ignoring prefixes already in the list.
+ * We don't have nsDef, but we can use the ns pointer (as that is necessarily in scope),
+ * and check the xmlns attributes. */
+ HashTable tmp_prefix_to_ns_table;
+ zend_hash_init(&tmp_prefix_to_ns_table, 0, NULL, NULL, false);
+ zend_hash_real_init_mixed(&tmp_prefix_to_ns_table);
+
+ for (const xmlNode *cur = node; cur != NULL; cur = cur->parent) {
+ if (cur->type == XML_ELEMENT_NODE) {
+ /* Register namespace of element */
+ if (cur->ns != NULL && cur->ns->prefix != NULL) {
+ const char *prefix = (const char *) cur->ns->prefix;
+ zend_hash_str_add_ptr(&tmp_prefix_to_ns_table, prefix, strlen(prefix), cur->ns);
+ }
+
+ /* Register xmlns attributes */
+ for (const xmlAttr *attr = cur->properties; attr != NULL; attr = attr->next) {
+ if (attr->ns != NULL && attr->ns->prefix != NULL && php_dom_ns_is_fast_ex(attr->ns, php_dom_ns_is_xmlns_magic_token)
+ && attr->children != NULL && attr->children->content != NULL) {
+ /* This attribute declares a namespace, get the relevant instance.
+ * The declared namespace is not the same as the namespace of this attribute (which is xmlns). */
+ const char *prefix = (const char *) attr->name;
+ xmlNsPtr ns = php_dom_libxml_ns_mapper_get_ns_raw_strings(ns_mapper, prefix, (const char *) attr->children->content);
+ zend_hash_str_add_ptr(&tmp_prefix_to_ns_table, prefix, strlen(prefix), ns);
+ }
+ }
+ }
+ }
+
+ in_scope_ns.count = zend_hash_num_elements(&tmp_prefix_to_ns_table);
+ in_scope_ns.list = safe_emalloc(in_scope_ns.count, sizeof(xmlNsPtr), 0);
+
+ size_t index = 0;
+ xmlNsPtr ns;
+ ZEND_HASH_MAP_FOREACH_PTR(&tmp_prefix_to_ns_table, ns) {
+ in_scope_ns.list[index++] = ns;
+ } ZEND_HASH_FOREACH_END();
+
+ zend_hash_destroy(&tmp_prefix_to_ns_table);
+
+ return in_scope_ns;
+}
+
+PHP_DOM_EXPORT php_dom_in_scope_ns php_dom_get_in_scope_ns_legacy(const xmlNode *node)
+{
+ ZEND_ASSERT(node != NULL);
+
+ php_dom_in_scope_ns in_scope_ns;
+ in_scope_ns.origin_is_ns_compat = false;
+ in_scope_ns.list = xmlGetNsList(node->doc, node);
+ in_scope_ns.count = 0;
+
+ if (in_scope_ns.list != NULL) {
+ while (in_scope_ns.list[in_scope_ns.count] != NULL) {
+ in_scope_ns.count++;
+ }
+ }
+
+ return in_scope_ns;
}
-void dom_ns_compat_copy_attribute_list_mark(xmlNsPtr copy, const xmlNs *original) {
- /* It's possible that the original list is shorter than the copy list
- * because of additional namespace copies from within a fragment. */
- while (original != NULL) {
- ZEND_ASSERT(copy != NULL);
- if (dom_ns_is_also_an_attribute(original)) {
- dom_ns_compat_mark_attribute(copy);
- }
- copy = copy->next;
- original = original->next;
- }
+PHP_DOM_EXPORT void php_dom_in_scope_ns_destroy(php_dom_in_scope_ns *in_scope_ns)
+{
+ ZEND_ASSERT(in_scope_ns != NULL);
+ if (in_scope_ns->origin_is_ns_compat) {
+ efree(in_scope_ns->list);
+ } else {
+ xmlFree(in_scope_ns->list);
+ }
}
#endif /* HAVE_LIBXML && HAVE_DOM */
diff --git a/ext/dom/namespace_compat.h b/ext/dom/namespace_compat.h
index ab514a08bbada..1147c62892292 100644
--- a/ext/dom/namespace_compat.h
+++ b/ext/dom/namespace_compat.h
@@ -17,7 +17,7 @@
#ifndef NAMESPACE_COMPAT_H
#define NAMESPACE_COMPAT_H
-#include
+#include "xml_common.h"
/* https://infra.spec.whatwg.org/#namespaces */
#define DOM_XHTML_NS_URI "http://www.w3.org/1999/xhtml"
@@ -27,13 +27,51 @@
#define DOM_XML_NS_URI "http://www.w3.org/XML/1998/namespace"
#define DOM_XMLNS_NS_URI "http://www.w3.org/2000/xmlns/"
+struct php_dom_ns_magic_token;
+typedef struct php_dom_ns_magic_token php_dom_ns_magic_token;
+
+struct _php_dom_libxml_ns_mapper;
+typedef struct _php_dom_libxml_ns_mapper php_dom_libxml_ns_mapper;
+
+PHP_DOM_EXPORT extern const php_dom_ns_magic_token *php_dom_ns_is_html_magic_token;
+PHP_DOM_EXPORT extern const php_dom_ns_magic_token *php_dom_ns_is_mathml_magic_token;
+PHP_DOM_EXPORT extern const php_dom_ns_magic_token *php_dom_ns_is_svg_magic_token;
+PHP_DOM_EXPORT extern const php_dom_ns_magic_token *php_dom_ns_is_xlink_magic_token;
+PHP_DOM_EXPORT extern const php_dom_ns_magic_token *php_dom_ns_is_xml_magic_token;
+PHP_DOM_EXPORT extern const php_dom_ns_magic_token *php_dom_ns_is_xmlns_magic_token;
+
+typedef struct _php_libxml_private_data_header php_libxml_private_data_header;
+struct _php_libxml_private_data_header;
+
/* These functions make it possible to make a namespace declaration also visible as an attribute by
- * setting a flag that can be checked with dom_ns_is_also_an_attribute().
- * This is used in the serializer for example. */
+ * creating an equivalent attribute node. */
+
+PHP_DOM_EXPORT php_dom_libxml_ns_mapper *php_dom_libxml_ns_mapper_create(void);
+PHP_DOM_EXPORT void php_dom_libxml_ns_mapper_destroy(php_dom_libxml_ns_mapper *mapper);
+PHP_DOM_EXPORT xmlNsPtr php_dom_libxml_ns_mapper_ensure_html_ns(php_dom_libxml_ns_mapper *mapper);
+PHP_DOM_EXPORT xmlNsPtr php_dom_libxml_ns_mapper_ensure_prefixless_xmlns_ns(php_dom_libxml_ns_mapper *mapper);
+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 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 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 php_libxml_private_data_header *php_dom_libxml_ns_mapper_header(php_dom_libxml_ns_mapper *mapper);
+PHP_DOM_EXPORT void php_dom_ns_compat_mark_attribute_list(php_dom_libxml_ns_mapper *mapper, xmlNodePtr node);
+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 xmlAttrPtr php_dom_ns_compat_mark_attribute(php_dom_libxml_ns_mapper *mapper, xmlNodePtr node, xmlNsPtr ns);
+
+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_fast_ex(xmlNsPtr ns, const php_dom_ns_magic_token *magic_token);
+PHP_DOM_EXPORT bool php_dom_ns_is_html_and_document_is_html(const xmlNode *nodep);
+
+typedef struct _php_dom_in_scope_ns {
+ xmlNsPtr *list;
+ size_t count;
+ bool origin_is_ns_compat;
+} php_dom_in_scope_ns;
-bool dom_ns_is_also_an_attribute(const xmlNs *ns);
-void dom_ns_compat_mark_attribute(xmlNsPtr ns);
-void dom_ns_compat_mark_attribute_list(xmlNsPtr ns);
-void dom_ns_compat_copy_attribute_list_mark(xmlNsPtr copy, const xmlNs *original);
+PHP_DOM_EXPORT php_dom_in_scope_ns php_dom_get_in_scope_ns(php_dom_libxml_ns_mapper *ns_mapper, const xmlNode *node);
+PHP_DOM_EXPORT php_dom_in_scope_ns php_dom_get_in_scope_ns_legacy(const xmlNode *node);
+PHP_DOM_EXPORT void php_dom_in_scope_ns_destroy(php_dom_in_scope_ns *in_scope_ns);
#endif
diff --git a/ext/dom/node.c b/ext/dom/node.c
index dfa5b825983c0..b51376ad24cf8 100644
--- a/ext/dom/node.c
+++ b/ext/dom/node.c
@@ -22,6 +22,8 @@
#include "php.h"
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
#include "php_dom.h"
+#include "namespace_compat.h"
+#include "internal_helpers.h"
/*
* class DOMNode
@@ -42,14 +44,19 @@ zend_string *dom_node_concatenated_name_helper(size_t name_len, const char *name
return str;
}
-zend_string *dom_node_get_node_name_attribute_or_element(const xmlNode *nodep)
+zend_string *dom_node_get_node_name_attribute_or_element(const xmlNode *nodep, bool uppercase)
{
+ zend_string *ret;
size_t name_len = strlen((const char *) nodep->name);
if (nodep->ns != NULL && nodep->ns->prefix != NULL) {
- return dom_node_concatenated_name_helper(name_len, (const char *) nodep->name, strlen((const char *) nodep->ns->prefix), (const char *) nodep->ns->prefix);
+ ret = dom_node_concatenated_name_helper(name_len, (const char *) nodep->name, strlen((const char *) nodep->ns->prefix), (const char *) nodep->ns->prefix);
} else {
- return zend_string_init((const char *) nodep->name, name_len, false);
+ ret = zend_string_init((const char *) nodep->name, name_len, false);
}
+ if (uppercase) {
+ zend_str_toupper(ZSTR_VAL(ret), ZSTR_LEN(ret));
+ }
+ return ret;
}
bool php_dom_is_node_connected(const xmlNode *node)
@@ -67,6 +74,7 @@ bool php_dom_is_node_connected(const xmlNode *node)
/* {{{ nodeName string
readonly=yes
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D095
+Modern spec URL: https://dom.spec.whatwg.org/#dom-node-nodename
Since:
*/
zend_result dom_node_node_name_read(dom_object *obj, zval *retval)
@@ -78,19 +86,20 @@ zend_result dom_node_node_name_read(dom_object *obj, zval *retval)
return FAILURE;
}
+ bool uppercase = false;
+
switch (nodep->type) {
- case XML_ATTRIBUTE_NODE:
case XML_ELEMENT_NODE:
- ZVAL_STR(retval, dom_node_get_node_name_attribute_or_element(nodep));
+ uppercase = php_dom_follow_spec_intern(obj) && php_dom_ns_is_html_and_document_is_html(nodep);
+ ZEND_FALLTHROUGH;
+ case XML_ATTRIBUTE_NODE:
+ ZVAL_NEW_STR(retval, dom_node_get_node_name_attribute_or_element(nodep, uppercase));
break;
case XML_NAMESPACE_DECL: {
xmlNsPtr ns = nodep->ns;
if (ns != NULL && ns->prefix) {
- xmlChar *qname = xmlStrdup((xmlChar *) "xmlns");
- qname = xmlStrcat(qname, (xmlChar *) ":");
- qname = xmlStrcat(qname, nodep->name);
- ZVAL_STRING(retval, (const char *) qname);
- xmlFree(qname);
+ zend_string *str = dom_node_concatenated_name_helper(strlen((const char *) ns->prefix), (const char *) ns->prefix, strlen("xmlns"), "xmlns");
+ ZVAL_NEW_STR(retval, str);
} else {
ZVAL_STRING(retval, (const char *) nodep->name);
}
@@ -131,6 +140,7 @@ zend_result dom_node_node_name_read(dom_object *obj, zval *retval)
/* {{{ nodeValue string
readonly=no
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D080
+Modern spec URL: https://dom.spec.whatwg.org/#dom-node-nodevalue
Since:
*/
zend_result dom_node_node_value_read(dom_object *obj, zval *retval)
@@ -144,9 +154,15 @@ zend_result dom_node_node_value_read(dom_object *obj, zval *retval)
/* Access to Element node is implemented as a convenience method */
switch (nodep->type) {
+ case XML_ELEMENT_NODE: {
+ if (php_dom_follow_spec_intern(obj)) {
+ ZVAL_NULL(retval);
+ break;
+ }
+ ZEND_FALLTHROUGH;
+ }
case XML_ATTRIBUTE_NODE:
case XML_TEXT_NODE:
- case XML_ELEMENT_NODE:
case XML_COMMENT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
@@ -188,6 +204,12 @@ zend_result dom_node_node_value_write(dom_object *obj, zval *newval)
/* Access to Element node is implemented as a convenience method */
switch (nodep->type) {
case XML_ATTRIBUTE_NODE:
+ if (php_dom_follow_spec_intern(obj)) {
+ dom_remove_all_children(nodep);
+ xmlAddChild(nodep, xmlNewTextLen((xmlChar *) ZSTR_VAL(str), ZSTR_LEN(str)));
+ break;
+ }
+ ZEND_FALLTHROUGH;
case XML_ELEMENT_NODE:
dom_remove_all_children(nodep);
ZEND_FALLTHROUGH;
@@ -295,7 +317,7 @@ zend_result dom_node_child_nodes_read(dom_object *obj, zval *retval)
return FAILURE;
}
- php_dom_create_iterator(retval, DOM_NODELIST);
+ php_dom_create_iterator(retval, DOM_NODELIST, php_dom_follow_spec_intern(obj));
intern = Z_DOMOBJ_P(retval);
dom_namednode_iter(obj, XML_ELEMENT_NODE, intern, NULL, NULL, 0, NULL, 0);
@@ -319,7 +341,7 @@ zend_result dom_node_first_child_read(dom_object *obj, zval *retval)
return FAILURE;
}
- if (dom_node_children_valid(nodep) == SUCCESS) {
+ if (dom_node_children_valid(nodep)) {
first = nodep->children;
}
@@ -350,7 +372,7 @@ zend_result dom_node_last_child_read(dom_object *obj, zval *retval)
return FAILURE;
}
- if (dom_node_children_valid(nodep) == SUCCESS) {
+ if (dom_node_children_valid(nodep)) {
last = nodep->last;
}
@@ -503,7 +525,7 @@ zend_result dom_node_attributes_read(dom_object *obj, zval *retval)
}
if (nodep->type == XML_ELEMENT_NODE) {
- php_dom_create_iterator(retval, DOM_NAMEDNODEMAP);
+ php_dom_create_iterator(retval, DOM_NAMEDNODEMAP, php_dom_follow_spec_intern(obj));
intern = Z_DOMOBJ_P(retval);
dom_namednode_iter(obj, XML_ATTRIBUTE_NODE, intern, NULL, NULL, 0, NULL, 0);
} else {
@@ -607,6 +629,7 @@ zend_result dom_node_namespace_uri_read(dom_object *obj, zval *retval)
/* {{{ prefix string
readonly=no
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSPrefix
+Modern spec URL: https://dom.spec.whatwg.org/#concept-element-namespace-prefix
Since: DOM Level 2
*/
zend_result dom_node_prefix_read(dom_object *obj, zval *retval)
@@ -640,7 +663,24 @@ zend_result dom_node_prefix_read(dom_object *obj, zval *retval)
ZVAL_STRING(retval, str);
}
return SUCCESS;
+}
+zend_result dom_modern_node_prefix_read(dom_object *obj, zval *retval)
+{
+ xmlNode *nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, true);
+ return FAILURE;
+ }
+
+ xmlNsPtr ns = nodep->ns;
+ if (ns != NULL && ns->prefix != NULL) {
+ ZVAL_STRING(retval, (const char *) ns->prefix);
+ } else {
+ ZVAL_NULL(retval);
+ }
+ return SUCCESS;
}
zend_result dom_node_prefix_write(dom_object *obj, zval *newval)
@@ -763,10 +803,18 @@ zend_result dom_node_base_uri_read(dom_object *obj, zval *retval)
baseuri = xmlNodeGetBase(nodep->doc, nodep);
if (baseuri) {
- ZVAL_STRING(retval, (char *) (baseuri));
+ ZVAL_STRING(retval, (const char *) baseuri);
xmlFree(baseuri);
} else {
- ZVAL_NULL(retval);
+ if (php_dom_follow_spec_intern(obj)) {
+ if (nodep->doc->URL) {
+ ZVAL_STRING(retval, (const char *) nodep->doc->URL);
+ } else {
+ ZVAL_STRING(retval, "about:blank");
+ }
+ } else {
+ ZVAL_NULL(retval);
+ }
}
return SUCCESS;
@@ -777,8 +825,23 @@ zend_result dom_node_base_uri_read(dom_object *obj, zval *retval)
/* {{{ textContent string
readonly=no
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-textContent
+Modern spec URL: https://dom.spec.whatwg.org/#dom-node-textcontent
Since: DOM Level 3
*/
+/* Determines when the operation is a no-op. */
+static bool dom_skip_text_content(dom_object *obj, xmlNodePtr nodep)
+{
+ if (php_dom_follow_spec_intern(obj)) {
+ int type = nodep->type;
+ if (type != XML_DOCUMENT_FRAG_NODE && type != XML_ELEMENT_NODE && type != XML_ATTRIBUTE_NODE
+ && type != XML_TEXT_NODE && type != XML_CDATA_SECTION_NODE && type != XML_COMMENT_NODE && type != XML_PI_NODE) {
+ /* Yes, success... It's a no-op for these cases. */
+ return true;
+ }
+ }
+ return false;
+}
+
zend_result dom_node_text_content_read(dom_object *obj, zval *retval)
{
xmlNode *nodep = dom_object_get_node(obj);
@@ -788,7 +851,11 @@ zend_result dom_node_text_content_read(dom_object *obj, zval *retval)
return FAILURE;
}
- php_dom_get_content_into_zval(nodep, retval, false);
+ if (dom_skip_text_content(obj, nodep)) {
+ ZVAL_NULL(retval);
+ } else {
+ php_dom_get_content_into_zval(nodep, retval, false);
+ }
return SUCCESS;
}
@@ -805,8 +872,17 @@ zend_result dom_node_text_content_write(dom_object *obj, zval *newval)
php_libxml_invalidate_node_list_cache(obj->document);
/* Typed property, this is already a string */
- ZEND_ASSERT(Z_TYPE_P(newval) == IS_STRING);
- const xmlChar *xmlChars = (const xmlChar *) Z_STRVAL_P(newval);
+ ZEND_ASSERT(Z_TYPE_P(newval) == IS_STRING || Z_TYPE_P(newval) == IS_NULL);
+ const xmlChar *xmlChars;
+ size_t len;
+ if (Z_TYPE_P(newval) == IS_NULL) {
+ xmlChars = (const xmlChar *) "";
+ len = 0;
+ } else {
+ xmlChars = (const xmlChar *) Z_STRVAL_P(newval);
+ len = Z_STRLEN_P(newval);
+ }
+
int type = nodep->type;
/* We can't directly call xmlNodeSetContent, because it might encode the string through
@@ -817,7 +893,7 @@ zend_result dom_node_text_content_write(dom_object *obj, zval *newval)
* the content without encoding. */
if (type == XML_DOCUMENT_FRAG_NODE || type == XML_ELEMENT_NODE || type == XML_ATTRIBUTE_NODE) {
dom_remove_all_children(nodep);
- xmlNode *textNode = xmlNewText(xmlChars);
+ xmlNode *textNode = xmlNewDocTextLen(nodep->doc, xmlChars, len);
xmlAddChild(nodep, textNode);
} else {
xmlNodeSetContent(nodep, xmlChars);
@@ -876,29 +952,15 @@ static xmlNodePtr _php_dom_insert_fragment(xmlNodePtr nodep, xmlNodePtr prevsib,
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727
Since:
*/
-PHP_METHOD(DOMNode, insertBefore)
+static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_object *intern, dom_object *childobj, xmlNodePtr parentp, xmlNodePtr child)
{
- zval *id, *node, *ref = NULL;
- xmlNodePtr child, new_child, parentp, refp;
- dom_object *intern, *childobj, *refpobj;
- int ret, stricterror;
-
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|O!", &node, dom_node_class_entry, &ref, dom_node_class_entry) == FAILURE) {
- RETURN_THROWS();
- }
-
- DOM_GET_OBJ(parentp, id, xmlNodePtr, intern);
-
- if (dom_node_children_valid(parentp) == FAILURE) {
+ if (!dom_node_children_valid(parentp)) {
RETURN_FALSE;
}
- DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
-
- new_child = NULL;
-
- stricterror = dom_get_strict_error(intern->document);
+ xmlNodePtr new_child = NULL;
+ bool stricterror = dom_get_strict_error(intern->document);
+ int ret;
if (dom_node_is_read_only(parentp) == SUCCESS ||
(child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
@@ -930,6 +992,8 @@ PHP_METHOD(DOMNode, insertBefore)
php_libxml_invalidate_node_list_cache(intern->document);
if (ref != NULL) {
+ xmlNodePtr refp;
+ dom_object *refpobj;
DOM_GET_OBJ(refp, ref, xmlNodePtr, refpobj);
if (refp->parent != parentp) {
php_dom_throw_error(NOT_FOUND_ERR, stricterror);
@@ -1050,58 +1114,198 @@ PHP_METHOD(DOMNode, insertBefore)
}
/* }}} end dom_node_insert_before */
+/* https://dom.spec.whatwg.org/#dom-node-insertbefore */
+static void dom_node_insert_before_modern(zval *return_value, zval *ref, dom_object *intern, dom_object *childobj, xmlNodePtr parentp, xmlNodePtr child)
+{
+ int ret;
+ xmlNodePtr refp = NULL;
+ dom_object *refobjp;
+ if (php_dom_pre_insert_is_parent_invalid(parentp)) {
+ php_dom_throw_error(HIERARCHY_REQUEST_ERR, /* strict */ true);
+ RETURN_THROWS();
+ }
+ if (ref != NULL) {
+ DOM_GET_OBJ(refp, ref, xmlNodePtr, refobjp);
+ }
+ php_libxml_invalidate_node_list_cache(intern->document);
+ php_dom_pre_insert(intern->document, child, parentp, refp);
+ DOM_RET_OBJ(child, &ret, intern);
+}
+
+static void dom_node_insert_before(INTERNAL_FUNCTION_PARAMETERS, bool modern)
+{
+ zval *id, *node, *ref = NULL;
+ xmlNodePtr child, parentp;
+ dom_object *intern, *childobj;
+
+ id = ZEND_THIS;
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|O!", &node, dom_get_node_ce(modern), &ref, dom_get_node_ce(modern)) == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ DOM_GET_OBJ(parentp, id, xmlNodePtr, intern);
+
+ DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
+
+ if (modern) {
+ dom_node_insert_before_modern(return_value, ref, intern, childobj, parentp, child);
+ } else {
+ dom_node_insert_before_legacy(return_value, ref, intern, childobj, parentp, child);
+ }
+}
+
+PHP_METHOD(DOMNode, insertBefore)
+{
+ dom_node_insert_before(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+PHP_METHOD(DOM_Node, insertBefore)
+{
+ dom_node_insert_before(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
+
+/* https://dom.spec.whatwg.org/#concept-node-replace */
+static zend_result dom_replace_node_validity_checks(xmlNodePtr parent, xmlNodePtr node, xmlNodePtr child)
+{
+ /* 1. If parent is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException. */
+ if (php_dom_pre_insert_is_parent_invalid(parent)) {
+ php_dom_throw_error(HIERARCHY_REQUEST_ERR, /* strict */ true);
+ return FAILURE;
+ }
+
+ /* 2. If node is a host-including inclusive ancestor of parent, then throw a "HierarchyRequestError" DOMException. */
+ if (dom_hierarchy(parent, node) != SUCCESS) {
+ php_dom_throw_error(HIERARCHY_REQUEST_ERR, /* strict */ true);
+ return FAILURE;
+ }
+
+ /* 3. If child’s parent is not parent, then throw a "NotFoundError" DOMException. */
+ if (child->parent != parent) {
+ php_dom_throw_error(NOT_FOUND_ERR, /* strict */ true);
+ return FAILURE;
+ }
+
+ /* 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException. */
+ if (node->type != XML_DOCUMENT_FRAG_NODE
+ && node->type != XML_DTD_NODE
+ && node->type != XML_ELEMENT_NODE
+ && node->type != XML_TEXT_NODE
+ && node->type != XML_CDATA_SECTION_NODE
+ && node->type != XML_COMMENT_NODE
+ && node->type != XML_PI_NODE) {
+ php_dom_throw_error(HIERARCHY_REQUEST_ERR, /* strict */ true);
+ return FAILURE;
+ }
+
+ /* 5. If either node is a Text node and parent is a document, or node is a doctype and parent is not a document,
+ * then throw a "HierarchyRequestError" DOMException. */
+ bool parent_is_document = parent->type == XML_DOCUMENT_NODE || parent->type == XML_HTML_DOCUMENT_NODE;
+ if (parent_is_document && (node->type == XML_TEXT_NODE || node->type == XML_CDATA_SECTION_NODE)) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot insert text as a child of a document", /* strict */ true);
+ return FAILURE;
+ }
+ if (!parent_is_document && node->type == XML_DTD_NODE) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot insert a document type into anything other than a document", /* strict */ true);
+ return FAILURE;
+ }
+
+ /* 6. If parent is a document, and any of the statements below, switched on the interface node implements, are true,
+ * then throw a "HierarchyRequestError" DOMException.
+ * Spec note: These statements _slightly_ differ from the pre-insert algorithm. */
+ if (parent_is_document) {
+ /* DocumentFragment */
+ if (node->type == XML_DOCUMENT_FRAG_NODE) {
+ if (!php_dom_fragment_insertion_hierarchy_check_replace(parent, node, child)) {
+ return FAILURE;
+ }
+ }
+ /* Element */
+ else if (node->type == XML_ELEMENT_NODE) {
+ /* parent has an element child that is not child ... */
+ if (xmlDocGetRootElement((xmlDocPtr) parent) != child) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot have more than one element child in a document", /* strict */ true);
+ return FAILURE;
+ }
+ /* ... or a doctype is following child. */
+ if (php_dom_has_sibling_following_node(child, XML_DTD_NODE)) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Document types must be the first child in a document", /* strict */ true);
+ return FAILURE;
+ }
+ }
+ /* DocumentType */
+ else if (node->type == XML_DTD_NODE) {
+ /* parent has a doctype child that is not child, or an element is preceding child. */
+ xmlDocPtr doc = (xmlDocPtr) parent;
+ if (doc->intSubset != (xmlDtdPtr) child || php_dom_has_sibling_preceding_node(child, XML_ELEMENT_NODE)) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Document types must be the first child in a document", /* strict */ true);
+ return FAILURE;
+ }
+ }
+ }
+
+ /* Steps 7 and onward perform the removal and insertion, and also track changes for mutation records.
+ * We don't implement mutation records so we can just skip straight to the replace part. */
+
+ return SUCCESS;
+}
+
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307
+Modern spec URL: https://dom.spec.whatwg.org/#dom-node-replacechild
Since:
*/
-PHP_METHOD(DOMNode, replaceChild)
+static void dom_node_replace_child(INTERNAL_FUNCTION_PARAMETERS, bool modern)
{
zval *id, *newnode, *oldnode;
xmlNodePtr newchild, oldchild, nodep;
dom_object *intern, *newchildobj, *oldchildobj;
- int stricterror;
- bool replacedoctype = false;
int ret;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &newnode, dom_node_class_entry, &oldnode, dom_node_class_entry) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &newnode, dom_get_node_ce(modern), &oldnode, dom_get_node_ce(modern)) == FAILURE) {
RETURN_THROWS();
}
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- if (dom_node_children_valid(nodep) == FAILURE) {
- RETURN_FALSE;
- }
-
DOM_GET_OBJ(newchild, newnode, xmlNodePtr, newchildobj);
DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr, oldchildobj);
- if (!nodep->children) {
- RETURN_FALSE;
- }
-
- stricterror = dom_get_strict_error(intern->document);
-
- if (dom_node_is_read_only(nodep) == SUCCESS ||
- (newchild->parent != NULL && dom_node_is_read_only(newchild->parent) == SUCCESS)) {
- php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror);
- RETURN_FALSE;
- }
+ bool stricterror = dom_get_strict_error(intern->document);
if (newchild->doc != nodep->doc && newchild->doc != NULL) {
php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror);
RETURN_FALSE;
}
- if (dom_hierarchy(nodep, newchild) == FAILURE) {
- php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror);
- RETURN_FALSE;
- }
+ if (modern) {
+ if (dom_replace_node_validity_checks(nodep, newchild, oldchild) != SUCCESS) {
+ RETURN_THROWS();
+ }
+ } else {
+ if (!dom_node_children_valid(nodep)) {
+ RETURN_FALSE;
+ }
- if (oldchild->parent != nodep) {
- php_dom_throw_error(NOT_FOUND_ERR, stricterror);
- RETURN_FALSE;
+ if (!nodep->children) {
+ RETURN_FALSE;
+ }
+
+ if (dom_node_is_read_only(nodep) == SUCCESS ||
+ (newchild->parent != NULL && dom_node_is_read_only(newchild->parent) == SUCCESS)) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror);
+ RETURN_FALSE;
+ }
+
+ if (dom_hierarchy(nodep, newchild) == FAILURE) {
+ php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror);
+ RETURN_FALSE;
+ }
+
+ if (oldchild->parent != nodep) {
+ php_dom_throw_error(NOT_FOUND_ERR, stricterror);
+ RETURN_FALSE;
+ }
}
if (newchild->type == XML_DOCUMENT_FRAG_NODE) {
@@ -1113,12 +1317,12 @@ PHP_METHOD(DOMNode, replaceChild)
xmlNodePtr last = newchild->last;
newchild = _php_dom_insert_fragment(nodep, prevsib, nextsib, newchild, intern);
- if (newchild) {
+ if (newchild && !modern) {
dom_reconcile_ns_list(nodep->doc, newchild, last);
}
} else if (oldchild != newchild) {
xmlDtdPtr intSubset = xmlGetIntSubset(nodep->doc);
- replacedoctype = (intSubset == (xmlDtd *) oldchild);
+ bool replacedoctype = (intSubset == (xmlDtd *) oldchild);
if (newchild->doc == NULL && nodep->doc != NULL) {
xmlSetTreeDoc(newchild, nodep->doc);
@@ -1126,7 +1330,9 @@ PHP_METHOD(DOMNode, replaceChild)
php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL);
}
xmlReplaceNode(oldchild, newchild);
- dom_reconcile_ns(nodep->doc, newchild);
+ if (!modern) {
+ dom_reconcile_ns(nodep->doc, newchild);
+ }
if (replacedoctype) {
nodep->doc->intSubset = (xmlDtd *) newchild;
@@ -1135,12 +1341,22 @@ PHP_METHOD(DOMNode, replaceChild)
php_libxml_invalidate_node_list_cache(intern->document);
DOM_RET_OBJ(oldchild, &ret, intern);
}
+
+PHP_METHOD(DOMNode, replaceChild)
+{
+ dom_node_replace_child(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+PHP_METHOD(DOM_Node, replaceChild)
+{
+ dom_node_replace_child(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
/* }}} end dom_node_replace_child */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066
Since:
*/
-PHP_METHOD(DOMNode, removeChild)
+static void dom_node_remove_child(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *node_ce)
{
zval *id, *node;
xmlNodePtr child, nodep;
@@ -1148,13 +1364,13 @@ PHP_METHOD(DOMNode, removeChild)
int ret, stricterror;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node, dom_node_class_entry) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node, node_ce) == FAILURE) {
RETURN_THROWS();
}
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- if (dom_node_children_valid(nodep) == FAILURE) {
+ if (!dom_node_children_valid(nodep)) {
RETURN_FALSE;
}
@@ -1177,31 +1393,31 @@ PHP_METHOD(DOMNode, removeChild)
php_libxml_invalidate_node_list_cache(intern->document);
DOM_RET_OBJ(child, &ret, intern);
}
+
+PHP_METHOD(DOMNode, removeChild)
+{
+ dom_node_remove_child(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_node_class_entry);
+}
+
+PHP_METHOD(DOM_Node, removeChild)
+{
+ dom_node_remove_child(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_modern_node_class_entry);
+}
/* }}} end dom_node_remove_child */
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107
+Modern spec URL: https://dom.spec.whatwg.org/#dom-node-appendchild
Since:
*/
-PHP_METHOD(DOMNode, appendChild)
+static void dom_node_append_child_legacy(zval *return_value, dom_object *intern, dom_object *childobj, xmlNodePtr nodep, xmlNodePtr child)
{
- zval *id, *node;
- xmlNodePtr child, nodep, new_child = NULL;
- dom_object *intern, *childobj;
+ xmlNodePtr new_child = NULL;
int ret, stricterror;
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node, dom_node_class_entry) == FAILURE) {
- RETURN_THROWS();
- }
-
- DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
-
- if (dom_node_children_valid(nodep) == FAILURE) {
+ if (!dom_node_children_valid(nodep)) {
RETURN_FALSE;
}
- DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
-
stricterror = dom_get_strict_error(intern->document);
if (dom_node_is_read_only(nodep) == SUCCESS ||
@@ -1272,6 +1488,16 @@ PHP_METHOD(DOMNode, appendChild)
xmlNodePtr last = child->last;
new_child = _php_dom_insert_fragment(nodep, nodep->last, NULL, child, intern);
dom_reconcile_ns_list(nodep->doc, new_child, last);
+ } else if (child->type == XML_DTD_NODE) {
+ if (nodep->doc->intSubset != NULL) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "A document may only contain one document type", stricterror);
+ RETURN_FALSE;
+ }
+ new_child = xmlAddChild(nodep, child);
+ if (UNEXPECTED(new_child == NULL)) {
+ goto cannot_add;
+ }
+ nodep->doc->intSubset = (xmlDtdPtr) new_child;
} else {
new_child = xmlAddChild(nodep, child);
if (UNEXPECTED(new_child == NULL)) {
@@ -1290,6 +1516,48 @@ PHP_METHOD(DOMNode, appendChild)
}
/* }}} end dom_node_append_child */
+PHP_METHOD(DOMNode, appendChild)
+{
+ zval *node;
+ xmlNodePtr nodep, child;
+ dom_object *intern, *childobj;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_OBJECT_OF_CLASS(node, dom_node_class_entry)
+ ZEND_PARSE_PARAMETERS_END();
+
+ DOM_GET_OBJ(nodep, ZEND_THIS, xmlNodePtr, intern);
+ DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
+
+ dom_node_append_child_legacy(return_value, intern, childobj, nodep, child);
+}
+
+PHP_METHOD(DOM_Node, appendChild)
+{
+ zval *node;
+ xmlNodePtr nodep, child;
+ dom_object *intern, *childobj;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_OBJECT_OF_CLASS(node, dom_modern_node_class_entry)
+ ZEND_PARSE_PARAMETERS_END();
+
+ DOM_GET_OBJ(nodep, ZEND_THIS, xmlNodePtr, intern);
+ DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
+
+ /* Parent check from pre-insertion validation done here:
+ * If parent is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException. */
+ if (php_dom_pre_insert_is_parent_invalid(nodep)) {
+ php_dom_throw_error(HIERARCHY_REQUEST_ERR, /* strict */ true);
+ RETURN_THROWS();
+ }
+ /* Append, this doesn't do the parent check so we do it here. */
+ php_libxml_invalidate_node_list_cache(intern->document);
+ php_dom_node_append(intern->document, child, nodep);
+ int ret;
+ DOM_RET_OBJ(child, &ret, intern);
+}
+
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187
Since:
*/
@@ -1306,7 +1574,7 @@ PHP_METHOD(DOMNode, hasChildNodes)
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- if (dom_node_children_valid(nodep) == FAILURE) {
+ if (!dom_node_children_valid(nodep)) {
RETURN_FALSE;
}
@@ -1336,25 +1604,51 @@ PHP_METHOD(DOMNode, cloneNode)
DOM_GET_OBJ(n, id, xmlNodePtr, intern);
- node = dom_clone_node(n, n->doc, intern, recursive);
+ php_dom_libxml_ns_mapper *ns_mapper = NULL;
+ bool clone_document = n->type == XML_DOCUMENT_NODE || n->type == XML_HTML_DOCUMENT_NODE;
+ if (php_dom_follow_spec_intern(intern)) {
+ if (clone_document) {
+ ns_mapper = php_dom_libxml_ns_mapper_create();
+ } else {
+ ns_mapper = php_dom_get_ns_mapper(intern);
+ }
+ }
+
+ node = dom_clone_node(ns_mapper, n, n->doc, recursive);
if (!node) {
+ if (clone_document && ns_mapper != NULL) {
+ php_dom_libxml_ns_mapper_destroy(ns_mapper);
+ }
RETURN_FALSE;
}
- if (node->type == XML_ATTRIBUTE_NODE && n->ns != NULL && node->ns == NULL) {
- /* Let reconciliation deal with this. The lifetime of the namespace poses no problem
- * because we're increasing the refcount of the document proxy at the return.
- * libxml2 doesn't set the ns because it can't know that this is safe. */
- node->ns = n->ns;
- }
-
/* If document cloned we want a new document proxy */
- if (node->doc != n->doc) {
- intern = NULL;
- }
+ if (clone_document) {
+ dom_object *new_intern;
+ if (ns_mapper) {
+ /* We have the issue here that we can't create a modern node without an intern.
+ * Fortunately, it's impossible to have a custom document class for the modern DOM (final base class),
+ * so we can solve this by invoking the instantiation helper directly. */
+ zend_class_entry *ce = n->type == XML_DOCUMENT_NODE ? dom_xml_document_class_entry : dom_html_document_class_entry;
+ new_intern = php_dom_instantiate_object_helper(return_value, ce, node, NULL);
+ } else {
+ DOM_RET_OBJ(node, &ret, NULL);
+ new_intern = Z_DOMOBJ_P(return_value);
+ }
+ php_dom_update_document_after_clone(intern, n, new_intern, node);
+ ZEND_ASSERT(new_intern->document->private_data == NULL);
+ new_intern->document->private_data = php_dom_libxml_ns_mapper_header(ns_mapper);
+ } else {
+ if (node->type == XML_ATTRIBUTE_NODE && n->ns != NULL && node->ns == NULL) {
+ /* Let reconciliation deal with this. The lifetime of the namespace poses no problem
+ * because we're increasing the refcount of the document proxy at the return.
+ * libxml2 doesn't set the ns because it can't know that this is safe. */
+ node->ns = n->ns;
+ }
- DOM_RET_OBJ(node, &ret, intern);
+ DOM_RET_OBJ(node, &ret, intern);
+ }
}
/* }}} end dom_node_clone_node */
@@ -1374,10 +1668,11 @@ PHP_METHOD(DOMNode, normalize)
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- php_libxml_invalidate_node_list_cache(intern->document);
-
- dom_normalize(nodep);
-
+ if (php_dom_follow_spec_intern(intern)) {
+ php_dom_normalize_modern(nodep);
+ } else {
+ php_dom_normalize_legacy(nodep);
+ }
}
/* }}} end dom_node_normalize */
@@ -1426,18 +1721,13 @@ PHP_METHOD(DOMNode, hasAttributes)
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode
Since: DOM Level 3
*/
-PHP_METHOD(DOMNode, isSameNode)
+static void dom_node_is_same_node(INTERNAL_FUNCTION_PARAMETERS, zval *node)
{
- zval *id, *node;
+ zval *id;
xmlNodePtr nodeotherp, nodep;
dom_object *intern, *nodeotherobj;
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node, dom_node_class_entry) == FAILURE) {
- RETURN_THROWS();
- }
-
- DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
DOM_GET_OBJ(nodeotherp, node, xmlNodePtr, nodeotherobj);
@@ -1447,6 +1737,30 @@ PHP_METHOD(DOMNode, isSameNode)
RETURN_FALSE;
}
}
+
+PHP_METHOD(DOMNode, isSameNode)
+{
+ zval *node;
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node, dom_node_class_entry) != SUCCESS) {
+ RETURN_THROWS();
+ }
+
+ dom_node_is_same_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, node);
+}
+
+PHP_METHOD(DOM_Node, isSameNode)
+{
+ zval *node;
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O!", &node, dom_modern_node_class_entry) != SUCCESS) {
+ RETURN_THROWS();
+ }
+
+ if (node == NULL) {
+ RETURN_FALSE;
+ }
+
+ dom_node_is_same_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, node);
+}
/* }}} end dom_node_is_same_node */
static bool php_dom_node_is_content_equal(const xmlNode *this, const xmlNode *other)
@@ -1473,55 +1787,55 @@ static bool php_dom_node_is_ns_prefix_equal(const xmlNode *this, const xmlNode *
return xmlStrEqual(this_ns, other_ns);
}
-static bool php_dom_node_is_equal_node(const xmlNode *this, const xmlNode *other);
+static bool php_dom_node_is_equal_node(const xmlNode *this, const xmlNode *other, bool spec_compliant);
#define PHP_DOM_FUNC_CAT(prefix, suffix) prefix##_##suffix
/* xmlNode and xmlNs have incompatible struct layouts, i.e. the next field is in a different offset */
-#define PHP_DOM_DEFINE_LIST_COUNTER_HELPER(type) \
- static size_t PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(const type *node) \
- { \
- size_t counter = 0; \
- while (node) { \
- counter++; \
- node = node->next; \
- } \
- return counter; \
- }
-#define PHP_DOM_DEFINE_LIST_EQUALITY_ORDERED_HELPER(type) \
- static bool PHP_DOM_FUNC_CAT(php_dom_node_list_equality_check_ordered, type)(const type *list1, const type *list2) \
- { \
- size_t count = PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list1); \
- if (count != PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list2)) { \
- return false; \
- } \
- for (size_t i = 0; i < count; i++) { \
- if (!php_dom_node_is_equal_node((const xmlNode *) list1, (const xmlNode *) list2)) { \
- return false; \
- } \
- list1 = list1->next; \
- list2 = list2->next; \
- } \
- return true; \
- }
-#define PHP_DOM_DEFINE_LIST_EQUALITY_UNORDERED_HELPER(type) \
- static bool PHP_DOM_FUNC_CAT(php_dom_node_list_equality_check_unordered, type)(const type *list1, const type *list2)\
- { \
- size_t count = PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list1); \
- if (count != PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list2)) { \
- return false; \
- } \
- for (const type *n1 = list1; n1 != NULL; n1 = n1->next) { \
- bool found = false; \
- for (const type *n2 = list2; n2 != NULL && !found; n2 = n2->next) { \
- if (php_dom_node_is_equal_node((const xmlNode *) n1, (const xmlNode *) n2)) { \
- found = true; \
- } \
- } \
- if (!found) { \
- return false; \
- } \
- } \
- return true; \
+#define PHP_DOM_DEFINE_LIST_COUNTER_HELPER(type) \
+ static size_t PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(const type *node) \
+ { \
+ size_t counter = 0; \
+ while (node) { \
+ counter++; \
+ node = node->next; \
+ } \
+ return counter; \
+ }
+#define PHP_DOM_DEFINE_LIST_EQUALITY_ORDERED_HELPER(type) \
+ static bool PHP_DOM_FUNC_CAT(php_dom_node_list_equality_check_ordered, type)(const type *list1, const type *list2, bool spec_compliant) \
+ { \
+ size_t count = PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list1); \
+ if (count != PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list2)) { \
+ return false; \
+ } \
+ for (size_t i = 0; i < count; i++) { \
+ if (!php_dom_node_is_equal_node((const xmlNode *) list1, (const xmlNode *) list2, spec_compliant)) { \
+ return false; \
+ } \
+ list1 = list1->next; \
+ list2 = list2->next; \
+ } \
+ return true; \
+ }
+#define PHP_DOM_DEFINE_LIST_EQUALITY_UNORDERED_HELPER(type) \
+ static bool PHP_DOM_FUNC_CAT(php_dom_node_list_equality_check_unordered, type)(const type *list1, const type *list2, bool spec_compliant)\
+ { \
+ size_t count = PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list1); \
+ if (count != PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list2)) { \
+ return false; \
+ } \
+ for (const type *n1 = list1; n1 != NULL; n1 = n1->next) { \
+ bool found = false; \
+ for (const type *n2 = list2; n2 != NULL && !found; n2 = n2->next) { \
+ if (php_dom_node_is_equal_node((const xmlNode *) n1, (const xmlNode *) n2, spec_compliant)) { \
+ found = true; \
+ } \
+ } \
+ if (!found) { \
+ return false; \
+ } \
+ } \
+ return true; \
}
PHP_DOM_DEFINE_LIST_COUNTER_HELPER(xmlNode)
@@ -1539,7 +1853,7 @@ static bool php_dom_is_equal_attr(const xmlAttr *this_attr, const xmlAttr *other
&& php_dom_node_is_content_equal((const xmlNode *) this_attr, (const xmlNode *) other_attr);
}
-static bool php_dom_node_is_equal_node(const xmlNode *this, const xmlNode *other)
+static bool php_dom_node_is_equal_node(const xmlNode *this, const xmlNode *other, bool spec_compliant)
{
ZEND_ASSERT(this != NULL);
ZEND_ASSERT(other != NULL);
@@ -1556,9 +1870,9 @@ static bool php_dom_node_is_equal_node(const xmlNode *this, const xmlNode *other
&& php_dom_node_is_ns_prefix_equal(this, other)
&& php_dom_node_is_ns_uri_equal(this, other)
/* Check attributes first, then namespace declarations, then children */
- && php_dom_node_list_equality_check_unordered_xmlNode((const xmlNode *) this->properties, (const xmlNode *) other->properties)
- && php_dom_node_list_equality_check_unordered_xmlNs(this->nsDef, other->nsDef)
- && php_dom_node_list_equality_check_ordered_xmlNode(this->children, other->children);
+ && php_dom_node_list_equality_check_unordered_xmlNode((const xmlNode *) this->properties, (const xmlNode *) other->properties, spec_compliant)
+ && (spec_compliant || php_dom_node_list_equality_check_unordered_xmlNs(this->nsDef, other->nsDef, false))
+ && php_dom_node_list_equality_check_ordered_xmlNode(this->children, other->children, spec_compliant);
} else if (this->type == XML_DTD_NODE) {
/* Note: in the living spec entity declarations and notations are no longer compared because they're considered obsolete. */
const xmlDtd *this_dtd = (const xmlDtd *) this;
@@ -1589,7 +1903,7 @@ static bool php_dom_node_is_equal_node(const xmlNode *this, const xmlNode *other
const xmlNs *other_ns = (const xmlNs *) other;
return xmlStrEqual(this_ns->prefix, other_ns->prefix) && xmlStrEqual(this_ns->href, other_ns->href);
} else if (this->type == XML_DOCUMENT_FRAG_NODE || this->type == XML_HTML_DOCUMENT_NODE || this->type == XML_DOCUMENT_NODE) {
- return php_dom_node_list_equality_check_ordered_xmlNode(this->children, other->children);
+ return php_dom_node_list_equality_check_ordered_xmlNode(this->children, other->children, spec_compliant);
}
return false;
@@ -1599,14 +1913,14 @@ static bool php_dom_node_is_equal_node(const xmlNode *this, const xmlNode *other
* URL: https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/DOM3-Core.html#core-Node3-isEqualNode (for old nodes removed from the living spec)
Since: DOM Level 3
*/
-PHP_METHOD(DOMNode, isEqualNode)
+static void dom_node_is_equal_node_common(INTERNAL_FUNCTION_PARAMETERS, bool modern)
{
zval *id, *node;
xmlNodePtr otherp, nodep;
- dom_object *unused_intern;
+ dom_object *intern;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "O!", &node, dom_node_class_entry) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O!", &node, dom_get_node_ce(modern)) == FAILURE) {
RETURN_THROWS();
}
@@ -1614,26 +1928,63 @@ PHP_METHOD(DOMNode, isEqualNode)
RETURN_FALSE;
}
- DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, unused_intern);
- DOM_GET_OBJ(otherp, node, xmlNodePtr, unused_intern);
+ DOM_GET_OBJ(otherp, node, xmlNodePtr, intern);
+ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
if (nodep == otherp) {
RETURN_TRUE;
}
/* Empty fragments/documents only match if they're both empty */
- if (UNEXPECTED(nodep == NULL || otherp == NULL)) {
+ if (nodep == NULL || otherp == NULL) {
RETURN_BOOL(nodep == NULL && otherp == NULL);
}
- RETURN_BOOL(php_dom_node_is_equal_node(nodep, otherp));
+ RETURN_BOOL(php_dom_node_is_equal_node(nodep, otherp, modern));
+}
+
+PHP_METHOD(DOMNode, isEqualNode)
+{
+ dom_node_is_equal_node_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+PHP_METHOD(DOM_Node, isEqualNode)
+{
+ dom_node_is_equal_node_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
}
/* }}} end DOMNode::isEqualNode */
+/* https://dom.spec.whatwg.org/#locate-a-namespace-prefix */
+static const xmlChar *dom_locate_a_namespace_prefix(xmlNodePtr elem, const char *uri)
+{
+ do {
+ /* 1. If element’s namespace is namespace and its namespace prefix is non-null, then return its namespace prefix. */
+ if (elem->ns != NULL && elem->ns->prefix != NULL && xmlStrEqual(elem->ns->href, BAD_CAST uri)) {
+ return elem->ns->prefix;
+ }
+
+ /* 2. If element has an attribute whose namespace prefix is "xmlns" and value is namespace,
+ * then return element’s first such attribute’s local name. */
+ for (xmlAttrPtr attr = elem->properties; attr != NULL; attr = attr->next) {
+ if (attr->ns != NULL && attr->children != NULL
+ && xmlStrEqual(attr->ns->prefix, BAD_CAST "xmlns") && xmlStrEqual(attr->children->content, BAD_CAST uri)) {
+ return attr->name;
+ }
+ }
+
+ /* 3. If element’s parent element is not null, then return the result of running locate a namespace prefix on that element using namespace. */
+ elem = elem->parent;
+ } while (elem != NULL && elem->type == XML_ELEMENT_NODE);
+
+ /* 4. Return null. */
+ return NULL;
+}
+
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix
+Modern spec URL: https://dom.spec.whatwg.org/#dom-node-lookupprefix
Since: DOM Level 3
*/
-PHP_METHOD(DOMNode, lookupPrefix)
+static void dom_node_lookup_prefix(INTERNAL_FUNCTION_PARAMETERS, bool modern)
{
zval *id;
xmlNodePtr nodep, lookupp = NULL;
@@ -1643,13 +1994,15 @@ PHP_METHOD(DOMNode, lookupPrefix)
char *uri;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &uri, &uri_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), modern ? "s!" : "s", &uri, &uri_len) == FAILURE) {
RETURN_THROWS();
}
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+ /* 1. If namespace is null or the empty string, then return null. */
if (uri_len > 0) {
+ /* 2. Switch on the interface this implements: */
switch (nodep->type) {
case XML_ELEMENT_NODE:
lookupp = nodep;
@@ -1666,22 +2019,110 @@ PHP_METHOD(DOMNode, lookupPrefix)
RETURN_NULL();
break;
default:
- lookupp = nodep->parent;
+ lookupp = nodep->parent;
}
if (lookupp != NULL) {
- nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, (xmlChar *) uri);
- if (nsptr && nsptr->prefix != NULL) {
- RETURN_STRING((char *) nsptr->prefix);
+ if (modern) {
+ const char * result = (const char *) dom_locate_a_namespace_prefix(lookupp, uri);
+ if (result != NULL) {
+ RETURN_STRING(result);
+ }
+ } else {
+ nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, (xmlChar *) uri);
+ if (nsptr && nsptr->prefix != NULL) {
+ RETURN_STRING((const char *) nsptr->prefix);
+ }
}
}
}
RETURN_NULL();
}
+
+PHP_METHOD(DOMNode, lookupPrefix)
+{
+ dom_node_lookup_prefix(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+PHP_METHOD(DOM_Node, lookupPrefix)
+{
+ dom_node_lookup_prefix(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
/* }}} end dom_node_lookup_prefix */
+/* https://dom.spec.whatwg.org/#locate-a-namespace */
+static const char *dom_locate_a_namespace(xmlNodePtr node, const zend_string *prefix)
+{
+ /* switch on the interface node implements: */
+ if (node->type == XML_ELEMENT_NODE) {
+ if (prefix != NULL) {
+ /* 1. If prefix is "xml", then return the XML namespace. */
+ if (zend_string_equals_literal_ci(prefix, "xml")) {
+ return DOM_XML_NS_URI;
+ }
+
+ /* 2. If prefix is "xmlns", then return the XMLNS namespace. */
+ if (zend_string_equals_literal_ci(prefix, "xmlns")) {
+ return DOM_XMLNS_NS_URI;
+ }
+ }
+
+ do {
+ /* 3. If its namespace is non-null and its namespace prefix is prefix, then return namespace. */
+ if (node->ns != NULL && xmlStrEqual(node->ns->prefix, BAD_CAST (prefix ? ZSTR_VAL(prefix) : NULL))) {
+ return (const char *) node->ns->href;
+ }
+
+ /* 4. If it has an attribute whose namespace is the XMLNS namespace, namespace prefix is "xmlns", and local name is prefix,
+ * or if prefix is null and it has an attribute whose namespace is the XMLNS namespace, namespace prefix is null, and local name is "xmlns",
+ * then return its value if it is not the empty string, and null otherwise. */
+ for (xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
+ if (attr->ns == NULL || !php_dom_ns_is_fast_ex(attr->ns, php_dom_ns_is_xmlns_magic_token)) {
+ continue;
+ }
+ if ((prefix != NULL && xmlStrEqual(attr->ns->prefix, BAD_CAST "xmlns") && xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(prefix)))
+ || (prefix == NULL && attr->ns->prefix == NULL && xmlStrEqual(attr->name, BAD_CAST "xmlns"))) {
+ if (attr->children != NULL && attr->children->content[0] != '\0') {
+ return (const char *) attr->children->content;
+ } else {
+ return NULL;
+ }
+ }
+ }
+
+ /* 5. If its parent element is null, then return null. */
+ if (node->parent == NULL || node->parent->type != XML_ELEMENT_NODE) {
+ return NULL;
+ }
+
+ /* 6. Return the result of running locate a namespace on its parent element using prefix. */
+ node = node->parent;
+ } while (true);
+ } else if (node->type == XML_DOCUMENT_NODE || node->type == XML_HTML_DOCUMENT_NODE) {
+ /* 1. If its document element is null, then return null. */
+ node = xmlDocGetRootElement((xmlDocPtr) node);
+ if (UNEXPECTED(node == NULL)) {
+ return NULL;
+ }
+
+ /* 2. Return the result of running locate a namespace on its document element using prefix. */
+ return dom_locate_a_namespace(node, prefix);
+ } else if (node->type == XML_DTD_NODE || node->type == XML_DOCUMENT_FRAG_NODE) {
+ return NULL;
+ } else {
+ /* 1. If its element is null, then return null / If its parent element is null, then return null. */
+ if (node->parent == NULL || node->parent->type != XML_ELEMENT_NODE) {
+ return NULL;
+ }
+
+ /* 2. Return the result of running locate a namespace on its element using prefix. */
+ return dom_locate_a_namespace(node->parent, prefix);
+ }
+}
+
/* {{{ URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace
+Modern spec URL: https://dom.spec.whatwg.org/#dom-node-isdefaultnamespace
Since: DOM Level 3
*/
PHP_METHOD(DOMNode, isDefaultNamespace)
@@ -1693,17 +2134,20 @@ PHP_METHOD(DOMNode, isDefaultNamespace)
size_t uri_len = 0;
char *uri;
- id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &uri, &uri_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &uri, &uri_len) != SUCCESS) {
RETURN_THROWS();
}
- DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
- nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
- }
+ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (uri_len > 0) {
+ if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+ nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
+ if (nodep == NULL) {
+ RETURN_FALSE;
+ }
+ }
- if (nodep && uri_len > 0) {
nsptr = xmlSearchNs(nodep->doc, nodep, NULL);
if (nsptr && xmlStrEqual(nsptr->href, (xmlChar *) uri)) {
RETURN_TRUE;
@@ -1712,9 +2156,31 @@ PHP_METHOD(DOMNode, isDefaultNamespace)
RETURN_FALSE;
}
+
+PHP_METHOD(DOM_Node, isDefaultNamespace)
+{
+ zval *id;
+ xmlNodePtr nodep;
+ dom_object *intern;
+ size_t uri_len = 0;
+ char *uri;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!", &uri, &uri_len) != SUCCESS) {
+ RETURN_THROWS();
+ }
+
+ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (uri_len == 0) {
+ uri = NULL;
+ }
+ const char *ns_uri = dom_locate_a_namespace(nodep, NULL);
+ RETURN_BOOL(xmlStrEqual(BAD_CAST uri, BAD_CAST ns_uri));
+}
/* }}} end dom_node_is_default_namespace */
/* {{{ URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI
+Modern spec URL: https://dom.spec.whatwg.org/#dom-node-lookupnamespaceuri
Since: DOM Level 3
*/
PHP_METHOD(DOMNode, lookupNamespaceURI)
@@ -1723,25 +2189,37 @@ PHP_METHOD(DOMNode, lookupNamespaceURI)
xmlNodePtr nodep;
dom_object *intern;
xmlNsPtr nsptr;
- size_t prefix_len;
- char *prefix;
+ zend_string *prefix;
id = ZEND_THIS;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!", &prefix, &prefix_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S!", &prefix) == FAILURE) {
RETURN_THROWS();
}
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
- if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
- nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
- if (nodep == NULL) {
+
+ if (php_dom_follow_spec_intern(intern)) {
+ if (prefix != NULL && ZSTR_LEN(prefix) == 0) {
+ prefix = NULL;
+ }
+ const char *ns_uri = dom_locate_a_namespace(nodep, prefix);
+ if (ns_uri == NULL) {
RETURN_NULL();
+ } else {
+ RETURN_STRING(ns_uri);
+ }
+ } else {
+ if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+ nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
+ if (nodep == NULL) {
+ RETURN_NULL();
+ }
}
- }
- nsptr = xmlSearchNs(nodep->doc, nodep, (xmlChar *) prefix);
- if (nsptr && nsptr->href != NULL) {
- RETURN_STRING((char *) nsptr->href);
+ nsptr = xmlSearchNs(nodep->doc, nodep, BAD_CAST (prefix ? ZSTR_VAL(prefix) : NULL));
+ if (nsptr && nsptr->href != NULL) {
+ RETURN_STRING((char *) nsptr->href);
+ }
}
RETURN_NULL();
@@ -1947,7 +2425,7 @@ PHP_METHOD(DOMNode, C14NFile)
/* }}} */
/* {{{ Gets an xpath for a node */
-PHP_METHOD(DOMNode, getNodePath)
+static void dom_node_get_node_path(INTERNAL_FUNCTION_PARAMETERS, bool throw)
{
zval *id;
xmlNode *nodep;
@@ -1962,13 +2440,28 @@ PHP_METHOD(DOMNode, getNodePath)
value = (char *) xmlGetNodePath(nodep);
if (value == NULL) {
- /* TODO Research if can return empty string */
+ /* This is only possible when an invalid argument is passed (e.g. namespace declaration, but that's not the case for this call site),
+ * or on allocation failure. So in other words, this only happens on allocation failure. */
+ if (throw) {
+ php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
+ RETURN_THROWS();
+ }
RETURN_NULL();
} else {
RETVAL_STRING(value);
xmlFree(value);
}
}
+
+PHP_METHOD(DOMNode, getNodePath)
+{
+ dom_node_get_node_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
+}
+
+PHP_METHOD(DOM_Node, getNodePath)
+{
+ dom_node_get_node_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
+}
/* }}} */
/* {{{ Gets line number for a node */
@@ -1991,6 +2484,18 @@ PHP_METHOD(DOMNode, getLineNo)
/* {{{ URL: https://dom.spec.whatwg.org/#dom-node-contains
Since:
*/
+static bool dom_node_contains(xmlNodePtr thisp, xmlNodePtr otherp)
+{
+ do {
+ if (otherp == thisp) {
+ return true;
+ }
+ otherp = otherp->parent;
+ } while (otherp);
+
+ return false;
+}
+
PHP_METHOD(DOMNode, contains)
{
zval *other, *id;
@@ -2013,14 +2518,27 @@ PHP_METHOD(DOMNode, contains)
DOM_GET_OBJ(otherp, other, xmlNodePtr, unused_intern);
DOM_GET_THIS_OBJ(thisp, id, xmlNodePtr, unused_intern);
- do {
- if (otherp == thisp) {
- RETURN_TRUE;
- }
- otherp = otherp->parent;
- } while (otherp);
+ RETURN_BOOL(dom_node_contains(thisp, otherp));
+}
- RETURN_FALSE;
+PHP_METHOD(DOM_Node, contains)
+{
+ zval *other, *id;
+ xmlNodePtr otherp, thisp;
+ dom_object *unused_intern;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_OBJECT_OF_CLASS_OR_NULL(other, dom_modern_node_class_entry)
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (other == NULL) {
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(otherp, other, xmlNodePtr, unused_intern);
+ DOM_GET_THIS_OBJ(thisp, id, xmlNodePtr, unused_intern);
+
+ RETURN_BOOL(dom_node_contains(thisp, otherp));
}
/* }}} */
@@ -2033,9 +2551,9 @@ PHP_METHOD(DOMNode, getRootNode)
xmlNodePtr thisp;
dom_object *intern;
/* Unused now because we don't support the shadow DOM nodes. Options only influence shadow DOM nodes. */
- zval *options = NULL;
+ zval *options;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &options) != SUCCESS) {
RETURN_THROWS();
}
@@ -2061,13 +2579,13 @@ PHP_METHOD(DOMNode, getRootNode)
#define DOCUMENT_POSITION_CONTAINED_BY 0x10
#define DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC 0x20
-PHP_METHOD(DOMNode, compareDocumentPosition)
+static void dom_node_compare_document_position(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *node_ce)
{
zval *id, *node_zval;
xmlNodePtr other, this;
dom_object *this_intern, *other_intern;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node_zval, dom_node_class_entry) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &node_zval, node_ce) != SUCCESS) {
RETURN_THROWS();
}
@@ -2205,7 +2723,7 @@ PHP_METHOD(DOMNode, compareDocumentPosition)
disconnected:;
zend_long ordering;
- if (UNEXPECTED(node1 == node2)) {
+ if (node1 == node2) {
/* Degenerate case, they're both NULL, but the ordering must be consistent... */
ZEND_ASSERT(node1 == NULL);
ordering = other_intern < this_intern ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING;
@@ -2214,6 +2732,16 @@ disconnected:;
}
RETURN_LONG(DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | ordering);
}
+
+PHP_METHOD(DOMNode, compareDocumentPosition)
+{
+ dom_node_compare_document_position(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_node_class_entry);
+}
+
+PHP_METHOD(DOM_Node, compareDocumentPosition)
+{
+ dom_node_compare_document_position(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_modern_node_class_entry);
+}
/* }}} */
/**
@@ -2225,6 +2753,11 @@ disconnected:;
* - If the user implements __sleep / __wakeup, then it's also not a problem because they will not enter the throwing methods.
*/
+PHP_METHOD(DOM_Node, __construct)
+{
+ ZEND_UNREACHABLE();
+}
+
PHP_METHOD(DOMNode, __sleep)
{
zend_throw_exception_ex(NULL, 0, "Serialization of '%s' is not allowed, unless serialization methods are implemented in a subclass", ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c
index b74a23ee7228b..74c5918c6d330 100644
--- a/ext/dom/nodelist.c
+++ b/ext/dom/nodelist.c
@@ -99,7 +99,7 @@ int php_dom_get_nodelist_length(dom_object *obj)
nodep = nodep->children;
}
dom_get_elements_by_tag_name_ns_raw(
- basep, nodep, (char *) objmap->ns, (char *) objmap->local, &count, INT_MAX - 1 /* because of <= */);
+ basep, nodep, objmap->ns, objmap->local, objmap->local_lower, &count, INT_MAX - 1 /* because of <= */);
}
objmap->cached_length = count;
@@ -200,7 +200,7 @@ void php_dom_nodelist_get_item_into_zval(dom_nnodemap_object *objmap, zend_long
nodep = basep->children;
}
}
- itemnode = dom_get_elements_by_tag_name_ns_raw(basep, nodep, (char *) objmap->ns, (char *) objmap->local, &count, relative_index);
+ itemnode = dom_get_elements_by_tag_name_ns_raw(basep, nodep, objmap->ns, objmap->local, objmap->local_lower, &count, relative_index);
}
cache_itemnode = true;
}
diff --git a/ext/dom/parentnode.c b/ext/dom/parentnode.c
index 9298c57553827..181cd6bc3b459 100644
--- a/ext/dom/parentnode.c
+++ b/ext/dom/parentnode.c
@@ -13,6 +13,7 @@
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Benjamin Eberlei |
+ | Niels Dossche |
+----------------------------------------------------------------------+
*/
@@ -23,6 +24,7 @@
#include "php.h"
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
#include "php_dom.h"
+#include "internal_helpers.h"
/* {{{ firstElementChild DomParentNode
readonly=yes
@@ -39,7 +41,7 @@ zend_result dom_parent_node_first_element_child_read(dom_object *obj, zval *retv
return FAILURE;
}
- if (dom_node_children_valid(nodep) == SUCCESS) {
+ if (dom_node_children_valid(nodep)) {
first = nodep->children;
while (first && first->type != XML_ELEMENT_NODE) {
@@ -72,7 +74,7 @@ zend_result dom_parent_node_last_element_child_read(dom_object *obj, zval *retva
return FAILURE;
}
- if (dom_node_children_valid(nodep) == SUCCESS) {
+ if (dom_node_children_valid(nodep)) {
last = nodep->last;
while (last && last->type != XML_ELEMENT_NODE) {
@@ -106,7 +108,7 @@ zend_result dom_parent_node_child_element_count(dom_object *obj, zval *retval)
return FAILURE;
}
- if (dom_node_children_valid(nodep) == SUCCESS) {
+ if (dom_node_children_valid(nodep)) {
first = nodep->children;
while (first != NULL) {
@@ -146,26 +148,269 @@ static xmlDocPtr dom_doc_from_context_node(xmlNodePtr contextNode)
}
}
-xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNode, zval *nodes, int nodesc)
+/* Citing from the docs (https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlAddChild):
+ * "Add a new node to @parent, at the end of the child (or property) list merging adjacent TEXT nodes (in which case @cur is freed)".
+ * So we must use a custom way of adding that does not merge. */
+static void dom_add_child_without_merging(xmlNodePtr parent, xmlNodePtr child)
+{
+ if (parent->children == NULL) {
+ parent->children = child;
+ } else {
+ xmlNodePtr last = parent->last;
+ last->next = child;
+ child->prev = last;
+ }
+ parent->last = child;
+ child->parent = parent;
+}
+
+static void dom_fragment_assign_parent_node(xmlNodePtr parentNode, xmlNodePtr fragment)
+{
+ xmlNodePtr node = fragment->children;
+
+ while (node != NULL) {
+ node->parent = parentNode;
+
+ if (node == fragment->last) {
+ break;
+ }
+ node = node->next;
+ }
+}
+
+/* This part is common logic between the pre-insertion validity and replaceChild code. */
+static bool dom_fragment_common_hierarchy_check_part(xmlNodePtr node, bool *seen_element)
+{
+ /* If node has more than one element child or has a Text node child. */
+ xmlNodePtr iter = node->children;
+ *seen_element = false;
+ while (iter != NULL) {
+ if (iter->type == XML_ELEMENT_NODE) {
+ if (*seen_element) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot have more than one element child in a document", /* strict */ true);
+ return false;
+ }
+ *seen_element = true;
+ } else if (iter->type == XML_TEXT_NODE || iter->type == XML_CDATA_SECTION_NODE) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot insert text as a child of a document", /* strict */ true);
+ return false;
+ }
+ iter = iter->next;
+ }
+ return true;
+}
+
+/* https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
+ * DocumentFragment validation part. */
+bool php_dom_fragment_insertion_hierarchy_check_pre_insertion(xmlNodePtr parent, xmlNodePtr node, xmlNodePtr child)
+{
+ bool seen_element;
+ if (!dom_fragment_common_hierarchy_check_part(node, &seen_element)) {
+ return false;
+ }
+
+ /* Otherwise, if node has one element child
+ * and either parent has an element child, child is a doctype, or child is non-null and a doctype is following child. */
+ if (seen_element) {
+ if (php_dom_has_child_of_type(parent, XML_ELEMENT_NODE)) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot have more than one element child in a document", /* strict */ true);
+ return false;
+ }
+
+ if (child != NULL && (child->type == XML_DTD_NODE || php_dom_has_sibling_following_node(child, XML_DTD_NODE))) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Document types must be the first child in a document", /* strict */ true);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* https://dom.spec.whatwg.org/#concept-node-replace
+ * DocumentFragment validation part. */
+bool php_dom_fragment_insertion_hierarchy_check_replace(xmlNodePtr parent, xmlNodePtr node, xmlNodePtr child)
+{
+ bool seen_element;
+ if (!dom_fragment_common_hierarchy_check_part(node, &seen_element)) {
+ return false;
+ }
+
+ /* Otherwise, if node has one element child
+ * and either parent has an element child that is not child or a doctype is following child. */
+ if (seen_element) {
+ xmlNodePtr iter = parent->children;
+ while (iter != NULL) {
+ if (iter->type == XML_ELEMENT_NODE && iter != child) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot have more than one element child in a document", /* strict */ true);
+ return false;
+ }
+ iter = iter->next;
+ }
+
+ ZEND_ASSERT(child != NULL);
+ if (php_dom_has_sibling_following_node(child, XML_DTD_NODE)) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Document types must be the first child in a document", /* strict */ true);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity */
+bool php_dom_pre_insert_is_parent_invalid(xmlNodePtr parent)
+{
+ return parent->type != XML_DOCUMENT_NODE
+ && parent->type != XML_HTML_DOCUMENT_NODE
+ && parent->type != XML_ELEMENT_NODE
+ && parent->type != XML_DOCUMENT_FRAG_NODE;
+}
+
+/* https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity */
+static bool dom_is_pre_insert_valid_without_step_1(php_libxml_ref_obj *document, xmlNodePtr parentNode, xmlNodePtr node, xmlNodePtr child, xmlDocPtr documentNode)
+{
+ ZEND_ASSERT(parentNode != NULL);
+
+ /* 1. If parent is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException.
+ * => Impossible */
+ ZEND_ASSERT(!php_dom_pre_insert_is_parent_invalid(parentNode));
+
+ if (node->doc != documentNode) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(document));
+ return false;
+ }
+
+ /* 3. If child is non-null and its parent is not parent, then throw a "NotFoundError" DOMException. */
+ if (child != NULL && child->parent != parentNode) {
+ php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(document));
+ return false;
+ }
+
+ bool parent_is_document = parentNode->type == XML_DOCUMENT_NODE || parentNode->type == XML_HTML_DOCUMENT_NODE;
+
+ if (/* 2. If node is a host-including inclusive ancestor of parent, then throw a "HierarchyRequestError" DOMException. */
+ dom_hierarchy(parentNode, node) != SUCCESS
+ /* 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException. */
+ || node->type == XML_ATTRIBUTE_NODE
+ || (php_dom_follow_spec_doc_ref(document) && (
+ node->type == XML_ENTITY_REF_NODE
+ || node->type == XML_ENTITY_NODE
+ || node->type == XML_NOTATION_NODE
+ || node->type == XML_DOCUMENT_NODE
+ || node->type == XML_HTML_DOCUMENT_NODE
+ || node->type >= XML_ELEMENT_DECL))) {
+ php_dom_throw_error(HIERARCHY_REQUEST_ERR, dom_get_strict_error(document));
+ return false;
+ }
+
+ if (php_dom_follow_spec_doc_ref(document)) {
+ /* 5. If either node is a Text node and parent is a document... */
+ if (parent_is_document && (node->type == XML_TEXT_NODE || node->type == XML_CDATA_SECTION_NODE)) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot insert text as a child of a document", /* strict */ true);
+ return false;
+ }
+
+ /* 5. ..., or node is a doctype and parent is not a document, then throw a "HierarchyRequestError" DOMException. */
+ if (!parent_is_document && node->type == XML_DTD_NODE) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot insert a document type into anything other than a document", /* strict */ true);
+ return false;
+ }
+
+ /* 6. If parent is a document, and any of the statements below, switched on the interface node implements,
+ * are true, then throw a "HierarchyRequestError" DOMException. */
+ if (parent_is_document) {
+ /* DocumentFragment */
+ if (node->type == XML_DOCUMENT_FRAG_NODE) {
+ if (!php_dom_fragment_insertion_hierarchy_check_pre_insertion(parentNode, node, child)) {
+ return false;
+ }
+ }
+ /* Element */
+ else if (node->type == XML_ELEMENT_NODE) {
+ /* parent has an element child, child is a doctype, or child is non-null and a doctype is following child. */
+ if (php_dom_has_child_of_type(parentNode, XML_ELEMENT_NODE)) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot have more than one element child in a document", /* strict */ true);
+ return false;
+ }
+ if (child != NULL && (child->type == XML_DTD_NODE || php_dom_has_sibling_following_node(child, XML_DTD_NODE))) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Document types must be the first child in a document", /* strict */ true);
+ return false;
+ }
+ }
+ /* DocumentType */
+ else if (node->type == XML_DTD_NODE) {
+ /* parent has a doctype child, child is non-null and an element is preceding child, or child is null and parent has an element child. */
+ if (php_dom_has_child_of_type(parentNode, XML_DTD_NODE)) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Cannot have more than one document type", /* strict */ true);
+ return false;
+ }
+ if ((child != NULL && php_dom_has_sibling_preceding_node(child, XML_ELEMENT_NODE))
+ || (child == NULL && php_dom_has_child_of_type(parentNode, XML_ELEMENT_NODE))) {
+ php_dom_throw_error_with_message(HIERARCHY_REQUEST_ERR, "Document types must be the first child in a document", /* strict */ true);
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+static void dom_free_node_after_zval_single_node_creation(xmlNodePtr node)
+{
+ /* For the object cases, the user did provide them, so they don't have to be freed as there are still references.
+ * For the newly created text nodes, we do have to free them. */
+ xmlNodePtr next;
+ for (xmlNodePtr child = node->children; child != NULL; child = next) {
+ next = child->next;
+ xmlUnlinkNode(child);
+ if (child->_private == NULL) {
+ xmlFreeNode(child);
+ }
+ }
+}
+
+/* https://dom.spec.whatwg.org/#converting-nodes-into-a-node */
+xmlNode* dom_zvals_to_single_node(php_libxml_ref_obj *document, xmlNode *contextNode, zval *nodes, uint32_t nodesc)
{
xmlDoc *documentNode;
- xmlNode *fragment;
xmlNode *newNode;
dom_object *newNodeObj;
documentNode = dom_doc_from_context_node(contextNode);
- fragment = xmlNewDocFragment(documentNode);
+ /* 1. Let node be null. */
+ xmlNodePtr node = NULL;
- if (!fragment) {
+ /* 2. => handled in the loop. */
+
+ /* 3. If nodes contains one node, then set node to nodes[0]. */
+ if (nodesc == 1) {
+ /* ... and return */
+ if (Z_TYPE_P(nodes) == IS_OBJECT) {
+ return dom_object_get_node(Z_DOMOBJ_P(nodes));
+ } else {
+ ZEND_ASSERT(Z_TYPE_P(nodes) == IS_STRING);
+ return xmlNewDocTextLen(documentNode, BAD_CAST Z_STRVAL_P(nodes), Z_STRLEN_P(nodes));
+ }
+ }
+
+ node = xmlNewDocFragment(documentNode);
+ if (UNEXPECTED(!node)) {
return NULL;
}
+ /* 4. Otherwise, set node to a new DocumentFragment node whose node document is document,
+ * and then append each node in nodes, if any, to it. */
for (uint32_t i = 0; i < nodesc; i++) {
if (Z_TYPE(nodes[i]) == IS_OBJECT) {
newNodeObj = Z_DOMOBJ_P(&nodes[i]);
newNode = dom_object_get_node(newNodeObj);
+ if (!dom_is_pre_insert_valid_without_step_1(document, node, newNode, NULL, documentNode)) {
+ goto err;
+ }
+
if (newNode->parent != NULL) {
xmlUnlinkNode(newNode);
}
@@ -173,99 +418,52 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
newNodeObj->document = document;
xmlSetTreeDoc(newNode, documentNode);
- /* Citing from the docs (https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlAddChild):
- * "Add a new node to @parent, at the end of the child (or property) list merging adjacent TEXT nodes (in which case @cur is freed)".
- * So we must take a copy if this situation arises to prevent a use-after-free. */
- bool will_free = newNode->type == XML_TEXT_NODE && fragment->last && fragment->last->type == XML_TEXT_NODE;
- if (will_free) {
- newNode = xmlCopyNode(newNode, 1);
- }
-
if (newNode->type == XML_DOCUMENT_FRAG_NODE) {
/* Unpack document fragment nodes, the behaviour differs for different libxml2 versions. */
newNode = newNode->children;
while (newNode) {
xmlNodePtr next = newNode->next;
xmlUnlinkNode(newNode);
- if (!xmlAddChild(fragment, newNode)) {
- goto err;
- }
+ dom_add_child_without_merging(node, newNode);
newNode = next;
}
- } else if (!xmlAddChild(fragment, newNode)) {
- if (will_free) {
- xmlFreeNode(newNode);
- }
- goto err;
+ } else {
+ dom_add_child_without_merging(node, newNode);
}
} else {
+ /* 2. Replace each string in nodes with a new Text node whose data is the string and node document is document. */
ZEND_ASSERT(Z_TYPE(nodes[i]) == IS_STRING);
- newNode = xmlNewDocText(documentNode, (xmlChar *) Z_STRVAL(nodes[i]));
-
- if (!xmlAddChild(fragment, newNode)) {
- xmlFreeNode(newNode);
- goto err;
- }
+ /* Text nodes can't violate the hierarchy at this point. */
+ newNode = xmlNewDocTextLen(documentNode, BAD_CAST Z_STRVAL(nodes[i]), Z_STRLEN(nodes[i]));
+ dom_add_child_without_merging(node, newNode);
}
}
- return fragment;
+ /* 5. Return node. */
+ return node;
err:
- xmlFreeNode(fragment);
+ /* For the object cases, the user did provide them, so they don't have to be freed as there are still references.
+ * For the newly created text nodes, we do have to free them. */
+ dom_free_node_after_zval_single_node_creation(node);
+ xmlFree(node);
return NULL;
}
-static void dom_fragment_assign_parent_node(xmlNodePtr parentNode, xmlNodePtr fragment)
-{
- xmlNodePtr node = fragment->children;
-
- while (node != NULL) {
- node->parent = parentNode;
-
- if (node == fragment->last) {
- break;
- }
- node = node->next;
- }
-
- fragment->children = NULL;
- fragment->last = NULL;
-}
-
-static zend_result dom_sanity_check_node_list_for_insertion(php_libxml_ref_obj *document, xmlNodePtr parentNode, zval *nodes, int nodesc)
+static zend_result dom_sanity_check_node_list_types(zval *nodes, int nodesc, zend_class_entry *node_ce)
{
- if (UNEXPECTED(parentNode == NULL)) {
- /* No error required, this must be a no-op per spec */
- return FAILURE;
- }
-
- xmlDocPtr documentNode = dom_doc_from_context_node(parentNode);
-
for (uint32_t i = 0; i < nodesc; i++) {
zend_uchar type = Z_TYPE(nodes[i]);
if (type == IS_OBJECT) {
const zend_class_entry *ce = Z_OBJCE(nodes[i]);
- if (instanceof_function(ce, dom_node_class_entry)) {
- xmlNodePtr node = dom_object_get_node(Z_DOMOBJ_P(nodes + i));
-
- if (node->doc != documentNode) {
- php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(document));
- return FAILURE;
- }
-
- if (node->type == XML_ATTRIBUTE_NODE || dom_hierarchy(parentNode, node) != SUCCESS) {
- php_dom_throw_error(HIERARCHY_REQUEST_ERR, dom_get_strict_error(document));
- return FAILURE;
- }
- } else {
- zend_argument_type_error(i + 1, "must be of type DOMNode|string, %s given", zend_zval_type_name(&nodes[i]));
+ if (!instanceof_function(ce, node_ce)) {
+ zend_argument_type_error(i + 1, "must be of type %s|string, %s given", ZSTR_VAL(node_ce->name), zend_zval_type_name(&nodes[i]));
return FAILURE;
}
} else if (type != IS_STRING) {
- zend_argument_type_error(i + 1, "must be of type DOMNode|string, %s given", zend_zval_type_name(&nodes[i]));
+ zend_argument_type_error(i + 1, "must be of type %s|string, %s given", ZSTR_VAL(node_ce->name), zend_zval_type_name(&nodes[i]));
return FAILURE;
}
}
@@ -273,7 +471,7 @@ static zend_result dom_sanity_check_node_list_for_insertion(php_libxml_ref_obj *
return SUCCESS;
}
-static void dom_pre_insert(xmlNodePtr insertion_point, xmlNodePtr parentNode, xmlNodePtr newchild, xmlNodePtr fragment)
+static void php_dom_pre_insert_helper(xmlNodePtr insertion_point, xmlNodePtr parentNode, xmlNodePtr newchild, xmlNodePtr last)
{
if (!insertion_point) {
/* Place it as last node */
@@ -285,61 +483,136 @@ static void dom_pre_insert(xmlNodePtr insertion_point, xmlNodePtr parentNode, xm
/* No children, because they moved out when they became a fragment */
parentNode->children = newchild;
}
- parentNode->last = fragment->last;
+ parentNode->last = last;
} else {
/* Insert fragment before insertion_point */
- fragment->last->next = insertion_point;
+ last->next = insertion_point;
if (insertion_point->prev) {
insertion_point->prev->next = newchild;
newchild->prev = insertion_point->prev;
}
- insertion_point->prev = fragment->last;
+ insertion_point->prev = last;
if (parentNode->children == insertion_point) {
parentNode->children = newchild;
}
}
}
-void dom_parent_node_append(dom_object *context, zval *nodes, uint32_t nodesc)
+static void dom_insert_node_list_cleanup(xmlNodePtr node)
{
- xmlNode *parentNode = dom_object_get_node(context);
- xmlNodePtr newchild, prevsib;
-
- if (UNEXPECTED(dom_sanity_check_node_list_for_insertion(context->document, parentNode, nodes, nodesc) != SUCCESS)) {
+ if (node->_private != NULL) {
+ /* Not a temporary node. */
return;
}
+ if (node->type == XML_DOCUMENT_FRAG_NODE) {
+ dom_free_node_after_zval_single_node_creation(node);
+ xmlFree(node); /* Don't free the children, now-empty fragment! */
+ } else if (node->type == XML_TEXT_NODE) {
+ ZEND_ASSERT(node->parent == NULL);
+ xmlFreeNode(node);
+ } else {
+ /* Must have been a directly-passed node. */
+ ZEND_ASSERT(node->_private != NULL);
+ }
+}
- php_libxml_invalidate_node_list_cache(context->document);
+/* https://dom.spec.whatwg.org/#concept-node-pre-insert */
+static void dom_insert_node_list_unchecked(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePtr parent, xmlNodePtr insertion_point)
+{
+ /* Step 1 should be checked by the caller. */
- xmlNode *fragment = dom_zvals_to_fragment(context->document, parentNode, nodes, nodesc);
+ if (node->type == XML_DOCUMENT_FRAG_NODE) {
+ /* Steps 2-3 are not applicable here, the condition is impossible. */
- if (fragment == NULL) {
- return;
- }
+ xmlNodePtr newchild = node->children;
- newchild = fragment->children;
- prevsib = parentNode->last;
+ /* 4. Insert node into parent before referenceChild (i.e. insertion_point here because of the impossible condition). */
+ if (newchild) {
+ xmlNodePtr last = node->last;
+ php_dom_pre_insert_helper(insertion_point, parent, newchild, last);
+ dom_fragment_assign_parent_node(parent, node);
+ if (!php_dom_follow_spec_doc_ref(document)) {
+ dom_reconcile_ns_list(parent->doc, newchild, last);
+ }
+ if (parent->doc && newchild->type == XML_DTD_NODE) {
+ parent->doc->intSubset = (xmlDtdPtr) newchild;
+ newchild->parent = (xmlNodePtr) parent->doc;
+ }
+ }
- if (newchild) {
- if (prevsib != NULL) {
- prevsib->next = newchild;
+ if (node->_private == NULL) {
+ xmlFree(node);
} else {
- parentNode->children = newchild;
+ node->children = NULL;
+ node->last = NULL;
+ }
+ } else {
+ /* 2. Let referenceChild be child.
+ * 3. If referenceChild is node, then set referenceChild to node’s next sibling. */
+ if (insertion_point == node) {
+ insertion_point = node->next;
}
- xmlNodePtr last = fragment->last;
- parentNode->last = last;
+ /* 4. Insert node into parent before referenceChild. */
+ xmlUnlinkNode(node);
+ php_dom_pre_insert_helper(insertion_point, parent, node, node);
+ node->parent = parent;
+ if (parent->doc && node->type == XML_DTD_NODE) {
+ parent->doc->intSubset = (xmlDtdPtr) node;
+ node->parent = (xmlNodePtr) parent->doc;
+ } else {
+ if (!php_dom_follow_spec_doc_ref(document)) {
+ dom_reconcile_ns(parent->doc, node);
+ }
+ }
+ }
+}
- newchild->prev = prevsib;
+/* https://dom.spec.whatwg.org/#concept-node-pre-insert */
+bool php_dom_pre_insert(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePtr parent, xmlNodePtr insertion_point)
+{
+ if (UNEXPECTED(node == NULL)) {
+ return false;
+ }
+
+ /* Step 1 checked here, other steps delegated to other function. */
+ if (dom_is_pre_insert_valid_without_step_1(document, parent, node, insertion_point, parent->doc)) {
+ dom_insert_node_list_unchecked(document, node, parent, insertion_point);
+ return true;
+ } else {
+ dom_insert_node_list_cleanup(node);
+ return false;
+ }
+}
+
+/* https://dom.spec.whatwg.org/#concept-node-append */
+void php_dom_node_append(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePtr parent)
+{
+ php_dom_pre_insert(document, node, parent, NULL);
+}
+
+/* https://dom.spec.whatwg.org/#dom-parentnode-append */
+void dom_parent_node_append(dom_object *context, zval *nodes, uint32_t nodesc)
+{
+ if (UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(context->document))) != SUCCESS)) {
+ return;
+ }
- dom_fragment_assign_parent_node(parentNode, fragment);
+ xmlNode *parentNode = dom_object_get_node(context);
+
+ php_libxml_invalidate_node_list_cache(context->document);
- dom_reconcile_ns_list(parentNode->doc, newchild, last);
+ /* 1. Let node be the result of converting nodes into a node given nodes and this’s node document. */
+ xmlNodePtr node = dom_zvals_to_single_node(context->document, parentNode, nodes, nodesc);
+ if (UNEXPECTED(node == NULL)) {
+ return;
}
- xmlFree(fragment);
+ /* 2. Append node to this. */
+ php_dom_node_append(context->document, node, parentNode);
}
+/* https://dom.spec.whatwg.org/#dom-parentnode-prepend */
void dom_parent_node_prepend(dom_object *context, zval *nodes, uint32_t nodesc)
{
xmlNode *parentNode = dom_object_get_node(context);
@@ -349,141 +622,91 @@ void dom_parent_node_prepend(dom_object *context, zval *nodes, uint32_t nodesc)
return;
}
- if (UNEXPECTED(dom_sanity_check_node_list_for_insertion(context->document, parentNode, nodes, nodesc) != SUCCESS)) {
+ if (UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(context->document))) != SUCCESS)) {
return;
}
php_libxml_invalidate_node_list_cache(context->document);
- xmlNode *fragment = dom_zvals_to_fragment(context->document, parentNode, nodes, nodesc);
-
- if (fragment == NULL) {
+ /* 1. Let node be the result of converting nodes into a node given nodes and this’s node document. */
+ xmlNodePtr node = dom_zvals_to_single_node(context->document, parentNode, nodes, nodesc);
+ if (UNEXPECTED(node == NULL)) {
return;
}
- xmlNode *newchild = fragment->children;
-
- if (newchild) {
- xmlNodePtr last = fragment->last;
-
- dom_pre_insert(parentNode->children, parentNode, newchild, fragment);
-
- dom_fragment_assign_parent_node(parentNode, fragment);
-
- dom_reconcile_ns_list(parentNode->doc, newchild, last);
- }
-
- xmlFree(fragment);
+ /* 2. Pre-insert node into this before this’s first child. */
+ php_dom_pre_insert(context->document, node, parentNode, parentNode->children);
}
+/* https://dom.spec.whatwg.org/#dom-childnode-after */
void dom_parent_node_after(dom_object *context, zval *nodes, uint32_t nodesc)
{
- /* Spec link: https://dom.spec.whatwg.org/#dom-childnode-after */
+ if (UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(context->document))) != SUCCESS)) {
+ return;
+ }
- xmlNode *prevsib = dom_object_get_node(context);
- xmlNodePtr newchild, parentNode;
- xmlNode *fragment;
- xmlDoc *doc;
+ xmlNode *thisp = dom_object_get_node(context);
- /* Spec step 1 */
- parentNode = prevsib->parent;
+ /* 1. Let parent be this’s parent. */
+ xmlNodePtr parentNode = thisp->parent;
- /* Sanity check for fragment, includes spec step 2 */
- if (UNEXPECTED(dom_sanity_check_node_list_for_insertion(context->document, parentNode, nodes, nodesc) != SUCCESS)) {
+ /* 2. If parent is null, then return. */
+ if (UNEXPECTED(parentNode == NULL)) {
return;
}
- /* Spec step 3: find first following child not in nodes; otherwise null */
- xmlNodePtr viable_next_sibling = prevsib->next;
- while (viable_next_sibling) {
- if (!dom_is_node_in_list(nodes, nodesc, viable_next_sibling)) {
- break;
- }
+ /* 3. Let viableNextSibling be this’s first following sibling not in nodes; otherwise null. */
+ xmlNodePtr viable_next_sibling = thisp->next;
+ while (viable_next_sibling && dom_is_node_in_list(nodes, nodesc, viable_next_sibling)) {
viable_next_sibling = viable_next_sibling->next;
}
- doc = prevsib->doc;
-
php_libxml_invalidate_node_list_cache(context->document);
- /* Spec step 4: convert nodes into fragment */
- fragment = dom_zvals_to_fragment(context->document, parentNode, nodes, nodesc);
-
- if (fragment == NULL) {
- return;
- }
-
- newchild = fragment->children;
-
- if (newchild) {
- xmlNodePtr last = fragment->last;
+ /* 4. Let node be the result of converting nodes into a node, given nodes and this’s node document. */
+ xmlNodePtr fragment = dom_zvals_to_single_node(context->document, parentNode, nodes, nodesc);
- /* Step 5: place fragment into the parent before viable_next_sibling */
- dom_pre_insert(viable_next_sibling, parentNode, newchild, fragment);
-
- dom_fragment_assign_parent_node(parentNode, fragment);
- dom_reconcile_ns_list(doc, newchild, last);
- }
-
- xmlFree(fragment);
+ /* 5. Pre-insert node into parent before viableNextSibling. */
+ php_dom_pre_insert(context->document, fragment, parentNode, viable_next_sibling);
}
+/* https://dom.spec.whatwg.org/#dom-childnode-before */
void dom_parent_node_before(dom_object *context, zval *nodes, uint32_t nodesc)
{
- /* Spec link: https://dom.spec.whatwg.org/#dom-childnode-before */
+ if (UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(context->document))) != SUCCESS)) {
+ return;
+ }
- xmlNode *nextsib = dom_object_get_node(context);
- xmlNodePtr newchild, parentNode;
- xmlNode *fragment;
- xmlDoc *doc;
+ xmlNode *thisp = dom_object_get_node(context);
- /* Spec step 1 */
- parentNode = nextsib->parent;
+ /* 1. Let parent be this’s parent. */
+ xmlNodePtr parentNode = thisp->parent;
- /* Sanity check for fragment, includes spec step 2 */
- if (UNEXPECTED(dom_sanity_check_node_list_for_insertion(context->document, parentNode, nodes, nodesc) != SUCCESS)) {
+ /* 2. If parent is null, then return. */
+ if (UNEXPECTED(parentNode == NULL)) {
return;
}
- /* Spec step 3: find first following child not in nodes; otherwise null */
- xmlNodePtr viable_previous_sibling = nextsib->prev;
- while (viable_previous_sibling) {
- if (!dom_is_node_in_list(nodes, nodesc, viable_previous_sibling)) {
- break;
- }
+ /* 3. Let viablePreviousSibling be this’s first preceding sibling not in nodes; otherwise null. */
+ xmlNodePtr viable_previous_sibling = thisp->prev;
+ while (viable_previous_sibling && dom_is_node_in_list(nodes, nodesc, viable_previous_sibling)) {
viable_previous_sibling = viable_previous_sibling->prev;
}
- doc = nextsib->doc;
-
php_libxml_invalidate_node_list_cache(context->document);
- /* Spec step 4: convert nodes into fragment */
- fragment = dom_zvals_to_fragment(context->document, parentNode, nodes, nodesc);
-
- if (fragment == NULL) {
- return;
- }
-
- newchild = fragment->children;
-
- if (newchild) {
- xmlNodePtr last = fragment->last;
+ /* 4. Let node be the result of converting nodes into a node, given nodes and this’s node document. */
+ xmlNodePtr fragment = dom_zvals_to_single_node(context->document, parentNode, nodes, nodesc);
- /* Step 5: if viable_previous_sibling is null, set it to the parent's first child, otherwise viable_previous_sibling's next sibling */
- if (!viable_previous_sibling) {
- viable_previous_sibling = parentNode->children;
- } else {
- viable_previous_sibling = viable_previous_sibling->next;
- }
- /* Step 6: place fragment into the parent after viable_previous_sibling */
- dom_pre_insert(viable_previous_sibling, parentNode, newchild, fragment);
-
- dom_fragment_assign_parent_node(parentNode, fragment);
- dom_reconcile_ns_list(doc, newchild, last);
+ /* 5. If viable_previous_sibling is null, set it to the parent's first child, otherwise viable_previous_sibling's next sibling. */
+ if (!viable_previous_sibling) {
+ viable_previous_sibling = parentNode->children;
+ } else {
+ viable_previous_sibling = viable_previous_sibling->next;
}
- xmlFree(fragment);
+ /* 6. Pre-insert node into parent before viablePreviousSibling. */
+ php_dom_pre_insert(context->document, fragment, parentNode, viable_previous_sibling);
}
static zend_result dom_child_removal_preconditions(const xmlNodePtr child, int stricterror)
@@ -499,7 +722,7 @@ static zend_result dom_child_removal_preconditions(const xmlNodePtr child, int s
return FAILURE;
}
- if (dom_node_children_valid(child->parent) == FAILURE) {
+ if (!dom_node_children_valid(child->parent)) {
return FAILURE;
}
@@ -528,95 +751,80 @@ void dom_child_node_remove(dom_object *context)
xmlUnlinkNode(child);
}
+/* https://dom.spec.whatwg.org/#dom-childnode-replacewith */
void dom_child_replace_with(dom_object *context, zval *nodes, uint32_t nodesc)
{
- /* Spec link: https://dom.spec.whatwg.org/#dom-childnode-replacewith */
+ if (UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(context->document))) != SUCCESS)) {
+ return;
+ }
xmlNodePtr child = dom_object_get_node(context);
- /* Spec step 1 */
+ /* 1. Let parent be this’s parent. */
xmlNodePtr parentNode = child->parent;
- /* Sanity check for fragment, includes spec step 2 */
- if (UNEXPECTED(dom_sanity_check_node_list_for_insertion(context->document, parentNode, nodes, nodesc) != SUCCESS)) {
- return;
- }
-
- int stricterror = dom_get_strict_error(context->document);
- if (UNEXPECTED(dom_child_removal_preconditions(child, stricterror) != SUCCESS)) {
+ /* 2. If parent is null, then return. */
+ if (UNEXPECTED(parentNode == NULL)) {
return;
}
- /* Spec step 3: find first following child not in nodes; otherwise null */
+ /* 3. Let viableNextSibling be this’s first following sibling not in nodes; otherwise null. */
xmlNodePtr viable_next_sibling = child->next;
- while (viable_next_sibling) {
- if (!dom_is_node_in_list(nodes, nodesc, viable_next_sibling)) {
- break;
- }
+ while (viable_next_sibling && dom_is_node_in_list(nodes, nodesc, viable_next_sibling)) {
viable_next_sibling = viable_next_sibling->next;
}
- xmlDocPtr doc = parentNode->doc;
- php_libxml_invalidate_node_list_cache(context->document);
-
- /* Spec step 4: convert nodes into fragment */
- xmlNodePtr fragment = dom_zvals_to_fragment(context->document, parentNode, nodes, nodesc);
- if (UNEXPECTED(fragment == NULL)) {
+ bool stricterror = dom_get_strict_error(context->document);
+ if (UNEXPECTED(dom_child_removal_preconditions(child, stricterror) != SUCCESS)) {
return;
}
- /* Spec step 5: perform the replacement */
-
- xmlNodePtr newchild = fragment->children;
+ php_libxml_invalidate_node_list_cache(context->document);
- /* Unlink it unless it became a part of the fragment.
- * Freeing will be taken care of by the lifetime of the returned dom object. */
- if (child->parent != fragment) {
- xmlUnlinkNode(child);
+ /* 4. Let node be the result of converting nodes into a node, given nodes and this’s node document. */
+ xmlNodePtr node = dom_zvals_to_single_node(context->document, parentNode, nodes, nodesc);
+ if (UNEXPECTED(node == NULL)) {
+ return;
}
- if (newchild) {
- xmlNodePtr last = fragment->last;
-
- dom_pre_insert(viable_next_sibling, parentNode, newchild, fragment);
+ /* Spec step 5-6: perform the replacement */
+ if (dom_is_pre_insert_valid_without_step_1(context->document, parentNode, node, viable_next_sibling, parentNode->doc)) {
+ /* Unlink it unless it became a part of the fragment.
+ * Freeing will be taken care of by the lifetime of the returned dom object. */
+ if (child->parent != node) {
+ xmlUnlinkNode(child);
+ }
- dom_fragment_assign_parent_node(parentNode, fragment);
- dom_reconcile_ns_list(doc, newchild, last);
+ dom_insert_node_list_unchecked(context->document, node, parentNode, viable_next_sibling);
+ } else {
+ dom_insert_node_list_cleanup(node);
}
-
- xmlFree(fragment);
}
+/* https://dom.spec.whatwg.org/#dom-parentnode-replacechildren */
void dom_parent_node_replace_children(dom_object *context, zval *nodes, uint32_t nodesc)
{
- /* Spec link: https://dom.spec.whatwg.org/#dom-parentnode-replacechildren */
-
- xmlNodePtr thisp = dom_object_get_node(context);
- /* Note: Only rule 2 of pre-insertion validity can be broken */
- if (UNEXPECTED(dom_sanity_check_node_list_for_insertion(context->document, thisp, nodes, nodesc) != SUCCESS)) {
+ if (UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(context->document))) != SUCCESS)) {
return;
}
- xmlNodePtr fragment = dom_zvals_to_fragment(context->document, thisp, nodes, nodesc);
- if (UNEXPECTED(fragment == NULL)) {
- return;
- }
+ xmlNodePtr thisp = dom_object_get_node(context);
php_libxml_invalidate_node_list_cache(context->document);
- dom_remove_all_children(thisp);
-
- xmlNodePtr newchild = fragment->children;
- if (newchild) {
- xmlNodePtr last = fragment->last;
-
- dom_pre_insert(NULL, thisp, newchild, fragment);
-
- dom_fragment_assign_parent_node(thisp, fragment);
- dom_reconcile_ns_list(thisp->doc, newchild, last);
+ /* 1. Let node be the result of converting nodes into a node given nodes and this’s node document. */
+ xmlNodePtr node = dom_zvals_to_single_node(context->document, thisp, nodes, nodesc);
+ if (UNEXPECTED(node == NULL)) {
+ return;
}
- xmlFree(fragment);
+ /* Spec steps 2-3: replace all */
+ if (dom_is_pre_insert_valid_without_step_1(context->document, thisp, node, NULL, thisp->doc)) {
+ dom_remove_all_children(thisp);
+ php_dom_pre_insert(context->document, node, thisp, NULL);
+ } else {
+ dom_insert_node_list_cleanup(node);
+ }
}
#endif
diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c
index 1c7e2691742fd..be3ef067876fe 100644
--- a/ext/dom/php_dom.c
+++ b/ext/dom/php_dom.c
@@ -23,6 +23,8 @@
#include "php.h"
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
#include "php_dom.h"
+#include "namespace_compat.h"
+#include "internal_helpers.h"
#include "php_dom_arginfo.h"
#include "dom_properties.h"
#include "zend_interfaces.h"
@@ -33,38 +35,62 @@
/* {{{ class entries */
PHP_DOM_EXPORT zend_class_entry *dom_node_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_node_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_domexception_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_parentnode_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_parentnode_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_childnode_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_childnode_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_domimplementation_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_domimplementation_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_documentfragment_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_documentfragment_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_document_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_html_document_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_xml_document_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_nodelist_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_nodelist_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_namednodemap_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_namednodemap_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_dtd_namednodemap_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_html_collection_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_characterdata_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_characterdata_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_attr_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_attr_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_element_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_element_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_text_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_text_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_comment_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_comment_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_cdatasection_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_cdatasection_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_documenttype_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_documenttype_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_notation_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_notation_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_entity_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_entity_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_entityreference_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_entityreference_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_processinginstruction_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_processinginstruction_class_entry;
PHP_DOM_EXPORT zend_class_entry *dom_abstract_base_document_class_entry;
#ifdef LIBXML_XPATH_ENABLED
PHP_DOM_EXPORT zend_class_entry *dom_xpath_class_entry;
+PHP_DOM_EXPORT zend_class_entry *dom_modern_xpath_class_entry;
#endif
PHP_DOM_EXPORT zend_class_entry *dom_namespace_node_class_entry;
/* }}} */
-zend_object_handlers dom_object_handlers;
-zend_object_handlers dom_nnodemap_object_handlers;
-zend_object_handlers dom_nodelist_object_handlers;
-zend_object_handlers dom_object_namespace_node_handlers;
+static zend_object_handlers dom_object_handlers;
+static zend_object_handlers dom_nnodemap_object_handlers;
+static zend_object_handlers dom_nodelist_object_handlers;
+static zend_object_handlers dom_modern_nnodemap_object_handlers;
+static zend_object_handlers dom_modern_nodelist_object_handlers;
+static zend_object_handlers dom_object_namespace_node_handlers;
+static zend_object_handlers dom_modern_domimplementation_object_handlers;
#ifdef LIBXML_XPATH_ENABLED
zend_object_handlers dom_xpath_object_handlers;
#endif
@@ -73,19 +99,30 @@ static HashTable classes;
/* {{{ prop handler tables */
static HashTable dom_document_prop_handlers;
static HashTable dom_xml_document_prop_handlers;
-static HashTable dom_html_document_prop_handlers;
+static HashTable dom_abstract_base_document_prop_handlers;
static HashTable dom_documentfragment_prop_handlers;
+static HashTable dom_modern_documentfragment_prop_handlers;
static HashTable dom_node_prop_handlers;
+static HashTable dom_modern_node_prop_handlers;
static HashTable dom_nodelist_prop_handlers;
static HashTable dom_namednodemap_prop_handlers;
static HashTable dom_characterdata_prop_handlers;
+static HashTable dom_modern_characterdata_prop_handlers;
static HashTable dom_attr_prop_handlers;
+static HashTable dom_modern_attr_prop_handlers;
static HashTable dom_element_prop_handlers;
+static HashTable dom_modern_element_prop_handlers;
+static HashTable dom_modern_element_prop_handlers;
static HashTable dom_text_prop_handlers;
+static HashTable dom_modern_text_prop_handlers;
static HashTable dom_documenttype_prop_handlers;
+static HashTable dom_modern_documenttype_prop_handlers;
static HashTable dom_notation_prop_handlers;
+static HashTable dom_modern_notation_prop_handlers;
static HashTable dom_entity_prop_handlers;
+static HashTable dom_modern_entity_prop_handlers;
static HashTable dom_processinginstruction_prop_handlers;
+static HashTable dom_modern_processinginstruction_prop_handlers;
static HashTable dom_namespace_node_prop_handlers;
#ifdef LIBXML_XPATH_ENABLED
static HashTable dom_xpath_prop_handlers;
@@ -128,8 +165,7 @@ int dom_node_is_read_only(xmlNodePtr node) {
}
/* }}} end dom_node_is_read_only */
-/* {{{ int dom_node_children_valid(xmlNodePtr node) */
-int dom_node_children_valid(xmlNodePtr node) {
+bool dom_node_children_valid(xmlNodePtr node) {
switch (node->type) {
case XML_DOCUMENT_TYPE_NODE:
case XML_DTD_NODE:
@@ -138,13 +174,11 @@ int dom_node_children_valid(xmlNodePtr node) {
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_NOTATION_NODE:
- return FAILURE;
- break;
+ return false;
default:
- return SUCCESS;
+ return true;
}
}
-/* }}} end dom_node_children_valid */
static const libxml_doc_props default_doc_props = {
.formatoutput = false,
@@ -184,7 +218,7 @@ libxml_doc_props const* dom_get_doc_props_read_only(const php_libxml_ref_obj *do
}
}
-static void dom_copy_doc_props(php_libxml_ref_obj *source_doc, php_libxml_ref_obj *dest_doc)
+static void dom_copy_document_ref(php_libxml_ref_obj *source_doc, php_libxml_ref_obj *dest_doc)
{
dom_doc_propsptr dest;
@@ -206,7 +240,7 @@ static void dom_copy_doc_props(php_libxml_ref_obj *source_doc, php_libxml_ref_ob
zend_hash_copy(dest->classmap, source->classmap, NULL);
}
- dest_doc->is_modern_api_class = source_doc->is_modern_api_class;
+ dest_doc->class_type = source_doc->class_type;
}
}
@@ -282,11 +316,21 @@ static void dom_register_prop_handler(HashTable *prop_handler, const char *name,
zend_string_release_ex(str, true);
}
+static void dom_overwrite_prop_handler(HashTable *prop_handler, const char *name, size_t name_len, const dom_prop_handler *hnd)
+{
+ zend_hash_str_update_ptr(prop_handler, name, name_len, (void *) hnd);
+}
+
#define DOM_REGISTER_PROP_HANDLER(prop_handler, name, prop_read_func, prop_write_func) do { \
static const dom_prop_handler hnd = {.read_func = prop_read_func, .write_func = prop_write_func}; \
dom_register_prop_handler(prop_handler, "" name, sizeof("" name) - 1, &hnd); \
} while (0)
+#define DOM_OVERWRITE_PROP_HANDLER(prop_handler, name, prop_read_func, prop_write_func) do { \
+ static const dom_prop_handler hnd = {.read_func = prop_read_func, .write_func = prop_write_func}; \
+ dom_overwrite_prop_handler(prop_handler, "" name, sizeof("" name) - 1, &hnd); \
+ } while (0)
+
static zval *dom_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot)
{
dom_object *obj = php_dom_obj_from_obj(object);
@@ -335,23 +379,20 @@ zval *dom_write_property(zend_object *object, zend_string *name, zval *value, vo
if (hnd) {
if (!hnd->write_func) {
- zend_throw_error(NULL, "Cannot write read-only property %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
+ zend_throw_error(NULL, "Cannot modify readonly property %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
return &EG(error_zval);
}
zend_property_info *prop = zend_get_property_info(object->ce, name, /* silent */ true);
- if (prop && ZEND_TYPE_IS_SET(prop->type)) {
- zval tmp;
- ZVAL_COPY(&tmp, value);
- if (!zend_verify_property_type(prop, &tmp, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)))) {
- zval_ptr_dtor(&tmp);
- return &EG(error_zval);
- }
- hnd->write_func(obj, &tmp);
+ ZEND_ASSERT(prop && ZEND_TYPE_IS_SET(prop->type));
+ zval tmp;
+ ZVAL_COPY(&tmp, value);
+ if (!zend_verify_property_type(prop, &tmp, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)))) {
zval_ptr_dtor(&tmp);
- } else {
- hnd->write_func(obj, value);
+ return &EG(error_zval);
}
+ hnd->write_func(obj, &tmp);
+ zval_ptr_dtor(&tmp);
return value;
}
@@ -456,7 +497,7 @@ void *php_dom_export_node(zval *object) /* {{{ */
/* }}} */
/* {{{ Get a simplexml_element object from dom to allow for processing */
-PHP_FUNCTION(dom_import_simplexml)
+static void dom_import_simplexml_common(INTERNAL_FUNCTION_PARAMETERS, php_libxml_class_type new_class)
{
zval *node;
xmlNodePtr nodep = NULL;
@@ -470,17 +511,55 @@ PHP_FUNCTION(dom_import_simplexml)
nodeobj = (php_libxml_node_object *) ((char *) Z_OBJ_P(node) - Z_OBJ_HT_P(node)->offset);
nodep = php_libxml_import_node(node);
- if (nodep && nodeobj && (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE)) {
+ if (nodep && nodeobj && nodeobj->document && (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE)) {
+ php_libxml_class_type old_class_type = nodeobj->document->class_type;
+ if (old_class_type != PHP_LIBXML_CLASS_UNSET && old_class_type != new_class) {
+ if (new_class == PHP_LIBXML_CLASS_MODERN) {
+ zend_argument_type_error(1, "must not be already imported as a DOMNode");
+ } else {
+ zend_argument_type_error(1, "must not be already imported as a DOM\\Node");
+ }
+ RETURN_THROWS();
+ }
+
+ /* Lock the node class type to prevent creating multiple representations of the same node. */
+ nodeobj->document->class_type = new_class;
+
+ if (old_class_type != PHP_LIBXML_CLASS_MODERN && new_class == PHP_LIBXML_CLASS_MODERN && nodep->doc != NULL) {
+ dom_document_convert_to_modern(nodeobj->document, nodep->doc);
+ }
+
DOM_RET_OBJ((xmlNodePtr) nodep, &ret, (dom_object *)nodeobj);
} else {
- zend_argument_value_error(1, "is not a valid node type");
+ zend_argument_type_error(1, "is not a valid node type");
RETURN_THROWS();
}
}
+
+PHP_FUNCTION(dom_import_simplexml)
+{
+ dom_import_simplexml_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LIBXML_CLASS_LEGACY);
+}
+
+PHP_FUNCTION(DOM_import_simplexml)
+{
+ dom_import_simplexml_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LIBXML_CLASS_MODERN);
+}
/* }}} */
static dom_object* dom_objects_set_class(zend_class_entry *class_type);
+void php_dom_update_document_after_clone(dom_object *original, xmlNodePtr original_node, dom_object *clone, xmlNodePtr cloned_node)
+{
+ dom_copy_document_ref(original->document, clone->document);
+ /* Workaround libxml2 bug, see https://gitlab.gnome.org/GNOME/libxml2/-/commit/07920b4381873187c02df53fa9b5d44aff3a7041 */
+#if LIBXML_VERSION < 20911
+ if (original_node->type == XML_HTML_DOCUMENT_NODE) {
+ cloned_node->type = XML_HTML_DOCUMENT_NODE;
+ }
+#endif
+}
+
static void dom_update_refcount_after_clone(dom_object *original, xmlNodePtr original_node, dom_object *clone, xmlNodePtr cloned_node)
{
/* If we cloned a document then we must create new doc proxy */
@@ -490,13 +569,7 @@ static void dom_update_refcount_after_clone(dom_object *original, xmlNodePtr ori
php_libxml_increment_doc_ref((php_libxml_node_object *)clone, cloned_node->doc);
php_libxml_increment_node_ptr((php_libxml_node_object *)clone, cloned_node, (void *)clone);
if (original->document != clone->document) {
- dom_copy_doc_props(original->document, clone->document);
- /* Workaround libxml2 bug, see https://gitlab.gnome.org/GNOME/libxml2/-/commit/07920b4381873187c02df53fa9b5d44aff3a7041 */
-#if LIBXML_VERSION < 20911
- if (original_node->type == XML_HTML_DOCUMENT_NODE) {
- cloned_node->type = XML_HTML_DOCUMENT_NODE;
- }
-#endif
+ php_dom_update_document_after_clone(original, original_node, clone, cloned_node);
}
}
@@ -505,16 +578,23 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
dom_object *intern = php_dom_obj_from_obj(zobject);
dom_object *clone = dom_objects_set_class(intern->std.ce);
- clone->std.handlers = &dom_object_handlers;
-
- if (instanceof_function(intern->std.ce, dom_node_class_entry)) {
+ if (instanceof_function(intern->std.ce, dom_node_class_entry) || instanceof_function(intern->std.ce, dom_modern_node_class_entry)) {
xmlNodePtr node = (xmlNodePtr)dom_object_get_node(intern);
if (node != NULL) {
- xmlNodePtr cloned_node = xmlDocCopyNode(node, node->doc, 1);
+ php_dom_libxml_ns_mapper *ns_mapper = NULL;
+ if (php_dom_follow_spec_intern(intern)) {
+ if (node->type == XML_DOCUMENT_NODE || node->type == XML_HTML_DOCUMENT_NODE) {
+ ns_mapper = php_dom_libxml_ns_mapper_create();
+ } else {
+ ns_mapper = php_dom_get_ns_mapper(intern);
+ }
+ }
+
+ xmlNodePtr cloned_node = dom_clone_node(ns_mapper, node, node->doc, true);
if (cloned_node != NULL) {
dom_update_refcount_after_clone(intern, node, clone, cloned_node);
}
-
+ clone->document->private_data = php_dom_libxml_ns_mapper_header(ns_mapper);
}
}
@@ -575,6 +655,10 @@ static zval *dom_nodelist_read_dimension(zend_object *object, zval *offset, int
static int dom_nodelist_has_dimension(zend_object *object, zval *member, int check_empty);
static zval *dom_nodemap_read_dimension(zend_object *object, zval *offset, int type, zval *rv);
static int dom_nodemap_has_dimension(zend_object *object, zval *member, int check_empty);
+static zval *dom_modern_nodemap_read_dimension(zend_object *object, zval *offset, int type, zval *rv);
+static int dom_modern_nodemap_has_dimension(zend_object *object, zval *member, int check_empty);
+static zval *dom_modern_nodelist_read_dimension(zend_object *object, zval *offset, int type, zval *rv);
+static int dom_modern_nodelist_has_dimension(zend_object *object, zval *member, int check_empty);
static zend_object *dom_objects_store_clone_obj(zend_object *zobject);
#ifdef LIBXML_XPATH_ENABLED
@@ -598,22 +682,6 @@ static void dom_free(void *ptr) {
efree(ptr);
}
-static void register_nondeprecated_xml_props(HashTable *table)
-{
- DOM_REGISTER_PROP_HANDLER(table, "encoding", dom_document_encoding_read, dom_document_encoding_write);
- DOM_REGISTER_PROP_HANDLER(table, "xmlEncoding", dom_document_encoding_read, NULL);
- DOM_REGISTER_PROP_HANDLER(table, "standalone", dom_document_standalone_read, dom_document_standalone_write);
- DOM_REGISTER_PROP_HANDLER(table, "xmlStandalone", dom_document_standalone_read, dom_document_standalone_write);
- DOM_REGISTER_PROP_HANDLER(table, "version", dom_document_version_read, dom_document_version_write);
- DOM_REGISTER_PROP_HANDLER(table, "xmlVersion", dom_document_version_read, dom_document_version_write);
- DOM_REGISTER_PROP_HANDLER(table, "formatOutput", dom_document_format_output_read, dom_document_format_output_write);
- DOM_REGISTER_PROP_HANDLER(table, "validateOnParse", dom_document_validate_on_parse_read, dom_document_validate_on_parse_write);
- DOM_REGISTER_PROP_HANDLER(table, "resolveExternals", dom_document_resolve_externals_read, dom_document_resolve_externals_write);
- DOM_REGISTER_PROP_HANDLER(table, "preserveWhiteSpace", dom_document_preserve_whitespace_read, dom_document_preserve_whitespace_write);
- DOM_REGISTER_PROP_HANDLER(table, "recover", dom_document_recover_read, dom_document_recover_write);
- DOM_REGISTER_PROP_HANDLER(table, "substituteEntities", dom_document_substitue_entities_read, dom_document_substitue_entities_write);
-}
-
/* {{{ PHP_MINIT_FUNCTION(dom) */
PHP_MINIT_FUNCTION(dom)
{
@@ -627,6 +695,11 @@ PHP_MINIT_FUNCTION(dom)
dom_object_handlers.has_property = dom_property_exists;
dom_object_handlers.get_debug_info = dom_get_debug_info;
+ memcpy(&dom_modern_domimplementation_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
+ /* The IDL has the [SameObject] constraint, which is incompatible with cloning because it imposes that there is only
+ * one instance per parent object. */
+ dom_modern_domimplementation_object_handlers.clone_obj = NULL;
+
memcpy(&dom_nnodemap_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
dom_nnodemap_object_handlers.free_obj = dom_nnodemap_objects_free_storage;
dom_nnodemap_object_handlers.read_dimension = dom_nodemap_read_dimension;
@@ -636,6 +709,14 @@ PHP_MINIT_FUNCTION(dom)
dom_nodelist_object_handlers.read_dimension = dom_nodelist_read_dimension;
dom_nodelist_object_handlers.has_dimension = dom_nodelist_has_dimension;
+ memcpy(&dom_modern_nnodemap_object_handlers, &dom_nnodemap_object_handlers, sizeof(zend_object_handlers));
+ dom_modern_nnodemap_object_handlers.read_dimension = dom_modern_nodemap_read_dimension;
+ dom_modern_nnodemap_object_handlers.has_dimension = dom_modern_nodemap_has_dimension;
+
+ memcpy(&dom_modern_nodelist_object_handlers, &dom_nodelist_object_handlers, sizeof(zend_object_handlers));
+ dom_modern_nodelist_object_handlers.read_dimension = dom_modern_nodelist_read_dimension;
+ dom_modern_nodelist_object_handlers.has_dimension = dom_modern_nodelist_has_dimension;
+
memcpy(&dom_object_namespace_node_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
dom_object_namespace_node_handlers.offset = XtOffsetOf(dom_object_namespace_node, dom.std);
dom_object_namespace_node_handlers.free_obj = dom_object_namespace_node_free_storage;
@@ -646,14 +727,21 @@ PHP_MINIT_FUNCTION(dom)
dom_domexception_class_entry = register_class_DOMException(zend_ce_exception);
dom_parentnode_class_entry = register_class_DOMParentNode();
-
+ dom_modern_parentnode_class_entry = register_class_DOM_ParentNode();
dom_childnode_class_entry = register_class_DOMChildNode();
+ dom_modern_childnode_class_entry = register_class_DOM_ChildNode();
dom_domimplementation_class_entry = register_class_DOMImplementation();
dom_domimplementation_class_entry->create_object = dom_objects_new;
+ dom_domimplementation_class_entry->default_object_handlers = &dom_object_handlers;
+
+ dom_modern_domimplementation_class_entry = register_class_DOM_Implementation();
+ dom_modern_domimplementation_class_entry->create_object = dom_objects_new;
+ dom_modern_domimplementation_class_entry->default_object_handlers = &dom_modern_domimplementation_object_handlers;
dom_node_class_entry = register_class_DOMNode();
dom_node_class_entry->create_object = dom_objects_new;
+ dom_node_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_node_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL);
@@ -676,8 +764,31 @@ PHP_MINIT_FUNCTION(dom)
DOM_REGISTER_PROP_HANDLER(&dom_node_prop_handlers, "textContent", dom_node_text_content_read, dom_node_text_content_write);
zend_hash_add_new_ptr(&classes, dom_node_class_entry->name, &dom_node_prop_handlers);
+ dom_modern_node_class_entry = register_class_DOM_Node();
+ dom_modern_node_class_entry->create_object = dom_objects_new;
+ dom_modern_node_class_entry->default_object_handlers = &dom_object_handlers;
+
+ zend_hash_init(&dom_modern_node_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "nodeType", dom_node_node_type_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "baseURI", dom_node_base_uri_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "isConnected", dom_node_is_connected_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "ownerDocument", dom_node_owner_document_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "parentNode", dom_node_parent_node_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "parentElement", dom_node_parent_element_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "childNodes", dom_node_child_nodes_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "firstChild", dom_node_first_child_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "lastChild", dom_node_last_child_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "previousSibling", dom_node_previous_sibling_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "nextSibling", dom_node_next_sibling_read, NULL);
+ /* We will set-up the setter for the derived classes afterwards on a class-by-class basis. */
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "nodeValue", dom_node_node_value_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "textContent", dom_node_text_content_read, NULL);
+ zend_hash_add_new_ptr(&classes, dom_modern_node_class_entry->name, &dom_modern_node_prop_handlers);
+
dom_namespace_node_class_entry = register_class_DOMNameSpaceNode();
dom_namespace_node_class_entry->create_object = dom_objects_namespace_node_new;
+ dom_namespace_node_class_entry->default_object_handlers = &dom_object_namespace_node_handlers;
zend_hash_init(&dom_namespace_node_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_namespace_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL);
@@ -694,58 +805,89 @@ PHP_MINIT_FUNCTION(dom)
dom_documentfragment_class_entry = register_class_DOMDocumentFragment(dom_node_class_entry, dom_parentnode_class_entry);
dom_documentfragment_class_entry->create_object = dom_objects_new;
+ dom_documentfragment_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_documentfragment_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_documentfragment_prop_handlers, "firstElementChild", dom_parent_node_first_element_child_read, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_documentfragment_prop_handlers, "lastElementChild", dom_parent_node_last_element_child_read, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_documentfragment_prop_handlers, "childElementCount", dom_parent_node_child_element_count, NULL);
-
zend_hash_merge(&dom_documentfragment_prop_handlers, &dom_node_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_documentfragment_class_entry->name, &dom_documentfragment_prop_handlers);
- dom_abstract_base_document_class_entry = register_class_DOM_Document(dom_node_class_entry, dom_parentnode_class_entry);
- /* No need to set create_object as it's abstract. */
- HashTable dom_abstract_base_document_prop_handlers;
+ dom_modern_documentfragment_class_entry = register_class_DOM_DocumentFragment(dom_modern_node_class_entry, dom_modern_parentnode_class_entry);
+ dom_modern_documentfragment_class_entry->create_object = dom_objects_new;
+ dom_modern_documentfragment_class_entry->default_object_handlers = &dom_object_handlers;
+ zend_hash_init(&dom_modern_documentfragment_prop_handlers, 0, NULL, NULL, true);
+
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_documentfragment_prop_handlers, "firstElementChild", dom_parent_node_first_element_child_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_documentfragment_prop_handlers, "lastElementChild", dom_parent_node_last_element_child_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_documentfragment_prop_handlers, "childElementCount", dom_parent_node_child_element_count, NULL);
+ zend_hash_merge(&dom_modern_documentfragment_prop_handlers, &dom_modern_node_prop_handlers, NULL, false);
+ DOM_OVERWRITE_PROP_HANDLER(&dom_modern_documentfragment_prop_handlers, "textContent", dom_node_text_content_read, dom_node_text_content_write);
+ zend_hash_add_new_ptr(&classes, dom_modern_documentfragment_class_entry->name, &dom_modern_documentfragment_prop_handlers);
+
+ dom_abstract_base_document_class_entry = register_class_DOM_Document(dom_modern_node_class_entry, dom_modern_parentnode_class_entry);
+ dom_abstract_base_document_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_abstract_base_document_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "implementation", dom_modern_document_implementation_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "URL", dom_document_document_uri_read, dom_document_document_uri_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "documentURI", dom_document_document_uri_read, dom_document_document_uri_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "characterSet", dom_document_encoding_read, dom_html_document_encoding_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "charset", dom_document_encoding_read, dom_html_document_encoding_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "inputEncoding", dom_document_encoding_read, dom_html_document_encoding_write);
DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "doctype", dom_document_doctype_read, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "documentElement", dom_document_document_element_read, NULL);
- DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "strictErrorChecking", dom_document_strict_error_checking_read, dom_document_strict_error_checking_write);
- DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "documentURI", dom_document_document_uri_read, dom_document_document_uri_write);
DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "firstElementChild", dom_parent_node_first_element_child_read, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "lastElementChild", dom_parent_node_last_element_child_read, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "childElementCount", dom_parent_node_child_element_count, NULL);
- zend_hash_merge(&dom_abstract_base_document_prop_handlers, &dom_node_prop_handlers, NULL, false);
- /* No need to register in &classes, because this is only used for merging. This is destroyed down below. */
+ zend_hash_merge(&dom_abstract_base_document_prop_handlers, &dom_modern_node_prop_handlers, NULL, false);
+ /* No need to register in &classes because this is an abstract class handler. */
- dom_document_class_entry = register_class_DOMDocument(dom_abstract_base_document_class_entry);
+ dom_document_class_entry = register_class_DOMDocument(dom_node_class_entry, dom_parentnode_class_entry);
dom_document_class_entry->create_object = dom_objects_new;
+ dom_document_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_document_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "doctype", dom_document_doctype_read, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "implementation", dom_document_implementation_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "documentElement", dom_document_document_element_read, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "actualEncoding", dom_document_encoding_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "encoding", dom_document_encoding_read, dom_document_encoding_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "xmlEncoding", dom_document_encoding_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "standalone", dom_document_standalone_read, dom_document_standalone_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "xmlStandalone", dom_document_standalone_read, dom_document_standalone_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "version", dom_document_version_read, dom_document_version_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "xmlVersion", dom_document_version_read, dom_document_version_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "strictErrorChecking", dom_document_strict_error_checking_read, dom_document_strict_error_checking_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "documentURI", dom_document_document_uri_read, dom_document_document_uri_write);
DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "config", dom_document_config_read, NULL);
- register_nondeprecated_xml_props(&dom_document_prop_handlers);
-
- zend_hash_merge(&dom_document_prop_handlers, &dom_abstract_base_document_prop_handlers, NULL, false);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "formatOutput", dom_document_format_output_read, dom_document_format_output_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "validateOnParse", dom_document_validate_on_parse_read, dom_document_validate_on_parse_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "resolveExternals", dom_document_resolve_externals_read, dom_document_resolve_externals_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "preserveWhiteSpace", dom_document_preserve_whitespace_read, dom_document_preserve_whitespace_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "recover", dom_document_recover_read, dom_document_recover_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "substituteEntities", dom_document_substitue_entities_read, dom_document_substitue_entities_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "firstElementChild", dom_parent_node_first_element_child_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "lastElementChild", dom_parent_node_last_element_child_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_document_prop_handlers, "childElementCount", dom_parent_node_child_element_count, NULL);
+
+ zend_hash_merge(&dom_document_prop_handlers, &dom_node_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_document_class_entry->name, &dom_document_prop_handlers);
dom_html_document_class_entry = register_class_DOM_HTMLDocument(dom_abstract_base_document_class_entry);
- dom_document_class_entry->create_object = dom_objects_new;
- zend_hash_init(&dom_html_document_prop_handlers, 0, NULL, NULL, true);
- DOM_REGISTER_PROP_HANDLER(&dom_html_document_prop_handlers, "encoding", dom_document_encoding_read, dom_html_document_encoding_write);
-
- zend_hash_merge(&dom_html_document_prop_handlers, &dom_abstract_base_document_prop_handlers, NULL, false);
- zend_hash_add_new_ptr(&classes, dom_html_document_class_entry->name, &dom_html_document_prop_handlers);
+ dom_html_document_class_entry->default_object_handlers = &dom_object_handlers;
+ zend_hash_add_new_ptr(&classes, dom_html_document_class_entry->name, &dom_abstract_base_document_prop_handlers);
dom_xml_document_class_entry = register_class_DOM_XMLDocument(dom_abstract_base_document_class_entry);
- dom_xml_document_class_entry->create_object = dom_objects_new;
+ dom_xml_document_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_xml_document_prop_handlers, 0, NULL, NULL, true);
- register_nondeprecated_xml_props(&dom_xml_document_prop_handlers);
+ DOM_REGISTER_PROP_HANDLER(&dom_xml_document_prop_handlers, "xmlEncoding", dom_document_encoding_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_xml_document_prop_handlers, "xmlStandalone", dom_document_standalone_read, dom_document_standalone_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_xml_document_prop_handlers, "xmlVersion", dom_document_version_read, dom_document_version_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_xml_document_prop_handlers, "formatOutput", dom_document_format_output_read, dom_document_format_output_write);
zend_hash_merge(&dom_xml_document_prop_handlers, &dom_abstract_base_document_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_xml_document_class_entry->name, &dom_xml_document_prop_handlers);
- zend_hash_destroy(&dom_abstract_base_document_prop_handlers);
-
dom_nodelist_class_entry = register_class_DOMNodeList(zend_ce_aggregate, zend_ce_countable);
dom_nodelist_class_entry->create_object = dom_nnodemap_objects_new;
dom_nodelist_class_entry->default_object_handlers = &dom_nodelist_object_handlers;
@@ -755,6 +897,13 @@ PHP_MINIT_FUNCTION(dom)
DOM_REGISTER_PROP_HANDLER(&dom_nodelist_prop_handlers, "length", dom_nodelist_length_read, NULL);
zend_hash_add_new_ptr(&classes, dom_nodelist_class_entry->name, &dom_nodelist_prop_handlers);
+ dom_modern_nodelist_class_entry = register_class_DOM_NodeList(zend_ce_aggregate, zend_ce_countable);
+ dom_modern_nodelist_class_entry->create_object = dom_nnodemap_objects_new;
+ dom_modern_nodelist_class_entry->default_object_handlers = &dom_modern_nodelist_object_handlers;
+ dom_modern_nodelist_class_entry->get_iterator = php_dom_get_iterator;
+
+ zend_hash_add_new_ptr(&classes, dom_modern_nodelist_class_entry->name, &dom_nodelist_prop_handlers);
+
dom_namednodemap_class_entry = register_class_DOMNamedNodeMap(zend_ce_aggregate, zend_ce_countable);
dom_namednodemap_class_entry->create_object = dom_nnodemap_objects_new;
dom_namednodemap_class_entry->default_object_handlers = &dom_nnodemap_object_handlers;
@@ -764,8 +913,30 @@ PHP_MINIT_FUNCTION(dom)
DOM_REGISTER_PROP_HANDLER(&dom_namednodemap_prop_handlers, "length", dom_namednodemap_length_read, NULL);
zend_hash_add_new_ptr(&classes, dom_namednodemap_class_entry->name, &dom_namednodemap_prop_handlers);
+ dom_modern_namednodemap_class_entry = register_class_DOM_NamedNodeMap(zend_ce_aggregate, zend_ce_countable);
+ dom_modern_namednodemap_class_entry->create_object = dom_nnodemap_objects_new;
+ dom_modern_namednodemap_class_entry->default_object_handlers = &dom_modern_nnodemap_object_handlers;
+ dom_modern_namednodemap_class_entry->get_iterator = php_dom_get_iterator;
+
+ zend_hash_add_new_ptr(&classes, dom_modern_namednodemap_class_entry->name, &dom_namednodemap_prop_handlers);
+
+ dom_modern_dtd_namednodemap_class_entry = register_class_DOM_DTDNamedNodeMap(zend_ce_aggregate, zend_ce_countable);
+ dom_modern_dtd_namednodemap_class_entry->create_object = dom_nnodemap_objects_new;
+ dom_modern_dtd_namednodemap_class_entry->default_object_handlers = &dom_modern_nnodemap_object_handlers;
+ dom_modern_dtd_namednodemap_class_entry->get_iterator = php_dom_get_iterator;
+
+ zend_hash_add_new_ptr(&classes, dom_modern_dtd_namednodemap_class_entry->name, &dom_namednodemap_prop_handlers);
+
+ dom_html_collection_class_entry = register_class_DOM_HTMLCollection(zend_ce_aggregate, zend_ce_countable);
+ dom_html_collection_class_entry->create_object = dom_nnodemap_objects_new;
+ dom_html_collection_class_entry->default_object_handlers = &dom_modern_nodelist_object_handlers;
+ dom_html_collection_class_entry->get_iterator = php_dom_get_iterator;
+
+ zend_hash_add_new_ptr(&classes, dom_html_collection_class_entry->name, &dom_nodelist_prop_handlers);
+
dom_characterdata_class_entry = register_class_DOMCharacterData(dom_node_class_entry, dom_childnode_class_entry);
dom_characterdata_class_entry->create_object = dom_objects_new;
+ dom_characterdata_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_characterdata_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_characterdata_prop_handlers, "data", dom_characterdata_data_read, dom_characterdata_data_write);
@@ -775,8 +946,23 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_merge(&dom_characterdata_prop_handlers, &dom_node_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_characterdata_class_entry->name, &dom_characterdata_prop_handlers);
+ dom_modern_characterdata_class_entry = register_class_DOM_CharacterData(dom_modern_node_class_entry, dom_modern_childnode_class_entry);
+ dom_modern_characterdata_class_entry->create_object = dom_objects_new;
+ dom_modern_characterdata_class_entry->default_object_handlers = &dom_object_handlers;
+
+ zend_hash_init(&dom_modern_characterdata_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_characterdata_prop_handlers, "data", dom_characterdata_data_read, dom_characterdata_data_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_characterdata_prop_handlers, "length", dom_characterdata_length_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_characterdata_prop_handlers, "previousElementSibling", dom_node_previous_element_sibling_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_characterdata_prop_handlers, "nextElementSibling", dom_node_next_element_sibling_read, NULL);
+ zend_hash_merge(&dom_modern_characterdata_prop_handlers, &dom_modern_node_prop_handlers, NULL, false);
+ DOM_OVERWRITE_PROP_HANDLER(&dom_modern_characterdata_prop_handlers, "nodeValue", dom_node_node_value_read, dom_node_node_value_write);
+ DOM_OVERWRITE_PROP_HANDLER(&dom_modern_characterdata_prop_handlers, "textContent", dom_node_text_content_read, dom_node_text_content_write);
+ zend_hash_add_new_ptr(&classes, dom_modern_characterdata_class_entry->name, &dom_modern_characterdata_prop_handlers);
+
dom_attr_class_entry = register_class_DOMAttr(dom_node_class_entry);
dom_attr_class_entry->create_object = dom_objects_new;
+ dom_attr_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_attr_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_attr_prop_handlers, "name", dom_attr_name_read, NULL);
@@ -787,8 +973,26 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_merge(&dom_attr_prop_handlers, &dom_node_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_attr_class_entry->name, &dom_attr_prop_handlers);
+ dom_modern_attr_class_entry = register_class_DOM_Attr(dom_modern_node_class_entry);
+ dom_modern_attr_class_entry->create_object = dom_objects_new;
+ dom_modern_attr_class_entry->default_object_handlers = &dom_object_handlers;
+
+ zend_hash_init(&dom_modern_attr_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_attr_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_attr_prop_handlers, "prefix", dom_modern_node_prefix_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_attr_prop_handlers, "localName", dom_node_local_name_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_attr_prop_handlers, "name", dom_attr_name_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_attr_prop_handlers, "value", dom_attr_value_read, dom_attr_value_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_attr_prop_handlers, "ownerElement", dom_attr_owner_element_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_attr_prop_handlers, "specified", dom_attr_specified_read, NULL);
+ zend_hash_merge(&dom_modern_attr_prop_handlers, &dom_node_prop_handlers, NULL, false);
+ DOM_OVERWRITE_PROP_HANDLER(&dom_modern_attr_prop_handlers, "nodeValue", dom_node_node_value_read, dom_node_node_value_write);
+ DOM_OVERWRITE_PROP_HANDLER(&dom_modern_attr_prop_handlers, "textContent", dom_node_text_content_read, dom_node_text_content_write);
+ zend_hash_add_new_ptr(&classes, dom_modern_attr_class_entry->name, &dom_modern_attr_prop_handlers);
+
dom_element_class_entry = register_class_DOMElement(dom_node_class_entry, dom_parentnode_class_entry, dom_childnode_class_entry);
dom_element_class_entry->create_object = dom_objects_new;
+ dom_element_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_element_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_element_prop_handlers, "tagName", dom_element_tag_name_read, NULL);
@@ -803,24 +1007,68 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_merge(&dom_element_prop_handlers, &dom_node_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_element_class_entry->name, &dom_element_prop_handlers);
+ dom_modern_element_class_entry = register_class_DOM_Element(dom_modern_node_class_entry, dom_modern_parentnode_class_entry, dom_modern_childnode_class_entry);
+ dom_modern_element_class_entry->create_object = dom_objects_new;
+ dom_modern_element_class_entry->default_object_handlers = &dom_object_handlers;
+
+ zend_hash_init(&dom_modern_element_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "prefix", dom_modern_node_prefix_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "localName", dom_node_local_name_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "tagName", dom_element_tag_name_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "id", dom_element_id_read, dom_element_id_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "className", dom_element_class_name_read, dom_element_class_name_write);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "attributes", dom_node_attributes_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "firstElementChild", dom_parent_node_first_element_child_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "lastElementChild", dom_parent_node_last_element_child_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "childElementCount", dom_parent_node_child_element_count, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "previousElementSibling", dom_node_previous_element_sibling_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "nextElementSibling", dom_node_next_element_sibling_read, NULL);
+ zend_hash_merge(&dom_modern_element_prop_handlers, &dom_modern_node_prop_handlers, NULL, false);
+ DOM_OVERWRITE_PROP_HANDLER(&dom_modern_element_prop_handlers, "textContent", dom_node_text_content_read, dom_node_text_content_write);
+ zend_hash_add_new_ptr(&classes, dom_modern_element_class_entry->name, &dom_modern_element_prop_handlers);
+
dom_text_class_entry = register_class_DOMText(dom_characterdata_class_entry);
dom_text_class_entry->create_object = dom_objects_new;
+ dom_text_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_text_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_text_prop_handlers, "wholeText", dom_text_whole_text_read, NULL);
zend_hash_merge(&dom_text_prop_handlers, &dom_characterdata_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_text_class_entry->name, &dom_text_prop_handlers);
+ dom_modern_text_class_entry = register_class_DOM_Text(dom_modern_characterdata_class_entry);
+ dom_modern_text_class_entry->create_object = dom_objects_new;
+ dom_modern_text_class_entry->default_object_handlers = &dom_object_handlers;
+
+ zend_hash_init(&dom_modern_text_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_text_prop_handlers, "wholeText", dom_text_whole_text_read, NULL);
+ zend_hash_merge(&dom_modern_text_prop_handlers, &dom_modern_characterdata_prop_handlers, NULL, false);
+ zend_hash_add_new_ptr(&classes, dom_modern_text_class_entry->name, &dom_modern_text_prop_handlers);
+
dom_comment_class_entry = register_class_DOMComment(dom_characterdata_class_entry);
dom_comment_class_entry->create_object = dom_objects_new;
+ dom_comment_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_add_new_ptr(&classes, dom_comment_class_entry->name, &dom_characterdata_prop_handlers);
+ dom_modern_comment_class_entry = register_class_DOM_Comment(dom_modern_characterdata_class_entry);
+ dom_modern_comment_class_entry->create_object = dom_objects_new;
+ dom_modern_comment_class_entry->default_object_handlers = &dom_object_handlers;
+ zend_hash_add_new_ptr(&classes, dom_modern_comment_class_entry->name, &dom_modern_characterdata_prop_handlers);
+
dom_cdatasection_class_entry = register_class_DOMCdataSection(dom_text_class_entry);
dom_cdatasection_class_entry->create_object = dom_objects_new;
+ dom_cdatasection_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_add_new_ptr(&classes, dom_cdatasection_class_entry->name, &dom_text_prop_handlers);
+ dom_modern_cdatasection_class_entry = register_class_DOM_CDATASection(dom_modern_text_class_entry);
+ dom_modern_cdatasection_class_entry->create_object = dom_objects_new;
+ dom_modern_cdatasection_class_entry->default_object_handlers = &dom_object_handlers;
+ zend_hash_add_new_ptr(&classes, dom_modern_cdatasection_class_entry->name, &dom_modern_text_prop_handlers);
+
dom_documenttype_class_entry = register_class_DOMDocumentType(dom_node_class_entry);
dom_documenttype_class_entry->create_object = dom_objects_new;
+ dom_documenttype_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_documenttype_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_documenttype_prop_handlers, "name", dom_documenttype_name_read, NULL);
@@ -832,8 +1080,23 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_merge(&dom_documenttype_prop_handlers, &dom_node_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_documenttype_class_entry->name, &dom_documenttype_prop_handlers);
+ dom_modern_documenttype_class_entry = register_class_DOM_DocumentType(dom_modern_node_class_entry, dom_modern_childnode_class_entry);
+ dom_modern_documenttype_class_entry->create_object = dom_objects_new;
+ dom_modern_documenttype_class_entry->default_object_handlers = &dom_object_handlers;
+
+ zend_hash_init(&dom_modern_documenttype_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_documenttype_prop_handlers, "name", dom_documenttype_name_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_documenttype_prop_handlers, "entities", dom_documenttype_entities_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_documenttype_prop_handlers, "notations", dom_documenttype_notations_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_documenttype_prop_handlers, "publicId", dom_documenttype_public_id_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_documenttype_prop_handlers, "systemId", dom_documenttype_system_id_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_documenttype_prop_handlers, "internalSubset", dom_documenttype_internal_subset_read, NULL);
+ zend_hash_merge(&dom_modern_documenttype_prop_handlers, &dom_node_prop_handlers, NULL, false);
+ zend_hash_add_new_ptr(&classes, dom_modern_documenttype_class_entry->name, &dom_modern_documenttype_prop_handlers);
+
dom_notation_class_entry = register_class_DOMNotation(dom_node_class_entry);
dom_notation_class_entry->create_object = dom_objects_new;
+ dom_notation_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_notation_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_notation_prop_handlers, "publicId", dom_notation_public_id_read, NULL);
@@ -841,8 +1104,19 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_merge(&dom_notation_prop_handlers, &dom_node_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_notation_class_entry->name, &dom_notation_prop_handlers);
+ dom_modern_notation_class_entry = register_class_DOM_Notation(dom_modern_node_class_entry);
+ dom_modern_notation_class_entry->create_object = dom_objects_new;
+ dom_modern_notation_class_entry->default_object_handlers = &dom_object_handlers;
+
+ zend_hash_init(&dom_modern_notation_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_notation_prop_handlers, "publicId", dom_notation_public_id_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_notation_prop_handlers, "systemId", dom_notation_system_id_read, NULL);
+ zend_hash_merge(&dom_modern_notation_prop_handlers, &dom_modern_node_prop_handlers, NULL, false);
+ zend_hash_add_new_ptr(&classes, dom_modern_notation_class_entry->name, &dom_modern_node_prop_handlers);
+
dom_entity_class_entry = register_class_DOMEntity(dom_node_class_entry);
dom_entity_class_entry->create_object = dom_objects_new;
+ dom_entity_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_entity_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_entity_prop_handlers, "publicId", dom_entity_public_id_read, NULL);
@@ -854,12 +1128,30 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_merge(&dom_entity_prop_handlers, &dom_node_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_entity_class_entry->name, &dom_entity_prop_handlers);
+ dom_modern_entity_class_entry = register_class_DOM_Entity(dom_modern_node_class_entry);
+ dom_modern_entity_class_entry->create_object = dom_objects_new;
+ dom_modern_entity_class_entry->default_object_handlers = &dom_object_handlers;
+
+ zend_hash_init(&dom_modern_entity_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_entity_prop_handlers, "publicId", dom_entity_public_id_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_entity_prop_handlers, "systemId", dom_entity_system_id_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_entity_prop_handlers, "notationName", dom_entity_notation_name_read, NULL);
+ zend_hash_merge(&dom_modern_entity_prop_handlers, &dom_modern_node_prop_handlers, NULL, false);
+ zend_hash_add_new_ptr(&classes, dom_modern_entity_class_entry->name, &dom_modern_entity_prop_handlers);
+
dom_entityreference_class_entry = register_class_DOMEntityReference(dom_node_class_entry);
dom_entityreference_class_entry->create_object = dom_objects_new;
+ dom_entityreference_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_add_new_ptr(&classes, dom_entityreference_class_entry->name, &dom_node_prop_handlers);
+ dom_modern_entityreference_class_entry = register_class_DOM_EntityReference(dom_modern_node_class_entry);
+ dom_modern_entityreference_class_entry->create_object = dom_objects_new;
+ dom_modern_entityreference_class_entry->default_object_handlers = &dom_object_handlers;
+ zend_hash_add_new_ptr(&classes, dom_modern_entityreference_class_entry->name, &dom_modern_node_prop_handlers);
+
dom_processinginstruction_class_entry = register_class_DOMProcessingInstruction(dom_node_class_entry);
dom_processinginstruction_class_entry->create_object = dom_objects_new;
+ dom_processinginstruction_class_entry->default_object_handlers = &dom_object_handlers;
zend_hash_init(&dom_processinginstruction_prop_handlers, 0, NULL, NULL, true);
DOM_REGISTER_PROP_HANDLER(&dom_processinginstruction_prop_handlers, "target", dom_processinginstruction_target_read, NULL);
@@ -867,6 +1159,16 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_merge(&dom_processinginstruction_prop_handlers, &dom_node_prop_handlers, NULL, false);
zend_hash_add_new_ptr(&classes, dom_processinginstruction_class_entry->name, &dom_processinginstruction_prop_handlers);
+ dom_modern_processinginstruction_class_entry = register_class_DOM_ProcessingInstruction(dom_modern_characterdata_class_entry);
+ dom_modern_processinginstruction_class_entry->create_object = dom_objects_new;
+ dom_modern_processinginstruction_class_entry->default_object_handlers = &dom_object_handlers;
+
+ zend_hash_init(&dom_modern_processinginstruction_prop_handlers, 0, NULL, NULL, true);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_processinginstruction_prop_handlers, "target", dom_processinginstruction_target_read, NULL);
+ DOM_REGISTER_PROP_HANDLER(&dom_modern_processinginstruction_prop_handlers, "data", dom_processinginstruction_data_read, dom_processinginstruction_data_write);
+ zend_hash_merge(&dom_modern_processinginstruction_prop_handlers, &dom_modern_characterdata_prop_handlers, NULL, false);
+ zend_hash_add_new_ptr(&classes, dom_modern_processinginstruction_class_entry->name, &dom_modern_processinginstruction_prop_handlers);
+
#ifdef LIBXML_XPATH_ENABLED
memcpy(&dom_xpath_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
dom_xpath_object_handlers.offset = XtOffsetOf(dom_xpath_object, dom) + XtOffsetOf(dom_object, std);
@@ -882,11 +1184,18 @@ PHP_MINIT_FUNCTION(dom)
DOM_REGISTER_PROP_HANDLER(&dom_xpath_prop_handlers, "document", dom_xpath_document_read, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_xpath_prop_handlers, "registerNodeNamespaces", dom_xpath_register_node_ns_read, dom_xpath_register_node_ns_write);
zend_hash_add_new_ptr(&classes, dom_xpath_class_entry->name, &dom_xpath_prop_handlers);
+
+ dom_modern_xpath_class_entry = register_class_DOM_XPath();
+ dom_modern_xpath_class_entry->create_object = dom_xpath_objects_new;
+ dom_modern_xpath_class_entry->default_object_handlers = &dom_xpath_object_handlers;
+
+ zend_hash_add_new_ptr(&classes, dom_modern_xpath_class_entry->name, &dom_xpath_prop_handlers);
#endif
register_php_dom_symbols(module_number);
php_libxml_register_export(dom_node_class_entry, php_dom_export_node);
+ php_libxml_register_export(dom_modern_node_class_entry, php_dom_export_node);
lexbor_memory_setup(dom_malloc, dom_realloc, dom_calloc, dom_free);
@@ -921,21 +1230,31 @@ PHP_MINFO_FUNCTION(dom)
PHP_MSHUTDOWN_FUNCTION(dom) /* {{{ */
{
zend_hash_destroy(&dom_document_prop_handlers);
- zend_hash_destroy(&dom_html_document_prop_handlers);
+ zend_hash_destroy(&dom_abstract_base_document_prop_handlers);
zend_hash_destroy(&dom_xml_document_prop_handlers);
zend_hash_destroy(&dom_documentfragment_prop_handlers);
+ zend_hash_destroy(&dom_modern_documentfragment_prop_handlers);
zend_hash_destroy(&dom_node_prop_handlers);
+ zend_hash_destroy(&dom_modern_node_prop_handlers);
zend_hash_destroy(&dom_namespace_node_prop_handlers);
zend_hash_destroy(&dom_nodelist_prop_handlers);
zend_hash_destroy(&dom_namednodemap_prop_handlers);
zend_hash_destroy(&dom_characterdata_prop_handlers);
+ zend_hash_destroy(&dom_modern_characterdata_prop_handlers);
zend_hash_destroy(&dom_attr_prop_handlers);
+ zend_hash_destroy(&dom_modern_attr_prop_handlers);
zend_hash_destroy(&dom_element_prop_handlers);
+ zend_hash_destroy(&dom_modern_element_prop_handlers);
zend_hash_destroy(&dom_text_prop_handlers);
+ zend_hash_destroy(&dom_modern_text_prop_handlers);
zend_hash_destroy(&dom_documenttype_prop_handlers);
+ zend_hash_destroy(&dom_modern_documenttype_prop_handlers);
zend_hash_destroy(&dom_notation_prop_handlers);
+ zend_hash_destroy(&dom_modern_notation_prop_handlers);
zend_hash_destroy(&dom_entity_prop_handlers);
+ zend_hash_destroy(&dom_modern_entity_prop_handlers);
zend_hash_destroy(&dom_processinginstruction_prop_handlers);
+ zend_hash_destroy(&dom_modern_processinginstruction_prop_handlers);
#ifdef LIBXML_XPATH_ENABLED
zend_hash_destroy(&dom_xpath_prop_handlers);
#endif
@@ -1028,6 +1347,12 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml
mapptr->local = xmlCharStrndup(local, len);
mapptr->free_local = true;
}
+ mapptr->local_lower = BAD_CAST estrdup(local);
+ if (len < 0) {
+ zend_str_tolower((char *) mapptr->local_lower, strlen((const char *) mapptr->local_lower));
+ } else {
+ zend_str_tolower((char *) mapptr->local_lower, len);
+ }
}
if (ns) {
@@ -1066,7 +1391,6 @@ static dom_object* dom_objects_set_class(zend_class_entry *class_type)
zend_object *dom_objects_new(zend_class_entry *class_type)
{
dom_object *intern = dom_objects_set_class(class_type);
- intern->std.handlers = &dom_object_handlers;
return &intern->std;
}
/* }}} */
@@ -1075,7 +1399,6 @@ static zend_object *dom_objects_namespace_node_new(zend_class_entry *class_type)
{
dom_object_namespace_node *intern = zend_object_alloc(sizeof(dom_object_namespace_node), class_type);
dom_objects_set_class_ex(class_type, &intern->dom);
- intern->dom.std.handlers = &dom_object_namespace_node_handlers;
return &intern->dom.std;
}
@@ -1126,6 +1449,9 @@ void dom_nnodemap_objects_free_storage(zend_object *object) /* {{{ */
if (objmap->free_ns) {
xmlFree(objmap->ns);
}
+ if (objmap->local_lower) {
+ efree(objmap->local_lower);
+ }
if (!Z_ISUNDEF(objmap->baseobj_zv)) {
zval_ptr_dtor(&objmap->baseobj_zv);
}
@@ -1152,6 +1478,7 @@ zend_object *dom_nnodemap_objects_new(zend_class_entry *class_type)
objmap->nodetype = 0;
objmap->ht = NULL;
objmap->local = NULL;
+ objmap->local_lower = NULL;
objmap->free_local = false;
objmap->ns = NULL;
objmap->free_ns = false;
@@ -1163,14 +1490,21 @@ zend_object *dom_nnodemap_objects_new(zend_class_entry *class_type)
return &intern->std;
}
-void php_dom_create_iterator(zval *return_value, int ce_type) /* {{{ */
+void php_dom_create_iterator(zval *return_value, dom_iterator_type iterator_type, bool modern) /* {{{ */
{
zend_class_entry *ce;
- if (ce_type == DOM_NAMEDNODEMAP) {
- ce = dom_namednodemap_class_entry;
+ if (iterator_type == DOM_NAMEDNODEMAP) {
+ ce = dom_get_namednodemap_ce(modern);
+ } else if (iterator_type == DOM_HTMLCOLLECTION) {
+ /* This only exists in modern DOM. */
+ ZEND_ASSERT(modern);
+ ce = dom_html_collection_class_entry;
+ } else if (iterator_type == DOM_DTD_NAMEDNODEMAP) {
+ ce = dom_get_dtd_namednodemap_ce(modern);
} else {
- ce = dom_nodelist_class_entry;
+ ZEND_ASSERT(iterator_type == DOM_NODELIST);
+ ce = dom_get_nodelist_ce(modern);
}
object_init_ex(return_value, ce);
@@ -1193,89 +1527,83 @@ PHP_DOM_EXPORT bool php_dom_create_object(xmlNodePtr obj, zval *return_value, do
return 1;
}
+ bool modern = domobj && php_dom_follow_spec_intern(domobj);
switch (obj->type) {
case XML_DOCUMENT_NODE:
{
- if (domobj && domobj->document->is_modern_api_class) {
- ce = dom_xml_document_class_entry;
- } else {
- ce = dom_document_class_entry;
- }
+ ce = dom_get_xml_document_ce(modern);
break;
}
case XML_HTML_DOCUMENT_NODE:
{
- if (domobj && domobj->document->is_modern_api_class) {
- ce = dom_html_document_class_entry;
- } else {
- ce = dom_document_class_entry;
- }
+ ce = dom_get_html_document_ce(modern);
break;
}
case XML_DTD_NODE:
case XML_DOCUMENT_TYPE_NODE:
{
- ce = dom_documenttype_class_entry;
+ ce = dom_get_documenttype_ce(modern);
break;
}
case XML_ELEMENT_NODE:
{
- ce = dom_element_class_entry;
+ ce = dom_get_element_ce(modern);
break;
}
case XML_ATTRIBUTE_NODE:
{
- ce = dom_attr_class_entry;
+ ce = dom_get_attr_ce(modern);
break;
}
case XML_TEXT_NODE:
{
- ce = dom_text_class_entry;
+ ce = dom_get_text_ce(modern);
break;
}
case XML_COMMENT_NODE:
{
- ce = dom_comment_class_entry;
+ ce = dom_get_comment_ce(modern);
break;
}
case XML_PI_NODE:
{
- ce = dom_processinginstruction_class_entry;
+ ce = dom_get_processinginstruction_ce(modern);
break;
}
case XML_ENTITY_REF_NODE:
{
- ce = dom_entityreference_class_entry;
+ ce = dom_get_entityreference_ce(modern);
break;
}
case XML_ENTITY_DECL:
case XML_ELEMENT_DECL:
{
- ce = dom_entity_class_entry;
+ ce = dom_get_entity_ce(modern);
break;
}
case XML_CDATA_SECTION_NODE:
{
- ce = dom_cdatasection_class_entry;
+ ce = dom_get_cdatasection_ce(modern);
break;
}
case XML_DOCUMENT_FRAG_NODE:
{
- ce = dom_documentfragment_class_entry;
+ ce = dom_get_documentfragment_ce(modern);
break;
}
case XML_NOTATION_NODE:
{
- ce = dom_notation_class_entry;
+ ce = dom_get_notation_ce(modern);
break;
}
case XML_NAMESPACE_DECL:
{
+ /* This has no modern equivalent */
ce = dom_namespace_node_class_entry;
break;
}
default:
- /* TODO Convert to a ZEND assertion? */
+ /* TODO you can actually hit this with fixed attributes in the DTD for example... */
zend_throw_error(NULL, "Unsupported node type: %d", obj->type);
ZVAL_NULL(return_value);
return 0;
@@ -1306,8 +1634,8 @@ dom_object *php_dom_instantiate_object_helper(zval *return_value, zend_class_ent
return intern;
}
-void php_dom_create_implementation(zval *retval) {
- object_init_ex(retval, dom_domimplementation_class_entry);
+void php_dom_create_implementation(zval *retval, bool modern) {
+ object_init_ex(retval, dom_get_domimplementation_ce(modern));
}
/* {{{ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child) */
@@ -1354,7 +1682,43 @@ bool dom_has_feature(zend_string *feature, zend_string *version)
}
/* }}} end dom_has_feature */
-xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, char *ns, char *local, int *cur, int index) /* {{{ */
+bool dom_match_qualified_name_according_to_spec(const xmlChar *qname, const xmlNode *nodep)
+{
+ const xmlChar *node_local = nodep->name;
+
+ /* The qualified name must be matched, which means either:
+ * - The local parts are equal and there is no ns prefix for this element (i.e. the fqn is in the local name).
+ * - There is a prefix, the prefixes are equal and the local parts are equal. */
+ if (nodep->ns != NULL && nodep->ns->prefix != NULL) {
+ const char *prefix = (const char *) nodep->ns->prefix;
+ /* 1. match prefix up to |prefix| characters.
+ * This won't overflow as it'll stop at the '\0' if the lengths don't match. */
+ size_t prefix_len = strlen(prefix);
+ if (strncmp((const char *) qname, prefix, prefix_len) != 0) {
+ return false;
+ }
+ /* 2. match ':' */
+ if (qname[prefix_len] != ':') {
+ return false;
+ }
+ /* 3. match local name */
+ return xmlStrEqual(qname + prefix_len + 1, node_local);
+ } else {
+ return xmlStrEqual(node_local, qname);
+ }
+}
+
+static bool dom_match_qualified_name_for_tag_name_equality(const xmlChar *local, const xmlChar *local_lower, const xmlNode *nodep, bool match_qname)
+{
+ if (!match_qname) {
+ return xmlStrEqual(nodep->name, local);
+ }
+
+ const xmlChar *local_to_use = nodep->doc->type == XML_HTML_DOCUMENT_NODE && php_dom_ns_is_fast(nodep, php_dom_ns_is_html_magic_token) ? local_lower : local;
+ return dom_match_qualified_name_according_to_spec(local_to_use, nodep);
+}
+
+xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, xmlChar *ns, xmlChar *local, xmlChar *local_lower, int *cur, int index) /* {{{ */
{
/* Can happen with detached document */
if (UNEXPECTED(nodep == NULL)) {
@@ -1369,10 +1733,12 @@ xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep,
* This is because for PHP ns == NULL has another meaning: "match every namespace" instead of "match the empty namespace". */
bool ns_match_any = ns == NULL || (ns[0] == '*' && ns[1] == '\0');
+ bool match_qname = ns == NULL && php_dom_follow_spec_node(basep);
+
while (*cur <= index) {
if (nodep->type == XML_ELEMENT_NODE) {
- if (local_match_any || xmlStrEqual(nodep->name, (xmlChar *)local)) {
- if (ns_match_any || (ns[0] == '\0' && nodep->ns == NULL) || (nodep->ns != NULL && xmlStrEqual(nodep->ns->href, (xmlChar *)ns))) {
+ if (local_match_any || dom_match_qualified_name_for_tag_name_equality(local, local_lower, nodep, match_qname)) {
+ if (ns_match_any || (ns[0] == '\0' && nodep->ns == NULL) || (nodep->ns != NULL && xmlStrEqual(nodep->ns->href, ns))) {
if (*cur == index) {
ret = nodep;
break;
@@ -1387,22 +1753,9 @@ xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep,
}
}
- if (nodep->next) {
- nodep = nodep->next;
- } else {
- /* Go upwards, until we find a parent node with a next sibling, or until we hit the base. */
- do {
- nodep = nodep->parent;
- if (nodep == basep) {
- return NULL;
- }
- /* This shouldn't happen, unless there's an invalidation bug somewhere. */
- if (UNEXPECTED(nodep == NULL)) {
- zend_throw_error(NULL, "Current node in traversal is not in the document. Please report this as a bug in php-src.");
- return NULL;
- }
- } while (nodep->next == NULL);
- nodep = nodep->next;
+ nodep = php_dom_next_in_tree_order(nodep, basep);
+ if (!nodep) {
+ return NULL;
}
}
return ret;
@@ -1411,63 +1764,96 @@ xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep,
static inline bool is_empty_node(xmlNodePtr nodep)
{
- xmlChar *strContent = xmlNodeGetContent(nodep);
- bool ret = strContent == NULL || *strContent == '\0';
- xmlFree(strContent);
- return ret;
+ return nodep->content == NULL || *nodep->content == '\0';
+}
+
+static inline void free_node(xmlNodePtr node)
+{
+ if (node->_private == NULL) {
+ xmlFreeNode(node);
+ }
}
-/* {{{ void dom_normalize (xmlNodePtr nodep) */
-void dom_normalize (xmlNodePtr nodep)
+static void dom_merge_adjacent_exclusive_text_nodes(xmlNodePtr node)
{
- xmlNodePtr child, nextp, newnextp;
- xmlAttrPtr attr;
- xmlChar *strContent;
+ xmlNodePtr nextp = node->next;
+ while (nextp != NULL && nextp->type == XML_TEXT_NODE) {
+ xmlNodePtr newnextp = nextp->next;
+ xmlChar *strContent = nextp->content;
+ if (strContent != NULL) {
+ xmlNodeAddContent(node, strContent);
+ }
+ xmlUnlinkNode(nextp);
+ free_node(nextp);
+ nextp = newnextp;
+ }
+}
- child = nodep->children;
+/* {{{ void php_dom_normalize_legacy(xmlNodePtr nodep) */
+void php_dom_normalize_legacy(xmlNodePtr nodep)
+{
+ xmlNodePtr child = nodep->children;
while(child != NULL) {
switch (child->type) {
case XML_TEXT_NODE:
- nextp = child->next;
- while (nextp != NULL) {
- if (nextp->type == XML_TEXT_NODE) {
- newnextp = nextp->next;
- strContent = xmlNodeGetContent(nextp);
- xmlNodeAddContent(child, strContent);
- xmlFree(strContent);
- xmlUnlinkNode(nextp);
- php_libxml_node_free_resource(nextp);
- nextp = newnextp;
- } else {
- break;
- }
- }
+ dom_merge_adjacent_exclusive_text_nodes(child);
if (is_empty_node(child)) {
- nextp = child->next;
+ xmlNodePtr nextp = child->next;
xmlUnlinkNode(child);
- php_libxml_node_free_resource(child);
+ free_node(child);
child = nextp;
continue;
}
break;
case XML_ELEMENT_NODE:
- dom_normalize (child);
- attr = child->properties;
+ php_dom_normalize_legacy(child);
+ xmlAttrPtr attr = child->properties;
while (attr != NULL) {
- dom_normalize((xmlNodePtr) attr);
+ php_dom_normalize_legacy((xmlNodePtr) attr);
attr = attr->next;
}
break;
- case XML_ATTRIBUTE_NODE:
- dom_normalize (child);
- break;
default:
break;
}
child = child->next;
}
}
-/* }}} end dom_normalize */
+/* }}} end php_dom_normalize_legacy */
+
+/* https://dom.spec.whatwg.org/#dom-node-normalize */
+void php_dom_normalize_modern(xmlNodePtr this)
+{
+ /* for each descendant exclusive Text node node of this: */
+ xmlNodePtr node = this->children;
+ while (node != NULL) {
+ if (node->type == XML_TEXT_NODE) {
+ /* 1. Let length be node’s length.
+ * We'll deviate a bit here: we'll just check if it's empty or not as we don't want to compute the length. */
+ bool is_empty = is_empty_node(node);
+
+ /* 2. If length is zero, then remove node and continue with the next exclusive Text node, if any. */
+ if (is_empty) {
+ xmlNodePtr next = node->next;
+ xmlUnlinkNode(node);
+ free_node(node);
+ node = next;
+ continue;
+ }
+
+ /* 3. Let data be the concatenation of the data of node’s contiguous exclusive Text nodes (excluding itself), in tree order.
+ * 4. Replace data with node node, offset length, count 0, and data data.
+ * 7. Remove node’s contiguous exclusive Text nodes (excluding itself), in tree order.
+ * => In other words: Concat every contiguous text node into node and delete the merged nodes. */
+ dom_merge_adjacent_exclusive_text_nodes(node);
+
+ /* Steps 5-6 deal with mutation records, we don't do that here. */
+ } else if (node->type == XML_ELEMENT_NODE) {
+ php_dom_normalize_modern(node);
+ }
+ node = node->next;
+ }
+}
static void dom_reconcile_ns_internal(xmlDocPtr doc, xmlNodePtr nodep, xmlNodePtr search_parent)
{
@@ -1500,38 +1886,6 @@ static void dom_reconcile_ns_internal(xmlDocPtr doc, xmlNodePtr nodep, xmlNodePt
}
}
-void php_dom_reconcile_attribute_namespace_after_insertion(xmlAttrPtr attrp)
-{
- ZEND_ASSERT(attrp != NULL);
-
- if (attrp->ns != NULL) {
- /* Try to link to an existing namespace. If that won't work, reconcile. */
- xmlNodePtr nodep = attrp->parent;
- xmlNsPtr matching_ns = xmlSearchNs(nodep->doc, nodep, attrp->ns->prefix);
- if (matching_ns && xmlStrEqual(matching_ns->href, attrp->ns->href)) {
- attrp->ns = matching_ns;
- } else {
- if (attrp->ns->prefix != NULL) {
- xmlReconciliateNs(nodep->doc, nodep);
- }
- }
- }
-}
-
-static void dom_libxml_reconcile_ensure_namespaces_are_declared(xmlNodePtr nodep)
-{
- /* Ideally we'd use the DOM-wrapped version, but we cannot: https://github.com/php/php-src/pull/12308. */
-#if 0
- /* Put on stack to avoid allocation.
- * Although libxml2 currently does not use this for the reconciliation, it still
- * makes sense to do this just in case libxml2's internal change in the future. */
- xmlDOMWrapCtxt dummy_ctxt = {0};
- xmlDOMWrapReconcileNamespaces(&dummy_ctxt, nodep, /* options */ 0);
-#else
- xmlReconciliateNs(nodep->doc, nodep);
-#endif
-}
-
void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) /* {{{ */
{
ZEND_ASSERT(nodep->type != XML_ATTRIBUTE_NODE);
@@ -1540,7 +1894,7 @@ void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) /* {{{ */
* we still want to do the internal reconciliation conditionally. */
if (nodep->type == XML_ELEMENT_NODE) {
dom_reconcile_ns_internal(doc, nodep, nodep->parent);
- dom_libxml_reconcile_ensure_namespaces_are_declared(nodep);
+ xmlReconciliateNs(doc, nodep);
}
}
/* }}} */
@@ -1569,7 +1923,7 @@ void dom_reconcile_ns_list(xmlDocPtr doc, xmlNodePtr nodep, xmlNodePtr last)
* dom_libxml_reconcile_ensure_namespaces_are_declared() performs its own recursion. */
while (true) {
/* The internal libxml2 call will already check the node type, no need for us to do it here. */
- dom_libxml_reconcile_ensure_namespaces_are_declared(nodep);
+ xmlReconciliateNs(doc, nodep);
if (nodep == last) {
break;
}
@@ -1577,6 +1931,52 @@ void dom_reconcile_ns_list(xmlDocPtr doc, xmlNodePtr nodep, xmlNodePtr last)
}
}
+/* https://dom.spec.whatwg.org/#validate-and-extract */
+int dom_validate_and_extract(const zend_string *namespace, const zend_string *qname, xmlChar **localName, xmlChar **prefix)
+{
+ /* 1. If namespace is the empty string, then set it to null.
+ * However, we're going to cheat and do the opposite to make
+ * implementation of the below steps with existing zend_ helpers easier. */
+ if (namespace == NULL) {
+ namespace = zend_empty_string;
+ }
+
+ /* 2. Validate qualifiedName. */
+ if (xmlValidateQName(BAD_CAST ZSTR_VAL(qname), /* allow spaces */ 0) != 0) {
+ return INVALID_CHARACTER_ERR;
+ }
+
+ /* Steps 3-5 */
+ *localName = xmlSplitQName2(BAD_CAST ZSTR_VAL(qname), prefix);
+
+ /* 6. If prefix is non-null and namespace is null, then throw a "NamespaceError" DOMException.
+ * Note that null namespace means empty string here becaue of step 1. */
+ if (*prefix != NULL && ZSTR_VAL(namespace)[0] == '\0') {
+ return NAMESPACE_ERR;
+ }
+
+ /* 7. If prefix is "xml" and namespace is not the XML namespace, then throw a "NamespaceError" DOMException. */
+ if (UNEXPECTED(!zend_string_equals_literal(namespace, "http://www.w3.org/XML/1998/namespace") && xmlStrEqual(*prefix, BAD_CAST "xml"))) {
+ return NAMESPACE_ERR;
+ }
+
+ /* 8. If either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace, then throw a "NamespaceError" DOMException. */
+ if (UNEXPECTED((zend_string_equals_literal(qname, "xmlns") || xmlStrEqual(*prefix, BAD_CAST "xmlns")) && !zend_string_equals_literal(namespace, "http://www.w3.org/2000/xmlns/"))) {
+ return NAMESPACE_ERR;
+ }
+
+ /* 9. If namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns", then throw a "NamespaceError" DOMException. */
+ if (UNEXPECTED(zend_string_equals_literal(namespace, "http://www.w3.org/2000/xmlns/") && !zend_string_equals_literal(qname, "xmlns") && !xmlStrEqual(*prefix, BAD_CAST "xmlns"))) {
+ return NAMESPACE_ERR;
+ }
+
+ if (*localName == NULL) {
+ *localName = xmlStrdup(BAD_CAST ZSTR_VAL(qname));
+ }
+
+ return 0;
+}
+
/*
http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS
@@ -1763,10 +2163,10 @@ static bool dom_nodemap_or_nodelist_process_offset_as_named(zval *offset, zend_l
return false;
}
-static zval *dom_nodelist_read_dimension(zend_object *object, zval *offset, int type, zval *rv) /* {{{ */
+static zval *dom_nodelist_read_dimension(zend_object *object, zval *offset, int type, zval *rv)
{
if (UNEXPECTED(!offset)) {
- zend_throw_error(NULL, "Cannot access DOMNodeList without offset");
+ zend_throw_error(NULL, "Cannot access %s without offset", ZSTR_VAL(object->ce->name));
return NULL;
}
@@ -1781,12 +2181,15 @@ static zval *dom_nodelist_read_dimension(zend_object *object, zval *offset, int
php_dom_nodelist_get_item_into_zval(php_dom_obj_from_obj(object)->ptr, lval, rv);
return rv;
-} /* }}} end dom_nodelist_read_dimension */
+}
static int dom_nodelist_has_dimension(zend_object *object, zval *member, int check_empty)
{
ZVAL_DEREF(member);
+ /* If it exists, it cannot be empty because nodes aren't empty. */
+ ZEND_IGNORE_VALUE(check_empty);
+
zend_long offset;
if (dom_nodemap_or_nodelist_process_offset_as_named(member, &offset)) {
/* does not support named lookup */
@@ -1794,7 +2197,59 @@ static int dom_nodelist_has_dimension(zend_object *object, zval *member, int che
}
return offset >= 0 && offset < php_dom_get_nodelist_length(php_dom_obj_from_obj(object));
-} /* }}} end dom_nodelist_has_dimension */
+}
+
+static zend_long dom_modern_nodelist_get_index(zval *offset, bool *failed)
+{
+ zend_ulong lval;
+ ZVAL_DEREF(offset);
+ if (Z_TYPE_P(offset) == IS_LONG) {
+ *failed = false;
+ return Z_LVAL_P(offset);
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ *failed = false;
+ return zend_dval_to_lval_safe(Z_DVAL_P(offset));
+ } else if (Z_TYPE_P(offset) == IS_STRING && ZEND_HANDLE_NUMERIC(Z_STR_P(offset), lval)) {
+ *failed = false;
+ return (zend_long) lval;
+ } else {
+ *failed = true;
+ return 0;
+ }
+}
+
+static zval *dom_modern_nodelist_read_dimension(zend_object *object, zval *offset, int type, zval *rv)
+{
+ if (UNEXPECTED(!offset)) {
+ zend_throw_error(NULL, "Cannot append to %s", ZSTR_VAL(object->ce->name));
+ return NULL;
+ }
+
+ bool failed;
+ zend_long lval = dom_modern_nodelist_get_index(offset, &failed);
+ if (UNEXPECTED(failed)) {
+ zend_illegal_container_offset(object->ce->name, offset, type);
+ return NULL;
+ }
+
+ php_dom_nodelist_get_item_into_zval(php_dom_obj_from_obj(object)->ptr, lval, rv);
+ return rv;
+}
+
+static int dom_modern_nodelist_has_dimension(zend_object *object, zval *member, int check_empty)
+{
+ /* If it exists, it cannot be empty because nodes aren't empty. */
+ ZEND_IGNORE_VALUE(check_empty);
+
+ bool failed;
+ zend_long lval = dom_modern_nodelist_get_index(member, &failed);
+ if (UNEXPECTED(failed)) {
+ zend_illegal_container_offset(object->ce->name, member, BP_VAR_IS);
+ return 0;
+ }
+
+ return lval >= 0 && lval < php_dom_get_nodelist_length(php_dom_obj_from_obj(object));
+}
void dom_remove_all_children(xmlNodePtr nodep)
{
@@ -1839,10 +2294,10 @@ void php_dom_get_content_into_zval(const xmlNode *nodep, zval *retval, bool defa
}
}
-static zval *dom_nodemap_read_dimension(zend_object *object, zval *offset, int type, zval *rv) /* {{{ */
+static zval *dom_nodemap_read_dimension(zend_object *object, zval *offset, int type, zval *rv)
{
if (UNEXPECTED(!offset)) {
- zend_throw_error(NULL, "Cannot access DOMNamedNodeMap without offset");
+ zend_throw_error(NULL, "Cannot access %s without offset", ZSTR_VAL(object->ce->name));
return NULL;
}
@@ -1851,7 +2306,7 @@ static zval *dom_nodemap_read_dimension(zend_object *object, zval *offset, int t
zend_long lval;
if (dom_nodemap_or_nodelist_process_offset_as_named(offset, &lval)) {
/* exceptional case, switch to named lookup */
- php_dom_named_node_map_get_named_item_into_zval(php_dom_obj_from_obj(object)->ptr, Z_STRVAL_P(offset), rv);
+ php_dom_named_node_map_get_named_item_into_zval(php_dom_obj_from_obj(object)->ptr, Z_STR_P(offset), rv);
return rv;
}
@@ -1863,38 +2318,338 @@ static zval *dom_nodemap_read_dimension(zend_object *object, zval *offset, int t
php_dom_named_node_map_get_item_into_zval(php_dom_obj_from_obj(object)->ptr, lval, rv);
return rv;
-} /* }}} end dom_nodemap_read_dimension */
+}
static int dom_nodemap_has_dimension(zend_object *object, zval *member, int check_empty)
{
ZVAL_DEREF(member);
+ /* If it exists, it cannot be empty because nodes aren't empty. */
+ ZEND_IGNORE_VALUE(check_empty);
+
zend_long offset;
if (dom_nodemap_or_nodelist_process_offset_as_named(member, &offset)) {
/* exceptional case, switch to named lookup */
- return php_dom_named_node_map_get_named_item(php_dom_obj_from_obj(object)->ptr, Z_STRVAL_P(member), false) != NULL;
+ return php_dom_named_node_map_get_named_item(php_dom_obj_from_obj(object)->ptr, Z_STR_P(member), false) != NULL;
}
return offset >= 0 && offset < php_dom_get_namednodemap_length(php_dom_obj_from_obj(object));
-} /* }}} end dom_nodemap_has_dimension */
+}
-xmlNodePtr dom_clone_node(xmlNodePtr node, xmlDocPtr doc, const dom_object *intern, bool recursive)
+static zval *dom_modern_nodemap_read_dimension(zend_object *object, zval *offset, int type, zval *rv)
{
- /* See http://www.xmlsoft.org/html/libxml-tree.html#xmlDocCopyNode for meaning of values */
- int extended_recursive = recursive;
- if (!recursive && node->type == XML_ELEMENT_NODE) {
- extended_recursive = 2;
+ if (UNEXPECTED(!offset)) {
+ zend_throw_error(NULL, "Cannot append to %s", ZSTR_VAL(object->ce->name));
+ return NULL;
}
- xmlNodePtr copy = xmlDocCopyNode(node, doc, extended_recursive);
- if (UNEXPECTED(!copy)) {
+
+ dom_nnodemap_object *map = php_dom_obj_from_obj(object)->ptr;
+
+ ZVAL_DEREF(offset);
+ if (Z_TYPE_P(offset) == IS_STRING) {
+ zend_ulong lval;
+ if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), lval)) {
+ php_dom_named_node_map_get_item_into_zval(map, (zend_long) lval, rv);
+ } else {
+ php_dom_named_node_map_get_named_item_into_zval(map, Z_STR_P(offset), rv);
+ }
+ } else if (Z_TYPE_P(offset) == IS_LONG) {
+ php_dom_named_node_map_get_item_into_zval(map, Z_LVAL_P(offset), rv);
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ php_dom_named_node_map_get_item_into_zval(map, zend_dval_to_lval_safe(Z_DVAL_P(offset)), rv);
+ } else {
+ zend_illegal_container_offset(object->ce->name, offset, type);
return NULL;
}
- if (intern->document && intern->document->is_modern_api_class) {
- dom_mark_namespaces_for_copy_based_on_copy(copy, node);
+ return rv;
+}
+
+static int dom_modern_nodemap_has_dimension(zend_object *object, zval *member, int check_empty)
+{
+ /* If it exists, it cannot be empty because nodes aren't empty. */
+ ZEND_IGNORE_VALUE(check_empty);
+
+ dom_object *obj = php_dom_obj_from_obj(object);
+ dom_nnodemap_object *map = obj->ptr;
+
+ ZVAL_DEREF(member);
+ if (Z_TYPE_P(member) == IS_STRING) {
+ zend_ulong lval;
+ if (ZEND_HANDLE_NUMERIC(Z_STR_P(member), lval)) {
+ return (zend_long) lval >= 0 && (zend_long) lval < php_dom_get_namednodemap_length(obj);
+ } else {
+ return php_dom_named_node_map_get_named_item(map, Z_STR_P(member), false) != NULL;
+ }
+ } else if (Z_TYPE_P(member) == IS_LONG) {
+ zend_long offset = Z_LVAL_P(member);
+ return offset >= 0 && offset < php_dom_get_namednodemap_length(obj);
+ } else if (Z_TYPE_P(member) == IS_DOUBLE) {
+ zend_long offset = zend_dval_to_lval_safe(Z_DVAL_P(member));
+ return offset >= 0 && offset < php_dom_get_namednodemap_length(obj);
+ } else {
+ zend_illegal_container_offset(object->ce->name, member, BP_VAR_IS);
+ return 0;
+ }
+}
+
+static xmlNodePtr dom_clone_container_helper(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr src_node, xmlDocPtr dst_doc)
+{
+ xmlNodePtr clone = xmlDocCopyNode(src_node, dst_doc, 0);
+ if (EXPECTED(clone != NULL)) {
+ /* Set namespace to the original, reconciliation will fix this up. */
+ clone->ns = src_node->ns;
+
+ if (src_node->type == XML_ELEMENT_NODE) {
+ xmlAttrPtr last_added_attr = NULL;
+
+ if (src_node->nsDef != NULL) {
+ xmlNsPtr current_ns = src_node->nsDef;
+ do {
+ php_dom_ns_compat_mark_attribute(ns_mapper, clone, current_ns);
+ } while ((current_ns = current_ns->next) != NULL);
+
+ last_added_attr = clone->properties;
+ while (last_added_attr->next != NULL) {
+ last_added_attr = last_added_attr->next;
+ }
+ }
+
+ /* Attribute cloning logic. */
+ for (xmlAttrPtr attr = src_node->properties; attr != NULL; attr = attr->next) {
+ xmlAttrPtr new_attr = (xmlAttrPtr) xmlDocCopyNode((xmlNodePtr) attr, dst_doc, 0);
+ if (UNEXPECTED(new_attr == NULL)) {
+ xmlFreeNode(clone);
+ return NULL;
+ }
+ if (last_added_attr == NULL) {
+ clone->properties = new_attr;
+ } else {
+ new_attr->prev = last_added_attr;
+ last_added_attr->next = new_attr;
+ }
+ new_attr->parent = clone;
+ last_added_attr = new_attr;
+
+ /* Set namespace to the original, reconciliation will fix this up. */
+ new_attr->ns = attr->ns;
+ }
+ }
}
+ return clone;
+}
+
+static xmlNodePtr dom_clone_helper(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr src_node, xmlDocPtr dst_doc, bool recursive)
+{
+ xmlNodePtr outer_clone = dom_clone_container_helper(ns_mapper, src_node, dst_doc);
+
+ if (!recursive || (src_node->type != XML_ELEMENT_NODE && src_node->type != XML_DOCUMENT_FRAG_NODE && src_node->type != XML_DOCUMENT_NODE && src_node->type != XML_HTML_DOCUMENT_NODE)) {
+ return outer_clone;
+ }
+
+ /* Handle dtd separately, because it is linked twice and requires a special copy function. */
+ if (src_node->type == XML_DOCUMENT_NODE || src_node->type == XML_HTML_DOCUMENT_NODE) {
+ dst_doc = (xmlDocPtr) outer_clone;
- return copy;
+ xmlDtdPtr original_subset = ((xmlDocPtr) src_node)->intSubset;
+ if (original_subset != NULL) {
+ dst_doc->intSubset = xmlCopyDtd(((xmlDocPtr) src_node)->intSubset);
+ if (UNEXPECTED(dst_doc->intSubset == NULL)) {
+ xmlFreeNode(outer_clone);
+ return NULL;
+ }
+ dst_doc->intSubset->parent = dst_doc;
+ xmlSetTreeDoc((xmlNodePtr) dst_doc->intSubset, dst_doc);
+ dst_doc->children = dst_doc->last = (xmlNodePtr) dst_doc->intSubset;
+ }
+ }
+
+ xmlNodePtr cloned_parent = outer_clone;
+ xmlNodePtr base = src_node;
+ src_node = src_node->children;
+ while (src_node != NULL) {
+ ZEND_ASSERT(src_node != base);
+
+ xmlNodePtr cloned;
+ if (src_node->type == XML_ELEMENT_NODE) {
+ cloned = dom_clone_container_helper(ns_mapper, src_node, dst_doc);
+ } else if (src_node->type == XML_DTD_NODE) {
+ /* Already handled. */
+ cloned = NULL;
+ } else {
+ cloned = xmlDocCopyNode(src_node, dst_doc, 1);
+ }
+
+ if (EXPECTED(cloned != NULL)) {
+ if (cloned_parent->children == NULL) {
+ cloned_parent->children = cloned;
+ } else {
+ cloned->prev = cloned_parent->last;
+ cloned_parent->last->next = cloned;
+ }
+ cloned->parent = cloned_parent;
+ cloned_parent->last = cloned;
+ }
+
+ if (src_node->type == XML_ELEMENT_NODE && src_node->children) {
+ cloned_parent = cloned;
+ src_node = src_node->children;
+ } else if (src_node->next) {
+ src_node = src_node->next;
+ } else {
+ /* Go upwards, until we find a parent node with a next sibling, or until we hit the base. */
+ do {
+ src_node = src_node->parent;
+ if (src_node == base) {
+ return outer_clone;
+ }
+ cloned_parent = cloned_parent->parent;
+ } while (src_node->next == NULL);
+ src_node = src_node->next;
+ }
+ }
+
+ return outer_clone;
+}
+
+xmlNodePtr dom_clone_node(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr node, xmlDocPtr doc, bool recursive)
+{
+ if (node->type == XML_DTD_NODE) {
+ /* The behaviour w.r.t. the internal subset is implementation-defined according to DOM 3.
+ * This follows what e.g. Java and C# do: copy it regardless of the recursiveness.
+ * Makes sense as the subset is not exactly a child in the normal sense. */
+ xmlDtdPtr dtd = xmlCopyDtd((xmlDtdPtr) node);
+ xmlSetTreeDoc((xmlNodePtr) dtd, doc);
+ return (xmlNodePtr) dtd;
+ }
+
+ if (ns_mapper != NULL) {
+ xmlNodePtr clone = dom_clone_helper(ns_mapper, node, doc, recursive);
+ if (EXPECTED(clone != NULL)) {
+ if (clone->type == XML_DOCUMENT_NODE || clone->type == XML_HTML_DOCUMENT_NODE || clone->type == XML_DOCUMENT_FRAG_NODE) {
+ for (xmlNodePtr child = clone->children; child != NULL; child = child->next) {
+ php_dom_libxml_reconcile_modern(ns_mapper, child);
+ }
+ } else {
+ php_dom_libxml_reconcile_modern(ns_mapper, clone);
+ }
+ }
+ return clone;
+ } else {
+ /* See http://www.xmlsoft.org/html/libxml-tree.html#xmlDocCopyNode for meaning of values */
+ int extended_recursive = recursive;
+ if (!recursive && node->type == XML_ELEMENT_NODE) {
+ extended_recursive = 2;
+ }
+ return xmlDocCopyNode(node, doc, extended_recursive);
+ }
+}
+
+bool php_dom_has_child_of_type(xmlNodePtr node, xmlElementType type)
+{
+ xmlNodePtr child = node->children;
+
+ while (child != NULL) {
+ if (child->type == type) {
+ return true;
+ }
+
+ child = child->next;
+ }
+
+ return false;
+}
+
+bool php_dom_has_sibling_following_node(xmlNodePtr node, xmlElementType type)
+{
+ xmlNodePtr next = node->next;
+
+ while (next != NULL) {
+ if (next->type == type) {
+ return true;
+ }
+
+ next = next->next;
+ }
+
+ return false;
+}
+
+bool php_dom_has_sibling_preceding_node(xmlNodePtr node, xmlElementType type)
+{
+ xmlNodePtr prev = node->prev;
+
+ while (prev != NULL) {
+ if (prev->type == type) {
+ return true;
+ }
+
+ prev = prev->prev;
+ }
+
+ return false;
+}
+
+xmlAttrPtr php_dom_get_attribute_node(xmlNodePtr elem, const xmlChar *name, size_t name_len)
+{
+ xmlChar *name_processed = BAD_CAST name;
+ if (php_dom_ns_is_html_and_document_is_html(elem)) {
+ char *lowercase_copy = zend_str_tolower_dup_ex((char *) name, name_len);
+ if (lowercase_copy != NULL) {
+ name_processed = BAD_CAST lowercase_copy;
+ }
+ }
+
+ xmlAttrPtr ret = NULL;
+ for (xmlAttrPtr attr = elem->properties; attr != NULL; attr = attr->next) {
+ if (dom_match_qualified_name_according_to_spec(name_processed, (xmlNodePtr) attr)) {
+ ret = attr;
+ break;
+ }
+ }
+
+ if (name_processed != name) {
+ efree(name_processed);
+ }
+
+ return ret;
+}
+
+/* Workaround for a libxml2 bug on Windows: https://gitlab.gnome.org/GNOME/libxml2/-/issues/611. */
+xmlChar *php_dom_libxml_fix_file_path(xmlChar *path)
+{
+ if (strncmp((char *) path, "file:/", sizeof("file:/") - 1) == 0) {
+ if (path[6] != '/' && path[6] != '\0' && path[7] != '/' && path[7] != '\0') {
+ /* The path is file:/xx... where xx != "//", which is broken */
+ xmlChar *new_path = xmlStrdup(BAD_CAST "file:///");
+ if (UNEXPECTED(new_path == NULL)) {
+ return path;
+ }
+ new_path = xmlStrcat(new_path, path + 6);
+ xmlFree(path);
+ return new_path;
+ }
+ }
+ return path;
+}
+
+xmlDocPtr php_dom_create_html_doc(void)
+{
+#ifdef LIBXML_HTML_ENABLED
+ xmlDocPtr lxml_doc = htmlNewDocNoDtD(NULL, NULL);
+ if (EXPECTED(lxml_doc)) {
+ lxml_doc->dict = xmlDictCreate();
+ }
+#else
+ /* If HTML support is not enabled, then htmlNewDocNoDtD() is not available.
+ * This code mimics the behaviour. */
+ xmlDocPtr lxml_doc = xmlNewDoc((const xmlChar *) "1.0");
+ if (EXPECTED(lxml_doc)) {
+ lxml_doc->type = XML_HTML_DOCUMENT_NODE;
+ lxml_doc->dict = xmlDictCreate();
+ }
+#endif
+ return lxml_doc;
}
#endif /* HAVE_DOM */
diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h
index 860e0bd697afc..fc94ed00f44cd 100644
--- a/ext/dom/php_dom.h
+++ b/ext/dom/php_dom.h
@@ -83,7 +83,7 @@ typedef struct _dom_nnodemap_object {
int nodetype;
int cached_length;
xmlHashTable *ht;
- xmlChar *local;
+ xmlChar *local, *local_lower;
xmlChar *ns;
php_libxml_cache_tag cache_tag;
dom_object *cached_obj;
@@ -107,6 +107,16 @@ typedef struct {
dom_object dom;
} dom_object_namespace_node;
+typedef enum _dom_iterator_type {
+ DOM_NODELIST,
+ DOM_NAMEDNODEMAP,
+ DOM_DTD_NAMEDNODEMAP,
+ DOM_HTMLCOLLECTION,
+} dom_iterator_type;
+
+struct _php_dom_libxml_ns_mapper;
+typedef struct _php_dom_libxml_ns_mapper php_dom_libxml_ns_mapper;
+
static inline dom_object_namespace_node *php_dom_namespace_node_obj_from_obj(zend_object *obj) {
return (dom_object_namespace_node*)((char*)(obj) - XtOffsetOf(dom_object_namespace_node, dom.std));
}
@@ -133,14 +143,15 @@ xmlNsPtr dom_get_ns_unchecked(xmlNodePtr nodep, char *uri, char *prefix);
void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep);
void dom_reconcile_ns_list(xmlDocPtr doc, xmlNodePtr nodep, xmlNodePtr last);
xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName);
-void dom_normalize (xmlNodePtr nodep);
-xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, char *ns, char *local, int *cur, int index);
-void php_dom_create_implementation(zval *retval);
+void php_dom_normalize_legacy(xmlNodePtr nodep);
+void php_dom_normalize_modern(xmlNodePtr nodep);
+xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, xmlChar *ns, xmlChar *local, xmlChar *local_lower, int *cur, int index);
+void php_dom_create_implementation(zval *retval, bool modern);
int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child);
bool dom_has_feature(zend_string *feature, zend_string *version);
int dom_node_is_read_only(xmlNodePtr node);
-int dom_node_children_valid(xmlNodePtr node);
-void php_dom_create_iterator(zval *return_value, int ce_type);
+bool dom_node_children_valid(xmlNodePtr node);
+void php_dom_create_iterator(zval *return_value, dom_iterator_type iterator_type, bool modern);
void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xmlHashTablePtr ht, const char *local, size_t local_len, const char *ns, size_t ns_len);
xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID);
xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index);
@@ -150,21 +161,51 @@ void dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece
xmlNodePtr php_dom_create_fake_namespace_decl(xmlNodePtr nodep, xmlNsPtr original, zval *return_value, dom_object *parent_intern);
void php_dom_get_content_into_zval(const xmlNode *nodep, zval *target, bool default_is_null);
zend_string *dom_node_concatenated_name_helper(size_t name_len, const char *name, size_t prefix_len, const char *prefix);
-zend_string *dom_node_get_node_name_attribute_or_element(const xmlNode *nodep);
+zend_string *dom_node_get_node_name_attribute_or_element(const xmlNode *nodep, bool uppercase);
bool php_dom_is_node_connected(const xmlNode *node);
bool php_dom_adopt_node(xmlNodePtr nodep, dom_object *dom_object_new_document, xmlDocPtr new_document);
xmlNsPtr dom_get_ns_resolve_prefix_conflict(xmlNodePtr tree, const char *uri);
-void php_dom_reconcile_attribute_namespace_after_insertion(xmlAttrPtr attrp);
-
+int dom_validate_and_extract(const zend_string *namespace, const zend_string *qname, xmlChar **localName, xmlChar **prefix);
+bool dom_match_qualified_name_according_to_spec(const xmlChar *qname, const xmlNode *nodep);
+bool php_dom_has_sibling_following_node(xmlNodePtr node, xmlElementType type);
+bool php_dom_has_sibling_preceding_node(xmlNodePtr node, xmlElementType type);
+bool php_dom_has_child_of_type(xmlNodePtr node, xmlElementType type);
+void php_dom_update_document_after_clone(dom_object *original, xmlNodePtr original_node, dom_object *clone, xmlNodePtr cloned_node);
void php_dom_document_constructor(INTERNAL_FUNCTION_PARAMETERS);
-
+xmlAttrPtr php_dom_get_attribute_node(xmlNodePtr elem, const xmlChar *name, size_t name_len);
+xmlChar *php_dom_libxml_fix_file_path(xmlChar *path);
+void dom_document_convert_to_modern(php_libxml_ref_obj *document, xmlDocPtr lxml_doc);
dom_object *php_dom_instantiate_object_helper(zval *return_value, zend_class_entry *ce, xmlNodePtr obj, dom_object *parent);
+xmlDocPtr php_dom_create_html_doc(void);
+
+static zend_always_inline xmlNodePtr php_dom_next_in_tree_order(const xmlNode *nodep, const xmlNode *basep)
+{
+ if (nodep->next) {
+ return nodep->next;
+ } else {
+ /* Go upwards, until we find a parent node with a next sibling, or until we hit the base. */
+ do {
+ nodep = nodep->parent;
+ if (nodep == basep) {
+ return NULL;
+ }
+ /* This shouldn't happen, unless there's an invalidation bug somewhere. */
+ if (UNEXPECTED(nodep == NULL)) {
+ zend_throw_error(NULL, "Current node in traversal is not in the document. Please report this as a bug in php-src.");
+ return NULL;
+ }
+ } while (nodep->next == NULL);
+ return nodep->next;
+ }
+}
typedef enum {
DOM_LOAD_STRING = 0,
DOM_LOAD_FILE = 1,
} dom_load_mode;
+#define DOM_DOCUMENT_MALFORMED ((xmlDocPtr) -1)
+
xmlDocPtr dom_document_parser(zval *id, dom_load_mode mode, const char *source, size_t source_len, size_t options, xmlCharEncodingHandlerPtr encoding);
/* parentnode */
@@ -175,20 +216,23 @@ void dom_parent_node_before(dom_object *context, zval *nodes, uint32_t nodesc);
void dom_parent_node_replace_children(dom_object *context, zval *nodes, uint32_t nodesc);
void dom_child_node_remove(dom_object *context);
void dom_child_replace_with(dom_object *context, zval *nodes, uint32_t nodesc);
-
void dom_remove_all_children(xmlNodePtr nodep);
+bool php_dom_fragment_insertion_hierarchy_check_pre_insertion(xmlNodePtr parent, xmlNodePtr node, xmlNodePtr child);
+bool php_dom_fragment_insertion_hierarchy_check_replace(xmlNodePtr parent, xmlNodePtr node, xmlNodePtr child);
+void php_dom_node_append(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePtr parent);
+bool php_dom_pre_insert(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePtr parent, xmlNodePtr insertion_point);
+bool php_dom_pre_insert_is_parent_invalid(xmlNodePtr parent);
/* nodemap and nodelist APIs */
-xmlNodePtr php_dom_named_node_map_get_named_item(dom_nnodemap_object *objmap, const char *named, bool may_transform);
-void php_dom_named_node_map_get_named_item_into_zval(dom_nnodemap_object *objmap, const char *named, zval *return_value);
+xmlNodePtr php_dom_named_node_map_get_named_item(dom_nnodemap_object *objmap, const zend_string *named, bool may_transform);
+void php_dom_named_node_map_get_named_item_into_zval(dom_nnodemap_object *objmap, const zend_string *named, zval *return_value);
xmlNodePtr php_dom_named_node_map_get_item(dom_nnodemap_object *objmap, zend_long index);
void php_dom_named_node_map_get_item_into_zval(dom_nnodemap_object *objmap, zend_long index, zval *return_value);
void php_dom_nodelist_get_item_into_zval(dom_nnodemap_object *objmap, zend_long index, zval *return_value);
int php_dom_get_namednodemap_length(dom_object *obj);
int php_dom_get_nodelist_length(dom_object *obj);
-xmlNodePtr dom_clone_node(xmlNodePtr node, xmlDocPtr doc, const dom_object *intern, bool recursive);
-void dom_mark_namespaces_for_copy_based_on_copy(xmlNodePtr copy, const xmlNode *original);
+xmlNodePtr dom_clone_node(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr node, xmlDocPtr doc, bool recursive);
#define DOM_GET_INTERN(__id, __intern) { \
__intern = Z_DOMOBJ_P(__id); \
@@ -205,9 +249,6 @@ void dom_mark_namespaces_for_copy_based_on_copy(xmlNodePtr copy, const xmlNode *
__ptr = (__prtype)((php_libxml_node_ptr *)__intern->ptr)->node; \
}
-#define DOM_NODELIST 0
-#define DOM_NAMEDNODEMAP 1
-
static zend_always_inline bool php_dom_is_cache_tag_stale_from_doc_ptr(const php_libxml_cache_tag *cache_tag, const php_libxml_ref_obj *doc_ptr)
{
ZEND_ASSERT(cache_tag != NULL);
@@ -223,11 +264,11 @@ static zend_always_inline bool php_dom_is_cache_tag_stale_from_doc_ptr(const php
static zend_always_inline bool php_dom_is_cache_tag_stale_from_node(const php_libxml_cache_tag *cache_tag, const xmlNodePtr node)
{
ZEND_ASSERT(node != NULL);
- php_libxml_node_ptr *private = node->_private;
- if (!private) {
+ php_libxml_node_ptr *_private = node->_private;
+ if (!_private) {
return true;
}
- php_libxml_node_object *object_private = private->_private;
+ php_libxml_node_object *object_private = _private->_private;
if (!object_private || !object_private->document) {
return true;
}
@@ -237,15 +278,45 @@ static zend_always_inline bool php_dom_is_cache_tag_stale_from_node(const php_li
static zend_always_inline void php_dom_mark_cache_tag_up_to_date_from_node(php_libxml_cache_tag *cache_tag, const xmlNodePtr node)
{
ZEND_ASSERT(cache_tag != NULL);
- php_libxml_node_ptr *private = node->_private;
- if (private) {
- php_libxml_node_object *object_private = private->_private;
+ php_libxml_node_ptr *_private = node->_private;
+ if (_private) {
+ php_libxml_node_object *object_private = _private->_private;
if (object_private->document) {
cache_tag->modification_nr = object_private->document->cache_tag.modification_nr;
}
}
}
+static zend_always_inline bool php_dom_follow_spec_doc_ref(const php_libxml_ref_obj *document)
+{
+ return document != NULL && document->class_type == PHP_LIBXML_CLASS_MODERN;
+}
+
+static zend_always_inline bool php_dom_follow_spec_intern(const dom_object *intern)
+{
+ ZEND_ASSERT(intern != NULL);
+ return php_dom_follow_spec_doc_ref(intern->document);
+}
+
+static zend_always_inline bool php_dom_follow_spec_node(const xmlNode *node)
+{
+ ZEND_ASSERT(node != NULL);
+ php_libxml_node_ptr *_private = node->_private;
+ if (_private) {
+ php_libxml_node_object *object_private = _private->_private;
+ if (object_private->document) {
+ return php_dom_follow_spec_doc_ref(object_private->document);
+ }
+ }
+ return false;
+}
+
+static zend_always_inline php_dom_libxml_ns_mapper *php_dom_get_ns_mapper(dom_object *intern)
+{
+ ZEND_ASSERT(intern->document != NULL);
+ return (php_dom_libxml_ns_mapper *) intern->document->private_data;
+}
+
PHP_MINIT_FUNCTION(dom);
PHP_MSHUTDOWN_FUNCTION(dom);
PHP_MINFO_FUNCTION(dom);
diff --git a/ext/dom/php_dom.stub.php b/ext/dom/php_dom.stub.php
index 8a6e87676f2eb..7f3a928a093a4 100644
--- a/ext/dom/php_dom.stub.php
+++ b/ext/dom/php_dom.stub.php
@@ -239,7 +239,6 @@
*/
const DOM_VALIDATION_ERR = UNKNOWN;
- /** @alias DOM\DocumentType */
class DOMDocumentType extends DOMNode
{
/** @readonly */
@@ -261,19 +260,16 @@ class DOMDocumentType extends DOMNode
public ?string $internalSubset;
}
- /** @alias DOM\CDATASection */
class DOMCdataSection extends DOMText
{
public function __construct(string $data) {}
}
- /** @alias DOM\Comment */
class DOMComment extends DOMCharacterData
{
public function __construct(string $data = "") {}
}
- /** @alias DOM\ParentNode */
interface DOMParentNode
{
/** @param DOMNode|string $nodes */
@@ -286,7 +282,6 @@ public function prepend(...$nodes): void;
public function replaceChildren(...$nodes): void;
}
- /** @alias DOM\ChildNode */
interface DOMChildNode
{
public function remove(): void;
@@ -301,7 +296,6 @@ public function after(...$nodes): void;
public function replaceWith(...$nodes): void;
}
- /** @alias DOM\Node */
class DOMNode
{
public const int DOCUMENT_POSITION_DISCONNECTED = 0x01;
@@ -347,7 +341,7 @@ class DOMNode
public bool $isConnected;
/** @readonly */
- public ?DOM\Document $ownerDocument;
+ public ?DOMDocument $ownerDocument;
/** @readonly */
public ?string $namespaceURI;
@@ -426,7 +420,6 @@ public function __sleep(): array {}
public function __wakeup(): void {}
}
- /** @alias DOM\NameSpaceNode */
class DOMNameSpaceNode
{
/** @readonly */
@@ -481,7 +474,6 @@ public function createDocumentType(string $qualifiedName, string $publicId = "",
public function createDocument(?string $namespace = null, string $qualifiedName = "", ?DOMDocumentType $doctype = null): DOMDocument {}
}
- /** @alias DOM\DocumentFragment */
class DOMDocumentFragment extends DOMNode implements DOMParentNode
{
/** @readonly */
@@ -512,12 +504,11 @@ public function prepend(...$nodes): void {}
/**
* @param DOMNode|string $nodes
- * @implementation-alias DOM\Document::replaceChildren
+ * @implementation-alias DOMDocument::replaceChildren
*/
public function replaceChildren(...$nodes): void {}
}
- /** @alias DOM\NodeList */
class DOMNodeList implements IteratorAggregate, Countable
{
/** @readonly */
@@ -532,7 +523,6 @@ public function getIterator(): Iterator {}
public function item(int $index) {}
}
- /** @alias DOM\CharacterData */
class DOMCharacterData extends DOMNode implements DOMChildNode
{
public string $data;
@@ -583,7 +573,6 @@ public function before(... $nodes): void {}
public function after(...$nodes): void {}
}
- /** @alias DOM\Attr */
class DOMAttr extends DOMNode
{
/** @readonly */
@@ -606,7 +595,6 @@ public function __construct(string $name, string $value = "") {}
public function isId(): bool {}
}
- /** @alias DOM\Element */
class DOMElement extends DOMNode implements \DOMParentNode, \DOMChildNode
{
/** @readonly */
@@ -672,7 +660,7 @@ public function removeAttributeNS(?string $namespace, string $localName): void {
public function removeAttributeNode(DOMAttr $attr) {}
/** @return DOMAttr|bool */
- public function setAttribute(string $qualifiedName, string $value) {} // TODO return type shouldn't depend on the call scope
+ public function setAttribute(string $qualifiedName, string $value) {}
/** @tentative-return-type */
public function setAttributeNS(?string $namespace, string $qualifiedName, string $value): void {}
@@ -719,17 +707,25 @@ public function insertAdjacentElement(string $where, DOMElement $element): ?DOME
public function insertAdjacentText(string $where, string $data): void {}
}
- class DOMDocument extends DOM\Document
+ class DOMDocument extends DOMNode implements DOMParentNode
{
+ /** @readonly */
+ public ?DOMDocumentType $doctype;
+
/** @readonly */
public DOMImplementation $implementation;
+ /** @readonly */
+ public ?DOMElement $documentElement;
+
/**
* @readonly
* @deprecated
*/
public ?string $actualEncoding;
+ public ?string $encoding;
+
/** @readonly */
public ?string $xmlEncoding;
@@ -741,6 +737,10 @@ class DOMDocument extends DOM\Document
public ?string $xmlVersion;
+ public bool $strictErrorChecking;
+
+ public ?string $documentURI;
+
/**
* @readonly
* @deprecated
@@ -759,17 +759,77 @@ class DOMDocument extends DOM\Document
public bool $substituteEntities;
+ /** @readonly */
+ public ?DOMElement $firstElementChild;
+
+ /** @readonly */
+ public ?DOMElement $lastElementChild;
+
+ /** @readonly */
+ public int $childElementCount;
+
public function __construct(string $version = "1.0", string $encoding = "") {}
+ /** @return DOMAttr|false */
+ public function createAttribute(string $localName) {}
+
+ /** @return DOMAttr|false */
+ public function createAttributeNS(?string $namespace, string $qualifiedName) {}
+
+ /** @return DOMCdataSection|false */
+ public function createCDATASection(string $data) {}
+
+ /** @tentative-return-type */
+ public function createComment(string $data): DOMComment {}
+
+ /** @tentative-return-type */
+ public function createDocumentFragment(): DOMDocumentFragment {}
+
+ /** @return DOMElement|false */
+ public function createElement(string $localName, string $value = "") {}
+
+ /** @return DOMElement|false */
+ public function createElementNS(?string $namespace, string $qualifiedName, string $value = "") {}
+
/** @return DOMEntityReference|false */
public function createEntityReference(string $name) {}
+ /** @return DOMProcessingInstruction|false */
+ public function createProcessingInstruction(string $target, string $data = "") {}
+
+ /** @tentative-return-type */
+ public function createTextNode(string $data): DOMText {}
+
+ /** @tentative-return-type */
+ public function getElementById(string $elementId): ?DOMElement {}
+
+ /**
+ * @tentative-return-type
+ * @implementation-alias DOMElement::getElementsByTagName
+ */
+ public function getElementsByTagName(string $qualifiedName): DOMNodeList {}
+
+ /**
+ * @tentative-return-type
+ * @implementation-alias DOMElement::getElementsByTagNameNS
+ */
+ public function getElementsByTagNameNS(?string $namespace, string $localName): DOMNodeList {}
+
+ /** @return DOMNode|false */
+ public function importNode(DOMNode $node, bool $deep = false) {}
+
/** @tentative-return-type */
public function load(string $filename, int $options = 0): bool {}
/** @tentative-return-type */
public function loadXML(string $source, int $options = 0): bool {}
+ /** @tentative-return-type */
+ public function normalizeDocument(): void {}
+
+ /** @tentative-return-type */
+ public function registerNodeClass(string $baseClass, ?string $extendedClass): true {}
+
/** @tentative-return-type */
public function save(string $filename, int $options = 0): int|false {}
@@ -790,11 +850,43 @@ public function saveHTMLFile(string $filename): int|false {}
/** @tentative-return-type */
public function saveXML(?DOMNode $node = null, int $options = 0): string|false {}
+#ifdef LIBXML_SCHEMAS_ENABLED
+ /** @tentative-return-type */
+ public function schemaValidate(string $filename, int $flags = 0): bool {}
+
+ /** @tentative-return-type */
+ public function schemaValidateSource(string $source, int $flags = 0): bool {}
+
+ /** @tentative-return-type */
+ public function relaxNGValidate(string $filename): bool {}
+
+ /** @tentative-return-type */
+ public function relaxNGValidateSource(string $source): bool {}
+#endif
+
/** @tentative-return-type */
public function validate(): bool {}
/** @tentative-return-type */
public function xinclude(int $options = 0): int|false {}
+
+ /** @tentative-return-type */
+ public function adoptNode(DOMNode $node): DOMNode|false {}
+
+ /**
+ * @param DOMNode|string $nodes
+ * @implementation-alias DOMElement::append
+ */
+ public function append(...$nodes): void {}
+
+ /**
+ * @param DOMNode|string $nodes
+ * @implementation-alias DOMElement::prepend
+ */
+ public function prepend(...$nodes): void {}
+
+ /** @param DOMNode|string $nodes */
+ public function replaceChildren(...$nodes): void {}
}
/** @alias DOM\DOMException */
@@ -807,7 +899,6 @@ final class DOMException extends Exception
public $code = 0; // TODO add proper type (i.e. int|string)
}
- /** @alias DOM\Text */
class DOMText extends DOMCharacterData
{
/** @readonly */
@@ -828,20 +919,19 @@ public function isElementContentWhitespace(): bool {}
public function splitText(int $offset) {}
}
- /** @alias DOM\NamedNodeMap */
class DOMNamedNodeMap implements IteratorAggregate, Countable
{
/** @readonly */
public int $length;
/** @tentative-return-type */
- public function getNamedItem(string $qualifiedName): ?DOMNode {} // TODO DOM spec returns DOMAttr
+ public function getNamedItem(string $qualifiedName): ?DOMNode {}
/** @tentative-return-type */
- public function getNamedItemNS(?string $namespace, string $localName): ?DOMNode {} // TODO DOM spec returns DOMAttr
+ public function getNamedItemNS(?string $namespace, string $localName): ?DOMNode {}
/** @tentative-return-type */
- public function item(int $index): ?DOMNode {} // TODO DOM spec returns DOMAttr
+ public function item(int $index): ?DOMNode {}
/** @tentative-return-type */
public function count(): int {}
@@ -849,7 +939,6 @@ public function count(): int {}
public function getIterator(): Iterator {}
}
- /** @alias DOM\Entity */
class DOMEntity extends DOMNode
{
/** @readonly */
@@ -880,13 +969,11 @@ class DOMEntity extends DOMNode
public ?string $version = null;
}
- /** @alias DOM\EntityReference */
class DOMEntityReference extends DOMNode
{
public function __construct(string $name) {}
}
- /** @alias DOM\Notation */
class DOMNotation extends DOMNode
{
/** @readonly */
@@ -896,7 +983,6 @@ class DOMNotation extends DOMNode
public string $systemId;
}
- /** @alias DOM\ProcessingInstruction */
class DOMProcessingInstruction extends DOMNode
{
/** @readonly */
@@ -908,18 +994,15 @@ public function __construct(string $name, string $value = "") {}
}
#ifdef LIBXML_XPATH_ENABLED
- /**
- * @not-serializable
- * @alias DOM\XPath
- */
+ /** @not-serializable */
class DOMXPath
{
/** @readonly */
- public DOM\Document $document;
+ public DOMDocument $document;
public bool $registerNodeNamespaces;
- public function __construct(DOM\Document $document, bool $registerNodeNS = true) {}
+ public function __construct(DOMDocument $document, bool $registerNodeNS = true) {}
/** @tentative-return-type */
public function evaluate(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true): mixed {}
@@ -944,11 +1027,6 @@ function dom_import_simplexml(object $node): DOMElement {}
namespace DOM
{
- /**
- * @var int
- * @cvalue PHP_ERR
- */
- const PHP_ERR = UNKNOWN;
/**
* @var int
* @cvalue INDEX_SIZE_ERR
@@ -1019,11 +1097,6 @@ function dom_import_simplexml(object $node): DOMElement {}
* @cvalue NAMESPACE_ERR
*/
const NAMESPACE_ERR = UNKNOWN;
- /**
- * @var int
- * @cvalue INVALID_ACCESS_ERR
- */
- const INVALID_ACCESS_ERR = UNKNOWN;
/**
* @var int
* @cvalue VALIDATION_ERR
@@ -1036,119 +1109,491 @@ function dom_import_simplexml(object $node): DOMElement {}
*/
const HTML_NO_DEFAULT_NS = UNKNOWN;
- abstract class Document extends \DOMNode implements \DOMParentNode
+ interface ParentNode
+ {
+ public function append(Node|string ...$nodes): void;
+ public function prepend(Node|string ...$nodes): void;
+ public function replaceChildren(Node|string ...$nodes): void;
+ }
+
+ interface ChildNode
{
+ public function remove(): void;
+ public function before(Node|string ...$nodes): void;
+ public function after(Node|string ...$nodes): void;
+ public function replaceWith(Node|string ...$nodes): void;
+ }
+
+ /**
+ * @strict-properties
+ * @not-serializable
+ */
+ class Implementation
+ {
+ public function createDocumentType(string $qualifiedName, string $publicId, string $systemId): DocumentType {}
+
+ public function createDocument(?string $namespace, string $qualifiedName, ?DocumentType $doctype = null): XMLDocument {}
+
+ public function createHTMLDocument(?string $title = null): HTMLDocument {}
+ }
+
+ /** @strict-properties */
+ class Node
+ {
+ private final function __construct() {}
+
/** @readonly */
- public ?DocumentType $doctype;
+ public int $nodeType;
+ /** @readonly */
+ public string $nodeName;
/** @readonly */
- public ?Element $documentElement;
+ public string $baseURI;
- public ?string $encoding;
+ /** @readonly */
+ public bool $isConnected;
+ /** @readonly */
+ public ?Document $ownerDocument;
- public bool $strictErrorChecking;
+ /** @implementation-alias DOMNode::getRootNode */
+ public function getRootNode(array $options = []): Node {}
+ /** @readonly */
+ public ?Node $parentNode;
+ /** @readonly */
+ public ?Element $parentElement;
+ /** @implementation-alias DOMNode::hasChildNodes */
+ public function hasChildNodes(): bool {}
+ /** @readonly */
+ public NodeList $childNodes;
+ /** @readonly */
+ public ?Node $firstChild;
+ /** @readonly */
+ public ?Node $lastChild;
+ /** @readonly */
+ public ?Node $previousSibling;
+ /** @readonly */
+ public ?Node $nextSibling;
- public ?string $documentURI;
+ public ?string $nodeValue;
+ public ?string $textContent;
+ /** @implementation-alias DOMNode::normalize */
+ public function normalize(): void {}
+
+ /** @implementation-alias DOMNode::cloneNode */
+ public function cloneNode(bool $deep = false): Node {}
+ public function isEqualNode(?Node $otherNode): bool {}
+ public function isSameNode(?Node $otherNode): bool {}
+
+ public const int DOCUMENT_POSITION_DISCONNECTED = 0x01;
+ public const int DOCUMENT_POSITION_PRECEDING = 0x02;
+ public const int DOCUMENT_POSITION_FOLLOWING = 0x04;
+ public const int DOCUMENT_POSITION_CONTAINS = 0x08;
+ public const int DOCUMENT_POSITION_CONTAINED_BY = 0x10;
+ public const int DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
+ public function compareDocumentPosition(Node $other): int {}
+ public function contains(?Node $other): bool {}
+
+ public function lookupPrefix(?string $namespace): ?string {}
+ /** @implementation-alias DOMNode::lookupNamespaceURI */
+ public function lookupNamespaceURI(?string $prefix): ?string {}
+ public function isDefaultNamespace(?string $namespace): bool {}
+
+ public function insertBefore(Node $node, ?Node $child): Node {}
+ public function appendChild(Node $node): Node {}
+ public function replaceChild(Node $node, Node $child): Node {}
+ public function removeChild(Node $child): Node {}
+
+ /** @implementation-alias DOMNode::getLineNo */
+ public function getLineNo(): int {}
+ public function getNodePath(): string {}
+ /** @implementation-alias DOMNode::C14N */
+ public function C14N(bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null): string|false {}
+ /** @implementation-alias DOMNode::C14NFile */
+ public function C14NFile(string $uri, bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null): int|false {}
+
+ /** @implementation-alias DOMNode::__sleep */
+ public function __sleep(): array {}
+ /** @implementation-alias DOMNode::__wakeup */
+ public function __wakeup(): void {}
+ }
+
+ class NodeList implements IteratorAggregate, Countable
+ {
/** @readonly */
- public ?Element $firstElementChild;
+ public int $length;
+ /** @implementation-alias DOMNodeList::count */
+ public function count(): int {}
+
+ /** @implementation-alias DOMNodeList::getIterator */
+ public function getIterator(): \Iterator {}
+
+ /** @implementation-alias DOMNodeList::item */
+ public function item(int $index): ?Node {}
+ }
+
+ class NamedNodeMap implements IteratorAggregate, Countable
+ {
/** @readonly */
- public ?Element $lastElementChild;
+ public int $length;
+
+ /** @implementation-alias DOMNamedNodeMap::item */
+ public function item(int $index): ?Attr {}
+ /** @implementation-alias DOMNamedNodeMap::getNamedItem */
+ public function getNamedItem(string $qualifiedName): ?Attr {}
+ /** @implementation-alias DOMNamedNodeMap::getNamedItemNS */
+ public function getNamedItemNS(?string $namespace, string $localName): ?Attr {}
+
+ /** @implementation-alias DOMNamedNodeMap::count */
+ public function count(): int {}
+
+ /** @implementation-alias DOMNamedNodeMap::getIterator */
+ public function getIterator(): \Iterator {}
+ }
+
+ class DTDNamedNodeMap implements IteratorAggregate, Countable
+ {
+ /** @readonly */
+ public int $length;
+
+ /** @implementation-alias DOMNamedNodeMap::item */
+ public function item(int $index): Entity|Notation|null {}
+ /** @implementation-alias DOMNamedNodeMap::getNamedItem */
+ public function getNamedItem(string $qualifiedName): Entity|Notation|null {}
+ /** @implementation-alias DOMNamedNodeMap::getNamedItemNS */
+ public function getNamedItemNS(?string $namespace, string $localName): Entity|Notation|null {}
+
+ /** @implementation-alias DOMNamedNodeMap::count */
+ public function count(): int {}
+
+ /** @implementation-alias DOMNamedNodeMap::getIterator */
+ public function getIterator(): \Iterator {}
+ }
+
+ class HTMLCollection implements IteratorAggregate, Countable
+ {
+ /** @readonly */
+ public int $length;
+
+ /** @implementation-alias DOMNodeList::item */
+ public function item(int $index): ?Element {}
+
+ /* TODO: implement namedItem */
+
+ /** @implementation-alias DOMNodeList::count */
+ public function count(): int {}
+
+ /** @implementation-alias DOMNodeList::getIterator */
+ public function getIterator(): \Iterator {}
+ }
+
+ class Element extends Node implements ParentNode, ChildNode
+ {
+ /** @readonly */
+ public ?string $namespaceURI;
+ /** @readonly */
+ public ?string $prefix;
+ /** @readonly */
+ public string $localName;
+ /** @readonly */
+ public string $tagName;
+
+ public string $id;
+ public string $className;
+
+ /** @implementation-alias DOMNode::hasAttributes */
+ public function hasAttributes(): bool {}
+ /** @readonly */
+ public NamedNodeMap $attributes;
+ /** @implementation-alias DOMElement::getAttributeNames */
+ public function getAttributeNames(): array {}
+ /** @implementation-alias DOMElement::getAttribute */
+ public function getAttribute(string $qualifiedName): ?string {}
+ /** @implementation-alias DOMElement::getAttributeNS */
+ public function getAttributeNS(?string $namespace, string $localName): ?string {}
+ /** @implementation-alias DOMElement::setAttribute */
+ public function setAttribute(string $qualifiedName, string $value): void {}
+ /** @implementation-alias DOMElement::setAttributeNS */
+ public function setAttributeNS(?string $namespace, string $qualifiedName, string $value): void {}
+ public function removeAttribute(string $qualifiedName): void {}
+ /** @implementation-alias DOMElement::removeAttributeNS */
+ public function removeAttributeNS(?string $namespace, string $localName): void {}
+ /** @implementation-alias DOMElement::toggleAttribute */
+ public function toggleAttribute(string $qualifiedName, ?bool $force = null): bool {}
+ /** @implementation-alias DOMElement::hasAttribute */
+ public function hasAttribute(string $qualifiedName): bool {}
+ /** @implementation-alias DOMElement::hasAttributeNS */
+ public function hasAttributeNS(?string $namespace, string $localName): bool {}
+
+ /** @implementation-alias DOMElement::getAttributeNode */
+ public function getAttributeNode(string $qualifiedName): ?Attr {}
+ /** @implementation-alias DOMElement::getAttributeNodeNS */
+ public function getAttributeNodeNS(?string $namespace, string $localName): ?Attr {}
+ /** @implementation-alias DOM\Element::setAttributeNodeNS */
+ public function setAttributeNode(Attr $attr) : ?Attr {}
+ public function setAttributeNodeNS(Attr $attr) : ?Attr {}
+ public function removeAttributeNode(Attr $attr) : Attr {}
+ public function getElementsByTagName(string $qualifiedName): HTMLCollection {}
+ public function getElementsByTagNameNS(?string $namespace, string $localName): HTMLCollection {}
+
+ public function insertAdjacentElement(string $where, Element $element): ?Element {}
+ /** @implementation-alias DOMElement::insertAdjacentText */
+ public function insertAdjacentText(string $where, string $data): void {}
+
+ /** @readonly */
+ public ?Element $firstElementChild;
+ /** @readonly */
+ public ?Element $lastElementChild;
/** @readonly */
public int $childElementCount;
+ /** @readonly */
+ public ?Element $previousElementSibling;
+ /** @readonly */
+ public ?Element $nextElementSibling;
- /** @return Attr|false */
- public function createAttribute(string $localName) {}
+ /** @implementation-alias DOMElement::setIdAttribute */
+ public function setIdAttribute(string $qualifiedName, bool $isId): void {}
+ /** @implementation-alias DOMElement::setIdAttributeNS */
+ public function setIdAttributeNS(?string $namespace, string $qualifiedName, bool $isId): void {}
+ public function setIdAttributeNode(Attr $attr, bool $isId): void {}
- /** @return Attr|false */
- public function createAttributeNS(?string $namespace, string $qualifiedName) {}
+ /** @implementation-alias DOMElement::remove */
+ public function remove(): void {}
+ /** @implementation-alias DOMElement::before */
+ public function before(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::after */
+ public function after(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::replaceWith */
+ public function replaceWith(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::append */
+ public function append(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::prepend */
+ public function prepend(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::replaceChildren */
+ public function replaceChildren(Node|string ...$nodes): void {}
+ }
- /** @return CDATASection|false */
- public function createCDATASection(string $data) {}
+ class Attr extends Node
+ {
+ /** @readonly */
+ public ?string $namespaceURI;
+ /** @readonly */
+ public ?string $prefix;
+ /** @readonly */
+ public string $localName;
+ /** @readonly */
+ public string $name;
+ public string $value;
- /** @tentative-return-type */
- public function createComment(string $data): Comment {}
+ /** @readonly */
+ public ?Element $ownerElement;
- /** @tentative-return-type */
- public function createDocumentFragment(): DocumentFragment {}
+ /** @readonly */
+ public bool $specified = true;
- /** @return Element|false */
- public function createElement(string $localName, string $value = "") {}
+ /** @implementation-alias DOMAttr::isId */
+ public function isId(): bool {}
+ }
- /** @return Element|false */
- public function createElementNS(?string $namespace, string $qualifiedName, string $value = "") {}
+ class CharacterData extends Node implements ChildNode
+ {
+ /** @readonly */
+ public ?Element $previousElementSibling;
+ /** @readonly */
+ public ?Element $nextElementSibling;
- /** @return ProcessingInstruction|false */
- public function createProcessingInstruction(string $target, string $data = "") {}
+ public string $data;
+ /** @readonly */
+ public int $length;
+ /** @implementation-alias DOMCharacterData::substringData */
+ public function substringData(int $offset, int $count): string {}
+ public function appendData(string $data): void {}
+ public function insertData(int $offset, string $data): void {}
+ public function deleteData(int $offset, int $count): void {}
+ public function replaceData(int $offset, int $count, string $data): void {}
- /** @tentative-return-type */
- public function createTextNode(string $data): Text {}
+ /** @implementation-alias DOMElement::remove */
+ public function remove(): void {}
+ /** @implementation-alias DOMElement::before */
+ public function before(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::after */
+ public function after(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::replaceWith */
+ public function replaceWith(Node|string ...$nodes): void {}
+ }
- /** @tentative-return-type */
- public function getElementById(string $elementId): ?Element {}
+ class Text extends CharacterData
+ {
+ /* No constructor because Node has a final private constructor, so PHP does not allow overriding that. */
- /** @tentative-return-type */
- public function getElementsByTagName(string $qualifiedName): NodeList {}
+ /** @implementation-alias DOMText::splitText */
+ public function splitText(int $offset): Text {}
+ /** @readonly */
+ public string $wholeText;
+ }
- /** @tentative-return-type */
- public function getElementsByTagNameNS(?string $namespace, string $localName): NodeList {}
+ class CDATASection extends Text {}
- /** @return Node|false */
- public function importNode(Node $node, bool $deep = false) {}
+ class ProcessingInstruction extends CharacterData
+ {
+ /** @readonly */
+ public string $target;
+ }
- /** @tentative-return-type */
- public function normalizeDocument(): void {}
+ class Comment extends CharacterData
+ {
+ /* No constructor because Node has a final private constructor, so PHP does not allow overriding that. */
+ }
- /** @tentative-return-type */
- public function registerNodeClass(string $baseClass, ?string $extendedClass): true {}
+ class DocumentType extends Node implements ChildNode
+ {
+ /** @readonly */
+ public string $name;
+ /** @readonly */
+ public DTDNamedNodeMap $entities;
+ /** @readonly */
+ public DTDNamedNodeMap $notations;
+ /** @readonly */
+ public string $publicId;
+ /** @readonly */
+ public string $systemId;
+ /** @readonly */
+ public ?string $internalSubset;
+
+ /** @implementation-alias DOMElement::remove */
+ public function remove(): void {}
+ /** @implementation-alias DOMElement::before */
+ public function before(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::after */
+ public function after(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::replaceWith */
+ public function replaceWith(Node|string ...$nodes): void {}
+ }
+
+ class DocumentFragment extends Node implements ParentNode
+ {
+ /** @readonly */
+ public ?Element $firstElementChild;
+ /** @readonly */
+ public ?Element $lastElementChild;
+ /** @readonly */
+ public int $childElementCount;
+
+ /** @implementation-alias DOMDocumentFragment::appendXML */
+ public function appendXML(string $data): bool {}
+ /** @implementation-alias DOMElement::append */
+ public function append(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::prepend */
+ public function prepend(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::replaceChildren */
+ public function replaceChildren(Node|string ...$nodes): void {}
+ }
+
+ class Entity extends Node
+ {
+ /** @readonly */
+ public ?string $publicId;
+ /** @readonly */
+ public ?string $systemId;
+ /** @readonly */
+ public ?string $notationName;
+ }
+
+ class EntityReference extends Node {}
+
+ class Notation extends Node
+ {
+ /** @readonly */
+ public string $publicId;
+ /** @readonly */
+ public string $systemId;
+ }
+
+ abstract class Document extends Node implements ParentNode
+ {
+ /** @readonly */
+ public Implementation $implementation;
+ /** @readonly */
+ public string $URL;
+ /** @readonly */
+ public string $documentURI;
+ public string $characterSet;
+ public string $charset;
+ public string $inputEncoding;
+
+ /** @readonly */
+ public ?DocumentType $doctype;
+ /** @readonly */
+ public ?Element $documentElement;
+ /** @implementation-alias DOM\Element::getElementsByTagName */
+ public function getElementsByTagName(string $qualifiedName): HTMLCollection {}
+ /** @implementation-alias DOM\Element::getElementsByTagNameNS */
+ public function getElementsByTagNameNS(?string $namespace, string $localName): HTMLCollection {}
+
+ public function createElement(string $localName): Element {}
+ public function createElementNS(?string $namespace, string $qualifiedName): Element {}
+ /** @implementation-alias DOMDocument::createDocumentFragment */
+ public function createDocumentFragment(): DocumentFragment {}
+ /** @implementation-alias DOMDocument::createTextNode */
+ public function createTextNode(string $data): Text {}
+ /** @implementation-alias DOMDocument::createCDATASection */
+ public function createCDATASection(string $data): CDATASection {}
+ /** @implementation-alias DOMDocument::createComment */
+ public function createComment(string $data): Comment {}
+ public function createProcessingInstruction(string $target, string $data): ProcessingInstruction {}
+
+ public function importNode(?Node $node, bool $deep = false): Node {}
+ public function adoptNode(Node $node): Node {}
+
+ /** @implementation-alias DOMDocument::createAttribute */
+ public function createAttribute(string $localName): Attr {}
+ /** @implementation-alias DOMDocument::createAttributeNS */
+ public function createAttributeNS(?string $namespace, string $qualifiedName): Attr {}
+
+ /** @readonly */
+ public ?Element $firstElementChild;
+ /** @readonly */
+ public ?Element $lastElementChild;
+ /** @readonly */
+ public int $childElementCount;
+
+ /** @implementation-alias DOMDocument::getElementById */
+ public function getElementById(string $elementId): ?Element {}
+
+ public function registerNodeClass(string $baseClass, ?string $extendedClass): void {}
#ifdef LIBXML_SCHEMAS_ENABLED
- /** @tentative-return-type */
+ /** @implementation-alias DOMDocument::schemaValidate */
public function schemaValidate(string $filename, int $flags = 0): bool {}
-
- /** @tentative-return-type */
+ /** @implementation-alias DOMDocument::schemaValidateSource */
public function schemaValidateSource(string $source, int $flags = 0): bool {}
-
- /** @tentative-return-type */
+ /** @implementation-alias DOMDocument::relaxNGValidate */
public function relaxNGValidate(string $filename): bool {}
-
- /** @tentative-return-type */
+ /** @implementation-alias DOMDocument::relaxNGValidateSource */
public function relaxNGValidateSource(string $source): bool {}
#endif
- /** @tentative-return-type */
- public function adoptNode(Node $node): Node|false {}
-
- /**
- * @param Node|string $nodes
- * @implementation-alias DOMElement::append
- */
- public function append(...$nodes): void {}
+ /** @implementation-alias DOMElement::append */
+ public function append(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMElement::prepend */
+ public function prepend(Node|string ...$nodes): void {}
+ /** @implementation-alias DOMDocument::replaceChildren */
+ public function replaceChildren(Node|string ...$nodes): void {}
- /**
- * @param Node|string $nodes
- * @implementation-alias DOMElement::prepend
- */
- public function prepend(...$nodes): void {}
-
- /** @param Node|string $nodes */
- public function replaceChildren(...$nodes): void {}
+ public function importLegacyNode(\DOMNode $node, bool $deep = false): Node {}
}
- /** @strict-properties */
final class HTMLDocument extends Document
{
- private function __construct() {}
-
public static function createEmpty(string $encoding = "UTF-8"): HTMLDocument {}
public static function createFromFile(string $path, int $options = 0, ?string $overrideEncoding = null): HTMLDocument {}
public static function createFromString(string $source, int $options = 0, ?string $overrideEncoding = null): HTMLDocument {}
- /** @implementation-alias DOMDocument::saveXML */
+ /** @implementation-alias DOM\XMLDocument::saveXML */
public function saveXML(?Node $node = null, int $options = 0): string|false {}
/** @implementation-alias DOMDocument::save */
@@ -1159,12 +1604,8 @@ public function saveHTML(?Node $node = null): string|false {}
public function saveHTMLFile(string $filename): int|false {}
}
- /** @strict-properties */
final class XMLDocument extends Document
{
- /** @implementation-alias DOM\HTMLDocument::__construct */
- private function __construct() {}
-
public static function createEmpty(string $version = "1.0", string $encoding = "UTF-8"): XMLDocument {}
public static function createFromFile(string $path, int $options = 0, ?string $overrideEncoding = null): XMLDocument {}
@@ -1172,58 +1613,57 @@ public static function createFromFile(string $path, int $options = 0, ?string $o
public static function createFromString(string $source, int $options = 0, ?string $overrideEncoding = null): XMLDocument {}
/** @readonly */
- public ?string $xmlEncoding;
-
- public bool $standalone;
+ public string $xmlEncoding;
public bool $xmlStandalone;
- public ?string $version;
-
- public ?string $xmlVersion;
+ public string $xmlVersion;
public bool $formatOutput;
- public bool $validateOnParse;
+ /** @implementation-alias DOMDocument::createEntityReference */
+ public function createEntityReference(string $name): EntityReference {}
- public bool $resolveExternals;
+ /** @implementation-alias DOMDocument::validate */
+ public function validate(): bool {}
- public bool $preserveWhiteSpace;
+ /** @implementation-alias DOMDocument::xinclude */
+ public function xinclude(int $options = 0): int|false {}
- public bool $recover;
+ public function saveXML(?Node $node = null, int $options = 0): string|false {}
- public bool $substituteEntities;
+ /** @implementation-alias DOMDocument::save */
+ public function saveXMLFile(string $filename, int $options = 0): int|false {}
+ }
- /**
- * @implementation-alias DOMDocument::createEntityReference
- * @return EntityReference|false
- */
- public function createEntityReference(string $name) {}
+#ifdef LIBXML_XPATH_ENABLED
+ /** @not-serializable */
+ final class XPath
+ {
+ /** @readonly */
+ public Document $document;
- /**
- * @implementation-alias DOMDocument::validate
- */
- public function validate(): bool {}
+ public bool $registerNodeNamespaces;
- /**
- * @tentative-return-type
- * @implementation-alias DOMDocument::xinclude
- */
- public function xinclude(int $options = 0): int|false {}
+ public function __construct(Document $document, bool $registerNodeNS = true) {}
- /**
- * @tentative-return-type
- * @implementation-alias DOMDocument::saveXML
- */
- public function saveXML(?Node $node = null, int $options = 0): string|false {}
+ public function evaluate(string $expression, ?Node $contextNode = null, bool $registerNodeNS = true): null|bool|float|string|NodeList {}
- /**
- * @tentative-return-type
- * @implementation-alias DOMDocument::save
- */
- public function saveXMLFile(string $filename, int $options = 0): int|false {}
+ public function query(string $expression, ?Node $contextNode = null, bool $registerNodeNS = true): NodeList {}
+
+ /** @implementation-alias DOMXPath::registerNamespace */
+ public function registerNamespace(string $prefix, string $namespace): bool {}
+
+ /** @implementation-alias DOMXPath::registerPhpFunctions */
+ public function registerPhpFunctions(string|array|null $restrict = null): void {}
+
+ /** @implementation-alias DOMXPath::registerPhpFunctionNS */
+ public function registerPhpFunctionNS(string $namespaceURI, string $name, callable $callable): void {}
+
+ /** @implementation-alias DOMXPath::quote */
+ public static function quote(string $str): string {}
}
+#endif
- /** @implementation-alias dom_import_simplexml */
function import_simplexml(object $node): Element {}
}
diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h
index 0c86ac8d73f5b..280b32e6152fb 100644
--- a/ext/dom/php_dom_arginfo.h
+++ b/ext/dom/php_dom_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 498e4aa2e670454b78808215e8efaedb2ce7d251 */
+ * Stub hash: bca273cb7255e24536575922505d3cce7488b32d */
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_dom_import_simplexml, 0, 1, DOMElement, 0)
ZEND_ARG_TYPE_INFO(0, node, IS_OBJECT, 0)
@@ -332,10 +332,61 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMDocument___construct, 0, 0, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"\"")
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMDocument_createAttribute, 0, 0, 1)
+ ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMDocument_createAttributeNS, 0, 0, 2)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOMDocument_createCDATASection arginfo_class_DOMCdataSection___construct
+
+ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DOMDocument_createComment, 0, 1, DOMComment, 0)
+ ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DOMDocument_createDocumentFragment, 0, 0, DOMDocumentFragment, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMDocument_createElement, 0, 0, 1)
+ ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_STRING, 0, "\"\"")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMDocument_createElementNS, 0, 0, 2)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_STRING, 0, "\"\"")
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMDocument_createEntityReference, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMDocument_createProcessingInstruction, 0, 0, 1)
+ ZEND_ARG_TYPE_INFO(0, target, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, data, IS_STRING, 0, "\"\"")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DOMDocument_createTextNode, 0, 1, DOMText, 0)
+ ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DOMDocument_getElementById, 0, 1, DOMElement, 1)
+ ZEND_ARG_TYPE_INFO(0, elementId, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOMDocument_getElementsByTagName arginfo_class_DOMElement_getElementsByTagName
+
+#define arginfo_class_DOMDocument_getElementsByTagNameNS arginfo_class_DOMElement_getElementsByTagNameNS
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMDocument_importNode, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, node, DOMNode, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, deep, _IS_BOOL, 0, "false")
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOMDocument_load, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
@@ -346,6 +397,13 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOMDocument_load
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
+#define arginfo_class_DOMDocument_normalizeDocument arginfo_class_DOMNode_normalize
+
+ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOMDocument_registerNodeClass, 0, 2, IS_TRUE, 0)
+ ZEND_ARG_TYPE_INFO(0, baseClass, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, extendedClass, IS_STRING, 1)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_DOMDocument_save, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
@@ -382,12 +440,48 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_DOMDocument_save
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOMDocument_schemaValidate, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOMDocument_schemaValidateSource, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, source, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOMDocument_relaxNGValidate, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOMDocument_relaxNGValidateSource, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, source, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+#endif
+
#define arginfo_class_DOMDocument_validate arginfo_class_DOMNode_hasAttributes
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_DOMDocument_xinclude, 0, 0, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DOMDocument_adoptNode, 0, 1, DOMNode, MAY_BE_FALSE)
+ ZEND_ARG_OBJ_INFO(0, node, DOMNode, 0)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOMDocument_append arginfo_class_DOMParentNode_append
+
+#define arginfo_class_DOMDocument_prepend arginfo_class_DOMParentNode_append
+
+#define arginfo_class_DOMDocument_replaceChildren arginfo_class_DOMParentNode_append
+
#define arginfo_class_DOMText___construct arginfo_class_DOMComment___construct
#define arginfo_class_DOMText_isWhitespaceInElementContent arginfo_class_DOMNode_hasAttributes
@@ -421,7 +515,7 @@ ZEND_END_ARG_INFO()
#if defined(LIBXML_XPATH_ENABLED)
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMXPath___construct, 0, 0, 1)
- ZEND_ARG_OBJ_INFO(0, document, DOM\\Document, 0)
+ ZEND_ARG_OBJ_INFO(0, document, DOMDocument, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, registerNodeNS, _IS_BOOL, 0, "true")
ZEND_END_ARG_INFO()
#endif
@@ -465,178 +559,542 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOMXPath_quote, 0, 1, IS_S
ZEND_END_ARG_INFO()
#endif
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOM_Document_createAttribute, 0, 0, 1)
- ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_ParentNode_append, 0, 0, IS_VOID, 0)
+ ZEND_ARG_VARIADIC_OBJ_TYPE_MASK(0, nodes, DOM\\\116ode, MAY_BE_STRING)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOM_ParentNode_prepend arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_ParentNode_replaceChildren arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_ChildNode_remove arginfo_class_DOMChildNode_remove
+
+#define arginfo_class_DOM_ChildNode_before arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_ChildNode_after arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_ChildNode_replaceWith arginfo_class_DOM_ParentNode_append
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Implementation_createDocumentType, 0, 3, DOM\\DocumentType, 0)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, publicId, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, systemId, IS_STRING, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOM_Document_createAttributeNS, 0, 0, 2)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Implementation_createDocument, 0, 2, DOM\\XMLDocument, 0)
ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, doctype, DOM\\DocumentType, 1, "null")
ZEND_END_ARG_INFO()
-#define arginfo_class_DOM_Document_createCDATASection arginfo_class_DOMCdataSection___construct
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Implementation_createHTMLDocument, 0, 0, DOM\\HTMLDocument, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, title, IS_STRING, 1, "null")
+ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createComment, 0, 1, DOM\\Comment, 0)
- ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+#define arginfo_class_DOM_Node___construct arginfo_class_DOMDocumentFragment___construct
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Node_getRootNode, 0, 0, DOM\\\116ode, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "[]")
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createDocumentFragment, 0, 0, DOM\\DocumentFragment, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Node_hasChildNodes, 0, 0, _IS_BOOL, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOM_Document_createElement, 0, 0, 1)
- ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_STRING, 0, "\"\"")
+#define arginfo_class_DOM_Node_normalize arginfo_class_DOMChildNode_remove
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Node_cloneNode, 0, 0, DOM\\\116ode, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, deep, _IS_BOOL, 0, "false")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Node_isEqualNode, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_OBJ_INFO(0, otherNode, DOM\\\116ode, 1)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOM_Node_isSameNode arginfo_class_DOM_Node_isEqualNode
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Node_compareDocumentPosition, 0, 1, IS_LONG, 0)
+ ZEND_ARG_OBJ_INFO(0, other, DOM\\\116ode, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Node_contains, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_OBJ_INFO(0, other, DOM\\\116ode, 1)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOM_Document_createElementNS, 0, 0, 2)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Node_lookupPrefix, 0, 1, IS_STRING, 1)
ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
- ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_STRING, 0, "\"\"")
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOM_Document_createProcessingInstruction, 0, 0, 1)
- ZEND_ARG_TYPE_INFO(0, target, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, data, IS_STRING, 0, "\"\"")
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Node_lookupNamespaceURI, 0, 1, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, prefix, IS_STRING, 1)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createTextNode, 0, 1, DOM\\Text, 0)
- ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Node_isDefaultNamespace, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_getElementById, 0, 1, DOM\\Element, 1)
- ZEND_ARG_TYPE_INFO(0, elementId, IS_STRING, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Node_insertBefore, 0, 2, DOM\\\116ode, 0)
+ ZEND_ARG_OBJ_INFO(0, node, DOM\\\116ode, 0)
+ ZEND_ARG_OBJ_INFO(0, child, DOM\\\116ode, 1)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Node_appendChild, 0, 1, DOM\\\116ode, 0)
+ ZEND_ARG_OBJ_INFO(0, node, DOM\\\116ode, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Node_replaceChild, 0, 2, DOM\\\116ode, 0)
+ ZEND_ARG_OBJ_INFO(0, node, DOM\\\116ode, 0)
+ ZEND_ARG_OBJ_INFO(0, child, DOM\\\116ode, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Node_removeChild, 0, 1, DOM\\\116ode, 0)
+ ZEND_ARG_OBJ_INFO(0, child, DOM\\\116ode, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Node_getLineNo, 0, 0, IS_LONG, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Node_getNodePath, 0, 0, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_Node_C14N, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, exclusive, _IS_BOOL, 0, "false")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, withComments, _IS_BOOL, 0, "false")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, xpath, IS_ARRAY, 1, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, nsPrefixes, IS_ARRAY, 1, "null")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_Node_C14NFile, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
+ ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, exclusive, _IS_BOOL, 0, "false")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, withComments, _IS_BOOL, 0, "false")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, xpath, IS_ARRAY, 1, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, nsPrefixes, IS_ARRAY, 1, "null")
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOM_Node___sleep arginfo_class_DOMNode___sleep
+
+#define arginfo_class_DOM_Node___wakeup arginfo_class_DOMChildNode_remove
+
+#define arginfo_class_DOM_NodeList_count arginfo_class_DOM_Node_getLineNo
+
+#define arginfo_class_DOM_NodeList_getIterator arginfo_class_DOMNodeList_getIterator
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_NodeList_item, 0, 1, DOM\\\116ode, 1)
+ ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_NamedNodeMap_item, 0, 1, DOM\\Attr, 1)
+ ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_getElementsByTagName, 0, 1, DOM\\\116odeList, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_NamedNodeMap_getNamedItem, 0, 1, DOM\\Attr, 1)
ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_getElementsByTagNameNS, 0, 2, DOM\\\116odeList, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_NamedNodeMap_getNamedItemNS, 0, 2, DOM\\Attr, 1)
ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOM_Document_importNode, 0, 0, 1)
- ZEND_ARG_OBJ_INFO(0, node, DOM\\\116ode, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, deep, _IS_BOOL, 0, "false")
-ZEND_END_ARG_INFO()
+#define arginfo_class_DOM_NamedNodeMap_count arginfo_class_DOM_Node_getLineNo
-#define arginfo_class_DOM_Document_normalizeDocument arginfo_class_DOMNode_normalize
+#define arginfo_class_DOM_NamedNodeMap_getIterator arginfo_class_DOMNodeList_getIterator
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Document_registerNodeClass, 0, 2, IS_TRUE, 0)
- ZEND_ARG_TYPE_INFO(0, baseClass, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO(0, extendedClass, IS_STRING, 1)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DOM_DTDNamedNodeMap_item, 0, 1, DOM\\Entity|DOM\\\116otation, MAY_BE_NULL)
+ ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
ZEND_END_ARG_INFO()
-#if defined(LIBXML_SCHEMAS_ENABLED)
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Document_schemaValidate, 0, 1, _IS_BOOL, 0)
- ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DOM_DTDNamedNodeMap_getNamedItem, 0, 1, DOM\\Entity|DOM\\\116otation, MAY_BE_NULL)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
ZEND_END_ARG_INFO()
-#endif
-#if defined(LIBXML_SCHEMAS_ENABLED)
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Document_schemaValidateSource, 0, 1, _IS_BOOL, 0)
- ZEND_ARG_TYPE_INFO(0, source, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DOM_DTDNamedNodeMap_getNamedItemNS, 0, 2, DOM\\Entity|DOM\\\116otation, MAY_BE_NULL)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
ZEND_END_ARG_INFO()
-#endif
-#if defined(LIBXML_SCHEMAS_ENABLED)
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Document_relaxNGValidate, 0, 1, _IS_BOOL, 0)
- ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
+#define arginfo_class_DOM_DTDNamedNodeMap_count arginfo_class_DOM_Node_getLineNo
+
+#define arginfo_class_DOM_DTDNamedNodeMap_getIterator arginfo_class_DOMNodeList_getIterator
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_HTMLCollection_item, 0, 1, DOM\\Element, 1)
+ ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
ZEND_END_ARG_INFO()
-#endif
-#if defined(LIBXML_SCHEMAS_ENABLED)
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Document_relaxNGValidateSource, 0, 1, _IS_BOOL, 0)
- ZEND_ARG_TYPE_INFO(0, source, IS_STRING, 0)
+#define arginfo_class_DOM_HTMLCollection_count arginfo_class_DOM_Node_getLineNo
+
+#define arginfo_class_DOM_HTMLCollection_getIterator arginfo_class_DOMNodeList_getIterator
+
+#define arginfo_class_DOM_Element_hasAttributes arginfo_class_DOM_Node_hasChildNodes
+
+#define arginfo_class_DOM_Element_getAttributeNames arginfo_class_DOMNode___sleep
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_getAttribute, 0, 1, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
ZEND_END_ARG_INFO()
-#endif
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DOM_Document_adoptNode, 0, 1, DOM\\\116ode, MAY_BE_FALSE)
- ZEND_ARG_OBJ_INFO(0, node, DOM\\\116ode, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_getAttributeNS, 0, 2, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_setAttribute, 0, 2, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0)
ZEND_END_ARG_INFO()
-#define arginfo_class_DOM_Document_append arginfo_class_DOMParentNode_append
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_setAttributeNS, 0, 3, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0)
+ZEND_END_ARG_INFO()
-#define arginfo_class_DOM_Document_prepend arginfo_class_DOMParentNode_append
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_removeAttribute, 0, 1, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ZEND_END_ARG_INFO()
-#define arginfo_class_DOM_Document_replaceChildren arginfo_class_DOMParentNode_append
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_removeAttributeNS, 0, 2, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
+ZEND_END_ARG_INFO()
-#define arginfo_class_DOM_HTMLDocument___construct arginfo_class_DOMDocumentFragment___construct
+#define arginfo_class_DOM_Element_toggleAttribute arginfo_class_DOMElement_toggleAttribute
-ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_HTMLDocument_createEmpty, 0, 0, DOM\\HTMLDocument, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"UTF-8\"")
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_hasAttribute, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_HTMLDocument_createFromFile, 0, 1, DOM\\HTMLDocument, 0)
- ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, overrideEncoding, IS_STRING, 1, "null")
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_hasAttributeNS, 0, 2, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_HTMLDocument_createFromString, 0, 1, DOM\\HTMLDocument, 0)
- ZEND_ARG_TYPE_INFO(0, source, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, overrideEncoding, IS_STRING, 1, "null")
+#define arginfo_class_DOM_Element_getAttributeNode arginfo_class_DOM_NamedNodeMap_getNamedItem
+
+#define arginfo_class_DOM_Element_getAttributeNodeNS arginfo_class_DOM_NamedNodeMap_getNamedItemNS
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Element_setAttributeNode, 0, 1, DOM\\Attr, 1)
+ ZEND_ARG_OBJ_INFO(0, attr, DOM\\Attr, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_HTMLDocument_saveXML, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
- ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, node, DOM\\\116ode, 1, "null")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
+#define arginfo_class_DOM_Element_setAttributeNodeNS arginfo_class_DOM_Element_setAttributeNode
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Element_removeAttributeNode, 0, 1, DOM\\Attr, 0)
+ ZEND_ARG_OBJ_INFO(0, attr, DOM\\Attr, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_HTMLDocument_saveXMLFile, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
- ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Element_getElementsByTagName, 0, 1, DOM\\HTMLCollection, 0)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_HTMLDocument_saveHTML, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
- ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, node, DOM\\\116ode, 1, "null")
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Element_getElementsByTagNameNS, 0, 2, DOM\\HTMLCollection, 0)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_HTMLDocument_saveHTMLFile, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
- ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Element_insertAdjacentElement, 0, 2, DOM\\Element, 1)
+ ZEND_ARG_TYPE_INFO(0, where, IS_STRING, 0)
+ ZEND_ARG_OBJ_INFO(0, element, DOM\\Element, 0)
ZEND_END_ARG_INFO()
-#define arginfo_class_DOM_XMLDocument___construct arginfo_class_DOMDocumentFragment___construct
+#define arginfo_class_DOM_Element_insertAdjacentText arginfo_class_DOMElement_insertAdjacentText
-ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_XMLDocument_createEmpty, 0, 0, DOM\\XMLDocument, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, version, IS_STRING, 0, "\"1.0\"")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"UTF-8\"")
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_setIdAttribute, 0, 2, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, isId, _IS_BOOL, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_XMLDocument_createFromFile, 0, 1, DOM\\XMLDocument, 0)
- ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, overrideEncoding, IS_STRING, 1, "null")
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_setIdAttributeNS, 0, 3, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, isId, _IS_BOOL, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_XMLDocument_createFromString, 0, 1, DOM\\XMLDocument, 0)
- ZEND_ARG_TYPE_INFO(0, source, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, overrideEncoding, IS_STRING, 1, "null")
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Element_setIdAttributeNode, 0, 2, IS_VOID, 0)
+ ZEND_ARG_OBJ_INFO(0, attr, DOM\\Attr, 0)
+ ZEND_ARG_TYPE_INFO(0, isId, _IS_BOOL, 0)
ZEND_END_ARG_INFO()
-#define arginfo_class_DOM_XMLDocument_createEntityReference arginfo_class_DOMDocument_createEntityReference
+#define arginfo_class_DOM_Element_remove arginfo_class_DOMChildNode_remove
+
+#define arginfo_class_DOM_Element_before arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_Element_after arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_Element_replaceWith arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_Element_append arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_Element_prepend arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_Element_replaceChildren arginfo_class_DOM_ParentNode_append
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_XMLDocument_validate, 0, 0, _IS_BOOL, 0)
+#define arginfo_class_DOM_Attr_isId arginfo_class_DOM_Node_hasChildNodes
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_CharacterData_substringData, 0, 2, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0)
+ ZEND_ARG_TYPE_INFO(0, count, IS_LONG, 0)
ZEND_END_ARG_INFO()
-#define arginfo_class_DOM_XMLDocument_xinclude arginfo_class_DOMDocument_xinclude
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_CharacterData_appendData, 0, 1, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_DOM_XMLDocument_saveXML, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
- ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, node, DOM\\\116ode, 1, "null")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_CharacterData_insertData, 0, 2, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0)
+ ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
ZEND_END_ARG_INFO()
-#define arginfo_class_DOM_XMLDocument_saveXMLFile arginfo_class_DOMDocument_save
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_CharacterData_deleteData, 0, 2, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0)
+ ZEND_ARG_TYPE_INFO(0, count, IS_LONG, 0)
+ZEND_END_ARG_INFO()
-ZEND_FUNCTION(dom_import_simplexml);
-ZEND_METHOD(DOMCdataSection, __construct);
-ZEND_METHOD(DOMComment, __construct);
-ZEND_METHOD(DOMNode, appendChild);
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_CharacterData_replaceData, 0, 3, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0)
+ ZEND_ARG_TYPE_INFO(0, count, IS_LONG, 0)
+ ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOM_CharacterData_remove arginfo_class_DOMChildNode_remove
+
+#define arginfo_class_DOM_CharacterData_before arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_CharacterData_after arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_CharacterData_replaceWith arginfo_class_DOM_ParentNode_append
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Text_splitText, 0, 1, DOM\\Text, 0)
+ ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOM_DocumentType_remove arginfo_class_DOMChildNode_remove
+
+#define arginfo_class_DOM_DocumentType_before arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_DocumentType_after arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_DocumentType_replaceWith arginfo_class_DOM_ParentNode_append
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_DocumentFragment_appendXML, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOM_DocumentFragment_append arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_DocumentFragment_prepend arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_DocumentFragment_replaceChildren arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_Document_getElementsByTagName arginfo_class_DOM_Element_getElementsByTagName
+
+#define arginfo_class_DOM_Document_getElementsByTagNameNS arginfo_class_DOM_Element_getElementsByTagNameNS
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createElement, 0, 1, DOM\\Element, 0)
+ ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createElementNS, 0, 2, DOM\\Element, 0)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createDocumentFragment, 0, 0, DOM\\DocumentFragment, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createTextNode, 0, 1, DOM\\Text, 0)
+ ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createCDATASection, 0, 1, DOM\\CDATASection, 0)
+ ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createComment, 0, 1, DOM\\Comment, 0)
+ ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createProcessingInstruction, 0, 2, DOM\\ProcessingInstruction, 0)
+ ZEND_ARG_TYPE_INFO(0, target, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_importNode, 0, 1, DOM\\\116ode, 0)
+ ZEND_ARG_OBJ_INFO(0, node, DOM\\\116ode, 1)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, deep, _IS_BOOL, 0, "false")
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOM_Document_adoptNode arginfo_class_DOM_Node_appendChild
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createAttribute, 0, 1, DOM\\Attr, 0)
+ ZEND_ARG_TYPE_INFO(0, localName, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_createAttributeNS, 0, 2, DOM\\Attr, 0)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_getElementById, 0, 1, DOM\\Element, 1)
+ ZEND_ARG_TYPE_INFO(0, elementId, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Document_registerNodeClass, 0, 2, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, baseClass, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, extendedClass, IS_STRING, 1)
+ZEND_END_ARG_INFO()
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Document_schemaValidate, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Document_schemaValidateSource, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, source, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Document_relaxNGValidate, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_Document_relaxNGValidateSource, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, source, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+#endif
+
+#define arginfo_class_DOM_Document_append arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_Document_prepend arginfo_class_DOM_ParentNode_append
+
+#define arginfo_class_DOM_Document_replaceChildren arginfo_class_DOM_ParentNode_append
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_Document_importLegacyNode, 0, 1, DOM\\\116ode, 0)
+ ZEND_ARG_OBJ_INFO(0, node, DOMNode, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, deep, _IS_BOOL, 0, "false")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_HTMLDocument_createEmpty, 0, 0, DOM\\HTMLDocument, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"UTF-8\"")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_HTMLDocument_createFromFile, 0, 1, DOM\\HTMLDocument, 0)
+ ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, overrideEncoding, IS_STRING, 1, "null")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_HTMLDocument_createFromString, 0, 1, DOM\\HTMLDocument, 0)
+ ZEND_ARG_TYPE_INFO(0, source, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, overrideEncoding, IS_STRING, 1, "null")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_HTMLDocument_saveXML, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
+ ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, node, DOM\\\116ode, 1, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_HTMLDocument_saveXMLFile, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
+ ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_HTMLDocument_saveHTML, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
+ ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, node, DOM\\\116ode, 1, "null")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_HTMLDocument_saveHTMLFile, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
+ ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_XMLDocument_createEmpty, 0, 0, DOM\\XMLDocument, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, version, IS_STRING, 0, "\"1.0\"")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"UTF-8\"")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_XMLDocument_createFromFile, 0, 1, DOM\\XMLDocument, 0)
+ ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, overrideEncoding, IS_STRING, 1, "null")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_XMLDocument_createFromString, 0, 1, DOM\\XMLDocument, 0)
+ ZEND_ARG_TYPE_INFO(0, source, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, overrideEncoding, IS_STRING, 1, "null")
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_XMLDocument_createEntityReference, 0, 1, DOM\\EntityReference, 0)
+ ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOM_XMLDocument_validate arginfo_class_DOM_Node_hasChildNodes
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_DOM_XMLDocument_xinclude, 0, 0, MAY_BE_LONG|MAY_BE_FALSE)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_DOM_XMLDocument_saveXML arginfo_class_DOM_HTMLDocument_saveXML
+
+#define arginfo_class_DOM_XMLDocument_saveXMLFile arginfo_class_DOM_HTMLDocument_saveXMLFile
+
+#if defined(LIBXML_XPATH_ENABLED)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOM_XPath___construct, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, document, DOM\\Document, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, registerNodeNS, _IS_BOOL, 0, "true")
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DOM_XPath_evaluate, 0, 1, DOM\\\116odeList, MAY_BE_NULL|MAY_BE_BOOL|MAY_BE_DOUBLE|MAY_BE_STRING)
+ ZEND_ARG_TYPE_INFO(0, expression, IS_STRING, 0)
+ ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, contextNode, DOM\\\116ode, 1, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, registerNodeNS, _IS_BOOL, 0, "true")
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DOM_XPath_query, 0, 1, DOM\\\116odeList, 0)
+ ZEND_ARG_TYPE_INFO(0, expression, IS_STRING, 0)
+ ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, contextNode, DOM\\\116ode, 1, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, registerNodeNS, _IS_BOOL, 0, "true")
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_XPath_registerNamespace, 0, 2, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, prefix, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOM_XPath_registerPhpFunctions, 0, 0, IS_VOID, 0)
+ ZEND_ARG_TYPE_MASK(0, restrict, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_NULL, "null")
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#define arginfo_class_DOM_XPath_registerPhpFunctionNS arginfo_class_DOMXPath_registerPhpFunctionNS
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#define arginfo_class_DOM_XPath_quote arginfo_class_DOMXPath_quote
+#endif
+
+ZEND_FUNCTION(dom_import_simplexml);
+ZEND_FUNCTION(DOM_import_simplexml);
+ZEND_METHOD(DOMCdataSection, __construct);
+ZEND_METHOD(DOMComment, __construct);
+ZEND_METHOD(DOMNode, appendChild);
ZEND_METHOD(DOMNode, C14N);
ZEND_METHOD(DOMNode, C14NFile);
ZEND_METHOD(DOMNode, cloneNode);
@@ -667,7 +1125,7 @@ ZEND_METHOD(DOMDocumentFragment, __construct);
ZEND_METHOD(DOMDocumentFragment, appendXML);
ZEND_METHOD(DOMElement, append);
ZEND_METHOD(DOMElement, prepend);
-ZEND_METHOD(DOM_Document, replaceChildren);
+ZEND_METHOD(DOMDocument, replaceChildren);
ZEND_METHOD(DOMNodeList, count);
ZEND_METHOD(DOMNodeList, getIterator);
ZEND_METHOD(DOMNodeList, item);
@@ -707,9 +1165,22 @@ ZEND_METHOD(DOMElement, replaceChildren);
ZEND_METHOD(DOMElement, insertAdjacentElement);
ZEND_METHOD(DOMElement, insertAdjacentText);
ZEND_METHOD(DOMDocument, __construct);
+ZEND_METHOD(DOMDocument, createAttribute);
+ZEND_METHOD(DOMDocument, createAttributeNS);
+ZEND_METHOD(DOMDocument, createCDATASection);
+ZEND_METHOD(DOMDocument, createComment);
+ZEND_METHOD(DOMDocument, createDocumentFragment);
+ZEND_METHOD(DOMDocument, createElement);
+ZEND_METHOD(DOMDocument, createElementNS);
ZEND_METHOD(DOMDocument, createEntityReference);
+ZEND_METHOD(DOMDocument, createProcessingInstruction);
+ZEND_METHOD(DOMDocument, createTextNode);
+ZEND_METHOD(DOMDocument, getElementById);
+ZEND_METHOD(DOMDocument, importNode);
ZEND_METHOD(DOMDocument, load);
ZEND_METHOD(DOMDocument, loadXML);
+ZEND_METHOD(DOMDocument, normalizeDocument);
+ZEND_METHOD(DOMDocument, registerNodeClass);
ZEND_METHOD(DOMDocument, save);
#if defined(LIBXML_HTML_ENABLED)
ZEND_METHOD(DOMDocument, loadHTML);
@@ -724,8 +1195,21 @@ ZEND_METHOD(DOMDocument, saveHTML);
ZEND_METHOD(DOMDocument, saveHTMLFile);
#endif
ZEND_METHOD(DOMDocument, saveXML);
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_METHOD(DOMDocument, schemaValidate);
+#endif
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_METHOD(DOMDocument, schemaValidateSource);
+#endif
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_METHOD(DOMDocument, relaxNGValidate);
+#endif
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ZEND_METHOD(DOMDocument, relaxNGValidateSource);
+#endif
ZEND_METHOD(DOMDocument, validate);
ZEND_METHOD(DOMDocument, xinclude);
+ZEND_METHOD(DOMDocument, adoptNode);
ZEND_METHOD(DOMText, __construct);
ZEND_METHOD(DOMText, isWhitespaceInElementContent);
ZEND_METHOD(DOMText, splitText);
@@ -757,47 +1241,61 @@ ZEND_METHOD(DOMXPath, registerPhpFunctionNS);
#if defined(LIBXML_XPATH_ENABLED)
ZEND_METHOD(DOMXPath, quote);
#endif
-ZEND_METHOD(DOM_Document, createAttribute);
-ZEND_METHOD(DOM_Document, createAttributeNS);
-ZEND_METHOD(DOM_Document, createCDATASection);
-ZEND_METHOD(DOM_Document, createComment);
-ZEND_METHOD(DOM_Document, createDocumentFragment);
+ZEND_METHOD(DOM_Implementation, createDocumentType);
+ZEND_METHOD(DOM_Implementation, createDocument);
+ZEND_METHOD(DOM_Implementation, createHTMLDocument);
+ZEND_METHOD(DOM_Node, __construct);
+ZEND_METHOD(DOM_Node, isEqualNode);
+ZEND_METHOD(DOM_Node, isSameNode);
+ZEND_METHOD(DOM_Node, compareDocumentPosition);
+ZEND_METHOD(DOM_Node, contains);
+ZEND_METHOD(DOM_Node, lookupPrefix);
+ZEND_METHOD(DOM_Node, isDefaultNamespace);
+ZEND_METHOD(DOM_Node, insertBefore);
+ZEND_METHOD(DOM_Node, appendChild);
+ZEND_METHOD(DOM_Node, replaceChild);
+ZEND_METHOD(DOM_Node, removeChild);
+ZEND_METHOD(DOM_Node, getNodePath);
+ZEND_METHOD(DOM_Element, removeAttribute);
+ZEND_METHOD(DOM_Element, setAttributeNodeNS);
+ZEND_METHOD(DOM_Element, removeAttributeNode);
+ZEND_METHOD(DOM_Element, getElementsByTagName);
+ZEND_METHOD(DOM_Element, getElementsByTagNameNS);
+ZEND_METHOD(DOM_Element, insertAdjacentElement);
+ZEND_METHOD(DOM_Element, setIdAttributeNode);
+ZEND_METHOD(DOM_CharacterData, appendData);
+ZEND_METHOD(DOM_CharacterData, insertData);
+ZEND_METHOD(DOM_CharacterData, deleteData);
+ZEND_METHOD(DOM_CharacterData, replaceData);
ZEND_METHOD(DOM_Document, createElement);
ZEND_METHOD(DOM_Document, createElementNS);
ZEND_METHOD(DOM_Document, createProcessingInstruction);
-ZEND_METHOD(DOM_Document, createTextNode);
-ZEND_METHOD(DOM_Document, getElementById);
-ZEND_METHOD(DOM_Document, getElementsByTagName);
-ZEND_METHOD(DOM_Document, getElementsByTagNameNS);
ZEND_METHOD(DOM_Document, importNode);
-ZEND_METHOD(DOM_Document, normalizeDocument);
-ZEND_METHOD(DOM_Document, registerNodeClass);
-#if defined(LIBXML_SCHEMAS_ENABLED)
-ZEND_METHOD(DOM_Document, schemaValidate);
-#endif
-#if defined(LIBXML_SCHEMAS_ENABLED)
-ZEND_METHOD(DOM_Document, schemaValidateSource);
-#endif
-#if defined(LIBXML_SCHEMAS_ENABLED)
-ZEND_METHOD(DOM_Document, relaxNGValidate);
-#endif
-#if defined(LIBXML_SCHEMAS_ENABLED)
-ZEND_METHOD(DOM_Document, relaxNGValidateSource);
-#endif
ZEND_METHOD(DOM_Document, adoptNode);
-ZEND_METHOD(DOM_HTMLDocument, __construct);
+ZEND_METHOD(DOM_Document, registerNodeClass);
+ZEND_METHOD(DOM_Document, importLegacyNode);
ZEND_METHOD(DOM_HTMLDocument, createEmpty);
ZEND_METHOD(DOM_HTMLDocument, createFromFile);
ZEND_METHOD(DOM_HTMLDocument, createFromString);
+ZEND_METHOD(DOM_XMLDocument, saveXML);
ZEND_METHOD(DOM_HTMLDocument, saveHTML);
ZEND_METHOD(DOM_HTMLDocument, saveHTMLFile);
ZEND_METHOD(DOM_XMLDocument, createEmpty);
ZEND_METHOD(DOM_XMLDocument, createFromFile);
ZEND_METHOD(DOM_XMLDocument, createFromString);
+#if defined(LIBXML_XPATH_ENABLED)
+ZEND_METHOD(DOM_XPath, __construct);
+#endif
+#if defined(LIBXML_XPATH_ENABLED)
+ZEND_METHOD(DOM_XPath, evaluate);
+#endif
+#if defined(LIBXML_XPATH_ENABLED)
+ZEND_METHOD(DOM_XPath, query);
+#endif
static const zend_function_entry ext_functions[] = {
ZEND_FE(dom_import_simplexml, arginfo_dom_import_simplexml)
- ZEND_RAW_FENTRY(ZEND_NS_NAME("DOM", "import_simplexml"), zif_dom_import_simplexml, arginfo_DOM_import_simplexml, 0, NULL, NULL)
+ ZEND_RAW_FENTRY(ZEND_NS_NAME("DOM", "import_simplexml"), zif_DOM_import_simplexml, arginfo_DOM_import_simplexml, 0, NULL, NULL)
ZEND_FE_END
};
@@ -876,7 +1374,7 @@ static const zend_function_entry class_DOMDocumentFragment_methods[] = {
ZEND_ME(DOMDocumentFragment, appendXML, arginfo_class_DOMDocumentFragment_appendXML, ZEND_ACC_PUBLIC)
ZEND_RAW_FENTRY("append", zim_DOMElement_append, arginfo_class_DOMDocumentFragment_append, ZEND_ACC_PUBLIC, NULL, NULL)
ZEND_RAW_FENTRY("prepend", zim_DOMElement_prepend, arginfo_class_DOMDocumentFragment_prepend, ZEND_ACC_PUBLIC, NULL, NULL)
- ZEND_RAW_FENTRY("replaceChildren", zim_DOM_Document_replaceChildren, arginfo_class_DOMDocumentFragment_replaceChildren, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("replaceChildren", zim_DOMDocument_replaceChildren, arginfo_class_DOMDocumentFragment_replaceChildren, ZEND_ACC_PUBLIC, NULL, NULL)
ZEND_FE_END
};
@@ -942,9 +1440,24 @@ static const zend_function_entry class_DOMElement_methods[] = {
static const zend_function_entry class_DOMDocument_methods[] = {
ZEND_ME(DOMDocument, __construct, arginfo_class_DOMDocument___construct, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, createAttribute, arginfo_class_DOMDocument_createAttribute, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, createAttributeNS, arginfo_class_DOMDocument_createAttributeNS, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, createCDATASection, arginfo_class_DOMDocument_createCDATASection, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, createComment, arginfo_class_DOMDocument_createComment, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, createDocumentFragment, arginfo_class_DOMDocument_createDocumentFragment, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, createElement, arginfo_class_DOMDocument_createElement, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, createElementNS, arginfo_class_DOMDocument_createElementNS, ZEND_ACC_PUBLIC)
ZEND_ME(DOMDocument, createEntityReference, arginfo_class_DOMDocument_createEntityReference, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, createProcessingInstruction, arginfo_class_DOMDocument_createProcessingInstruction, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, createTextNode, arginfo_class_DOMDocument_createTextNode, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, getElementById, arginfo_class_DOMDocument_getElementById, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("getElementsByTagName", zim_DOMElement_getElementsByTagName, arginfo_class_DOMDocument_getElementsByTagName, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getElementsByTagNameNS", zim_DOMElement_getElementsByTagNameNS, arginfo_class_DOMDocument_getElementsByTagNameNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOMDocument, importNode, arginfo_class_DOMDocument_importNode, ZEND_ACC_PUBLIC)
ZEND_ME(DOMDocument, load, arginfo_class_DOMDocument_load, ZEND_ACC_PUBLIC)
ZEND_ME(DOMDocument, loadXML, arginfo_class_DOMDocument_loadXML, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, normalizeDocument, arginfo_class_DOMDocument_normalizeDocument, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, registerNodeClass, arginfo_class_DOMDocument_registerNodeClass, ZEND_ACC_PUBLIC)
ZEND_ME(DOMDocument, save, arginfo_class_DOMDocument_save, ZEND_ACC_PUBLIC)
#if defined(LIBXML_HTML_ENABLED)
ZEND_ME(DOMDocument, loadHTML, arginfo_class_DOMDocument_loadHTML, ZEND_ACC_PUBLIC)
@@ -959,8 +1472,24 @@ static const zend_function_entry class_DOMDocument_methods[] = {
ZEND_ME(DOMDocument, saveHTMLFile, arginfo_class_DOMDocument_saveHTMLFile, ZEND_ACC_PUBLIC)
#endif
ZEND_ME(DOMDocument, saveXML, arginfo_class_DOMDocument_saveXML, ZEND_ACC_PUBLIC)
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ ZEND_ME(DOMDocument, schemaValidate, arginfo_class_DOMDocument_schemaValidate, ZEND_ACC_PUBLIC)
+#endif
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ ZEND_ME(DOMDocument, schemaValidateSource, arginfo_class_DOMDocument_schemaValidateSource, ZEND_ACC_PUBLIC)
+#endif
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ ZEND_ME(DOMDocument, relaxNGValidate, arginfo_class_DOMDocument_relaxNGValidate, ZEND_ACC_PUBLIC)
+#endif
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ ZEND_ME(DOMDocument, relaxNGValidateSource, arginfo_class_DOMDocument_relaxNGValidateSource, ZEND_ACC_PUBLIC)
+#endif
ZEND_ME(DOMDocument, validate, arginfo_class_DOMDocument_validate, ZEND_ACC_PUBLIC)
ZEND_ME(DOMDocument, xinclude, arginfo_class_DOMDocument_xinclude, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOMDocument, adoptNode, arginfo_class_DOMDocument_adoptNode, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("append", zim_DOMElement_append, arginfo_class_DOMDocument_append, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("prepend", zim_DOMElement_prepend, arginfo_class_DOMDocument_prepend, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOMDocument, replaceChildren, arginfo_class_DOMDocument_replaceChildren, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
@@ -1016,66 +1545,254 @@ static const zend_function_entry class_DOMXPath_methods[] = {
};
#endif
-static const zend_function_entry class_DOM_Document_methods[] = {
- ZEND_ME(DOM_Document, createAttribute, arginfo_class_DOM_Document_createAttribute, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, createAttributeNS, arginfo_class_DOM_Document_createAttributeNS, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, createCDATASection, arginfo_class_DOM_Document_createCDATASection, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, createComment, arginfo_class_DOM_Document_createComment, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, createDocumentFragment, arginfo_class_DOM_Document_createDocumentFragment, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, createElement, arginfo_class_DOM_Document_createElement, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, createElementNS, arginfo_class_DOM_Document_createElementNS, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, createProcessingInstruction, arginfo_class_DOM_Document_createProcessingInstruction, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, createTextNode, arginfo_class_DOM_Document_createTextNode, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, getElementById, arginfo_class_DOM_Document_getElementById, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, getElementsByTagName, arginfo_class_DOM_Document_getElementsByTagName, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, getElementsByTagNameNS, arginfo_class_DOM_Document_getElementsByTagNameNS, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, importNode, arginfo_class_DOM_Document_importNode, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, normalizeDocument, arginfo_class_DOM_Document_normalizeDocument, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_Document, registerNodeClass, arginfo_class_DOM_Document_registerNodeClass, ZEND_ACC_PUBLIC)
-#if defined(LIBXML_SCHEMAS_ENABLED)
- ZEND_ME(DOM_Document, schemaValidate, arginfo_class_DOM_Document_schemaValidate, ZEND_ACC_PUBLIC)
-#endif
-#if defined(LIBXML_SCHEMAS_ENABLED)
- ZEND_ME(DOM_Document, schemaValidateSource, arginfo_class_DOM_Document_schemaValidateSource, ZEND_ACC_PUBLIC)
-#endif
-#if defined(LIBXML_SCHEMAS_ENABLED)
- ZEND_ME(DOM_Document, relaxNGValidate, arginfo_class_DOM_Document_relaxNGValidate, ZEND_ACC_PUBLIC)
-#endif
-#if defined(LIBXML_SCHEMAS_ENABLED)
- ZEND_ME(DOM_Document, relaxNGValidateSource, arginfo_class_DOM_Document_relaxNGValidateSource, ZEND_ACC_PUBLIC)
-#endif
- ZEND_ME(DOM_Document, adoptNode, arginfo_class_DOM_Document_adoptNode, ZEND_ACC_PUBLIC)
- ZEND_RAW_FENTRY("append", zim_DOMElement_append, arginfo_class_DOM_Document_append, ZEND_ACC_PUBLIC, NULL, NULL)
- ZEND_RAW_FENTRY("prepend", zim_DOMElement_prepend, arginfo_class_DOM_Document_prepend, ZEND_ACC_PUBLIC, NULL, NULL)
- ZEND_ME(DOM_Document, replaceChildren, arginfo_class_DOM_Document_replaceChildren, ZEND_ACC_PUBLIC)
+static const zend_function_entry class_DOM_ParentNode_methods[] = {
+ ZEND_RAW_FENTRY("append", NULL, arginfo_class_DOM_ParentNode_append, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT, NULL, NULL)
+ ZEND_RAW_FENTRY("prepend", NULL, arginfo_class_DOM_ParentNode_prepend, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT, NULL, NULL)
+ ZEND_RAW_FENTRY("replaceChildren", NULL, arginfo_class_DOM_ParentNode_replaceChildren, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT, NULL, NULL)
ZEND_FE_END
};
-static const zend_function_entry class_DOM_HTMLDocument_methods[] = {
- ZEND_ME(DOM_HTMLDocument, __construct, arginfo_class_DOM_HTMLDocument___construct, ZEND_ACC_PRIVATE)
- ZEND_ME(DOM_HTMLDocument, createEmpty, arginfo_class_DOM_HTMLDocument_createEmpty, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
- ZEND_ME(DOM_HTMLDocument, createFromFile, arginfo_class_DOM_HTMLDocument_createFromFile, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
- ZEND_ME(DOM_HTMLDocument, createFromString, arginfo_class_DOM_HTMLDocument_createFromString, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
- ZEND_RAW_FENTRY("saveXML", zim_DOMDocument_saveXML, arginfo_class_DOM_HTMLDocument_saveXML, ZEND_ACC_PUBLIC, NULL, NULL)
- ZEND_RAW_FENTRY("saveXMLFile", zim_DOMDocument_save, arginfo_class_DOM_HTMLDocument_saveXMLFile, ZEND_ACC_PUBLIC, NULL, NULL)
- ZEND_ME(DOM_HTMLDocument, saveHTML, arginfo_class_DOM_HTMLDocument_saveHTML, ZEND_ACC_PUBLIC)
- ZEND_ME(DOM_HTMLDocument, saveHTMLFile, arginfo_class_DOM_HTMLDocument_saveHTMLFile, ZEND_ACC_PUBLIC)
+static const zend_function_entry class_DOM_ChildNode_methods[] = {
+ ZEND_RAW_FENTRY("remove", NULL, arginfo_class_DOM_ChildNode_remove, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT, NULL, NULL)
+ ZEND_RAW_FENTRY("before", NULL, arginfo_class_DOM_ChildNode_before, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT, NULL, NULL)
+ ZEND_RAW_FENTRY("after", NULL, arginfo_class_DOM_ChildNode_after, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT, NULL, NULL)
+ ZEND_RAW_FENTRY("replaceWith", NULL, arginfo_class_DOM_ChildNode_replaceWith, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT, NULL, NULL)
ZEND_FE_END
};
-static const zend_function_entry class_DOM_XMLDocument_methods[] = {
- ZEND_RAW_FENTRY("__construct", zim_DOM_HTMLDocument___construct, arginfo_class_DOM_XMLDocument___construct, ZEND_ACC_PRIVATE, NULL, NULL)
- ZEND_ME(DOM_XMLDocument, createEmpty, arginfo_class_DOM_XMLDocument_createEmpty, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
- ZEND_ME(DOM_XMLDocument, createFromFile, arginfo_class_DOM_XMLDocument_createFromFile, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
- ZEND_ME(DOM_XMLDocument, createFromString, arginfo_class_DOM_XMLDocument_createFromString, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
- ZEND_RAW_FENTRY("createEntityReference", zim_DOMDocument_createEntityReference, arginfo_class_DOM_XMLDocument_createEntityReference, ZEND_ACC_PUBLIC, NULL, NULL)
- ZEND_RAW_FENTRY("validate", zim_DOMDocument_validate, arginfo_class_DOM_XMLDocument_validate, ZEND_ACC_PUBLIC, NULL, NULL)
- ZEND_RAW_FENTRY("xinclude", zim_DOMDocument_xinclude, arginfo_class_DOM_XMLDocument_xinclude, ZEND_ACC_PUBLIC, NULL, NULL)
- ZEND_RAW_FENTRY("saveXML", zim_DOMDocument_saveXML, arginfo_class_DOM_XMLDocument_saveXML, ZEND_ACC_PUBLIC, NULL, NULL)
- ZEND_RAW_FENTRY("saveXMLFile", zim_DOMDocument_save, arginfo_class_DOM_XMLDocument_saveXMLFile, ZEND_ACC_PUBLIC, NULL, NULL)
+static const zend_function_entry class_DOM_Implementation_methods[] = {
+ ZEND_ME(DOM_Implementation, createDocumentType, arginfo_class_DOM_Implementation_createDocumentType, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Implementation, createDocument, arginfo_class_DOM_Implementation_createDocument, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Implementation, createHTMLDocument, arginfo_class_DOM_Implementation_createHTMLDocument, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
+static const zend_function_entry class_DOM_Node_methods[] = {
+ ZEND_ME(DOM_Node, __construct, arginfo_class_DOM_Node___construct, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
+ ZEND_RAW_FENTRY("getRootNode", zim_DOMNode_getRootNode, arginfo_class_DOM_Node_getRootNode, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("hasChildNodes", zim_DOMNode_hasChildNodes, arginfo_class_DOM_Node_hasChildNodes, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("normalize", zim_DOMNode_normalize, arginfo_class_DOM_Node_normalize, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("cloneNode", zim_DOMNode_cloneNode, arginfo_class_DOM_Node_cloneNode, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_Node, isEqualNode, arginfo_class_DOM_Node_isEqualNode, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Node, isSameNode, arginfo_class_DOM_Node_isSameNode, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Node, compareDocumentPosition, arginfo_class_DOM_Node_compareDocumentPosition, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Node, contains, arginfo_class_DOM_Node_contains, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Node, lookupPrefix, arginfo_class_DOM_Node_lookupPrefix, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("lookupNamespaceURI", zim_DOMNode_lookupNamespaceURI, arginfo_class_DOM_Node_lookupNamespaceURI, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_Node, isDefaultNamespace, arginfo_class_DOM_Node_isDefaultNamespace, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Node, insertBefore, arginfo_class_DOM_Node_insertBefore, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Node, appendChild, arginfo_class_DOM_Node_appendChild, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Node, replaceChild, arginfo_class_DOM_Node_replaceChild, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Node, removeChild, arginfo_class_DOM_Node_removeChild, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("getLineNo", zim_DOMNode_getLineNo, arginfo_class_DOM_Node_getLineNo, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_Node, getNodePath, arginfo_class_DOM_Node_getNodePath, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("C14N", zim_DOMNode_C14N, arginfo_class_DOM_Node_C14N, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("C14NFile", zim_DOMNode_C14NFile, arginfo_class_DOM_Node_C14NFile, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("__sleep", zim_DOMNode___sleep, arginfo_class_DOM_Node___sleep, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("__wakeup", zim_DOMNode___wakeup, arginfo_class_DOM_Node___wakeup, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_NodeList_methods[] = {
+ ZEND_RAW_FENTRY("count", zim_DOMNodeList_count, arginfo_class_DOM_NodeList_count, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getIterator", zim_DOMNodeList_getIterator, arginfo_class_DOM_NodeList_getIterator, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("item", zim_DOMNodeList_item, arginfo_class_DOM_NodeList_item, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_NamedNodeMap_methods[] = {
+ ZEND_RAW_FENTRY("item", zim_DOMNamedNodeMap_item, arginfo_class_DOM_NamedNodeMap_item, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getNamedItem", zim_DOMNamedNodeMap_getNamedItem, arginfo_class_DOM_NamedNodeMap_getNamedItem, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getNamedItemNS", zim_DOMNamedNodeMap_getNamedItemNS, arginfo_class_DOM_NamedNodeMap_getNamedItemNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("count", zim_DOMNamedNodeMap_count, arginfo_class_DOM_NamedNodeMap_count, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getIterator", zim_DOMNamedNodeMap_getIterator, arginfo_class_DOM_NamedNodeMap_getIterator, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_DTDNamedNodeMap_methods[] = {
+ ZEND_RAW_FENTRY("item", zim_DOMNamedNodeMap_item, arginfo_class_DOM_DTDNamedNodeMap_item, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getNamedItem", zim_DOMNamedNodeMap_getNamedItem, arginfo_class_DOM_DTDNamedNodeMap_getNamedItem, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getNamedItemNS", zim_DOMNamedNodeMap_getNamedItemNS, arginfo_class_DOM_DTDNamedNodeMap_getNamedItemNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("count", zim_DOMNamedNodeMap_count, arginfo_class_DOM_DTDNamedNodeMap_count, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getIterator", zim_DOMNamedNodeMap_getIterator, arginfo_class_DOM_DTDNamedNodeMap_getIterator, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_HTMLCollection_methods[] = {
+ ZEND_RAW_FENTRY("item", zim_DOMNodeList_item, arginfo_class_DOM_HTMLCollection_item, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("count", zim_DOMNodeList_count, arginfo_class_DOM_HTMLCollection_count, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getIterator", zim_DOMNodeList_getIterator, arginfo_class_DOM_HTMLCollection_getIterator, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_Element_methods[] = {
+ ZEND_RAW_FENTRY("hasAttributes", zim_DOMNode_hasAttributes, arginfo_class_DOM_Element_hasAttributes, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getAttributeNames", zim_DOMElement_getAttributeNames, arginfo_class_DOM_Element_getAttributeNames, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getAttribute", zim_DOMElement_getAttribute, arginfo_class_DOM_Element_getAttribute, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getAttributeNS", zim_DOMElement_getAttributeNS, arginfo_class_DOM_Element_getAttributeNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("setAttribute", zim_DOMElement_setAttribute, arginfo_class_DOM_Element_setAttribute, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("setAttributeNS", zim_DOMElement_setAttributeNS, arginfo_class_DOM_Element_setAttributeNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_Element, removeAttribute, arginfo_class_DOM_Element_removeAttribute, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("removeAttributeNS", zim_DOMElement_removeAttributeNS, arginfo_class_DOM_Element_removeAttributeNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("toggleAttribute", zim_DOMElement_toggleAttribute, arginfo_class_DOM_Element_toggleAttribute, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("hasAttribute", zim_DOMElement_hasAttribute, arginfo_class_DOM_Element_hasAttribute, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("hasAttributeNS", zim_DOMElement_hasAttributeNS, arginfo_class_DOM_Element_hasAttributeNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getAttributeNode", zim_DOMElement_getAttributeNode, arginfo_class_DOM_Element_getAttributeNode, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getAttributeNodeNS", zim_DOMElement_getAttributeNodeNS, arginfo_class_DOM_Element_getAttributeNodeNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("setAttributeNode", zim_DOM_Element_setAttributeNodeNS, arginfo_class_DOM_Element_setAttributeNode, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_Element, setAttributeNodeNS, arginfo_class_DOM_Element_setAttributeNodeNS, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Element, removeAttributeNode, arginfo_class_DOM_Element_removeAttributeNode, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Element, getElementsByTagName, arginfo_class_DOM_Element_getElementsByTagName, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Element, getElementsByTagNameNS, arginfo_class_DOM_Element_getElementsByTagNameNS, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Element, insertAdjacentElement, arginfo_class_DOM_Element_insertAdjacentElement, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("insertAdjacentText", zim_DOMElement_insertAdjacentText, arginfo_class_DOM_Element_insertAdjacentText, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("setIdAttribute", zim_DOMElement_setIdAttribute, arginfo_class_DOM_Element_setIdAttribute, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("setIdAttributeNS", zim_DOMElement_setIdAttributeNS, arginfo_class_DOM_Element_setIdAttributeNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_Element, setIdAttributeNode, arginfo_class_DOM_Element_setIdAttributeNode, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("remove", zim_DOMElement_remove, arginfo_class_DOM_Element_remove, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("before", zim_DOMElement_before, arginfo_class_DOM_Element_before, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("after", zim_DOMElement_after, arginfo_class_DOM_Element_after, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("replaceWith", zim_DOMElement_replaceWith, arginfo_class_DOM_Element_replaceWith, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("append", zim_DOMElement_append, arginfo_class_DOM_Element_append, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("prepend", zim_DOMElement_prepend, arginfo_class_DOM_Element_prepend, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("replaceChildren", zim_DOMElement_replaceChildren, arginfo_class_DOM_Element_replaceChildren, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_Attr_methods[] = {
+ ZEND_RAW_FENTRY("isId", zim_DOMAttr_isId, arginfo_class_DOM_Attr_isId, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_CharacterData_methods[] = {
+ ZEND_RAW_FENTRY("substringData", zim_DOMCharacterData_substringData, arginfo_class_DOM_CharacterData_substringData, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_CharacterData, appendData, arginfo_class_DOM_CharacterData_appendData, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_CharacterData, insertData, arginfo_class_DOM_CharacterData_insertData, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_CharacterData, deleteData, arginfo_class_DOM_CharacterData_deleteData, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_CharacterData, replaceData, arginfo_class_DOM_CharacterData_replaceData, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("remove", zim_DOMElement_remove, arginfo_class_DOM_CharacterData_remove, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("before", zim_DOMElement_before, arginfo_class_DOM_CharacterData_before, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("after", zim_DOMElement_after, arginfo_class_DOM_CharacterData_after, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("replaceWith", zim_DOMElement_replaceWith, arginfo_class_DOM_CharacterData_replaceWith, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_Text_methods[] = {
+ ZEND_RAW_FENTRY("splitText", zim_DOMText_splitText, arginfo_class_DOM_Text_splitText, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_CDATASection_methods[] = {
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_ProcessingInstruction_methods[] = {
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_Comment_methods[] = {
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_DocumentType_methods[] = {
+ ZEND_RAW_FENTRY("remove", zim_DOMElement_remove, arginfo_class_DOM_DocumentType_remove, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("before", zim_DOMElement_before, arginfo_class_DOM_DocumentType_before, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("after", zim_DOMElement_after, arginfo_class_DOM_DocumentType_after, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("replaceWith", zim_DOMElement_replaceWith, arginfo_class_DOM_DocumentType_replaceWith, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_DocumentFragment_methods[] = {
+ ZEND_RAW_FENTRY("appendXML", zim_DOMDocumentFragment_appendXML, arginfo_class_DOM_DocumentFragment_appendXML, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("append", zim_DOMElement_append, arginfo_class_DOM_DocumentFragment_append, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("prepend", zim_DOMElement_prepend, arginfo_class_DOM_DocumentFragment_prepend, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("replaceChildren", zim_DOMElement_replaceChildren, arginfo_class_DOM_DocumentFragment_replaceChildren, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_Entity_methods[] = {
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_EntityReference_methods[] = {
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_Notation_methods[] = {
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_Document_methods[] = {
+ ZEND_RAW_FENTRY("getElementsByTagName", zim_DOM_Element_getElementsByTagName, arginfo_class_DOM_Document_getElementsByTagName, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getElementsByTagNameNS", zim_DOM_Element_getElementsByTagNameNS, arginfo_class_DOM_Document_getElementsByTagNameNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_Document, createElement, arginfo_class_DOM_Document_createElement, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Document, createElementNS, arginfo_class_DOM_Document_createElementNS, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("createDocumentFragment", zim_DOMDocument_createDocumentFragment, arginfo_class_DOM_Document_createDocumentFragment, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("createTextNode", zim_DOMDocument_createTextNode, arginfo_class_DOM_Document_createTextNode, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("createCDATASection", zim_DOMDocument_createCDATASection, arginfo_class_DOM_Document_createCDATASection, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("createComment", zim_DOMDocument_createComment, arginfo_class_DOM_Document_createComment, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_Document, createProcessingInstruction, arginfo_class_DOM_Document_createProcessingInstruction, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Document, importNode, arginfo_class_DOM_Document_importNode, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_Document, adoptNode, arginfo_class_DOM_Document_adoptNode, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("createAttribute", zim_DOMDocument_createAttribute, arginfo_class_DOM_Document_createAttribute, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("createAttributeNS", zim_DOMDocument_createAttributeNS, arginfo_class_DOM_Document_createAttributeNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("getElementById", zim_DOMDocument_getElementById, arginfo_class_DOM_Document_getElementById, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_Document, registerNodeClass, arginfo_class_DOM_Document_registerNodeClass, ZEND_ACC_PUBLIC)
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ ZEND_RAW_FENTRY("schemaValidate", zim_DOMDocument_schemaValidate, arginfo_class_DOM_Document_schemaValidate, ZEND_ACC_PUBLIC, NULL, NULL)
+#endif
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ ZEND_RAW_FENTRY("schemaValidateSource", zim_DOMDocument_schemaValidateSource, arginfo_class_DOM_Document_schemaValidateSource, ZEND_ACC_PUBLIC, NULL, NULL)
+#endif
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ ZEND_RAW_FENTRY("relaxNGValidate", zim_DOMDocument_relaxNGValidate, arginfo_class_DOM_Document_relaxNGValidate, ZEND_ACC_PUBLIC, NULL, NULL)
+#endif
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ ZEND_RAW_FENTRY("relaxNGValidateSource", zim_DOMDocument_relaxNGValidateSource, arginfo_class_DOM_Document_relaxNGValidateSource, ZEND_ACC_PUBLIC, NULL, NULL)
+#endif
+ ZEND_RAW_FENTRY("append", zim_DOMElement_append, arginfo_class_DOM_Document_append, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("prepend", zim_DOMElement_prepend, arginfo_class_DOM_Document_prepend, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("replaceChildren", zim_DOMDocument_replaceChildren, arginfo_class_DOM_Document_replaceChildren, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_Document, importLegacyNode, arginfo_class_DOM_Document_importLegacyNode, ZEND_ACC_PUBLIC)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_HTMLDocument_methods[] = {
+ ZEND_ME(DOM_HTMLDocument, createEmpty, arginfo_class_DOM_HTMLDocument_createEmpty, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ ZEND_ME(DOM_HTMLDocument, createFromFile, arginfo_class_DOM_HTMLDocument_createFromFile, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ ZEND_ME(DOM_HTMLDocument, createFromString, arginfo_class_DOM_HTMLDocument_createFromString, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ ZEND_RAW_FENTRY("saveXML", zim_DOM_XMLDocument_saveXML, arginfo_class_DOM_HTMLDocument_saveXML, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("saveXMLFile", zim_DOMDocument_save, arginfo_class_DOM_HTMLDocument_saveXMLFile, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_HTMLDocument, saveHTML, arginfo_class_DOM_HTMLDocument_saveHTML, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_HTMLDocument, saveHTMLFile, arginfo_class_DOM_HTMLDocument_saveHTMLFile, ZEND_ACC_PUBLIC)
+ ZEND_FE_END
+};
+
+static const zend_function_entry class_DOM_XMLDocument_methods[] = {
+ ZEND_ME(DOM_XMLDocument, createEmpty, arginfo_class_DOM_XMLDocument_createEmpty, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ ZEND_ME(DOM_XMLDocument, createFromFile, arginfo_class_DOM_XMLDocument_createFromFile, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ ZEND_ME(DOM_XMLDocument, createFromString, arginfo_class_DOM_XMLDocument_createFromString, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ ZEND_RAW_FENTRY("createEntityReference", zim_DOMDocument_createEntityReference, arginfo_class_DOM_XMLDocument_createEntityReference, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("validate", zim_DOMDocument_validate, arginfo_class_DOM_XMLDocument_validate, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("xinclude", zim_DOMDocument_xinclude, arginfo_class_DOM_XMLDocument_xinclude, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_ME(DOM_XMLDocument, saveXML, arginfo_class_DOM_XMLDocument_saveXML, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("saveXMLFile", zim_DOMDocument_save, arginfo_class_DOM_XMLDocument_saveXMLFile, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_FE_END
+};
+
+#if defined(LIBXML_XPATH_ENABLED)
+static const zend_function_entry class_DOM_XPath_methods[] = {
+ ZEND_ME(DOM_XPath, __construct, arginfo_class_DOM_XPath___construct, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_XPath, evaluate, arginfo_class_DOM_XPath_evaluate, ZEND_ACC_PUBLIC)
+ ZEND_ME(DOM_XPath, query, arginfo_class_DOM_XPath_query, ZEND_ACC_PUBLIC)
+ ZEND_RAW_FENTRY("registerNamespace", zim_DOMXPath_registerNamespace, arginfo_class_DOM_XPath_registerNamespace, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("registerPhpFunctions", zim_DOMXPath_registerPhpFunctions, arginfo_class_DOM_XPath_registerPhpFunctions, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("registerPhpFunctionNS", zim_DOMXPath_registerPhpFunctionNS, arginfo_class_DOM_XPath_registerPhpFunctionNS, ZEND_ACC_PUBLIC, NULL, NULL)
+ ZEND_RAW_FENTRY("quote", zim_DOMXPath_quote, arginfo_class_DOM_XPath_quote, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL)
+ ZEND_FE_END
+};
+#endif
+
static void register_php_dom_symbols(int module_number)
{
REGISTER_LONG_CONSTANT("XML_ELEMENT_NODE", XML_ELEMENT_NODE, CONST_PERSISTENT);
@@ -1126,7 +1843,6 @@ static void register_php_dom_symbols(int module_number)
REGISTER_LONG_CONSTANT("DOM_NAMESPACE_ERR", NAMESPACE_ERR, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DOM_INVALID_ACCESS_ERR", INVALID_ACCESS_ERR, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DOM_VALIDATION_ERR", VALIDATION_ERR, CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("DOM\\PHP_ERR", PHP_ERR, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DOM\\INDEX_SIZE_ERR", INDEX_SIZE_ERR, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DOM\\STRING_SIZE_ERR", DOMSTRING_SIZE_ERR, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DOM\\HIERARCHY_REQUEST_ERR", HIERARCHY_REQUEST_ERR, CONST_PERSISTENT);
@@ -1141,7 +1857,6 @@ static void register_php_dom_symbols(int module_number)
REGISTER_LONG_CONSTANT("DOM\\SYNTAX_ERR", SYNTAX_ERR, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DOM\\INVALID_MODIFICATION_ERR", INVALID_MODIFICATION_ERR, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DOM\\NAMESPACE_ERR", NAMESPACE_ERR, CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("DOM\\INVALID_ACCESS_ERR", INVALID_ACCESS_ERR, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DOM\\VALIDATION_ERR", VALIDATION_ERR, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DOM\\HTML_NO_DEFAULT_NS", DOM_HTML_NO_DEFAULT_NS, CONST_PERSISTENT);
}
@@ -1152,7 +1867,6 @@ static zend_class_entry *register_class_DOMDocumentType(zend_class_entry *class_
INIT_CLASS_ENTRY(ce, "DOMDocumentType", class_DOMDocumentType_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
- zend_register_class_alias("DOM\\DocumentType", class_entry);
zval property_name_default_value;
ZVAL_UNDEF(&property_name_default_value);
@@ -1201,7 +1915,6 @@ static zend_class_entry *register_class_DOMCdataSection(zend_class_entry *class_
INIT_CLASS_ENTRY(ce, "DOMCdataSection", class_DOMCdataSection_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMText);
- zend_register_class_alias("DOM\\CDATASection", class_entry);
return class_entry;
}
@@ -1212,7 +1925,6 @@ static zend_class_entry *register_class_DOMComment(zend_class_entry *class_entry
INIT_CLASS_ENTRY(ce, "DOMComment", class_DOMComment_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMCharacterData);
- zend_register_class_alias("DOM\\Comment", class_entry);
return class_entry;
}
@@ -1223,7 +1935,6 @@ static zend_class_entry *register_class_DOMParentNode(void)
INIT_CLASS_ENTRY(ce, "DOMParentNode", class_DOMParentNode_methods);
class_entry = zend_register_internal_interface(&ce);
- zend_register_class_alias("DOM\\ParentNode", class_entry);
return class_entry;
}
@@ -1234,7 +1945,6 @@ static zend_class_entry *register_class_DOMChildNode(void)
INIT_CLASS_ENTRY(ce, "DOMChildNode", class_DOMChildNode_methods);
class_entry = zend_register_internal_interface(&ce);
- zend_register_class_alias("DOM\\ChildNode", class_entry);
return class_entry;
}
@@ -1245,7 +1955,6 @@ static zend_class_entry *register_class_DOMNode(void)
INIT_CLASS_ENTRY(ce, "DOMNode", class_DOMNode_methods);
class_entry = zend_register_internal_class_ex(&ce, NULL);
- zend_register_class_alias("DOM\\Node", class_entry);
zval const_DOCUMENT_POSITION_DISCONNECTED_value;
ZVAL_LONG(&const_DOCUMENT_POSITION_DISCONNECTED_value, 0x1);
@@ -1366,8 +2075,8 @@ static zend_class_entry *register_class_DOMNode(void)
zval property_ownerDocument_default_value;
ZVAL_UNDEF(&property_ownerDocument_default_value);
zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, 1);
- zend_string *property_ownerDocument_class_DOM_Document = zend_string_init("DOM\\Document", sizeof("DOM\\Document")-1, 1);
- zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOM_Document, 0, MAY_BE_NULL));
+ zend_string *property_ownerDocument_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1);
+ zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL));
zend_string_release(property_ownerDocument_name);
zval property_namespaceURI_default_value;
@@ -1409,7 +2118,6 @@ static zend_class_entry *register_class_DOMNameSpaceNode(void)
INIT_CLASS_ENTRY(ce, "DOMNameSpaceNode", class_DOMNameSpaceNode_methods);
class_entry = zend_register_internal_class_ex(&ce, NULL);
- zend_register_class_alias("DOM\\NameSpaceNode", class_entry);
zval property_nodeName_default_value;
ZVAL_UNDEF(&property_nodeName_default_value);
@@ -1494,7 +2202,6 @@ static zend_class_entry *register_class_DOMDocumentFragment(zend_class_entry *cl
INIT_CLASS_ENTRY(ce, "DOMDocumentFragment", class_DOMDocumentFragment_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
zend_class_implements(class_entry, 1, class_entry_DOMParentNode);
- zend_register_class_alias("DOM\\DocumentFragment", class_entry);
zval property_firstElementChild_default_value;
ZVAL_UNDEF(&property_firstElementChild_default_value);
@@ -1526,7 +2233,6 @@ static zend_class_entry *register_class_DOMNodeList(zend_class_entry *class_entr
INIT_CLASS_ENTRY(ce, "DOMNodeList", class_DOMNodeList_methods);
class_entry = zend_register_internal_class_ex(&ce, NULL);
zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable);
- zend_register_class_alias("DOM\\NodeList", class_entry);
zval property_length_default_value;
ZVAL_UNDEF(&property_length_default_value);
@@ -1544,7 +2250,6 @@ static zend_class_entry *register_class_DOMCharacterData(zend_class_entry *class
INIT_CLASS_ENTRY(ce, "DOMCharacterData", class_DOMCharacterData_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
zend_class_implements(class_entry, 1, class_entry_DOMChildNode);
- zend_register_class_alias("DOM\\CharacterData", class_entry);
zval property_data_default_value;
ZVAL_UNDEF(&property_data_default_value);
@@ -1581,7 +2286,6 @@ static zend_class_entry *register_class_DOMAttr(zend_class_entry *class_entry_DO
INIT_CLASS_ENTRY(ce, "DOMAttr", class_DOMAttr_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
- zend_register_class_alias("DOM\\Attr", class_entry);
zval property_name_default_value;
ZVAL_UNDEF(&property_name_default_value);
@@ -1624,7 +2328,6 @@ static zend_class_entry *register_class_DOMElement(zend_class_entry *class_entry
INIT_CLASS_ENTRY(ce, "DOMElement", class_DOMElement_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
zend_class_implements(class_entry, 2, class_entry_DOMParentNode, class_entry_DOMChildNode);
- zend_register_class_alias("DOM\\Element", class_entry);
zval property_tagName_default_value;
ZVAL_UNDEF(&property_tagName_default_value);
@@ -1687,12 +2390,20 @@ static zend_class_entry *register_class_DOMElement(zend_class_entry *class_entry
return class_entry;
}
-static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entry_DOM_Document)
+static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entry_DOMNode, zend_class_entry *class_entry_DOMParentNode)
{
zend_class_entry ce, *class_entry;
INIT_CLASS_ENTRY(ce, "DOMDocument", class_DOMDocument_methods);
- class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Document);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
+ zend_class_implements(class_entry, 1, class_entry_DOMParentNode);
+
+ zval property_doctype_default_value;
+ ZVAL_UNDEF(&property_doctype_default_value);
+ zend_string *property_doctype_name = zend_string_init("doctype", sizeof("doctype") - 1, 1);
+ zend_string *property_doctype_class_DOMDocumentType = zend_string_init("DOMDocumentType", sizeof("DOMDocumentType")-1, 1);
+ zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_DOMDocumentType, 0, MAY_BE_NULL));
+ zend_string_release(property_doctype_name);
zval property_implementation_default_value;
ZVAL_UNDEF(&property_implementation_default_value);
@@ -1701,12 +2412,25 @@ static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entr
zend_declare_typed_property(class_entry, property_implementation_name, &property_implementation_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_implementation_class_DOMImplementation, 0, 0));
zend_string_release(property_implementation_name);
+ zval property_documentElement_default_value;
+ ZVAL_UNDEF(&property_documentElement_default_value);
+ zend_string *property_documentElement_name = zend_string_init("documentElement", sizeof("documentElement") - 1, 1);
+ zend_string *property_documentElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
+ zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_DOMElement, 0, MAY_BE_NULL));
+ zend_string_release(property_documentElement_name);
+
zval property_actualEncoding_default_value;
ZVAL_UNDEF(&property_actualEncoding_default_value);
zend_string *property_actualEncoding_name = zend_string_init("actualEncoding", sizeof("actualEncoding") - 1, 1);
zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
zend_string_release(property_actualEncoding_name);
+ zval property_encoding_default_value;
+ ZVAL_UNDEF(&property_encoding_default_value);
+ zend_string *property_encoding_name = zend_string_init("encoding", sizeof("encoding") - 1, 1);
+ zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_encoding_name);
+
zval property_xmlEncoding_default_value;
ZVAL_UNDEF(&property_xmlEncoding_default_value);
zend_string *property_xmlEncoding_name = zend_string_init("xmlEncoding", sizeof("xmlEncoding") - 1, 1);
@@ -1737,6 +2461,18 @@ static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entr
zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
zend_string_release(property_xmlVersion_name);
+ zval property_strictErrorChecking_default_value;
+ ZVAL_UNDEF(&property_strictErrorChecking_default_value);
+ zend_string *property_strictErrorChecking_name = zend_string_init("strictErrorChecking", sizeof("strictErrorChecking") - 1, 1);
+ zend_declare_typed_property(class_entry, property_strictErrorChecking_name, &property_strictErrorChecking_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+ zend_string_release(property_strictErrorChecking_name);
+
+ zval property_documentURI_default_value;
+ ZVAL_UNDEF(&property_documentURI_default_value);
+ zend_string *property_documentURI_name = zend_string_init("documentURI", sizeof("documentURI") - 1, 1);
+ zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_documentURI_name);
+
zval property_config_default_value;
ZVAL_UNDEF(&property_config_default_value);
zend_string *property_config_name = zend_string_init("config", sizeof("config") - 1, 1);
@@ -1779,6 +2515,26 @@ static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entr
zend_declare_typed_property(class_entry, property_substituteEntities_name, &property_substituteEntities_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
zend_string_release(property_substituteEntities_name);
+ zval property_firstElementChild_default_value;
+ ZVAL_UNDEF(&property_firstElementChild_default_value);
+ zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1);
+ zend_string *property_firstElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
+ zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL));
+ zend_string_release(property_firstElementChild_name);
+
+ zval property_lastElementChild_default_value;
+ ZVAL_UNDEF(&property_lastElementChild_default_value);
+ zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1);
+ zend_string *property_lastElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
+ zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL));
+ zend_string_release(property_lastElementChild_name);
+
+ zval property_childElementCount_default_value;
+ ZVAL_UNDEF(&property_childElementCount_default_value);
+ zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1);
+ zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(property_childElementCount_name);
+
return class_entry;
}
@@ -1806,7 +2562,6 @@ static zend_class_entry *register_class_DOMText(zend_class_entry *class_entry_DO
INIT_CLASS_ENTRY(ce, "DOMText", class_DOMText_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMCharacterData);
- zend_register_class_alias("DOM\\Text", class_entry);
zval property_wholeText_default_value;
ZVAL_UNDEF(&property_wholeText_default_value);
@@ -1824,7 +2579,6 @@ static zend_class_entry *register_class_DOMNamedNodeMap(zend_class_entry *class_
INIT_CLASS_ENTRY(ce, "DOMNamedNodeMap", class_DOMNamedNodeMap_methods);
class_entry = zend_register_internal_class_ex(&ce, NULL);
zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable);
- zend_register_class_alias("DOM\\NamedNodeMap", class_entry);
zval property_length_default_value;
ZVAL_UNDEF(&property_length_default_value);
@@ -1841,7 +2595,6 @@ static zend_class_entry *register_class_DOMEntity(zend_class_entry *class_entry_
INIT_CLASS_ENTRY(ce, "DOMEntity", class_DOMEntity_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
- zend_register_class_alias("DOM\\Entity", class_entry);
zval property_publicId_default_value;
ZVAL_UNDEF(&property_publicId_default_value);
@@ -1888,7 +2641,6 @@ static zend_class_entry *register_class_DOMEntityReference(zend_class_entry *cla
INIT_CLASS_ENTRY(ce, "DOMEntityReference", class_DOMEntityReference_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
- zend_register_class_alias("DOM\\EntityReference", class_entry);
return class_entry;
}
@@ -1899,7 +2651,6 @@ static zend_class_entry *register_class_DOMNotation(zend_class_entry *class_entr
INIT_CLASS_ENTRY(ce, "DOMNotation", class_DOMNotation_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
- zend_register_class_alias("DOM\\Notation", class_entry);
zval property_publicId_default_value;
ZVAL_UNDEF(&property_publicId_default_value);
@@ -1922,7 +2673,6 @@ static zend_class_entry *register_class_DOMProcessingInstruction(zend_class_entr
INIT_CLASS_ENTRY(ce, "DOMProcessingInstruction", class_DOMProcessingInstruction_methods);
class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
- zend_register_class_alias("DOM\\ProcessingInstruction", class_entry);
zval property_target_default_value;
ZVAL_UNDEF(&property_target_default_value);
@@ -1947,13 +2697,12 @@ static zend_class_entry *register_class_DOMXPath(void)
INIT_CLASS_ENTRY(ce, "DOMXPath", class_DOMXPath_methods);
class_entry = zend_register_internal_class_ex(&ce, NULL);
class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE;
- zend_register_class_alias("DOM\\XPath", class_entry);
zval property_document_default_value;
ZVAL_UNDEF(&property_document_default_value);
zend_string *property_document_name = zend_string_init("document", sizeof("document") - 1, 1);
- zend_string *property_document_class_DOM_Document = zend_string_init("DOM\\Document", sizeof("DOM\\Document")-1, 1);
- zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_DOM_Document, 0, 0));
+ zend_string *property_document_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1);
+ zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_DOMDocument, 0, 0));
zend_string_release(property_document_name);
zval property_registerNodeNamespaces_default_value;
@@ -1966,117 +2715,732 @@ static zend_class_entry *register_class_DOMXPath(void)
}
#endif
-static zend_class_entry *register_class_DOM_Document(zend_class_entry *class_entry_DOMNode, zend_class_entry *class_entry_DOMParentNode)
+static zend_class_entry *register_class_DOM_ParentNode(void)
{
zend_class_entry ce, *class_entry;
- INIT_NS_CLASS_ENTRY(ce, "DOM", "Document", class_DOM_Document_methods);
- class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode);
- class_entry->ce_flags |= ZEND_ACC_ABSTRACT;
- zend_class_implements(class_entry, 1, class_entry_DOMParentNode);
-
- zval property_doctype_default_value;
- ZVAL_UNDEF(&property_doctype_default_value);
- zend_string *property_doctype_name = zend_string_init("doctype", sizeof("doctype") - 1, 1);
- zend_string *property_doctype_class_DOM_DocumentType = zend_string_init("DOM\\DocumentType", sizeof("DOM\\DocumentType")-1, 1);
- zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_DOM_DocumentType, 0, MAY_BE_NULL));
- zend_string_release(property_doctype_name);
-
- zval property_documentElement_default_value;
- ZVAL_UNDEF(&property_documentElement_default_value);
- zend_string *property_documentElement_name = zend_string_init("documentElement", sizeof("documentElement") - 1, 1);
- zend_string *property_documentElement_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
- zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_DOM_Element, 0, MAY_BE_NULL));
- zend_string_release(property_documentElement_name);
-
- zval property_encoding_default_value;
- ZVAL_UNDEF(&property_encoding_default_value);
- zend_string *property_encoding_name = zend_string_init("encoding", sizeof("encoding") - 1, 1);
- zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
- zend_string_release(property_encoding_name);
-
- zval property_strictErrorChecking_default_value;
- ZVAL_UNDEF(&property_strictErrorChecking_default_value);
- zend_string *property_strictErrorChecking_name = zend_string_init("strictErrorChecking", sizeof("strictErrorChecking") - 1, 1);
- zend_declare_typed_property(class_entry, property_strictErrorChecking_name, &property_strictErrorChecking_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
- zend_string_release(property_strictErrorChecking_name);
-
- zval property_documentURI_default_value;
- ZVAL_UNDEF(&property_documentURI_default_value);
- zend_string *property_documentURI_name = zend_string_init("documentURI", sizeof("documentURI") - 1, 1);
- zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
- zend_string_release(property_documentURI_name);
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "ParentNode", class_DOM_ParentNode_methods);
+ class_entry = zend_register_internal_interface(&ce);
- zval property_firstElementChild_default_value;
- ZVAL_UNDEF(&property_firstElementChild_default_value);
- zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1);
- zend_string *property_firstElementChild_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
- zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOM_Element, 0, MAY_BE_NULL));
- zend_string_release(property_firstElementChild_name);
+ return class_entry;
+}
- zval property_lastElementChild_default_value;
- ZVAL_UNDEF(&property_lastElementChild_default_value);
- zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1);
- zend_string *property_lastElementChild_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
- zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOM_Element, 0, MAY_BE_NULL));
- zend_string_release(property_lastElementChild_name);
+static zend_class_entry *register_class_DOM_ChildNode(void)
+{
+ zend_class_entry ce, *class_entry;
- zval property_childElementCount_default_value;
- ZVAL_UNDEF(&property_childElementCount_default_value);
- zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1);
- zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
- zend_string_release(property_childElementCount_name);
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "ChildNode", class_DOM_ChildNode_methods);
+ class_entry = zend_register_internal_interface(&ce);
return class_entry;
}
-static zend_class_entry *register_class_DOM_HTMLDocument(zend_class_entry *class_entry_DOM_Document)
+static zend_class_entry *register_class_DOM_Implementation(void)
{
zend_class_entry ce, *class_entry;
- INIT_NS_CLASS_ENTRY(ce, "DOM", "HTMLDocument", class_DOM_HTMLDocument_methods);
- class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Document);
- class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES;
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "Implementation", class_DOM_Implementation_methods);
+ class_entry = zend_register_internal_class_ex(&ce, NULL);
+ class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE;
return class_entry;
}
-static zend_class_entry *register_class_DOM_XMLDocument(zend_class_entry *class_entry_DOM_Document)
+static zend_class_entry *register_class_DOM_Node(void)
{
zend_class_entry ce, *class_entry;
- INIT_NS_CLASS_ENTRY(ce, "DOM", "XMLDocument", class_DOM_XMLDocument_methods);
- class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Document);
- class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES;
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "Node", class_DOM_Node_methods);
+ class_entry = zend_register_internal_class_ex(&ce, NULL);
+ class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES;
- zval property_xmlEncoding_default_value;
- ZVAL_UNDEF(&property_xmlEncoding_default_value);
- zend_string *property_xmlEncoding_name = zend_string_init("xmlEncoding", sizeof("xmlEncoding") - 1, 1);
- zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
- zend_string_release(property_xmlEncoding_name);
+ zval const_DOCUMENT_POSITION_DISCONNECTED_value;
+ ZVAL_LONG(&const_DOCUMENT_POSITION_DISCONNECTED_value, 0x1);
+ zend_string *const_DOCUMENT_POSITION_DISCONNECTED_name = zend_string_init_interned("DOCUMENT_POSITION_DISCONNECTED", sizeof("DOCUMENT_POSITION_DISCONNECTED") - 1, 1);
+ zend_declare_typed_class_constant(class_entry, const_DOCUMENT_POSITION_DISCONNECTED_name, &const_DOCUMENT_POSITION_DISCONNECTED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(const_DOCUMENT_POSITION_DISCONNECTED_name);
- zval property_standalone_default_value;
- ZVAL_UNDEF(&property_standalone_default_value);
- zend_string *property_standalone_name = zend_string_init("standalone", sizeof("standalone") - 1, 1);
- zend_declare_typed_property(class_entry, property_standalone_name, &property_standalone_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
- zend_string_release(property_standalone_name);
+ zval const_DOCUMENT_POSITION_PRECEDING_value;
+ ZVAL_LONG(&const_DOCUMENT_POSITION_PRECEDING_value, 0x2);
+ zend_string *const_DOCUMENT_POSITION_PRECEDING_name = zend_string_init_interned("DOCUMENT_POSITION_PRECEDING", sizeof("DOCUMENT_POSITION_PRECEDING") - 1, 1);
+ zend_declare_typed_class_constant(class_entry, const_DOCUMENT_POSITION_PRECEDING_name, &const_DOCUMENT_POSITION_PRECEDING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(const_DOCUMENT_POSITION_PRECEDING_name);
- zval property_xmlStandalone_default_value;
- ZVAL_UNDEF(&property_xmlStandalone_default_value);
- zend_string *property_xmlStandalone_name = zend_string_init("xmlStandalone", sizeof("xmlStandalone") - 1, 1);
- zend_declare_typed_property(class_entry, property_xmlStandalone_name, &property_xmlStandalone_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
- zend_string_release(property_xmlStandalone_name);
+ zval const_DOCUMENT_POSITION_FOLLOWING_value;
+ ZVAL_LONG(&const_DOCUMENT_POSITION_FOLLOWING_value, 0x4);
+ zend_string *const_DOCUMENT_POSITION_FOLLOWING_name = zend_string_init_interned("DOCUMENT_POSITION_FOLLOWING", sizeof("DOCUMENT_POSITION_FOLLOWING") - 1, 1);
+ zend_declare_typed_class_constant(class_entry, const_DOCUMENT_POSITION_FOLLOWING_name, &const_DOCUMENT_POSITION_FOLLOWING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(const_DOCUMENT_POSITION_FOLLOWING_name);
- zval property_version_default_value;
- ZVAL_UNDEF(&property_version_default_value);
- zend_string *property_version_name = zend_string_init("version", sizeof("version") - 1, 1);
- zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
- zend_string_release(property_version_name);
+ zval const_DOCUMENT_POSITION_CONTAINS_value;
+ ZVAL_LONG(&const_DOCUMENT_POSITION_CONTAINS_value, 0x8);
+ zend_string *const_DOCUMENT_POSITION_CONTAINS_name = zend_string_init_interned("DOCUMENT_POSITION_CONTAINS", sizeof("DOCUMENT_POSITION_CONTAINS") - 1, 1);
+ zend_declare_typed_class_constant(class_entry, const_DOCUMENT_POSITION_CONTAINS_name, &const_DOCUMENT_POSITION_CONTAINS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(const_DOCUMENT_POSITION_CONTAINS_name);
+
+ zval const_DOCUMENT_POSITION_CONTAINED_BY_value;
+ ZVAL_LONG(&const_DOCUMENT_POSITION_CONTAINED_BY_value, 0x10);
+ zend_string *const_DOCUMENT_POSITION_CONTAINED_BY_name = zend_string_init_interned("DOCUMENT_POSITION_CONTAINED_BY", sizeof("DOCUMENT_POSITION_CONTAINED_BY") - 1, 1);
+ zend_declare_typed_class_constant(class_entry, const_DOCUMENT_POSITION_CONTAINED_BY_name, &const_DOCUMENT_POSITION_CONTAINED_BY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(const_DOCUMENT_POSITION_CONTAINED_BY_name);
+
+ zval const_DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC_value;
+ ZVAL_LONG(&const_DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC_value, 0x20);
+ zend_string *const_DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC_name = zend_string_init_interned("DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", sizeof("DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC") - 1, 1);
+ zend_declare_typed_class_constant(class_entry, const_DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC_name, &const_DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(const_DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC_name);
+
+ zval property_nodeType_default_value;
+ ZVAL_UNDEF(&property_nodeType_default_value);
+ zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, 1);
+ zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(property_nodeType_name);
+
+ zval property_nodeName_default_value;
+ ZVAL_UNDEF(&property_nodeName_default_value);
+ zend_string *property_nodeName_name = zend_string_init("nodeName", sizeof("nodeName") - 1, 1);
+ zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_nodeName_name);
+
+ zval property_baseURI_default_value;
+ ZVAL_UNDEF(&property_baseURI_default_value);
+ zend_string *property_baseURI_name = zend_string_init("baseURI", sizeof("baseURI") - 1, 1);
+ zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_baseURI_name);
+
+ zval property_isConnected_default_value;
+ ZVAL_UNDEF(&property_isConnected_default_value);
+ zend_string *property_isConnected_name = zend_string_init("isConnected", sizeof("isConnected") - 1, 1);
+ zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+ zend_string_release(property_isConnected_name);
+
+ zval property_ownerDocument_default_value;
+ ZVAL_UNDEF(&property_ownerDocument_default_value);
+ zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, 1);
+ zend_string *property_ownerDocument_class_DOM_Document = zend_string_init("DOM\\Document", sizeof("DOM\\Document")-1, 1);
+ zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOM_Document, 0, MAY_BE_NULL));
+ zend_string_release(property_ownerDocument_name);
+
+ zval property_parentNode_default_value;
+ ZVAL_UNDEF(&property_parentNode_default_value);
+ zend_string *property_parentNode_name = zend_string_init("parentNode", sizeof("parentNode") - 1, 1);
+ zend_string *property_parentNode_class_DOM_Node = zend_string_init("DOM\\\116ode", sizeof("DOM\\\116ode")-1, 1);
+ zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOM_Node, 0, MAY_BE_NULL));
+ zend_string_release(property_parentNode_name);
+
+ zval property_parentElement_default_value;
+ ZVAL_UNDEF(&property_parentElement_default_value);
+ zend_string *property_parentElement_name = zend_string_init("parentElement", sizeof("parentElement") - 1, 1);
+ zend_string *property_parentElement_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_parentElement_name);
+
+ zval property_childNodes_default_value;
+ ZVAL_UNDEF(&property_childNodes_default_value);
+ zend_string *property_childNodes_name = zend_string_init("childNodes", sizeof("childNodes") - 1, 1);
+ zend_string *property_childNodes_class_DOM_NodeList = zend_string_init("DOM\\\116odeList", sizeof("DOM\\\116odeList")-1, 1);
+ zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_DOM_NodeList, 0, 0));
+ zend_string_release(property_childNodes_name);
+
+ zval property_firstChild_default_value;
+ ZVAL_UNDEF(&property_firstChild_default_value);
+ zend_string *property_firstChild_name = zend_string_init("firstChild", sizeof("firstChild") - 1, 1);
+ zend_string *property_firstChild_class_DOM_Node = zend_string_init("DOM\\\116ode", sizeof("DOM\\\116ode")-1, 1);
+ zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_DOM_Node, 0, MAY_BE_NULL));
+ zend_string_release(property_firstChild_name);
+
+ zval property_lastChild_default_value;
+ ZVAL_UNDEF(&property_lastChild_default_value);
+ zend_string *property_lastChild_name = zend_string_init("lastChild", sizeof("lastChild") - 1, 1);
+ zend_string *property_lastChild_class_DOM_Node = zend_string_init("DOM\\\116ode", sizeof("DOM\\\116ode")-1, 1);
+ zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_DOM_Node, 0, MAY_BE_NULL));
+ zend_string_release(property_lastChild_name);
+
+ zval property_previousSibling_default_value;
+ ZVAL_UNDEF(&property_previousSibling_default_value);
+ zend_string *property_previousSibling_name = zend_string_init("previousSibling", sizeof("previousSibling") - 1, 1);
+ zend_string *property_previousSibling_class_DOM_Node = zend_string_init("DOM\\\116ode", sizeof("DOM\\\116ode")-1, 1);
+ zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_DOM_Node, 0, MAY_BE_NULL));
+ zend_string_release(property_previousSibling_name);
+
+ zval property_nextSibling_default_value;
+ ZVAL_UNDEF(&property_nextSibling_default_value);
+ zend_string *property_nextSibling_name = zend_string_init("nextSibling", sizeof("nextSibling") - 1, 1);
+ zend_string *property_nextSibling_class_DOM_Node = zend_string_init("DOM\\\116ode", sizeof("DOM\\\116ode")-1, 1);
+ zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_DOM_Node, 0, MAY_BE_NULL));
+ zend_string_release(property_nextSibling_name);
+
+ zval property_nodeValue_default_value;
+ ZVAL_UNDEF(&property_nodeValue_default_value);
+ zend_string *property_nodeValue_name = zend_string_init("nodeValue", sizeof("nodeValue") - 1, 1);
+ zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_nodeValue_name);
+
+ zval property_textContent_default_value;
+ ZVAL_UNDEF(&property_textContent_default_value);
+ zend_string *property_textContent_name = zend_string_init("textContent", sizeof("textContent") - 1, 1);
+ zend_declare_typed_property(class_entry, property_textContent_name, &property_textContent_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_textContent_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_NodeList(zend_class_entry *class_entry_DOM_IteratorAggregate, zend_class_entry *class_entry_DOM_Countable)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "NodeList", class_DOM_NodeList_methods);
+ class_entry = zend_register_internal_class_ex(&ce, NULL);
+ zend_class_implements(class_entry, 2, class_entry_DOM_IteratorAggregate, class_entry_DOM_Countable);
+
+ zval property_length_default_value;
+ ZVAL_UNDEF(&property_length_default_value);
+ zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1);
+ zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(property_length_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_NamedNodeMap(zend_class_entry *class_entry_DOM_IteratorAggregate, zend_class_entry *class_entry_DOM_Countable)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "NamedNodeMap", class_DOM_NamedNodeMap_methods);
+ class_entry = zend_register_internal_class_ex(&ce, NULL);
+ zend_class_implements(class_entry, 2, class_entry_DOM_IteratorAggregate, class_entry_DOM_Countable);
+
+ zval property_length_default_value;
+ ZVAL_UNDEF(&property_length_default_value);
+ zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1);
+ zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(property_length_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_DTDNamedNodeMap(zend_class_entry *class_entry_DOM_IteratorAggregate, zend_class_entry *class_entry_DOM_Countable)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "DTDNamedNodeMap", class_DOM_DTDNamedNodeMap_methods);
+ class_entry = zend_register_internal_class_ex(&ce, NULL);
+ zend_class_implements(class_entry, 2, class_entry_DOM_IteratorAggregate, class_entry_DOM_Countable);
+
+ zval property_length_default_value;
+ ZVAL_UNDEF(&property_length_default_value);
+ zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1);
+ zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(property_length_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_HTMLCollection(zend_class_entry *class_entry_DOM_IteratorAggregate, zend_class_entry *class_entry_DOM_Countable)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "HTMLCollection", class_DOM_HTMLCollection_methods);
+ class_entry = zend_register_internal_class_ex(&ce, NULL);
+ zend_class_implements(class_entry, 2, class_entry_DOM_IteratorAggregate, class_entry_DOM_Countable);
+
+ zval property_length_default_value;
+ ZVAL_UNDEF(&property_length_default_value);
+ zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1);
+ zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(property_length_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_Element(zend_class_entry *class_entry_DOM_Node, zend_class_entry *class_entry_DOM_ParentNode, zend_class_entry *class_entry_DOM_ChildNode)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "Element", class_DOM_Element_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Node);
+ zend_class_implements(class_entry, 2, class_entry_DOM_ParentNode, class_entry_DOM_ChildNode);
+
+ zval property_namespaceURI_default_value;
+ ZVAL_UNDEF(&property_namespaceURI_default_value);
+ zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1);
+ zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_namespaceURI_name);
+
+ zval property_prefix_default_value;
+ ZVAL_UNDEF(&property_prefix_default_value);
+ zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1);
+ zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_prefix_name);
+
+ zval property_localName_default_value;
+ ZVAL_UNDEF(&property_localName_default_value);
+ zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1);
+ zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_localName_name);
+
+ zval property_tagName_default_value;
+ ZVAL_UNDEF(&property_tagName_default_value);
+ zend_string *property_tagName_name = zend_string_init("tagName", sizeof("tagName") - 1, 1);
+ zend_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_tagName_name);
+
+ zval property_id_default_value;
+ ZVAL_UNDEF(&property_id_default_value);
+ zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1);
+ zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_id_name);
+
+ zval property_className_default_value;
+ ZVAL_UNDEF(&property_className_default_value);
+ zend_string *property_className_name = zend_string_init("className", sizeof("className") - 1, 1);
+ zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_className_name);
+
+ zval property_attributes_default_value;
+ ZVAL_UNDEF(&property_attributes_default_value);
+ zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1);
+ zend_string *property_attributes_class_DOM_NamedNodeMap = zend_string_init("DOM\\\116amedNodeMap", sizeof("DOM\\\116amedNodeMap")-1, 1);
+ zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_DOM_NamedNodeMap, 0, 0));
+ zend_string_release(property_attributes_name);
+
+ zval property_firstElementChild_default_value;
+ ZVAL_UNDEF(&property_firstElementChild_default_value);
+ zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1);
+ zend_string *property_firstElementChild_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_firstElementChild_name);
+
+ zval property_lastElementChild_default_value;
+ ZVAL_UNDEF(&property_lastElementChild_default_value);
+ zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1);
+ zend_string *property_lastElementChild_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_lastElementChild_name);
+
+ zval property_childElementCount_default_value;
+ ZVAL_UNDEF(&property_childElementCount_default_value);
+ zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1);
+ zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(property_childElementCount_name);
+
+ zval property_previousElementSibling_default_value;
+ ZVAL_UNDEF(&property_previousElementSibling_default_value);
+ zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, 1);
+ zend_string *property_previousElementSibling_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_previousElementSibling_name);
+
+ zval property_nextElementSibling_default_value;
+ ZVAL_UNDEF(&property_nextElementSibling_default_value);
+ zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, 1);
+ zend_string *property_nextElementSibling_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_nextElementSibling_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_Attr(zend_class_entry *class_entry_DOM_Node)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "Attr", class_DOM_Attr_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Node);
+
+ zval property_namespaceURI_default_value;
+ ZVAL_UNDEF(&property_namespaceURI_default_value);
+ zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1);
+ zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_namespaceURI_name);
+
+ zval property_prefix_default_value;
+ ZVAL_UNDEF(&property_prefix_default_value);
+ zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1);
+ zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_prefix_name);
+
+ zval property_localName_default_value;
+ ZVAL_UNDEF(&property_localName_default_value);
+ zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1);
+ zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_localName_name);
+
+ zval property_name_default_value;
+ ZVAL_UNDEF(&property_name_default_value);
+ zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1);
+ zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_name_name);
+
+ zval property_value_default_value;
+ ZVAL_UNDEF(&property_value_default_value);
+ zend_string *property_value_name = zend_string_init("value", sizeof("value") - 1, 1);
+ zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_value_name);
+
+ zval property_ownerElement_default_value;
+ ZVAL_UNDEF(&property_ownerElement_default_value);
+ zend_string *property_ownerElement_name = zend_string_init("ownerElement", sizeof("ownerElement") - 1, 1);
+ zend_string *property_ownerElement_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_ownerElement_name);
+
+ zval property_specified_default_value;
+ ZVAL_TRUE(&property_specified_default_value);
+ zend_string *property_specified_name = zend_string_init("specified", sizeof("specified") - 1, 1);
+ zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+ zend_string_release(property_specified_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_CharacterData(zend_class_entry *class_entry_DOM_Node, zend_class_entry *class_entry_DOM_ChildNode)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "CharacterData", class_DOM_CharacterData_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Node);
+ zend_class_implements(class_entry, 1, class_entry_DOM_ChildNode);
+
+ zval property_previousElementSibling_default_value;
+ ZVAL_UNDEF(&property_previousElementSibling_default_value);
+ zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, 1);
+ zend_string *property_previousElementSibling_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_previousElementSibling_name);
+
+ zval property_nextElementSibling_default_value;
+ ZVAL_UNDEF(&property_nextElementSibling_default_value);
+ zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, 1);
+ zend_string *property_nextElementSibling_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_nextElementSibling_name);
+
+ zval property_data_default_value;
+ ZVAL_UNDEF(&property_data_default_value);
+ zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, 1);
+ zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_data_name);
+
+ zval property_length_default_value;
+ ZVAL_UNDEF(&property_length_default_value);
+ zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1);
+ zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(property_length_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_Text(zend_class_entry *class_entry_DOM_CharacterData)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "Text", class_DOM_Text_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_CharacterData);
+
+ zval property_wholeText_default_value;
+ ZVAL_UNDEF(&property_wholeText_default_value);
+ zend_string *property_wholeText_name = zend_string_init("wholeText", sizeof("wholeText") - 1, 1);
+ zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_wholeText_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_CDATASection(zend_class_entry *class_entry_DOM_Text)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "CDATASection", class_DOM_CDATASection_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Text);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_ProcessingInstruction(zend_class_entry *class_entry_DOM_CharacterData)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "ProcessingInstruction", class_DOM_ProcessingInstruction_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_CharacterData);
+
+ zval property_target_default_value;
+ ZVAL_UNDEF(&property_target_default_value);
+ zend_string *property_target_name = zend_string_init("target", sizeof("target") - 1, 1);
+ zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_target_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_Comment(zend_class_entry *class_entry_DOM_CharacterData)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "Comment", class_DOM_Comment_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_CharacterData);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_DocumentType(zend_class_entry *class_entry_DOM_Node, zend_class_entry *class_entry_DOM_ChildNode)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "DocumentType", class_DOM_DocumentType_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Node);
+ zend_class_implements(class_entry, 1, class_entry_DOM_ChildNode);
+
+ zval property_name_default_value;
+ ZVAL_UNDEF(&property_name_default_value);
+ zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1);
+ zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_name_name);
+
+ zval property_entities_default_value;
+ ZVAL_UNDEF(&property_entities_default_value);
+ zend_string *property_entities_name = zend_string_init("entities", sizeof("entities") - 1, 1);
+ zend_string *property_entities_class_DOM_DTDNamedNodeMap = zend_string_init("DOM\\DTDNamedNodeMap", sizeof("DOM\\DTDNamedNodeMap")-1, 1);
+ zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_DOM_DTDNamedNodeMap, 0, 0));
+ zend_string_release(property_entities_name);
+
+ zval property_notations_default_value;
+ ZVAL_UNDEF(&property_notations_default_value);
+ zend_string *property_notations_name = zend_string_init("notations", sizeof("notations") - 1, 1);
+ zend_string *property_notations_class_DOM_DTDNamedNodeMap = zend_string_init("DOM\\DTDNamedNodeMap", sizeof("DOM\\DTDNamedNodeMap")-1, 1);
+ zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_DOM_DTDNamedNodeMap, 0, 0));
+ zend_string_release(property_notations_name);
+
+ zval property_publicId_default_value;
+ ZVAL_UNDEF(&property_publicId_default_value);
+ zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1);
+ zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_publicId_name);
+
+ zval property_systemId_default_value;
+ ZVAL_UNDEF(&property_systemId_default_value);
+ zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1);
+ zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_systemId_name);
+
+ zval property_internalSubset_default_value;
+ ZVAL_UNDEF(&property_internalSubset_default_value);
+ zend_string *property_internalSubset_name = zend_string_init("internalSubset", sizeof("internalSubset") - 1, 1);
+ zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_internalSubset_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_DocumentFragment(zend_class_entry *class_entry_DOM_Node, zend_class_entry *class_entry_DOM_ParentNode)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "DocumentFragment", class_DOM_DocumentFragment_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Node);
+ zend_class_implements(class_entry, 1, class_entry_DOM_ParentNode);
+
+ zval property_firstElementChild_default_value;
+ ZVAL_UNDEF(&property_firstElementChild_default_value);
+ zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1);
+ zend_string *property_firstElementChild_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_firstElementChild_name);
+
+ zval property_lastElementChild_default_value;
+ ZVAL_UNDEF(&property_lastElementChild_default_value);
+ zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1);
+ zend_string *property_lastElementChild_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_lastElementChild_name);
+
+ zval property_childElementCount_default_value;
+ ZVAL_UNDEF(&property_childElementCount_default_value);
+ zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1);
+ zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(property_childElementCount_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_Entity(zend_class_entry *class_entry_DOM_Node)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "Entity", class_DOM_Entity_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Node);
+
+ zval property_publicId_default_value;
+ ZVAL_UNDEF(&property_publicId_default_value);
+ zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1);
+ zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_publicId_name);
+
+ zval property_systemId_default_value;
+ ZVAL_UNDEF(&property_systemId_default_value);
+ zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1);
+ zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_systemId_name);
+
+ zval property_notationName_default_value;
+ ZVAL_UNDEF(&property_notationName_default_value);
+ zend_string *property_notationName_name = zend_string_init("notationName", sizeof("notationName") - 1, 1);
+ zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_string_release(property_notationName_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_EntityReference(zend_class_entry *class_entry_DOM_Node)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "EntityReference", class_DOM_EntityReference_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Node);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_Notation(zend_class_entry *class_entry_DOM_Node)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "Notation", class_DOM_Notation_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Node);
+
+ zval property_publicId_default_value;
+ ZVAL_UNDEF(&property_publicId_default_value);
+ zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1);
+ zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_publicId_name);
+
+ zval property_systemId_default_value;
+ ZVAL_UNDEF(&property_systemId_default_value);
+ zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1);
+ zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_systemId_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_Document(zend_class_entry *class_entry_DOM_Node, zend_class_entry *class_entry_DOM_ParentNode)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "Document", class_DOM_Document_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Node);
+ class_entry->ce_flags |= ZEND_ACC_ABSTRACT;
+ zend_class_implements(class_entry, 1, class_entry_DOM_ParentNode);
+
+ zval property_implementation_default_value;
+ ZVAL_UNDEF(&property_implementation_default_value);
+ zend_string *property_implementation_name = zend_string_init("implementation", sizeof("implementation") - 1, 1);
+ zend_string *property_implementation_class_DOM_Implementation = zend_string_init("DOM\\Implementation", sizeof("DOM\\Implementation")-1, 1);
+ zend_declare_typed_property(class_entry, property_implementation_name, &property_implementation_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_implementation_class_DOM_Implementation, 0, 0));
+ zend_string_release(property_implementation_name);
+
+ zval property_URL_default_value;
+ ZVAL_UNDEF(&property_URL_default_value);
+ zend_string *property_URL_name = zend_string_init("URL", sizeof("URL") - 1, 1);
+ zend_declare_typed_property(class_entry, property_URL_name, &property_URL_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_URL_name);
+
+ zval property_documentURI_default_value;
+ ZVAL_UNDEF(&property_documentURI_default_value);
+ zend_string *property_documentURI_name = zend_string_init("documentURI", sizeof("documentURI") - 1, 1);
+ zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_documentURI_name);
+
+ zval property_characterSet_default_value;
+ ZVAL_UNDEF(&property_characterSet_default_value);
+ zend_string *property_characterSet_name = zend_string_init("characterSet", sizeof("characterSet") - 1, 1);
+ zend_declare_typed_property(class_entry, property_characterSet_name, &property_characterSet_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_characterSet_name);
+
+ zval property_charset_default_value;
+ ZVAL_UNDEF(&property_charset_default_value);
+ zend_string *property_charset_name = zend_string_init("charset", sizeof("charset") - 1, 1);
+ zend_declare_typed_property(class_entry, property_charset_name, &property_charset_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_charset_name);
+
+ zval property_inputEncoding_default_value;
+ ZVAL_UNDEF(&property_inputEncoding_default_value);
+ zend_string *property_inputEncoding_name = zend_string_init("inputEncoding", sizeof("inputEncoding") - 1, 1);
+ zend_declare_typed_property(class_entry, property_inputEncoding_name, &property_inputEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_inputEncoding_name);
+
+ zval property_doctype_default_value;
+ ZVAL_UNDEF(&property_doctype_default_value);
+ zend_string *property_doctype_name = zend_string_init("doctype", sizeof("doctype") - 1, 1);
+ zend_string *property_doctype_class_DOM_DocumentType = zend_string_init("DOM\\DocumentType", sizeof("DOM\\DocumentType")-1, 1);
+ zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_DOM_DocumentType, 0, MAY_BE_NULL));
+ zend_string_release(property_doctype_name);
+
+ zval property_documentElement_default_value;
+ ZVAL_UNDEF(&property_documentElement_default_value);
+ zend_string *property_documentElement_name = zend_string_init("documentElement", sizeof("documentElement") - 1, 1);
+ zend_string *property_documentElement_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_documentElement_name);
+
+ zval property_firstElementChild_default_value;
+ ZVAL_UNDEF(&property_firstElementChild_default_value);
+ zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1);
+ zend_string *property_firstElementChild_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_firstElementChild_name);
+
+ zval property_lastElementChild_default_value;
+ ZVAL_UNDEF(&property_lastElementChild_default_value);
+ zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1);
+ zend_string *property_lastElementChild_class_DOM_Element = zend_string_init("DOM\\Element", sizeof("DOM\\Element")-1, 1);
+ zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOM_Element, 0, MAY_BE_NULL));
+ zend_string_release(property_lastElementChild_name);
+
+ zval property_childElementCount_default_value;
+ ZVAL_UNDEF(&property_childElementCount_default_value);
+ zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1);
+ zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+ zend_string_release(property_childElementCount_name);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_HTMLDocument(zend_class_entry *class_entry_DOM_Document)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "HTMLDocument", class_DOM_HTMLDocument_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Document);
+ class_entry->ce_flags |= ZEND_ACC_FINAL;
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_DOM_XMLDocument(zend_class_entry *class_entry_DOM_Document)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "XMLDocument", class_DOM_XMLDocument_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_DOM_Document);
+ class_entry->ce_flags |= ZEND_ACC_FINAL;
+
+ zval property_xmlEncoding_default_value;
+ ZVAL_UNDEF(&property_xmlEncoding_default_value);
+ zend_string *property_xmlEncoding_name = zend_string_init("xmlEncoding", sizeof("xmlEncoding") - 1, 1);
+ zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+ zend_string_release(property_xmlEncoding_name);
+
+ zval property_xmlStandalone_default_value;
+ ZVAL_UNDEF(&property_xmlStandalone_default_value);
+ zend_string *property_xmlStandalone_name = zend_string_init("xmlStandalone", sizeof("xmlStandalone") - 1, 1);
+ zend_declare_typed_property(class_entry, property_xmlStandalone_name, &property_xmlStandalone_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+ zend_string_release(property_xmlStandalone_name);
zval property_xmlVersion_default_value;
ZVAL_UNDEF(&property_xmlVersion_default_value);
zend_string *property_xmlVersion_name = zend_string_init("xmlVersion", sizeof("xmlVersion") - 1, 1);
- zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+ zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
zend_string_release(property_xmlVersion_name);
zval property_formatOutput_default_value;
@@ -2085,35 +3449,31 @@ static zend_class_entry *register_class_DOM_XMLDocument(zend_class_entry *class_
zend_declare_typed_property(class_entry, property_formatOutput_name, &property_formatOutput_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
zend_string_release(property_formatOutput_name);
- zval property_validateOnParse_default_value;
- ZVAL_UNDEF(&property_validateOnParse_default_value);
- zend_string *property_validateOnParse_name = zend_string_init("validateOnParse", sizeof("validateOnParse") - 1, 1);
- zend_declare_typed_property(class_entry, property_validateOnParse_name, &property_validateOnParse_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
- zend_string_release(property_validateOnParse_name);
+ return class_entry;
+}
- zval property_resolveExternals_default_value;
- ZVAL_UNDEF(&property_resolveExternals_default_value);
- zend_string *property_resolveExternals_name = zend_string_init("resolveExternals", sizeof("resolveExternals") - 1, 1);
- zend_declare_typed_property(class_entry, property_resolveExternals_name, &property_resolveExternals_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
- zend_string_release(property_resolveExternals_name);
+#if defined(LIBXML_XPATH_ENABLED)
+static zend_class_entry *register_class_DOM_XPath(void)
+{
+ zend_class_entry ce, *class_entry;
- zval property_preserveWhiteSpace_default_value;
- ZVAL_UNDEF(&property_preserveWhiteSpace_default_value);
- zend_string *property_preserveWhiteSpace_name = zend_string_init("preserveWhiteSpace", sizeof("preserveWhiteSpace") - 1, 1);
- zend_declare_typed_property(class_entry, property_preserveWhiteSpace_name, &property_preserveWhiteSpace_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
- zend_string_release(property_preserveWhiteSpace_name);
+ INIT_NS_CLASS_ENTRY(ce, "DOM", "XPath", class_DOM_XPath_methods);
+ class_entry = zend_register_internal_class_ex(&ce, NULL);
+ class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE;
- zval property_recover_default_value;
- ZVAL_UNDEF(&property_recover_default_value);
- zend_string *property_recover_name = zend_string_init("recover", sizeof("recover") - 1, 1);
- zend_declare_typed_property(class_entry, property_recover_name, &property_recover_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
- zend_string_release(property_recover_name);
+ zval property_document_default_value;
+ ZVAL_UNDEF(&property_document_default_value);
+ zend_string *property_document_name = zend_string_init("document", sizeof("document") - 1, 1);
+ zend_string *property_document_class_DOM_Document = zend_string_init("DOM\\Document", sizeof("DOM\\Document")-1, 1);
+ zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_DOM_Document, 0, 0));
+ zend_string_release(property_document_name);
- zval property_substituteEntities_default_value;
- ZVAL_UNDEF(&property_substituteEntities_default_value);
- zend_string *property_substituteEntities_name = zend_string_init("substituteEntities", sizeof("substituteEntities") - 1, 1);
- zend_declare_typed_property(class_entry, property_substituteEntities_name, &property_substituteEntities_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
- zend_string_release(property_substituteEntities_name);
+ zval property_registerNodeNamespaces_default_value;
+ ZVAL_UNDEF(&property_registerNodeNamespaces_default_value);
+ zend_string *property_registerNodeNamespaces_name = zend_string_init("registerNodeNamespaces", sizeof("registerNodeNamespaces") - 1, 1);
+ zend_declare_typed_property(class_entry, property_registerNodeNamespaces_name, &property_registerNodeNamespaces_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+ zend_string_release(property_registerNodeNamespaces_name);
return class_entry;
}
+#endif
diff --git a/ext/dom/serialize_common.h b/ext/dom/serialize_common.h
new file mode 100644
index 0000000000000..35203592da9ce
--- /dev/null
+++ b/ext/dom/serialize_common.h
@@ -0,0 +1,28 @@
+/*
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | https://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Niels Dossche |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef SERIALIZE_COMMON_H
+#define SERIALIZE_COMMON_H
+
+#include
+#include
+
+static zend_always_inline bool dom_local_name_compare_ex(const xmlNode *node, const char *tag, size_t tag_length, size_t name_length)
+{
+ return name_length == tag_length && zend_binary_strcmp((const char *) node->name, name_length, tag, tag_length) == 0;
+}
+
+#endif
diff --git a/ext/dom/tests/DOM4_ChildNode_wrong_document.phpt b/ext/dom/tests/DOM4_ChildNode_wrong_document.phpt
index aa06d90bb26fb..cf51c3581a34d 100644
--- a/ext/dom/tests/DOM4_ChildNode_wrong_document.phpt
+++ b/ext/dom/tests/DOM4_ChildNode_wrong_document.phpt
@@ -6,34 +6,27 @@ dom
loadXML('');
+function test($method) {
+ $dom1 = new DOMDocument;
+ $dom1->loadXML('');
-$dom2 = new DOMDocument;
-$dom2->loadXML('');
+ $dom2 = new DOMDocument;
+ $dom2->loadXML('');
-$element = $dom1->documentElement;
+ $element = $dom1->documentElement;
-try {
- $element->after($dom2->documentElement->firstChild);
- echo "FAIL";
-} catch (DOMException $e) {
- echo $e->getMessage() . "\n";
+ try {
+ $element->$method($dom2->documentElement->firstChild);
+ echo "FAIL";
+ } catch (DOMException $e) {
+ echo $e->getMessage() . "\n";
+ }
}
-try {
- $element->before($dom2->documentElement->firstChild);
- echo "FAIL";
-} catch (DOMException $e) {
- echo $e->getMessage() . "\n";
-}
+test("after");
+test("before");
+test("replaceWith");
-try {
- $element->replaceWith($dom2->documentElement->firstChild);
- echo "FAIL";
-} catch (DOMException $e) {
- echo $e->getMessage();
-}
?>
--EXPECT--
Wrong Document Error
diff --git a/ext/dom/tests/DOM4_ParentNode_append_wrong_document.phpt b/ext/dom/tests/DOM4_ParentNode_append_wrong_document.phpt
index f9db709f0eb41..9df1603cab0c0 100644
--- a/ext/dom/tests/DOM4_ParentNode_append_wrong_document.phpt
+++ b/ext/dom/tests/DOM4_ParentNode_append_wrong_document.phpt
@@ -6,27 +6,25 @@ dom
loadXML('');
+function test($method) {
+ $dom1 = new DOMDocument;
+ $dom1->loadXML('');
-$dom2 = new DOMDocument;
-$dom2->loadXML('');
+ $dom2 = new DOMDocument;
+ $dom2->loadXML('');
-$element = $dom1->documentElement;
+ $element = $dom1->documentElement;
-try {
- $element->append($dom2->documentElement->firstChild);
- echo "FAIL";
-} catch (DOMException $e) {
- echo $e->getMessage() . "\n";
+ try {
+ $element->$method($dom2->documentElement->firstChild);
+ echo "FAIL";
+ } catch (DOMException $e) {
+ echo $e->getMessage() . "\n";
+ }
}
-try {
- $element->prepend($dom2->documentElement->firstChild);
- echo "FAIL";
-} catch (DOMException $e) {
- echo $e->getMessage();
-}
+test("append");
+test("prepend");
?>
--EXPECT--
Wrong Document Error
diff --git a/ext/dom/tests/DOMDocument_adoptNode.phpt b/ext/dom/tests/DOMDocument_adoptNode.phpt
index 81fe4c564971a..2382cabd5136f 100644
--- a/ext/dom/tests/DOMDocument_adoptNode.phpt
+++ b/ext/dom/tests/DOMDocument_adoptNode.phpt
@@ -141,7 +141,7 @@ string(27) "
Not Supported Error
-- Adopt a document (strict error off) --
-Warning: DOM\Document::adoptNode(): Not Supported Error in %s on line %d
+Warning: DOMDocument::adoptNode(): Not Supported Error in %s on line %d
-- Adopt an attribute --
bool(true)
bool(true)
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt
index 3baa24c50c65f..fd476749fe20e 100644
--- a/ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt
+++ b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt
@@ -35,5 +35,5 @@ var_dump($result);
?>
--EXPECTF--
-Warning: DOM\Document::relaxNGValidateSource(): Did not expect element pear there in %s on line %d
+Warning: DOMDocument::relaxNGValidateSource(): Did not expect element pear there in %s on line %d
bool(false)
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt
index 76aa3a04939d7..da00943c7caf2 100644
--- a/ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt
+++ b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt
@@ -31,7 +31,7 @@ var_dump($result);
?>
--EXPECTF--
-Warning: DOM\Document::relaxNGValidateSource(): xmlRelaxNGParseElement: element has no content in %s on line %d
+Warning: DOMDocument::relaxNGValidateSource(): xmlRelaxNGParseElement: element has no content in %s on line %d
-Warning: DOM\Document::relaxNGValidateSource(): Invalid RelaxNG in %s on line %d
+Warning: DOMDocument::relaxNGValidateSource(): Invalid RelaxNG in %s on line %d
bool(false)
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt b/ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt
index aff2680b3daee..aa38ca5c1ed26 100644
--- a/ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt
+++ b/ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt
@@ -20,5 +20,5 @@ $result = $doc->relaxNGValidate($rng);
var_dump($result);
?>
--EXPECTF--
-Warning: DOM\Document::relaxNGValidate(): Did not expect element pear there in %s on line %d
+Warning: DOMDocument::relaxNGValidate(): Did not expect element pear there in %s on line %d
bool(false)
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt b/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt
index 5dde5e8ced926..1ad46e014a0a7 100644
--- a/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt
+++ b/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt
@@ -20,9 +20,9 @@ $result = $doc->relaxNGValidate($rng);
var_dump($result);
?>
--EXPECTF--
-Warning: DOM\Document::relaxNGValidate(): I/O warning : failed to load external entity "%s/foo.rng" in %s on line %d
+Warning: DOMDocument::relaxNGValidate(): I/O warning : failed to load external entity "%s/foo.rng" in %s on line %d
-Warning: DOM\Document::relaxNGValidate(): xmlRelaxNGParse: could not load %s/foo.rng in %s on line %d
+Warning: DOMDocument::relaxNGValidate(): xmlRelaxNGParse: could not load %s/foo.rng in %s on line %d
-Warning: DOM\Document::relaxNGValidate(): Invalid RelaxNG in %s on line %d
+Warning: DOMDocument::relaxNGValidate(): Invalid RelaxNG in %s on line %d
bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt
index f71d192a616ed..c21403605647e 100644
--- a/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt
@@ -17,13 +17,13 @@ var_dump($result);
?>
--EXPECTF--
-Warning: DOM\Document::schemaValidateSource(): Entity: line 1: parser error : Start tag expected, '<' not found in %s on line %d
+Warning: DOMDocument::schemaValidateSource(): Entity: line 1: parser error : Start tag expected, '<' not found in %s on line %d
-Warning: DOM\Document::schemaValidateSource(): string that is not a schema in %s on line %d
+Warning: DOMDocument::schemaValidateSource(): string that is not a schema in %s on line %d
-Warning: DOM\Document::schemaValidateSource(): ^ in %s on line %d
+Warning: DOMDocument::schemaValidateSource(): ^ in %s on line %d
-Warning: DOM\Document::schemaValidateSource(): Failed to parse the XML resource 'in_memory_buffer'. in %s on line %d
+Warning: DOMDocument::schemaValidateSource(): Failed to parse the XML resource 'in_memory_buffer'. in %s on line %d
-Warning: DOM\Document::schemaValidateSource(): Invalid Schema in %s on line %d
+Warning: DOMDocument::schemaValidateSource(): Invalid Schema in %s on line %d
bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt
index b9fea75807a47..00b1a9b1dd115 100644
--- a/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt
@@ -19,5 +19,5 @@ var_dump($result);
?>
--EXPECTF--
-Warning: DOM\Document::schemaValidateSource(): Element 'books': No matching global declaration available for the validation root. in %s on line %d
+Warning: DOMDocument::schemaValidateSource(): Element 'books': No matching global declaration available for the validation root. in %s on line %d
bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt
index bdeb74ff6c2c9..ec295a55e3391 100644
--- a/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt
@@ -20,4 +20,4 @@ try {
?>
--EXPECT--
-DOM\Document::schemaValidateSource(): Argument #1 ($source) must not be empty
+DOMDocument::schemaValidateSource(): Argument #1 ($source) must not be empty
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt
index 2923943a3c8f5..b31c14651f293 100644
--- a/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt
@@ -17,13 +17,13 @@ var_dump($result);
?>
--EXPECTF--
-Warning: DOM\Document::schemaValidate(): %s/book-not-a-schema.xsd:1: parser error : Start tag expected, '<' not found in %s on line %d
+Warning: DOMDocument::schemaValidate(): %sbook-not-a-schema.xsd:1: parser error : Start tag expected, '<' not found in %s on line %d
-Warning: DOM\Document::schemaValidate(): Let's see what happens upon parsing a file that doesn't contain a schema. in %s on line %d
+Warning: DOMDocument::schemaValidate(): Let's see what happens upon parsing a file that doesn't contain a schema. in %s on line %d
-Warning: DOM\Document::schemaValidate(): ^ in %s on line %d
+Warning: DOMDocument::schemaValidate(): ^ in %s on line %d
-Warning: DOM\Document::schemaValidate(): Failed to parse the XML resource '%s/book-not-a-schema.xsd'. in %s on line %d
+Warning: DOMDocument::schemaValidate(): Failed to parse the XML resource '%sbook-not-a-schema.xsd'. in %s on line %d
-Warning: DOM\Document::schemaValidate(): Invalid Schema in %s on line %d
+Warning: DOMDocument::schemaValidate(): Invalid Schema in %s on line %d
bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt
index ddc491c70ca3f..47282575ef2b7 100644
--- a/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt
@@ -17,5 +17,5 @@ var_dump($result);
?>
--EXPECTF--
-Warning: DOM\Document::schemaValidate(): Element 'books': No matching global declaration available for the validation root. in %s on line %d
+Warning: DOMDocument::schemaValidate(): Element 'books': No matching global declaration available for the validation root. in %s on line %d
bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt
index d48ed3d1963b2..274463e62e139 100644
--- a/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt
@@ -20,4 +20,4 @@ try {
?>
--EXPECT--
-DOM\Document::schemaValidate(): Argument #1 ($filename) must not be empty
+DOMDocument::schemaValidate(): Argument #1 ($filename) must not be empty
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt
index 2c179ed35bd45..3b277fd6cdb97 100644
--- a/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt
@@ -17,9 +17,9 @@ var_dump($result);
?>
--EXPECTF--
-Warning: DOM\Document::schemaValidate(): I/O warning : failed to load external entity "%s/non-existent-file" in %s on line %d
+Warning: DOMDocument::schemaValidate(): I/O warning : failed to load external entity "%snon-existent-file" in %s on line %d
-Warning: DOM\Document::schemaValidate(): Failed to locate the main schema resource at '%s/non-existent-file'. in %s on line %d
+Warning: DOMDocument::schemaValidate(): Failed to locate the main schema resource at '%snon-existent-file'. in %s on line %d
-Warning: DOM\Document::schemaValidate(): Invalid Schema in %s on line %d
+Warning: DOMDocument::schemaValidate(): Invalid Schema in %s on line %d
bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error6.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error6.phpt
index 3668921264cf2..c5d99b20a3fec 100644
--- a/ext/dom/tests/DOMDocument_schemaValidate_error6.phpt
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error6.phpt
@@ -19,7 +19,7 @@ var_dump($doc->schemaValidate(str_repeat(" ", PHP_MAXPATHLEN + 1)));
?>
--EXPECTF--
-DOM\Document::schemaValidate(): Argument #1 ($filename) must not contain any null bytes
+DOMDocument::schemaValidate(): Argument #1 ($filename) must not contain any null bytes
-Warning: DOM\Document::schemaValidate(): Invalid Schema file source in %s on line %d
+Warning: DOMDocument::schemaValidate(): Invalid Schema file source in %s on line %d
bool(false)
diff --git a/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt b/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt
index 3def63da9b5a9..b44d6395c309a 100644
--- a/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt
+++ b/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt
@@ -56,4 +56,4 @@ See if strictErrorChecking is off
bool(false)
Should raise PHP error because strictErrorChecking is off
-Warning: DOM\Document::createAttribute(): Invalid Character Error in %s on line %d
+Warning: DOMDocument::createAttribute(): Invalid Character Error in %s on line %d
diff --git a/ext/dom/tests/DOMElement_append_hierarchy_test.phpt b/ext/dom/tests/DOMElement_append_hierarchy_test.phpt
index 2d70b10fe9f70..63583c05bf532 100644
--- a/ext/dom/tests/DOMElement_append_hierarchy_test.phpt
+++ b/ext/dom/tests/DOMElement_append_hierarchy_test.phpt
@@ -22,6 +22,13 @@ $b_world = $b_hello->nextSibling;
$b_hello->append($b_world->firstChild);
var_dump($dom->saveHTML());
+echo "-- Append hello with world's child and text --\n";
+$dom = clone $dom_original;
+$b_hello = $dom->firstChild->firstChild;
+$b_world = $b_hello->nextSibling;
+$b_hello->append($b_world->firstChild, "foo");
+var_dump($dom->saveHTML());
+
echo "-- Append world's child with hello --\n";
$dom = clone $dom_original;
$b_hello = $dom->firstChild->firstChild;
@@ -39,6 +46,16 @@ try {
}
var_dump($dom->saveHTML());
+echo "-- Append hello with itself and text --\n";
+$dom = clone $dom_original;
+$b_hello = $dom->firstChild->firstChild;
+try {
+ $b_hello->append($b_hello, "foo");
+} catch (\DOMException $e) {
+ echo $e->getMessage(), "\n";
+}
+var_dump($dom->saveHTML());
+
echo "-- Append world's i tag with the parent --\n";
$dom = clone $dom_original;
$b_hello = $dom->firstChild->firstChild;
@@ -70,6 +87,9 @@ string(39) "helloworld
-- Append hello with world's child --
string(39) "helloworld
"
+-- Append hello with world's child and text --
+string(42) "helloworldfoo
+"
-- Append world's child with hello --
string(39) "worldhello
"
@@ -77,6 +97,10 @@ string(39) "worldhello
Hierarchy Request Error
string(39) "helloworld
"
+-- Append hello with itself and text --
+Hierarchy Request Error
+string(27) "world
+"
-- Append world's i tag with the parent --
Hierarchy Request Error
string(39) "helloworld
diff --git a/ext/dom/tests/DOMElement_get_or_has_attribute_ns_xmlns.phpt b/ext/dom/tests/DOMElement_get_or_has_attribute_ns_xmlns.phpt
new file mode 100644
index 0000000000000..400f2f9908b13
--- /dev/null
+++ b/ext/dom/tests/DOMElement_get_or_has_attribute_ns_xmlns.phpt
@@ -0,0 +1,21 @@
+--TEST--
+DOMElement::{get,has}AttributeNS() with xmlns
+--EXTENSIONS--
+dom
+--FILE--
+loadXML('');
+
+var_dump($dom->documentElement->getAttributeNS('http://www.w3.org/2000/xmlns/', 'a'));
+var_dump($dom->documentElement->getAttributeNS('http://www.w3.org/2000/xmlns/', 'b'));
+var_dump($dom->documentElement->hasAttributeNS('http://www.w3.org/2000/xmlns/', 'a'));
+var_dump($dom->documentElement->hasAttributeNS('http://www.w3.org/2000/xmlns/', 'b'));
+
+?>
+--EXPECT--
+string(5) "urn:a"
+string(0) ""
+bool(true)
+bool(false)
diff --git a/ext/dom/tests/DOMElement_insertAdjacentText.phpt b/ext/dom/tests/DOMElement_insertAdjacentText.phpt
index 58af0812d6fe5..937f35f47acb9 100644
--- a/ext/dom/tests/DOMElement_insertAdjacentText.phpt
+++ b/ext/dom/tests/DOMElement_insertAdjacentText.phpt
@@ -78,4 +78,4 @@ Syntax Error
--- Normal cases starting from empty element ---
A
BA
-string(2) "BA"
+string(1) "A"
diff --git a/ext/dom/tests/DOMElement_prepend_hierarchy_test.phpt b/ext/dom/tests/DOMElement_prepend_hierarchy_test.phpt
index 4d9cf24a61828..b1a9910e0ee1c 100644
--- a/ext/dom/tests/DOMElement_prepend_hierarchy_test.phpt
+++ b/ext/dom/tests/DOMElement_prepend_hierarchy_test.phpt
@@ -22,6 +22,13 @@ $b_world = $b_hello->nextSibling;
$b_hello->prepend($b_world->firstChild);
var_dump($dom->saveHTML());
+echo "-- Prepend hello with world's child and text --\n";
+$dom = clone $dom_original;
+$b_hello = $dom->firstChild->firstChild;
+$b_world = $b_hello->nextSibling;
+$b_hello->prepend($b_world->firstChild, "foo");
+var_dump($dom->saveHTML());
+
echo "-- Prepend world's child with hello --\n";
$dom = clone $dom_original;
$b_hello = $dom->firstChild->firstChild;
@@ -29,6 +36,13 @@ $b_world = $b_hello->nextSibling;
$b_world->firstChild->prepend($b_hello);
var_dump($dom->saveHTML());
+echo "-- Prepend world's child with hello and text --\n";
+$dom = clone $dom_original;
+$b_hello = $dom->firstChild->firstChild;
+$b_world = $b_hello->nextSibling;
+$b_world->firstChild->prepend($b_hello, "foo");
+var_dump($dom->saveHTML());
+
echo "-- Prepend hello with itself --\n";
$dom = clone $dom_original;
$b_hello = $dom->firstChild->firstChild;
@@ -39,6 +53,16 @@ try {
}
var_dump($dom->saveHTML());
+echo "-- Prepend hello with itself and text --\n";
+$dom = clone $dom_original;
+$b_hello = $dom->firstChild->firstChild;
+try {
+ $b_hello->prepend($b_hello, "foo");
+} catch (\DOMException $e) {
+ echo $e->getMessage(), "\n";
+}
+var_dump($dom->saveHTML());
+
echo "-- Prepend world's i tag with the parent --\n";
$dom = clone $dom_original;
$b_hello = $dom->firstChild->firstChild;
@@ -70,13 +94,23 @@ string(39) "worldhello
-- Prepend hello with world's child --
string(39) "worldhello
"
+-- Prepend hello with world's child and text --
+string(42) "worldfoohello
+"
-- Prepend world's child with hello --
string(39) "helloworld
"
+-- Prepend world's child with hello and text --
+string(42) "hellofooworld
+"
-- Prepend hello with itself --
Hierarchy Request Error
string(39) "helloworld
"
+-- Prepend hello with itself and text --
+Hierarchy Request Error
+string(27) "world
+"
-- Prepend world's i tag with the parent --
Hierarchy Request Error
string(39) "helloworld
diff --git a/ext/dom/tests/DOMNode_normalize_advanced.phpt b/ext/dom/tests/DOMNode_normalize_advanced.phpt
new file mode 100644
index 0000000000000..99cd922363529
--- /dev/null
+++ b/ext/dom/tests/DOMNode_normalize_advanced.phpt
@@ -0,0 +1,32 @@
+--TEST--
+DOMNode::normalize() advanced
+--EXTENSIONS--
+dom
+--FILE--
+appendChild($dom->createElement("root"));
+$child1 = $root->appendChild($dom->createElement("child1"));
+$child2 = $root->appendChild($dom->createElement("child2"));
+
+$child1->appendChild($dom->createTextNode("abc"));
+$child1->appendChild($dom->createTextNode(""));
+$child1->appendChild($dom->createTextNode("def"));
+
+$child2->appendChild($dom->createTextNode(""));
+$child2->setAttribute("foo", "bar");
+
+echo $dom->saveXML();
+
+$root->normalize();
+
+var_dump($child1->childNodes[0]->textContent);
+var_dump($child2->childNodes[0]);
+
+?>
+--EXPECT--
+
+abcdef
+string(6) "abcdef"
+NULL
diff --git a/ext/dom/tests/dom_import_simplexml.phpt b/ext/dom/tests/dom_import_simplexml.phpt
index c5dc5a3e4c0af..f38ea1227ca3b 100644
--- a/ext/dom/tests/dom_import_simplexml.phpt
+++ b/ext/dom/tests/dom_import_simplexml.phpt
@@ -12,6 +12,13 @@ if(!$s) {
}
$dom = dom_import_simplexml($s);
print $dom->ownerDocument->saveXML();
+
+// This should fail because it has been imported already above in legacy DOM
+try {
+ DOM\import_simplexml($s);
+} catch (TypeError $e) {
+ echo $e->getMessage(), "\n";
+}
?>
--EXPECT--
@@ -25,3 +32,4 @@ print $dom->ownerDocument->saveXML();
John Steinbeck
+DOM\import_simplexml(): Argument #1 ($node) must not be already imported as a DOMNode
diff --git a/ext/dom/tests/domobject_debug_handler.phpt b/ext/dom/tests/domobject_debug_handler.phpt
index c97655a63a14d..a1cbabffbb239 100644
--- a/ext/dom/tests/domobject_debug_handler.phpt
+++ b/ext/dom/tests/domobject_debug_handler.phpt
@@ -20,12 +20,14 @@ object(DOMDocument)#1 (41) {
["dynamicProperty"]=>
object(stdClass)#2 (0) {
}
+ ["doctype"]=>
+ NULL
["implementation"]=>
string(22) "(object value omitted)"
+ ["documentElement"]=>
+ string(22) "(object value omitted)"
["actualEncoding"]=>
NULL
- ["config"]=>
- NULL
["encoding"]=>
NULL
["xmlEncoding"]=>
@@ -38,6 +40,12 @@ object(DOMDocument)#1 (41) {
string(3) "1.0"
["xmlVersion"]=>
string(3) "1.0"
+ ["strictErrorChecking"]=>
+ bool(true)
+ ["documentURI"]=>
+ string(%d) "%s"
+ ["config"]=>
+ NULL
["formatOutput"]=>
bool(false)
["validateOnParse"]=>
@@ -50,14 +58,6 @@ object(DOMDocument)#1 (41) {
bool(false)
["substituteEntities"]=>
bool(false)
- ["doctype"]=>
- NULL
- ["documentElement"]=>
- string(22) "(object value omitted)"
- ["strictErrorChecking"]=>
- bool(true)
- ["documentURI"]=>
- string(%d) "%s"
["firstElementChild"]=>
string(22) "(object value omitted)"
["lastElementChild"]=>
diff --git a/ext/dom/tests/gh11830/document_variation.phpt b/ext/dom/tests/gh11830/document_variation.phpt
index 89eed3dff22c0..1f291b946878f 100644
--- a/ext/dom/tests/gh11830/document_variation.phpt
+++ b/ext/dom/tests/gh11830/document_variation.phpt
@@ -4,68 +4,80 @@ GH-11830 (ParentNode methods should perform their checks upfront) - document var
dom
--FILE--
loadXML(<<
-
-XML);
-
-$otherElement = $otherDoc->documentElement;
+function test($method) {
+ $otherDoc = new DOMDocument;
+ $otherDoc->loadXML(<<
+
+ XML);
-$doc = new DOMDocument;
-$doc->loadXML(<<
-
-
-
-
-XML);
+ $otherElement = $otherDoc->documentElement;
-$testElement = $doc->documentElement->firstElementChild->nextElementSibling->firstElementChild;
+ $doc = new DOMDocument;
+ $doc->loadXML(<<
+
+
+
+
+ XML);
-try {
- $doc->documentElement->firstElementChild->prepend($testElement, $otherElement);
-} catch (\DOMException $e) {
- echo $e->getMessage(), "\n";
-}
+ $testElement = $doc->documentElement->firstElementChild->nextElementSibling->firstElementChild;
-try {
- $doc->documentElement->firstElementChild->append($testElement, $otherElement);
-} catch (\DOMException $e) {
- echo $e->getMessage(), "\n";
-}
+ try {
+ $doc->documentElement->firstElementChild->$method($testElement, $otherElement);
+ } catch (\DOMException $e) {
+ echo $e->getMessage(), "\n";
+ }
-try {
- $doc->documentElement->firstElementChild->before($testElement, $otherElement);
-} catch (\DOMException $e) {
- echo $e->getMessage(), "\n";
+ echo $otherDoc->saveXML();
+ echo $doc->saveXML();
}
-try {
- $doc->documentElement->firstElementChild->after($testElement, $otherElement);
-} catch (\DOMException $e) {
- echo $e->getMessage(), "\n";
-}
-
-try {
- $doc->documentElement->firstElementChild->replaceWith($testElement, $otherElement);
-} catch (\DOMException $e) {
- echo $e->getMessage(), "\n";
-}
-
-echo $otherDoc->saveXML();
-echo $doc->saveXML();
+test("prepend");
+test("append");
+test("before");
+test("after");
+test("replaceWith");
?>
--EXPECT--
Wrong Document Error
+
+
+
+
+
+
+
Wrong Document Error
+
+
+
+
+
+
+
Wrong Document Error
+
+
+
+
+
+
+
Wrong Document Error
+
+
+
+
+
+
+
Wrong Document Error
-
+
diff --git a/ext/dom/tests/gh11830/hierarchy_variation.phpt b/ext/dom/tests/gh11830/hierarchy_variation.phpt
index bd6534ee71b12..4430684618749 100644
--- a/ext/dom/tests/gh11830/hierarchy_variation.phpt
+++ b/ext/dom/tests/gh11830/hierarchy_variation.phpt
@@ -4,59 +4,43 @@ GH-11830 (ParentNode methods should perform their checks upfront) - hierarchy va
dom
--FILE--
loadXML(<<
-
-
-
-
-XML);
-
-$container = $doc->documentElement;
-$alone = $container->firstElementChild;
-$testElement = $alone->nextElementSibling->firstElementChild;
-
-try {
- $testElement->prepend($alone, $container);
-} catch (\DOMException $e) {
- echo $e->getMessage(), "\n";
-}
-
-try {
- $testElement->append($alone, $container);
-} catch (\DOMException $e) {
- echo $e->getMessage(), "\n";
-}
+function test($method) {
+ $doc = new DOMDocument;
+ $doc->loadXML(<<
+
+
+
+
+ XML);
-try {
- $testElement->before($alone, $container);
-} catch (\DOMException $e) {
- echo $e->getMessage(), "\n";
-}
+ $container = $doc->documentElement;
+ $alone = $container->firstElementChild;
+ $testElement = $alone->nextElementSibling->firstElementChild;
-try {
- $testElement->after($alone, $container);
-} catch (\DOMException $e) {
- echo $e->getMessage(), "\n";
-}
+ try {
+ $testElement->$method($alone, $container);
+ } catch (\DOMException $e) {
+ echo $e->getMessage(), "\n";
+ }
-try {
- $testElement->replaceWith($alone, $container);
-} catch (\DOMException $e) {
- echo $e->getMessage(), "\n";
+ echo $doc->saveXML();
}
-echo $doc->saveXML();
+test("prepend");
+test("append");
+test("before");
+test("after");
+test("replaceWith");
?>
--EXPECT--
Hierarchy Request Error
+
Hierarchy Request Error
+
Hierarchy Request Error
+
Hierarchy Request Error
+
Hierarchy Request Error
-
-
-
-
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_GB18030.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_GB18030.phpt
index c0139661e3077..05a348df0ce28 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_GB18030.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_GB18030.phpt
@@ -6,7 +6,7 @@ dom
encoding);
+var_dump($dom->charset);
$dom->documentElement->firstChild->nextElementSibling->textContent = "é";
$output = $dom->saveHTML();
echo $output, "\n";
@@ -14,7 +14,7 @@ $dom->saveHTMLFile(__DIR__ . "/gb18030_output.tmp");
var_dump(file_get_contents(__DIR__ . "/gb18030_output.tmp") === $output);
echo "--- After changing encoding to UTF-8 ---\n";
-$dom->encoding = "UTF-8";
+$dom->charset = "UTF-8";
echo $dom->saveHTML(), "\n";
?>
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_Shift_JIS.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_Shift_JIS.phpt
index c021d7022f275..84e835c1d8d89 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_Shift_JIS.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_Shift_JIS.phpt
@@ -6,7 +6,7 @@ dom
encoding);
+var_dump($dom->charset);
$dom->documentElement->firstChild->nextElementSibling->textContent .= "é";
$output = $dom->saveHTML();
echo $output, "\n";
@@ -14,7 +14,7 @@ $dom->saveHTMLFile(__DIR__ . "/shift_jis.tmp");
var_dump(file_get_contents(__DIR__ . "/shift_jis.tmp") === $output);
echo "--- After changing encoding to UTF-8 ---\n";
-$dom->encoding = "UTF-8";
+$dom->charset = "UTF-8";
echo $dom->saveHTML(), "\n";
?>
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF16BE_BOM.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF16BE_BOM.phpt
index 9e10859f1914c..315384345a4b9 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF16BE_BOM.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF16BE_BOM.phpt
@@ -6,7 +6,7 @@ dom
encoding);
+var_dump($dom->characterSet);
$dom->documentElement->firstChild->nextElementSibling->textContent = "é";
$output = $dom->saveHTML();
echo $output, "\n";
@@ -14,7 +14,7 @@ $dom->saveHTMLFile(__DIR__ . "/utf16be_bom_output.tmp");
var_dump(file_get_contents(__DIR__ . "/utf16be_bom_output.tmp") === $output);
echo "--- After changing encoding to UTF-8 ---\n";
-$dom->encoding = "UTF-8";
+$dom->characterSet = "UTF-8";
echo $dom->saveHTML(), "\n";
?>
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF16LE_BOM.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF16LE_BOM.phpt
index 7006163e3de07..8b0183a9f055e 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF16LE_BOM.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF16LE_BOM.phpt
@@ -6,7 +6,7 @@ dom
encoding);
+var_dump($dom->inputEncoding);
$dom->documentElement->firstChild->nextElementSibling->textContent = "é";
$output = $dom->saveHTML();
echo $output, "\n";
@@ -14,7 +14,7 @@ $dom->saveHTMLFile(__DIR__ . "/utf16le_bom_output.tmp");
var_dump(file_get_contents(__DIR__ . "/utf16le_bom_output.tmp") === $output);
echo "--- After changing encoding to UTF-8 ---\n";
-$dom->encoding = "UTF-8";
+$dom->inputEncoding = "UTF-8";
echo $dom->saveHTML(), "\n";
?>
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF8_BOM.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF8_BOM.phpt
index 65326ad6b0370..c23ca5a9a47ec 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF8_BOM.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_UTF8_BOM.phpt
@@ -6,7 +6,7 @@ dom
encoding);
+var_dump($dom->charset);
$dom->documentElement->firstChild->nextElementSibling->textContent = "é";
$output = $dom->saveHTML();
echo $output, "\n";
@@ -14,7 +14,7 @@ $dom->saveHTMLFile(__DIR__ . "/utf8_bom_output.tmp");
var_dump(file_get_contents(__DIR__ . "/utf8_bom_output.tmp") === $output);
echo "--- After changing encoding to UTF-8 ---\n";
-$dom->encoding = "UTF-8";
+$dom->charset = "UTF-8";
echo $dom->saveHTML(), "\n";
?>
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_Windows1251.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_Windows1251.phpt
index 5b85639996d9c..98d313a554028 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_Windows1251.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_Windows1251.phpt
@@ -6,7 +6,7 @@ dom
encoding);
+var_dump($dom->charset);
$dom->documentElement->firstChild->nextElementSibling->textContent .= "é"; // Note: won't show up in Windows 1251 because it doesn't exist there
$output = $dom->saveHTML();
echo $output, "\n";
@@ -14,7 +14,7 @@ $dom->saveHTMLFile(__DIR__ . "/windows1251_output.tmp");
var_dump(file_get_contents(__DIR__ . "/windows1251_output.tmp") === $output);
echo "--- After changing encoding to UTF-8 ---\n";
-$dom->encoding = "UTF-8";
+$dom->charset = "UTF-8";
echo $dom->saveHTML(), "\n";
?>
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_http_header.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_http_header.phpt
index 130447228f4d8..8a4271c3a0a88 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_http_header.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_http_header.phpt
@@ -63,7 +63,7 @@ foreach ($tests as $name => $headers) {
['pid' => $pid, 'uri' => $uri] = http_server($responses);
for ($i = 0; $i < count($responses); $i++) {
$result = DOM\HTMLDocument::createFromFile($uri, LIBXML_NOERROR);
- echo $result->textContent;
+ echo $result->getElementsByTagName("p")[0]->textContent, "\n";
}
http_server_kill($pid);
}
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_override_encoding.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_override_encoding.phpt
index 4f6f9943d2b62..ef1aca0f9f6f8 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_override_encoding.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_override_encoding.phpt
@@ -14,12 +14,12 @@ try {
// The override encoding matches with the document encoding attribute
$dom = DOM\HTMLDocument::createFromFile(__DIR__ . '/gb18030_without_charset.html', overrideEncoding: 'GB18030');
var_dump($dom->documentElement->lastChild->textContent);
-var_dump($dom->encoding);
+var_dump($dom->charset);
// The override encoding mismatches with the document encoding attribute
$dom = DOM\HTMLDocument::createFromFile(__DIR__ . '/fallback_encoding.html', overrideEncoding: 'Windows-1252');
var_dump($dom->documentElement->lastChild->textContent);
-var_dump($dom->encoding);
+var_dump($dom->charset);
?>
--EXPECT--
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromString_override_encoding.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromString_override_encoding.phpt
index b276be453eec0..d68e0131df9d8 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromString_override_encoding.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromString_override_encoding.phpt
@@ -14,12 +14,12 @@ try {
// The override encoding matches with the document encoding attribute
$dom = DOM\HTMLDocument::createFromString(file_get_contents(__DIR__ . '/gb18030_without_charset.html'), overrideEncoding: 'GB18030');
var_dump($dom->documentElement->lastChild->textContent);
-var_dump($dom->encoding);
+var_dump($dom->charset);
// The override encoding mismatches with the document encoding attribute
$dom = DOM\HTMLDocument::createFromString(file_get_contents(__DIR__ . '/fallback_encoding.html'), overrideEncoding: 'Windows-1252');
var_dump($dom->documentElement->lastChild->textContent);
-var_dump($dom->encoding);
+var_dump($dom->charset);
?>
--EXPECT--
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_01.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_01.phpt
index 3988767e58064..13fbdc684b336 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_01.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_01.phpt
@@ -8,9 +8,11 @@ dom
// UTF-8 -> UTF-8
// Create a UTF-8 string where a UTF-8 byte sequence falls over the boundary of the 4096 byte buffer
$dom = DOM\HTMLDocument::createEmpty();
-$dom->append(str_repeat("A", 4096 - 2) . "\xf0\x90\x8d\x88AA");
+$element = $dom->createElement("container");
+$dom->append($element);
+$element->append(str_repeat("A", 4096 - 2 - strlen("")) . "\xf0\x90\x8d\x88AA");
var_dump($dom->saveHTML());
?>
--EXPECT--
-string(4100) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA𐍈AA"
+string(4112) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA𐍈AA"
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_02.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_02.phpt
index 5ac5694a89dc3..c8e9736533ad0 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_02.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_02.phpt
@@ -7,9 +7,11 @@ dom
// UTF-8 -> GB18030
$dom = DOM\HTMLDocument::createEmpty("GB18030");
+$element = $dom->createElement("container");
+$dom->append($element);
// Create a UTF-8 string where a UTF-8 byte sequence falls over the boundary of the 4096 byte buffer
// *and* the sequence also falls over the boundary for the result
-$dom->append(str_repeat("A", 4096 - 2) . "\xf0\x90\x8d\x88AA");
+$element->append(str_repeat("A", 4096 - 2 - strlen("")) . "\xf0\x90\x8d\x88AA");
var_dump($output = $dom->saveHTML());
// GB18030 encoding of the above UTF-8 symbol
@@ -20,7 +22,7 @@ var_dump($output[4097] == "\x30");
?>
--EXPECT--
-string(4100) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�0�0AA"
+string(4112) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�0�0AA"
bool(true)
bool(true)
bool(true)
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_03.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_03.phpt
index d68257ca80fee..5e66a0b0411cc 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_03.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_03.phpt
@@ -7,11 +7,13 @@ dom
// UTF-8 -> GB18030
$dom = DOM\HTMLDocument::createEmpty("GB18030");
+$element = $dom->createElement("container");
+$dom->append($element);
// Create a UTF-8 string where an invalid UTF-8 byte sequence falls over the boundary of the 4096 byte buffer
// Note: the strange ?1?7 sequence is the GB18030 encoding for the unicode replacement character
-$dom->append(str_repeat("A", 4096 - 2) . "\xff\xff\xff");
+$element->append(str_repeat("A", 4096 - 2 - strlen("")) . "\xff\xff\xff");
var_dump($dom->saveHTML());
?>
--EXPECT--
-string(4106) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�1�7�1�7�1�7"
+string(4118) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�1�7�1�7�1�7"
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_04.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_04.phpt
index ccff90a83320f..1bde3303269b5 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_04.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_04.phpt
@@ -7,10 +7,12 @@ dom
// UTF-8 -> UTF-8
$dom = DOM\HTMLDocument::createEmpty();
+$element = $dom->createElement("container");
+$dom->append($element);
// Create a UTF-8 string where an invalid UTF-8 byte sequence falls over the boundary of the 4096 byte buffer
-$dom->append(str_repeat("A", 4096 - 2) . "\xff\xff\xff");
+$element->append(str_repeat("A", 4096 - 2 - strlen("")) . "\xff\xff\xff");
var_dump($dom->saveHTML());
?>
--EXPECT--
-string(4103) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA���"
+string(4115) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA���"
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_05.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_05.phpt
index e7da1e439b70a..0c44159c8b6ce 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_05.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_05.phpt
@@ -11,8 +11,8 @@ $padding_required_until_4094 = 4094 - strlen($header);
$trailer = "\x90\x30\xd5\x30";
$dom = DOM\HTMLDocument::createFromString($header . str_repeat("A", $padding_required_until_4094) . $trailer);
// GB18030 byte sequence crossing the 4096 boundary
-var_dump($dom->encoding);
-$dom->encoding = "UTF-8";
+var_dump($dom->charset);
+$dom->charset = "UTF-8";
var_dump($dom->saveHTML());
?>
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_06.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_06.phpt
index 0b472b466fbed..ea5962a1ae6a6 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_06.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_06.phpt
@@ -7,10 +7,12 @@ dom
// UTF-8 -> UTF-8
$dom = DOM\HTMLDocument::createEmpty();
+$element = $dom->createElement("container");
+$dom->append($element);
// Create a UTF-8 string where a *broken* UTF-8 byte sequence falls over the boundary of the 4096 byte buffer
-$dom->append(str_repeat("A", 4096 - 1) . "\xf0\x90");
+$element->append(str_repeat("A", 4096 - 1 - strlen("")) . "\xf0\x90");
var_dump($dom->saveHTML());
?>
--EXPECT--
-string(4101) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA��"
+string(4110) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�"
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_07.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_07.phpt
index 6cf2d1d8f5e4b..4f60cccaba155 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_07.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_edge_case_07.phpt
@@ -11,8 +11,8 @@ $padding_required_until_4095 = 4095 - strlen($header);
$trailer = "\x90\x30";
$dom = DOM\HTMLDocument::createFromString($header . str_repeat("A", $padding_required_until_4095) . $trailer);
// GB18030 *broken* byte sequence crossing the 4096 boundary
-var_dump($dom->encoding);
-$dom->encoding = "UTF-8";
+var_dump($dom->charset);
+$dom->charset = "UTF-8";
var_dump($dom->saveHTML());
?>
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_field_test.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_field_test.phpt
index bab3532565b82..c5c5aec382d58 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_field_test.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_encoding_field_test.phpt
@@ -6,23 +6,23 @@ dom
encoding);
-$dom->encoding = "CSeuckr";
-var_dump($dom->encoding);
+var_dump($dom->charset);
+$dom->inputEncoding = "CSeuckr";
+var_dump($dom->characterSet);
try {
- $dom->encoding = "nope";
+ $dom->charset = "nope";
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
-var_dump($dom->encoding);
-$dom->encoding = "Windows-1251";
-var_dump($dom->encoding);
+var_dump($dom->charset);
+$dom->inputEncoding = "Windows-1251";
+var_dump($dom->characterSet);
try {
- $dom->encoding = NULL;
+ $dom->charset = "";
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
-var_dump($dom->encoding);
+var_dump($dom->inputEncoding);
echo $dom->saveHTML();
try {
diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt
index 9ffd02dc5d7d8..f431b6cd31902 100644
--- a/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt
+++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt
@@ -6,7 +6,7 @@ dom
encoding);
+var_dump($dom->inputEncoding);
echo $dom->saveHTML();
?>
diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_adopt_DOMDocument.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_adopt_DOMDocument.phpt
deleted file mode 100644
index cff51dac28f6b..0000000000000
--- a/ext/dom/tests/modern/html/interactions/HTMLDocument_adopt_DOMDocument.phpt
+++ /dev/null
@@ -1,30 +0,0 @@
---TEST--
-DOM\HTMLDocument adopts a DOMDocument
---EXTENSIONS--
-dom
---FILE--
-loadHTML(<<
-
-
-
-
-
-
-HTML);
-
-$dom2 = DOM\HTMLDocument::createEmpty();
-$dom2->appendChild($dom2->adoptNode($dom->documentElement));
-echo $dom2->saveHTML();
-
-?>
---EXPECT--
-
-
-
-
-
-
diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_clone.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_clone.phpt
index 1a04dd7beae29..e5420d06b9727 100644
--- a/ext/dom/tests/modern/html/interactions/HTMLDocument_clone.phpt
+++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_clone.phpt
@@ -18,6 +18,6 @@ var_dump(get_class($element->ownerDocument));
?>
--EXPECTF--
Warning: DOM\HTMLDocument::createFromString(): tree error unexpected-token-in-initial-mode in Entity, line: 1, column: 2 in %s on line %d
-string(4) "html"
+string(4) "HTML"
string(3) "foo"
string(16) "DOM\HTMLDocument"
diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_documentURI.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_documentURI.phpt
index 9430aac9da30a..a24ebb7bf3416 100644
--- a/ext/dom/tests/modern/html/interactions/HTMLDocument_documentURI.phpt
+++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_documentURI.phpt
@@ -42,6 +42,6 @@ var_dump($dom->documentURI);
?>
--EXPECTF--
-string(%d) "file:/%stest%20foo.html"
+string(%d) "file://%stest%20foo.html"
string(12) "php://memory"
string(16) "dummy://foo/ bar"
diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_getElementsByTagName.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_getElementsByTagName.phpt
index 3af5c2d01eb72..19759c95677ed 100644
--- a/ext/dom/tests/modern/html/interactions/HTMLDocument_getElementsByTagName.phpt
+++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_getElementsByTagName.phpt
@@ -67,19 +67,19 @@ var_dump($dom->getElementsByTagNameNS("http://www.w3.org/1998/Math/MathML", "cir
?>
--EXPECT--
--- getElementsByTagName ---
-string(1) "p"
+string(1) "P"
string(4) "math"
string(6) "mtable"
string(3) "svg"
string(6) "circle"
--- getElementsByTagNameNS (*) ---
-string(1) "p"
+string(1) "P"
string(4) "math"
string(6) "mtable"
string(3) "svg"
string(6) "circle"
--- getElementsByTagNameNS (xhtml) ---
-string(1) "p"
+string(1) "P"
NULL
NULL
NULL
diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_01.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_01.phpt
index e7f4fb630f542..6ae7589270b73 100644
--- a/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_01.phpt
+++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_01.phpt
@@ -10,8 +10,8 @@ $dom->registerNodeClass("DOM\\HTMLDocument", "DOMDocument");
?>
--EXPECTF--
-Fatal error: Uncaught Error: DOM\Document::registerNodeClass(): Argument #2 ($extendedClass) must be a class name derived from DOM\HTMLDocument or null, DOMDocument given in %s:%d
+Fatal error: Uncaught TypeError: DOMDocument::registerNodeClass(): Argument #1 ($baseClass) must be a class name derived from DOMNode, DOM\HTMLDocument given in %s:%d
Stack trace:
-#0 %s(%d): DOM\Document->registerNodeClass('DOM\\HTMLDocumen...', 'DOMDocument')
+#0 %s(%d): DOMDocument->registerNodeClass('DOM\\HTMLDocumen...', 'DOMDocument')
#1 {main}
thrown in %s on line %d
diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_02.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_02.phpt
index f9b8493cda34a..3eb1f0cae8af1 100644
--- a/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_02.phpt
+++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_02.phpt
@@ -10,7 +10,7 @@ class Custom extends DOM\Document {
}
}
-$dom = new DOMDocument();
+$dom = DOM\HTMLDocument::createEmpty();
try {
$dom->registerNodeClass("DOM\\Document", "Custom");
} catch (ValueError $e) {
@@ -28,9 +28,9 @@ $element->ownerDocument->foo();
?>
--EXPECTF--
DOM\Document::registerNodeClass(): Argument #1 ($baseClass) must not be an abstract class
-string(11) "DOMDocument"
+string(16) "DOM\HTMLDocument"
-Fatal error: Uncaught Error: Call to undefined method DOMDocument::foo() in %s:%d
+Fatal error: Uncaught Error: Call to undefined method DOM\HTMLDocument::foo() in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_03.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_03.phpt
new file mode 100644
index 0000000000000..859212a086708
--- /dev/null
+++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_registerNodeClass_03.phpt
@@ -0,0 +1,25 @@
+--TEST--
+DOM\HTMLDocument::registerNodeClass 03
+--EXTENSIONS--
+dom
+--FILE--
+test);
+ return strrev($this->tagName);
+ }
+}
+
+$dom = DOM\HTMLDocument::createFromString("foo
", LIBXML_NOERROR);
+$dom->registerNodeClass("DOM\\Element", "Custom");
+
+var_dump($dom->getElementsByTagName('div')[0]->reverseTagName());
+
+?>
+--EXPECT--
+int(1)
+string(3) "VID"
diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt
index 4a6e816313229..08e70cfa43019 100644
--- a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt
+++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt
@@ -5,45 +5,57 @@ dom
--FILE--
foo
", LIBXML_NOERROR);
-$dom->strictErrorChecking = false;
+$dom->registerNodeClass("DOM\\Element", "MyElement");
// Destroy reference to the DOM
$child = $dom->documentElement;
unset($dom);
// Regain reference using the ownerDocument property
-// Should be a DOM\HTML5Document
+// Should be a DOM\HTMLDocument
$dom = $child->ownerDocument;
var_dump($dom);
// Test if property is preserved (any random doc_props property will do)
-var_dump($dom->strictErrorChecking);
+var_dump(get_class($dom->getElementsByTagName("p")->item(0)));
?>
--EXPECT--
-object(DOM\HTMLDocument)#1 (26) {
- ["encoding"]=>
+object(DOM\HTMLDocument)#1 (25) {
+ ["implementation"]=>
+ string(22) "(object value omitted)"
+ ["URL"]=>
+ string(11) "about:blank"
+ ["documentURI"]=>
+ string(11) "about:blank"
+ ["characterSet"]=>
+ string(5) "UTF-8"
+ ["charset"]=>
+ string(5) "UTF-8"
+ ["inputEncoding"]=>
string(5) "UTF-8"
["doctype"]=>
NULL
["documentElement"]=>
string(22) "(object value omitted)"
- ["strictErrorChecking"]=>
- bool(false)
- ["documentURI"]=>
- NULL
["firstElementChild"]=>
string(22) "(object value omitted)"
["lastElementChild"]=>
string(22) "(object value omitted)"
["childElementCount"]=>
int(1)
+ ["nodeType"]=>
+ int(13)
["nodeName"]=>
string(9) "#document"
- ["nodeValue"]=>
+ ["baseURI"]=>
+ string(11) "about:blank"
+ ["isConnected"]=>
+ bool(true)
+ ["ownerDocument"]=>
NULL
- ["nodeType"]=>
- int(13)
["parentNode"]=>
NULL
["parentElement"]=>
@@ -58,21 +70,9 @@ object(DOM\HTMLDocument)#1 (26) {
NULL
["nextSibling"]=>
NULL
- ["attributes"]=>
- NULL
- ["isConnected"]=>
- bool(true)
- ["ownerDocument"]=>
- NULL
- ["namespaceURI"]=>
- NULL
- ["prefix"]=>
- string(0) ""
- ["localName"]=>
- NULL
- ["baseURI"]=>
+ ["nodeValue"]=>
NULL
["textContent"]=>
- string(3) "foo"
+ NULL
}
-bool(false)
+string(9) "MyElement"
diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt
index 9c4d016fef81c..379a3da4b2fa1 100644
--- a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt
+++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt
@@ -5,9 +5,11 @@ dom
--FILE--
foo", LIBXML_NOERROR);
-$dom->strictErrorChecking = false;
-$child = $dom->appendChild($dom->createElement('html'));
+$dom->registerNodeClass("DOM\\Element", "MyElement");
+$child = $dom->documentElement->appendChild($dom->createElement('html'));
// Destroy reference to the DOM
unset($dom);
@@ -17,33 +19,43 @@ unset($dom);
$dom = $child->ownerDocument;
var_dump($dom);
// Test if property is preserved (any random doc_props property will do)
-var_dump($dom->strictErrorChecking);
+var_dump(get_class($dom->getElementsByTagName("p")->item(0)));
?>
--EXPECT--
-object(DOM\HTMLDocument)#1 (26) {
- ["encoding"]=>
+object(DOM\HTMLDocument)#1 (25) {
+ ["implementation"]=>
+ string(22) "(object value omitted)"
+ ["URL"]=>
+ string(11) "about:blank"
+ ["documentURI"]=>
+ string(11) "about:blank"
+ ["characterSet"]=>
+ string(5) "UTF-8"
+ ["charset"]=>
+ string(5) "UTF-8"
+ ["inputEncoding"]=>
string(5) "UTF-8"
["doctype"]=>
NULL
["documentElement"]=>
string(22) "(object value omitted)"
- ["strictErrorChecking"]=>
- bool(false)
- ["documentURI"]=>
- NULL
["firstElementChild"]=>
string(22) "(object value omitted)"
["lastElementChild"]=>
string(22) "(object value omitted)"
["childElementCount"]=>
- int(2)
+ int(1)
+ ["nodeType"]=>
+ int(13)
["nodeName"]=>
string(9) "#document"
- ["nodeValue"]=>
+ ["baseURI"]=>
+ string(11) "about:blank"
+ ["isConnected"]=>
+ bool(true)
+ ["ownerDocument"]=>
NULL
- ["nodeType"]=>
- int(13)
["parentNode"]=>
NULL
["parentElement"]=>
@@ -58,21 +70,9 @@ object(DOM\HTMLDocument)#1 (26) {
NULL
["nextSibling"]=>
NULL
- ["attributes"]=>
- NULL
- ["isConnected"]=>
- bool(true)
- ["ownerDocument"]=>
- NULL
- ["namespaceURI"]=>
- NULL
- ["prefix"]=>
- string(0) ""
- ["localName"]=>
- NULL
- ["baseURI"]=>
+ ["nodeValue"]=>
NULL
["textContent"]=>
- string(3) "foo"
+ NULL
}
-bool(false)
+string(9) "MyElement"
diff --git a/ext/dom/tests/modern/html/interactions/noscript.phpt b/ext/dom/tests/modern/html/interactions/noscript.phpt
index 839845e330f22..d93dae79c650f 100644
--- a/ext/dom/tests/modern/html/interactions/noscript.phpt
+++ b/ext/dom/tests/modern/html/interactions/noscript.phpt
@@ -9,27 +9,29 @@ echo "--- Parsing ---\n";
$dom = DOM\HTMLDocument::createFromString("", DOM\HTML_NO_DEFAULT_NS);
var_dump($dom->documentElement->textContent);
+var_dump($dom->documentElement->namespaceURI);
echo $dom->saveHTML(), "\n";
-echo $dom->saveXML();
+echo $dom->saveXML(), "\n";
echo "--- Modifying the text content: tag ---\n";
-$xpath = new DOMXPath($dom);
+$xpath = new DOM\XPath($dom);
$noscript = $xpath->query("//noscript")[0];
$noscript->textContent = "bye
";
echo $dom->saveHTML(), "\n";
-echo $dom->saveXML();
+echo $dom->saveXML(), "\n";
echo "--- Modifying the text content: trick ---\n";
$noscript->textContent = "";
echo $dom->saveHTML(), "\n";
-echo $dom->saveXML();
+echo $dom->saveXML(), "\n";
?>
--EXPECT--
--- Parsing ---
string(2) "hi"
+NULL
diff --git a/ext/dom/tests/modern/html/parser/HTMLDocument_createFromFile_createFromString_BOM_buffer_edge.phpt b/ext/dom/tests/modern/html/parser/HTMLDocument_createFromFile_createFromString_BOM_buffer_edge.phpt
index 8d7d70e6d9f8c..b666167d2b4de 100644
--- a/ext/dom/tests/modern/html/parser/HTMLDocument_createFromFile_createFromString_BOM_buffer_edge.phpt
+++ b/ext/dom/tests/modern/html/parser/HTMLDocument_createFromFile_createFromString_BOM_buffer_edge.phpt
@@ -10,11 +10,13 @@ $trailer = "