#50761 [Com]: system.multiCall crashes
ID: 50761
Comment by: hiroaki dot kawai at gmail dot com
Reported By: hiroaki dot kawai at gmail dot com
Status: Verified
Bug Type: XMLRPC-EPI related
Operating System: *
PHP Version: 5.*, 6
New Comment:
Created a patch files.
PHP_5_2 http://mp.i-revo.jp/user.php/kcvcrlkq/attach/188
PHP_5_3 http://mp.i-revo.jp/user.php/kcvcrlkq/attach/189
trunk http://mp.i-revo.jp/user.php/kcvcrlkq/attach/190
Previous Comments:
------------------------------------------------------------------------
[2010-01-15 08:52:45] jani@php.net
I hope that patch is against latest SVN checkout of PHP_5_3 and
propably applies also to trunk and PHP_5_2 ? Could you please put the
patch somewhere to be downloaded from.
------------------------------------------------------------------------
[2010-01-15 07:03:28] hiroaki dot kawai at gmail dot com
Description:
------------
xmlrpc-epi supports system.multiCall(), which packs multiple xmlrpc
method call transactions into one. Using this method in php extension
cause php process crash.
The point was that we must let xmlrpc-epi to decode the multicall
request. We must check the method name in the callback function.
This bug exists very long time. http://bugs.php.net/bug.php?id=27446
patch is available:
-------------------------
--- xmlrpc-epi-php.c.orig 2009-08-18 09:41:43.000000000 +0900
+++ xmlrpc-epi-php.c 2010-01-14 13:58:48.028867000 +0900
@@ -892,12 +892,23 @@
static XMLRPC_VALUE php_xmlrpc_callback(XMLRPC_SERVER server,
XMLRPC_REQUEST xRequest, void* data) /* {{{ */
{
xmlrpc_callback_data* pData = (xmlrpc_callback_data*)data;
+ zval** php_function;
zval* xmlrpc_params;
zval* callback_params[3];
TSRMLS_FETCH();
/* convert xmlrpc to native php types */
+ ZVAL_STRING(pData->xmlrpc_method,
XMLRPC_RequestGetMethodName(xRequest), 1);
xmlrpc_params =
XMLRPC_to_PHP(XMLRPC_RequestGetData(xRequest));
+
+ /* check if the called method has been previous registered */
+ if(zend_hash_find(Z_ARRVAL_P(pData->server->method_map),
+ Z_STRVAL_P(pData->xmlrpc_method),
+ Z_STRLEN_P(pData->xmlrpc_method) + 1,
+ (void**)&php_function) == SUCCESS) {
+
+ pData->php_function = *php_function;
+ }
/* setup data hoojum */
callback_params[0] = pData->xmlrpc_method;
@@ -913,7 +924,7 @@
zval_ptr_dtor(&xmlrpc_params);
- return NULL;
+ return PHP_to_XMLRPC(pData->return_data TSRMLS_CC);
}
/* }}} */
@@ -1082,34 +1093,17 @@
if (xRequest) {
const char* methodname =
XMLRPC_RequestGetMethodName(xRequest);
- zval **php_function;
XMLRPC_VALUE xAnswer = NULL;
MAKE_STD_ZVAL(data.xmlrpc_method); /* init.
very important. spent a frustrating day finding this out. */
MAKE_STD_ZVAL(data.return_data);
Z_TYPE_P(data.return_data) = IS_NULL; /* in
case value is never init'd, we don't dtor to think it is a string or
something */
Z_TYPE_P(data.xmlrpc_method) = IS_NULL;
- if (!methodname) {
- methodname = "";
- }
-
/* setup some data to pass to the callback
function */
- Z_STRVAL_P(data.xmlrpc_method) =
estrdup(methodname);
- Z_STRLEN_P(data.xmlrpc_method) =
strlen(methodname);
- Z_TYPE_P(data.xmlrpc_method) = IS_STRING;
data.caller_params = *caller_params;
data.php_executed = 0;
data.server = server;
- /* check if the called method has been
previous registered */
- if (zend_hash_find(Z_ARRVAL_P(server-
>method_map),
-
Z_STRVAL_P(data.xmlrpc_method),
-
Z_STRLEN_P(data.xmlrpc_method) + 1,
-
(void**)&php_function) == SUCCESS) {
-
- data.php_function = *php_function;
- }
-
/* We could just call the php method directly
ourselves at this point, but we do this
* with a C callback in case the xmlrpc
library ever implements some cool usage stats,
* or somesuch.
@@ -1119,7 +1113,7 @@
zval_dtor(data.return_data);
FREE_ZVAL(data.return_data);
data.return_data =
XMLRPC_to_PHP(xAnswer);
- } else if (data.php_executed &&
!out.b_php_out) {
+ } else if (data.php_executed && !out.b_php_out
&& !xAnswer) {
xAnswer =
PHP_to_XMLRPC(data.return_data TSRMLS_CC);
}
Reproduce code:
---------------
<?php
$req = '<?xml version="1.0"?>
<methodCall>
<methodName>system.multiCall</methodName>
<params><param><value><array><data>
<value><struct>
<member><name>methodName</name><value><string>testMethodA</string></value></member>
<member><name>params</name><value><array><data><value><string>A</string></value></data></array></value></member>
</struct></value>
<value><struct>
<member><name>methodName</name><value><string>testMethodB</string></value></member>
<member><name>params</name><value><array><data><value><string>B</string></value></data></array></value></member>
</struct></value>
</data></array></value></param></params>
</methodCall>';
function testA($methodName, $params, $var){ return "C"; }
function testB($methodName, $params, $var){ return "D"; }
$server = xmlrpc_server_create();
xmlrpc_server_register_method($server, 'testMethodA', 'testA');
xmlrpc_server_register_method($server, 'testMethodB', 'testB');
$res = xmlrpc_server_call_method($server, $req, null);
echo $res;
Expected result:
----------------
<?xml version="1.0" encoding="iso-8859-1"?>
<methodResponse>
<params>
<param>
<value>
<array>
<data>
<value>
<array>
<data>
<value>
<string>C</string>
</value>
</data>
</array>
</value>
<value>
<array>
<data>
<value>
<string>D</string>
</value>
</data>
</array>
</value>
</data>
</array>
</value>
</param>
</params>
</methodResponse>
Actual result:
--------------
Segmentation fault
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=50761&edit=1
Thread (5 messages)