-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
[RFC] Improve callbacks in ext/dom and ext/xsl #12627
Conversation
14499b1
to
5274a1c
Compare
542ae01
to
d219188
Compare
cfc2fe5
to
d7ee39b
Compare
d7ee39b
to
48bcd44
Compare
$xpath->registerPhpFunctions(null); | ||
$xpath->evaluate("//a[php:function('var_dump', string(@href))]"); | ||
|
||
echo "--- Error cases ---\n"; |
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.
We usually split error cases into a different test file
|
||
$xpath = new DOMXPath($doc); | ||
|
||
echo "--- Error cases ---\n"; |
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.
Ditto
ext/dom/xpath.c
Outdated
|
||
static void dom_xpath_proxy_factory(xmlNodePtr node, zval *child, dom_object *intern, xmlXPathParserContextPtr ctxt) | ||
{ | ||
(void) ctxt; |
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.
Don't we have a ZEND_UNUSED
macro attribute for those cases?
ext/dom/xpath.c
Outdated
if (!zend_is_executing()) { | ||
xmlGenericError(xmlGenericErrorContext, | ||
"xmlExtFunctionTest: Function called from outside of PHP\n"); | ||
error = 1; |
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.
Early return to have the happy path without any indentation?
Also maybe UNEXPECTED()
?
ext/dom/xpath.c
Outdated
ZEND_PARSE_PARAMETERS_END(); | ||
|
||
if (zend_string_equals_literal(namespace, "http://php.net/xpath")) { | ||
zend_argument_value_error(1, "must not be \"http://php.net/xpath\" because it is reserved for PHP"); |
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.
zend_argument_value_error(1, "must not be \"http://php.net/xpath\" because it is reserved for PHP"); | |
zend_argument_value_error(1, "must not be \"http://php.net/xpath\" because it is reserved by PHP"); |
Seems more logical?
ext/dom/xpath_callbacks.c
Outdated
if (UNEXPECTED(result == FAILURE)) { | ||
return FAILURE; | ||
} |
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.
This looks wrong.
I wouldn't expect result to ever be FAILURE
see the comment in zend_API.h
:
/* Can only return FAILURE if EG(active) is false during late engine shutdown.
* If the call or call setup throws, EG(exception) will be set and the retval
* will be UNDEF. Otherwise, the retval will be a non-UNDEF value. */
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.
Good catch, a bit surprising though.
if (UNEXPECTED(num_args == 0)) { | ||
zend_throw_error(NULL, "Function name must be passed as the first argument"); | ||
goto cleanup_no_obj; | ||
} |
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.
Is this an API usage failure? As this seems like it should only ever be possible to hit this case if C code does something wrong? Which maybe means this should be an assertion? Or am I missing something?
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.
Yes this is possible to hit by using a wrong XSL template that does: php:function()
in its xpath expression instead of php:function('function_name')
.
ext/dom/xpath_callbacks.c
Outdated
/* Last element of the stack is the function name */ | ||
xmlXPathObjectPtr obj = valuePop(ctxt); | ||
if (obj->stringval == NULL) { | ||
zend_type_error("Handler name must be a string"); | ||
goto cleanup; | ||
} |
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.
Ditto
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.
See #12627 (comment) it's possible to hit this using php:function(1234)
for example
I believe I fixed or replied to all issues. |
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.
LGTM
The |
Yes it's not documented yet, we're tracking documentation status in php/doc-en#3872.
Indeed, adding an entry there for the version number, and if I were you I'd make a copy of the registerPHPFunctions xml document as a start for registerPHPFunctionNS and modify from there. Same thing should be done for DOMXPath, but if you get a PR going for XSLTProcessor that is already great and can serve as a basis for DOMXPath's version of registerPHPFunctionNS. The docs repo contains instructions on how to build the docs locally. |
Thanks @nielsdos, as I suggested this change in the internals RFC discussion I am absolutely interested in this addition. It will serve my XSL 2.0 transpiler library very well. So, I'd say it's my turn to thank you for the implementation! And I'll do my best to come up with both PRs. |
See the PR @ doc-en. |
RFC link: https://wiki.php.net/rfc/improve_callbacks_dom_and_xsl