diff --git a/ext/dom/tests/php_function_edge_cases.phpt b/ext/dom/tests/php_function_edge_cases.phpt new file mode 100644 index 0000000000000..1091b50ce19bd --- /dev/null +++ b/ext/dom/tests/php_function_edge_cases.phpt @@ -0,0 +1,27 @@ +--TEST-- +php:function() edge cases +--EXTENSIONS-- +dom +--FILE-- +loadHTML('hello'); +$xpath = new DOMXpath($doc); +$xpath->registerNamespace("php", "http://php.net/xpath"); +$xpath->registerPHPFunctions(); +try { + $xpath->query("//a[php:function(3)]"); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + $xpath->query("//a[php:function()]"); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Handler name must be a string +Function name must be passed as the first argument diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c index 62e11f6b99bfb..af85e898ba44c 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -70,6 +70,11 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, return; } + if (UNEXPECTED(nargs == 0)) { + zend_throw_error(NULL, "Function name must be passed as the first argument"); + return; + } + fci.param_count = nargs - 1; if (fci.param_count > 0) { fci.params = safe_emalloc(fci.param_count, sizeof(zval), 0); @@ -132,7 +137,7 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, if (obj->stringval == NULL) { zend_type_error("Handler name must be a string"); xmlXPathFreeObject(obj); - goto cleanup; + goto cleanup_no_callable; } ZVAL_STRING(&fci.function_name, (char *) obj->stringval); xmlXPathFreeObject(obj); @@ -177,6 +182,7 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, cleanup: zend_string_release_ex(callable, 0); zval_ptr_dtor_nogc(&fci.function_name); +cleanup_no_callable: if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&fci.params[i]); diff --git a/ext/xsl/tests/php_function_edge_cases.phpt b/ext/xsl/tests/php_function_edge_cases.phpt new file mode 100644 index 0000000000000..23a06b111bb50 --- /dev/null +++ b/ext/xsl/tests/php_function_edge_cases.phpt @@ -0,0 +1,45 @@ +--TEST-- +php:function() edge cases +--EXTENSIONS-- +xsl +--FILE-- +loadXML(' + + + + + '); + + $inputdom = new DomDocument(); + $inputdom->loadXML(' + '); + + $proc = new XsltProcessor(); + $proc->registerPhpFunctions(); + $xsl = $proc->importStylesheet($xsl); + try { + $proc->transformToDoc($inputdom); + } catch (Exception $e) { + echo $e->getMessage(), "\n"; + } +} + +try { + test(""); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +test("3"); + +?> +--EXPECTF-- +Function name must be passed as the first argument + +Warning: XSLTProcessor::transformToDoc(): Handler name must be a string in %s on line %d diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index 0ddef864f050f..5de4b809ff9a5 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -141,6 +141,11 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t return; } + if (UNEXPECTED(nargs == 0)) { + zend_throw_error(NULL, "Function name must be passed as the first argument"); + return; + } + fci.param_count = nargs - 1; if (fci.param_count > 0) { args = safe_emalloc(fci.param_count, sizeof(zval), 0);