Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ PHP NEWS
passing an array of CURLFile or CURLStringFile objects to
CURLOPT_POSTFIELDS. (Sjoerd Langkemper)

- DOM:
. Fixed use-after-free when a php:function() callback of DOMXPath or
Dom\XPath modifies nodes that are still being evaluated; such
modifications now throw a DOMException or Error. (Ilia Alshanetsky)

- FPM:
. Use recommended TYPE, HELP order for OpenMetrics metadata.
(Marcel Hernandez)
Expand Down Expand Up @@ -204,6 +209,13 @@ PHP NEWS
. Fixed xml_get_current_byte_index() returning negative values for byte
indexes beyond 2 GiB on Windows x64. (Marc Bennewitz)

- XSL:
. Fixed a use-after-free when a transformation was started on a processor
that is already transforming. (Ilia Alshanetsky)
. Fixed use-after-free when a php:function() callback or an entity loader
modifies the document being transformed; such modifications now throw a
DOMException or Error. (Ilia Alshanetsky)

- Zlib:
. Fixed inflate_init() dropping the preset dictionary for raw streams with
a non-default window. (Ilia Alshanetsky)
Expand Down
26 changes: 26 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ PHP 8.7 UPGRADE NOTES
. Nested arrays in CURLOPT_POSTFIELDS now throw a TypeError, instead of being
silently converted to the string "Array".

- DOM:
. While DOMXPath or Dom\XPath evaluates an expression with PHP functions
registered, the nodes it can reach are read-only: the tree of the
evaluated document, the tree of every node a php:function() callback
returned, and the detached subtree of the context node or of a node
passed to a callback. Modifying such a node throws a DOMException with
code DOM_NO_MODIFICATION_ALLOWED_ERR (a warning when strictErrorChecking
is disabled), and modifying it through SimpleXML throws an Error.
Creating and modifying new nodes and setting document properties such as
formatOutput or documentURI are still allowed.

- PDO:
. PDOStatement::bindColumn() now throws a ValueError when the column name is
not present in the result set. It previously reported the condition
Expand Down Expand Up @@ -64,6 +75,21 @@ PHP 8.7 UPGRADE NOTES
to 16 by default. Set the stream context option max_filter_count to change
this.

- XSL:
. XSLTProcessor::transformToDoc(), XSLTProcessor::transformToUri() and
XSLTProcessor::transformToXml() now throw an Error when called while the
same processor is already transforming, for example from a php:function()
callback or from a suspended Fiber. Use a separate XSLTProcessor instance
instead.
. While XSLTProcessor transforms a document, the tree of that document, the
tree of every node a php:function() callback returned, and the detached
subtree of the current node or of a node passed to a callback are
read-only. Modifying such a node, for example from a callback or an entity
loader, throws a DOMException with code DOM_NO_MODIFICATION_ALLOWED_ERR (a
warning when strictErrorChecking is disabled), and modifying it through
SimpleXML throws an Error. Set XSLTProcessor::$cloneDocument to true to
transform a copy and keep the original document modifiable.

========================================
2. New Features
========================================
Expand Down
4 changes: 4 additions & 0 deletions ext/dom/attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ PHP_METHOD(DOMAttr, __construct)
RETURN_THROWS();
}

if (dom_throw_if_node_read_only(Z_DOMOBJ_P(ZEND_THIS)->document, dom_object_get_node(Z_DOMOBJ_P(ZEND_THIS)))) {
return;
}

intern = Z_DOMOBJ_P(ZEND_THIS);

name_valid = xmlValidateName(BAD_CAST name, 0);
Expand Down
4 changes: 4 additions & 0 deletions ext/dom/cdatasection.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ PHP_METHOD(DOMCdataSection, __construct)
RETURN_THROWS();
}

if (dom_throw_if_node_read_only(Z_DOMOBJ_P(ZEND_THIS)->document, dom_object_get_node(Z_DOMOBJ_P(ZEND_THIS)))) {
return;
}

nodep = xmlNewCDataBlock(NULL, BAD_CAST value, value_len);

if (!nodep) {
Expand Down
15 changes: 15 additions & 0 deletions ext/dom/characterdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ static void dom_character_data_append_data(INTERNAL_FUNCTION_PARAMETERS)
}

DOM_GET_OBJ(nodep, ZEND_THIS, xmlNodePtr, intern);
if (dom_throw_if_node_read_only(intern->document, nodep)) {
return;
}
xmlTextConcat(nodep, BAD_CAST arg, arg_len);
}

