In PHP 5.1.6, this doesn't happen. I don't know what version association.drupal.org is running, but it doesn't happen there either. However, in PHP 5.3.1, the checking of $param_arr in call_user_func_array() is stricter. At it's simplest, here's an example of where it goes wrong (which is the point of this report):
xmlrpc('http://www.example.com/xmlrpc.php', 'system.listMethods');
The unlisted third argument there is the beginning of the $args that will eventually, in xmlrpc_server_call(), cause the following error in PHP 5.3.1: call_user_func_array() expects parameter 2 to be array, null given in includes/xmlrpcs.inc on line 209. To fix this, we would either need to a) ensure that all coded xmlrpc() calls always pass in an empty array() for the third argument or b) default to an empty array (instead of NULL) in all arg-less requests made to the XML-RPC server.
There are actually two errors that are caused whenever an arg-less request is made - the one above, but also: Undefined property: stdClass::$params in includes/xmlrpcs.inc on line 68., which references this usage:
$result = xmlrpc_server_call($xmlrpc_server, $xmlrpc_server->message->methodname, $xmlrpc_server->message->params);
When an XML-RPC client requests a method that has no argument (such as system.listMethods), then $xmlrpc_server->message->params is never set, and the above error triggers. Params are only ever set (via the XML parser kicked off by xml_message_parse(); see also xmlrpc_message_tag_close()) when there are actually params passed through. If there are no params, it's never defaulted to anything, eventually becoming the "undefined property" in the message above. This "undefined property" becomes NULL, gets passed to xmlrpc_server_call() and then causes the error about call_user_func_array().
The attached patch causes the server to (liberally) accept XML with no params, and defaults $xmlrpc_server->message->params to an array if no values are passed through. We DO want to use isset() here, because a param of '' or 0 should be perfectly valid.
Affects both 6 and 7; patches attached for both.
[NOTE: This is my first core patch in *years*. I will fail. Newb me.]
| Comment | File | Size | Author |
|---|---|---|---|
| #8 | 647336-xmlrpc-no-params.patch | 2.49 KB | boombatower |
| #6 | 647336-xmlrpc-no-params.patch | 2.49 KB | boombatower |
| drupal_7_xmlrpc_params.diff | 797 bytes | morbus iff | |
| drupal_6_xmlrpc_params.diff | 768 bytes | morbus iff |
Comments
Comment #1
chx commentedneeds a test.
Comment #2
chx commentedOn further consideration this is untestable as it requires PHP 5.3 to fail in the first place and we can't hook inside the function anywyas. It's simple enough.
Comment #3
morbus iffThe crux of the test, here, would be an arg-less method, such as system.listMethods. Our current xmlrpc.test only tests for (invented) methods that have parameters. We COULD probably go with a test like:
This should always return a list of XML-RPC methods, with or without the patch.
Without the patch, however, it'd fail in PHP's greater than >5.3.
Comment #4
boombatower commentedI had a patch very similar to this one (committed), only that it applied to all PHP versions. This follows the same pattern, I'll go ahead and modify the test to include the failing case so at least the tests will fail on a PHP 5.3 install.
This caused the testing system to crap since it relies on this (when running on PHP 5.3).
Comment #5
dries commented@boombatower, so you're going to submit a new patch? I'm a bit confused about your comment.
Comment #6
boombatower commentedComment #7
dries commented'addition callbacks' -- should that be 'additional callbacks'?
Otherwise looks good to me.
Comment #8
boombatower commentedYep.
Comment #9
dries commentedCommitted to CVS HEAD. Thanks!
Comment #10
morbus iffSetting to d6 to see if they want it.
Comment #11
gábor hojtsyThanks, committed.