Skip to content

Commit 1083872

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-16465: Heap buffer overflow in DOMNode->getElementByTagName
2 parents cb6025c + d70f3ba commit 1083872

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

ext/dom/element.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,12 @@ static void dom_element_get_elements_by_tag_name(INTERNAL_FUNCTION_PARAMETERS, b
816816
dom_object *intern, *namednode;
817817
char *name;
818818

819-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
819+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &name, &name_len) == FAILURE) {
820+
RETURN_THROWS();
821+
}
822+
823+
if (name_len > INT_MAX) {
824+
zend_argument_value_error(1, "is too long");
820825
RETURN_THROWS();
821826
}
822827

@@ -1239,7 +1244,17 @@ static void dom_element_get_elements_by_tag_name_ns(INTERNAL_FUNCTION_PARAMETERS
12391244
dom_object *intern, *namednode;
12401245
char *uri, *name;
12411246

1242-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!s", &uri, &uri_len, &name, &name_len) == FAILURE) {
1247+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p!p", &uri, &uri_len, &name, &name_len) == FAILURE) {
1248+
RETURN_THROWS();
1249+
}
1250+
1251+
if (uri_len > INT_MAX) {
1252+
zend_argument_value_error(1, "is too long");
1253+
RETURN_THROWS();
1254+
}
1255+
1256+
if (name_len > INT_MAX) {
1257+
zend_argument_value_error(2, "is too long");
12431258
RETURN_THROWS();
12441259
}
12451260

ext/dom/php_dom.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,23 +1474,19 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml
14741474
const xmlChar* tmp;
14751475

14761476
if (local) {
1477-
int len = local_len > INT_MAX ? -1 : (int) local_len;
1477+
int len = (int) local_len;
14781478
if (doc != NULL && (tmp = xmlDictExists(doc->dict, (const xmlChar *)local, len)) != NULL) {
14791479
mapptr->local = BAD_CAST tmp;
14801480
} else {
14811481
mapptr->local = xmlCharStrndup(local, len);
14821482
mapptr->free_local = true;
14831483
}
14841484
mapptr->local_lower = BAD_CAST estrdup(local);
1485-
if (len < 0) {
1486-
zend_str_tolower((char *) mapptr->local_lower, strlen((const char *) mapptr->local_lower));
1487-
} else {
1488-
zend_str_tolower((char *) mapptr->local_lower, len);
1489-
}
1485+
zend_str_tolower((char *) mapptr->local_lower, len);
14901486
}
14911487

14921488
if (ns) {
1493-
int len = ns_len > INT_MAX ? -1 : (int) ns_len;
1489+
int len = (int) ns_len;
14941490
if (doc != NULL && (tmp = xmlDictExists(doc->dict, (const xmlChar *)ns, len)) != NULL) {
14951491
mapptr->ns = BAD_CAST tmp;
14961492
} else {

ext/dom/tests/gh16465.phpt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
GH-16465 (Heap buffer overflow in DOMNode->getElementByTagName)
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$v10 = new DOMElement("a");
9+
try {
10+
$v10->getElementsByTagName("text\0something");
11+
} catch (ValueError $e) {
12+
echo $e->getMessage(), "\n";
13+
}
14+
try {
15+
$v10->getElementsByTagNameNS("", "text\0something");
16+
} catch (ValueError $e) {
17+
echo $e->getMessage(), "\n";
18+
}
19+
try {
20+
$v10->getElementsByTagNameNS("text\0something", "");
21+
} catch (ValueError $e) {
22+
echo $e->getMessage(), "\n";
23+
}
24+
25+
?>
26+
--EXPECT--
27+
DOMElement::getElementsByTagName(): Argument #1 ($qualifiedName) must not contain any null bytes
28+
DOMElement::getElementsByTagNameNS(): Argument #2 ($localName) must not contain any null bytes
29+
DOMElement::getElementsByTagNameNS(): Argument #1 ($namespace) must not contain any null bytes

0 commit comments

Comments
 (0)