-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Handle libxml2 OOM more consistently #11927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -842,7 +842,12 @@ PHP_METHOD(DOM_Document, createElementNS) | |
if (errorcode == 0) { | ||
if (xmlValidateName((xmlChar *) localname, 0) == 0) { | ||
nodep = xmlNewDocNode(docp, NULL, (xmlChar *) localname, (xmlChar *) value); | ||
if (nodep != NULL && uri != NULL) { | ||
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); | ||
if (nsptr == NULL) { | ||
nsptr = dom_get_ns(nodep, uri, &errorcode, prefix); | ||
|
@@ -860,17 +865,11 @@ PHP_METHOD(DOM_Document, createElementNS) | |
} | ||
|
||
if (errorcode != 0) { | ||
if (nodep != NULL) { | ||
xmlFreeNode(nodep); | ||
} | ||
xmlFreeNode(nodep); | ||
php_dom_throw_error(errorcode, dom_get_strict_error(intern->document)); | ||
RETURN_FALSE; | ||
} | ||
|
||
if (nodep == NULL) { | ||
RETURN_FALSE; | ||
} | ||
|
||
DOM_RET_OBJ(nodep, &ret, intern); | ||
} | ||
/* }}} end dom_document_create_element_ns */ | ||
|
@@ -904,7 +903,12 @@ PHP_METHOD(DOM_Document, createAttributeNS) | |
if (errorcode == 0) { | ||
if (xmlValidateName((xmlChar *) localname, 0) == 0) { | ||
nodep = (xmlNodePtr) xmlNewDocProp(docp, (xmlChar *) localname, NULL); | ||
if (nodep != NULL && uri_len > 0) { | ||
if (UNEXPECTED(nodep == NULL)) { | ||
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); | ||
RETURN_THROWS(); | ||
} | ||
|
||
if (uri_len > 0) { | ||
nsptr = xmlSearchNsByHref(nodep->doc, root, (xmlChar *) uri); | ||
if (nsptr == NULL || nsptr->prefix == NULL) { | ||
nsptr = dom_get_ns(root, uri, &errorcode, prefix ? prefix : "default"); | ||
|
@@ -926,17 +930,11 @@ PHP_METHOD(DOM_Document, createAttributeNS) | |
} | ||
|
||
if (errorcode != 0) { | ||
if (nodep != NULL) { | ||
xmlFreeProp((xmlAttrPtr) nodep); | ||
} | ||
xmlFreeProp((xmlAttrPtr) nodep); | ||
php_dom_throw_error(errorcode, dom_get_strict_error(intern->document)); | ||
RETURN_FALSE; | ||
} | ||
Comment on lines
932
to
936
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same reply as above ^^ :) |
||
|
||
if (nodep == NULL) { | ||
RETURN_FALSE; | ||
} | ||
|
||
DOM_RET_OBJ(nodep, &ret, intern); | ||
} | ||
/* }}} end dom_document_create_attribute_ns */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -138,6 +138,8 @@ PHP_METHOD(DOMImplementation, createDocument) | |
RETURN_THROWS(); | ||
} | ||
if (doctype->doc != NULL) { | ||
/* As the new document is the context node, and the default for strict error checking | ||
* is true, this will always throw. */ | ||
php_dom_throw_error(WRONG_DOCUMENT_ERR, 1); | ||
RETURN_THROWS(); | ||
} | ||
|
@@ -172,7 +174,9 @@ PHP_METHOD(DOMImplementation, createDocument) | |
if (localname != NULL) { | ||
xmlFree(localname); | ||
} | ||
RETURN_FALSE; | ||
/* See above for strict error checking argument. */ | ||
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes it possible to add the tentative |
||
RETURN_THROWS(); | ||
} | ||
|
||
if (doctype != NULL) { | ||
|
@@ -195,8 +199,7 @@ PHP_METHOD(DOMImplementation, createDocument) | |
} | ||
xmlFreeDoc(docp); | ||
xmlFree(localname); | ||
/* Need some better type of error here */ | ||
php_dom_throw_error(PHP_ERR, 1); | ||
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); | ||
RETURN_THROWS(); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -687,7 +687,8 @@ zend_result dom_node_prefix_write(dom_object *obj, zval *newval) | |
(nodep->type == XML_ATTRIBUTE_NODE && zend_string_equals_literal(prefix_str, "xmlns") && | ||
strcmp(strURI, (char *) DOM_XMLNS_NAMESPACE)) || | ||
(nodep->type == XML_ATTRIBUTE_NODE && !strcmp((char *) nodep->name, "xmlns"))) { | ||
ns = NULL; | ||
php_dom_throw_error(NAMESPACE_ERR, dom_get_strict_error(obj->document)); | ||
return FAILURE; | ||
} else { | ||
curns = nsnode->nsDef; | ||
while (curns != NULL) { | ||
|
@@ -699,14 +700,15 @@ zend_result dom_node_prefix_write(dom_object *obj, zval *newval) | |
} | ||
if (ns == NULL) { | ||
ns = xmlNewNs(nsnode, nodep->ns->href, (xmlChar *)prefix); | ||
/* Sadly, we cannot distinguish between OOM and namespace conflict. | ||
* But OOM will almost never happen. */ | ||
if (UNEXPECTED(ns == NULL)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note to self: recheck if OOM is the only way in this path that this can return NULL. |
||
php_dom_throw_error(NAMESPACE_ERR, /* strict */ true); | ||
return FAILURE; | ||
} | ||
} | ||
} | ||
|
||
if (ns == NULL) { | ||
php_dom_throw_error(NAMESPACE_ERR, dom_get_strict_error(obj->document)); | ||
return FAILURE; | ||
} | ||
|
||
xmlSetNs(nodep, ns); | ||
} | ||
break; | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably makes sense to rewrite this code prior to the
if(errorcode == 0)
and use this as a guard as the only other case that seems to fail as far as I can see is on line 862.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also
nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
that has an out-parameter that can set theerrorcode
. And on line 844 the error code can also be set initially. I think I'm going to keep it as-is because it has a single easy-to-spot error handling block for theerrorcode
this way.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right 👍