Expand Down Expand Up @@ -202,6 +205,10 @@ static void dom_character_data_insert_data(INTERNAL_FUNCTION_PARAMETERS, bool re

DOM_GET_OBJ(node, id, xmlNodePtr, intern);

if (dom_throw_if_node_read_only(intern->document, node)) {
RETURN_FALSE;
}

const xmlChar *cur = php_dom_get_content_or_empty(node);

length = xmlUTF8Strlen(cur);
Expand Down Expand Up @@ -267,6 +274,10 @@ static void dom_character_data_delete_data(INTERNAL_FUNCTION_PARAMETERS, bool re

DOM_GET_OBJ(node, id, xmlNodePtr, intern);

if (dom_throw_if_node_read_only(intern->document, node)) {
RETURN_FALSE;
}

const xmlChar *cur = php_dom_get_content_or_empty(node);

length = xmlUTF8Strlen(cur);
Expand Down Expand Up @@ -337,6 +348,10 @@ static void dom_character_data_replace_data(INTERNAL_FUNCTION_PARAMETERS, bool r

DOM_GET_OBJ(node, id, xmlNodePtr, intern);

if (dom_throw_if_node_read_only(intern->document, node)) {
RETURN_FALSE;
}

const xmlChar *cur = php_dom_get_content_or_empty(node);

length = xmlUTF8Strlen(cur);
Expand Down
4 changes: 4 additions & 0 deletions ext/dom/comment.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ PHP_METHOD(DOMComment, __construct)
RETURN_THROWS();
}

if (dom_throw_if_node_read_only(Z_DOMOBJ_P(ZEND_THIS)->document, dom_object_get_node(Z_DOMOBJ_P(ZEND_THIS)))) {
return;
}

nodep = xmlNewComment(BAD_CAST value);

if (!nodep) {
Expand Down
16 changes: 16 additions & 0 deletions ext/dom/document.c
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,10 @@ static void dom_document_adopt_node(INTERNAL_FUNCTION_PARAMETERS, bool modern)
RETURN_FALSE;
}

if (dom_throw_if_node_read_only(dom_object_nodep->document, nodep)) {
RETURN_FALSE;
}

xmlDocPtr new_document;
dom_object *dom_object_new_document;
zval *new_document_zval = ZEND_THIS;
Expand Down Expand Up @@ -1254,6 +1258,10 @@ PHP_METHOD(DOMDocument, normalizeDocument)

DOM_GET_OBJ(docp, id, xmlDocPtr, intern);

if (dom_throw_if_node_read_only(intern->document, (xmlNodePtr) docp)) {
return;
}

php_dom_normalize_legacy((xmlNodePtr) docp);
}
/* }}} end dom_document_normalize_document */
Expand Down Expand Up @@ -1801,6 +1809,10 @@ PHP_METHOD(DOMDocument, xinclude)

DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);

if (dom_throw_if_node_read_only(intern->document, (xmlNodePtr) docp)) {
RETURN_FALSE;
}

int err = dom_perform_xinclude(docp, intern, flags);

if (err) {
Expand All @@ -1827,6 +1839,10 @@ PHP_METHOD(Dom_XMLDocument, xinclude)

DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);

if (dom_throw_if_node_read_only(intern->document, (xmlNodePtr) docp)) {
RETURN_THROWS();
}

int err = dom_perform_xinclude(docp, intern, flags);

if (err < 0) {
Expand Down
8 changes: 8 additions & 0 deletions ext/dom/documentfragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ PHP_METHOD(DOMDocumentFragment, __construct)

ZEND_PARSE_PARAMETERS_NONE();

if (dom_throw_if_node_read_only(Z_DOMOBJ_P(ZEND_THIS)->document, dom_object_get_node(Z_DOMOBJ_P(ZEND_THIS)))) {
return;
}

nodep = xmlNewDocFragment(NULL);

if (!nodep) {
Expand Down Expand Up @@ -74,6 +78,10 @@ PHP_METHOD(DOMDocumentFragment, appendXML) {
RETURN_FALSE;
}

if (dom_throw_if_node_read_only(intern->document, nodep)) {
RETURN_FALSE;
}

if (data) {
PHP_LIBXML_SANITIZE_GLOBALS(parse);
err = xmlParseBalancedChunkMemory(nodep->doc, NULL, NULL, 0, BAD_CAST data, &lst);
Expand Down
6 changes: 6 additions & 0 deletions ext/dom/domimplementation.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ PHP_METHOD(DOMImplementation, createDocument)
php_dom_throw_error(WRONG_DOCUMENT_ERR, true);
RETURN_THROWS();
}
if (dom_throw_if_node_read_only(doctobj->document, (xmlNodePtr) doctype)) {
RETURN_THROWS();
}
} else {
doctobj = NULL;
}
Expand Down Expand Up @@ -261,6 +264,9 @@ PHP_METHOD(Dom_Implementation, createDocument)

if (dtd != NULL) {
DOM_GET_OBJ(doctype, dtd, xmlDtdPtr, doctobj);
if (dom_throw_if_node_read_only(doctobj->document, (xmlNodePtr) doctype)) {
RETURN_THROWS();
}
}

xmlDocPtr document = NULL;
Expand Down
Loading
Loading