From bddcd6f104f7347fbf8d3324f870d73725f7d7e5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 26 May 2021 17:02:39 +0200 Subject: [PATCH 1/3] Use E_ERROR for some DOM out-of-memory error conditions --- ext/dom/document.c | 22 +++++++++++++--------- ext/dom/php_dom.stub.php | 6 +++--- ext/dom/php_dom_arginfo.h | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/ext/dom/document.c b/ext/dom/document.c index 85879790a75f3..07f28af5c3cc4 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -506,6 +506,10 @@ int dom_document_config_read(dom_object *obj, zval *retval) /* }}} */ +ZEND_NORETURN static void php_dom_fatal_libxml_error(void) { + zend_error_noreturn(E_ERROR, "Libxml error: Likely out of memory"); +} + /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547 Since: */ @@ -533,7 +537,7 @@ PHP_METHOD(DOMDocument, createElement) node = xmlNewDocNode(docp, NULL, (xmlChar *) name, (xmlChar *) value); if (!node) { - RETURN_FALSE; + php_dom_fatal_libxml_error(); } DOM_RET_OBJ(node, &ret, intern); @@ -558,9 +562,9 @@ PHP_METHOD(DOMDocument, createDocumentFragment) DOM_GET_OBJ(docp, id, xmlDocPtr, intern); - node = xmlNewDocFragment(docp); + node = xmlNewDocFragment(docp); if (!node) { - RETURN_FALSE; + php_dom_fatal_libxml_error(); } DOM_RET_OBJ(node, &ret, intern); @@ -589,7 +593,7 @@ PHP_METHOD(DOMDocument, createTextNode) node = xmlNewDocText(docp, (xmlChar *) value); if (!node) { - RETURN_FALSE; + php_dom_fatal_libxml_error(); } DOM_RET_OBJ(node, &ret, intern); @@ -618,7 +622,7 @@ PHP_METHOD(DOMDocument, createComment) node = xmlNewDocComment(docp, (xmlChar *) value); if (!node) { - RETURN_FALSE; + php_dom_fatal_libxml_error(); } DOM_RET_OBJ(node, &ret, intern); @@ -647,7 +651,7 @@ PHP_METHOD(DOMDocument, createCDATASection) node = xmlNewCDataBlock(docp, (xmlChar *) value, value_len); if (!node) { - RETURN_FALSE; + php_dom_fatal_libxml_error(); } DOM_RET_OBJ(node, &ret, intern); @@ -681,7 +685,7 @@ PHP_METHOD(DOMDocument, createProcessingInstruction) node = xmlNewPI((xmlChar *) name, (xmlChar *) value); if (!node) { - RETURN_FALSE; + php_dom_fatal_libxml_error(); } node->doc = docp; @@ -717,7 +721,7 @@ PHP_METHOD(DOMDocument, createAttribute) node = xmlNewDocProp(docp, (xmlChar *) name, NULL); if (!node) { - RETURN_FALSE; + php_dom_fatal_libxml_error(); } DOM_RET_OBJ((xmlNodePtr) node, &ret, intern); @@ -752,7 +756,7 @@ PHP_METHOD(DOMDocument, createEntityReference) node = xmlNewReference(docp, (xmlChar *) name); if (!node) { - RETURN_FALSE; + php_dom_fatal_libxml_error(); } DOM_RET_OBJ((xmlNodePtr) node, &ret, intern); diff --git a/ext/dom/php_dom.stub.php b/ext/dom/php_dom.stub.php index dec474bd85eb3..e1944b010abb6 100644 --- a/ext/dom/php_dom.stub.php +++ b/ext/dom/php_dom.stub.php @@ -467,10 +467,10 @@ public function createAttributeNS(?string $namespace, string $qualifiedName) {} /** @return DOMCdataSection|false */ public function createCDATASection(string $data) {} - /** @return DOMComment|false */ + /** @return DOMComment */ public function createComment(string $data) {} - /** @return DOMDocumentFragment|false */ + /** @return DOMDocumentFragment */ public function createDocumentFragment() {} /** @return DOMElement|false */ @@ -485,7 +485,7 @@ public function createEntityReference(string $name) {} /** @return DOMProcessingInstruction|false */ public function createProcessingInstruction(string $target, string $data = "") {} - /** @return DOMText|false */ + /** @return DOMText */ public function createTextNode(string $data) {} /** @return DOMElement|null */ diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h index 1b77719f4caaf..0966982f87966 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: f9bcfaa9c0ed58949c4ee58fbf1833359010be7d */ + * Stub hash: 6045721c540d168c7e2323b6c7b685c073d17971 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_dom_import_simplexml, 0, 1, DOMElement, 1) ZEND_ARG_TYPE_INFO(0, node, IS_OBJECT, 0) From 2b7ea23baa303ff6039c8c459e0c48f991240951 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 16 Jul 2021 15:31:26 +0200 Subject: [PATCH 2/3] Throw DomException instead --- ext/dom/document.c | 28 ++++++++++++++++------------ ext/dom/domexception.c | 3 +++ ext/dom/domexception.h | 4 +++- ext/dom/php_dom.c | 1 + 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/ext/dom/document.c b/ext/dom/document.c index 07f28af5c3cc4..9070e09966828 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -506,10 +506,6 @@ int dom_document_config_read(dom_object *obj, zval *retval) /* }}} */ -ZEND_NORETURN static void php_dom_fatal_libxml_error(void) { - zend_error_noreturn(E_ERROR, "Libxml error: Likely out of memory"); -} - /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547 Since: */ @@ -537,7 +533,8 @@ PHP_METHOD(DOMDocument, createElement) node = xmlNewDocNode(docp, NULL, (xmlChar *) name, (xmlChar *) value); if (!node) { - php_dom_fatal_libxml_error(); + php_dom_throw_error(LIBXML_ERR, /* strict */ true); + RETURN_THROWS(); } DOM_RET_OBJ(node, &ret, intern); @@ -564,7 +561,8 @@ PHP_METHOD(DOMDocument, createDocumentFragment) node = xmlNewDocFragment(docp); if (!node) { - php_dom_fatal_libxml_error(); + php_dom_throw_error(LIBXML_ERR, /* strict */ true); + RETURN_THROWS(); } DOM_RET_OBJ(node, &ret, intern); @@ -593,7 +591,8 @@ PHP_METHOD(DOMDocument, createTextNode) node = xmlNewDocText(docp, (xmlChar *) value); if (!node) { - php_dom_fatal_libxml_error(); + php_dom_throw_error(LIBXML_ERR, /* strict */ true); + RETURN_THROWS(); } DOM_RET_OBJ(node, &ret, intern); @@ -622,7 +621,8 @@ PHP_METHOD(DOMDocument, createComment) node = xmlNewDocComment(docp, (xmlChar *) value); if (!node) { - php_dom_fatal_libxml_error(); + php_dom_throw_error(LIBXML_ERR, /* strict */ true); + RETURN_THROWS(); } DOM_RET_OBJ(node, &ret, intern); @@ -651,7 +651,8 @@ PHP_METHOD(DOMDocument, createCDATASection) node = xmlNewCDataBlock(docp, (xmlChar *) value, value_len); if (!node) { - php_dom_fatal_libxml_error(); + php_dom_throw_error(LIBXML_ERR, /* strict */ true); + RETURN_THROWS(); } DOM_RET_OBJ(node, &ret, intern); @@ -685,7 +686,8 @@ PHP_METHOD(DOMDocument, createProcessingInstruction) node = xmlNewPI((xmlChar *) name, (xmlChar *) value); if (!node) { - php_dom_fatal_libxml_error(); + php_dom_throw_error(LIBXML_ERR, /* strict */ true); + RETURN_THROWS(); } node->doc = docp; @@ -721,7 +723,8 @@ PHP_METHOD(DOMDocument, createAttribute) node = xmlNewDocProp(docp, (xmlChar *) name, NULL); if (!node) { - php_dom_fatal_libxml_error(); + php_dom_throw_error(LIBXML_ERR, /* strict */ true); + RETURN_THROWS(); } DOM_RET_OBJ((xmlNodePtr) node, &ret, intern); @@ -756,7 +759,8 @@ PHP_METHOD(DOMDocument, createEntityReference) node = xmlNewReference(docp, (xmlChar *) name); if (!node) { - php_dom_fatal_libxml_error(); + php_dom_throw_error(LIBXML_ERR, /* strict */ true); + RETURN_THROWS(); } DOM_RET_OBJ((xmlNodePtr) node, &ret, intern); diff --git a/ext/dom/domexception.c b/ext/dom/domexception.c index 03b94b630f18e..451fb7117d651 100644 --- a/ext/dom/domexception.c +++ b/ext/dom/domexception.c @@ -97,6 +97,9 @@ void php_dom_throw_error(int error_code, int strict_error) case VALIDATION_ERR: error_message = "Validation Error"; break; + case LIBXML_ERR: + error_message = "Unknown LibXML error, likely out of memory"; + break; default: error_message = "Unhandled Error"; } diff --git a/ext/dom/domexception.h b/ext/dom/domexception.h index 799b4fd189a63..10cad51f42bff 100644 --- a/ext/dom/domexception.h +++ b/ext/dom/domexception.h @@ -43,7 +43,9 @@ typedef enum { /* Introduced in DOM Level 2: */ INVALID_ACCESS_ERR = 15, /* Introduced in DOM Level 3: */ - VALIDATION_ERR = 16 + VALIDATION_ERR = 16, + /* Unknown libxml error, likely out of memory. */ + LIBXML_ERR = 128, } dom_exception_code; #endif /* DOM_EXCEPTION_H */ diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index ccf74d23d0ed8..2fe15dc099466 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -839,6 +839,7 @@ PHP_MINIT_FUNCTION(dom) REGISTER_LONG_CONSTANT("DOM_NAMESPACE_ERR", NAMESPACE_ERR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("DOM_INVALID_ACCESS_ERR", INVALID_ACCESS_ERR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("DOM_VALIDATION_ERR", VALIDATION_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_LIBXML_ERR", LIBXML_ERR, CONST_CS | CONST_PERSISTENT); php_libxml_register_export(dom_node_class_entry, php_dom_export_node); From 83ccf1c42ec0a6c8114162996aa966b0b5842a51 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 16 Jul 2021 15:43:30 +0200 Subject: [PATCH 3/3] Use INVALID_STATE_ERR instead --- ext/dom/document.c | 16 ++++++++-------- ext/dom/domexception.c | 3 --- ext/dom/domexception.h | 4 +--- ext/dom/php_dom.c | 1 - 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/ext/dom/document.c b/ext/dom/document.c index 9070e09966828..4dee5548f1887 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -533,7 +533,7 @@ PHP_METHOD(DOMDocument, createElement) node = xmlNewDocNode(docp, NULL, (xmlChar *) name, (xmlChar *) value); if (!node) { - php_dom_throw_error(LIBXML_ERR, /* strict */ true); + php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); RETURN_THROWS(); } @@ -561,7 +561,7 @@ PHP_METHOD(DOMDocument, createDocumentFragment) node = xmlNewDocFragment(docp); if (!node) { - php_dom_throw_error(LIBXML_ERR, /* strict */ true); + php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); RETURN_THROWS(); } @@ -591,7 +591,7 @@ PHP_METHOD(DOMDocument, createTextNode) node = xmlNewDocText(docp, (xmlChar *) value); if (!node) { - php_dom_throw_error(LIBXML_ERR, /* strict */ true); + php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); RETURN_THROWS(); } @@ -621,7 +621,7 @@ PHP_METHOD(DOMDocument, createComment) node = xmlNewDocComment(docp, (xmlChar *) value); if (!node) { - php_dom_throw_error(LIBXML_ERR, /* strict */ true); + php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); RETURN_THROWS(); } @@ -651,7 +651,7 @@ PHP_METHOD(DOMDocument, createCDATASection) node = xmlNewCDataBlock(docp, (xmlChar *) value, value_len); if (!node) { - php_dom_throw_error(LIBXML_ERR, /* strict */ true); + php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); RETURN_THROWS(); } @@ -686,7 +686,7 @@ PHP_METHOD(DOMDocument, createProcessingInstruction) node = xmlNewPI((xmlChar *) name, (xmlChar *) value); if (!node) { - php_dom_throw_error(LIBXML_ERR, /* strict */ true); + php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); RETURN_THROWS(); } @@ -723,7 +723,7 @@ PHP_METHOD(DOMDocument, createAttribute) node = xmlNewDocProp(docp, (xmlChar *) name, NULL); if (!node) { - php_dom_throw_error(LIBXML_ERR, /* strict */ true); + php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); RETURN_THROWS(); } @@ -759,7 +759,7 @@ PHP_METHOD(DOMDocument, createEntityReference) node = xmlNewReference(docp, (xmlChar *) name); if (!node) { - php_dom_throw_error(LIBXML_ERR, /* strict */ true); + php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); RETURN_THROWS(); } diff --git a/ext/dom/domexception.c b/ext/dom/domexception.c index 451fb7117d651..03b94b630f18e 100644 --- a/ext/dom/domexception.c +++ b/ext/dom/domexception.c @@ -97,9 +97,6 @@ void php_dom_throw_error(int error_code, int strict_error) case VALIDATION_ERR: error_message = "Validation Error"; break; - case LIBXML_ERR: - error_message = "Unknown LibXML error, likely out of memory"; - break; default: error_message = "Unhandled Error"; } diff --git a/ext/dom/domexception.h b/ext/dom/domexception.h index 10cad51f42bff..799b4fd189a63 100644 --- a/ext/dom/domexception.h +++ b/ext/dom/domexception.h @@ -43,9 +43,7 @@ typedef enum { /* Introduced in DOM Level 2: */ INVALID_ACCESS_ERR = 15, /* Introduced in DOM Level 3: */ - VALIDATION_ERR = 16, - /* Unknown libxml error, likely out of memory. */ - LIBXML_ERR = 128, + VALIDATION_ERR = 16 } dom_exception_code; #endif /* DOM_EXCEPTION_H */ diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 2fe15dc099466..ccf74d23d0ed8 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -839,7 +839,6 @@ PHP_MINIT_FUNCTION(dom) REGISTER_LONG_CONSTANT("DOM_NAMESPACE_ERR", NAMESPACE_ERR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("DOM_INVALID_ACCESS_ERR", INVALID_ACCESS_ERR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("DOM_VALIDATION_ERR", VALIDATION_ERR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("DOM_LIBXML_ERR", LIBXML_ERR, CONST_CS | CONST_PERSISTENT); php_libxml_register_export(dom_node_class_entry, php_dom_export_node);