summaryrefslogtreecommitdiff
path: root/ext/xmlrpc
diff options
context:
space:
mode:
authorIlia Alshanetsky <iliaa@php.net>2010-01-17 17:19:38 +0000
committerIlia Alshanetsky <iliaa@php.net>2010-01-17 17:19:38 +0000
commitebe5ff73f8809b35791dcd9a8c940a15bde4d807 (patch)
tree09dc59069ff88da28b4c224289a17750e0f7c59c /ext/xmlrpc
parent6cd6c32d0f745ea0f51bf3c1684c253863bfba96 (diff)
downloadphp-git-ebe5ff73f8809b35791dcd9a8c940a15bde4d807.tar.gz
Fixed bug #50761 (system.multiCall crashes in xmlrpc extension).
Diffstat (limited to 'ext/xmlrpc')
-rw-r--r--ext/xmlrpc/tests/bug50761.phpt62
-rw-r--r--ext/xmlrpc/xmlrpc-epi-php.c35
2 files changed, 78 insertions, 19 deletions
diff --git a/ext/xmlrpc/tests/bug50761.phpt b/ext/xmlrpc/tests/bug50761.phpt
new file mode 100644
index 0000000000..653d8502f1
--- /dev/null
+++ b/ext/xmlrpc/tests/bug50761.phpt
@@ -0,0 +1,62 @@
+--TEST--
+Bug #50761 (system.multiCall crashes)
+--FILE--
+<?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;
+?>
+--EXPECT--
+<?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>
diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c
index b68de241e2..4c09299a07 100644
--- a/ext/xmlrpc/xmlrpc-epi-php.c
+++ b/ext/xmlrpc/xmlrpc-epi-php.c
@@ -911,12 +911,26 @@ PHP_FUNCTION(xmlrpc_server_destroy)
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();
+ zval_dtor(pData->xmlrpc_method);
+ zval_dtor(pData->return_data);
+
/* 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;
@@ -932,7 +946,7 @@ static XMLRPC_VALUE php_xmlrpc_callback(XMLRPC_SERVER server, XMLRPC_REQUEST xRe
zval_ptr_dtor(&xmlrpc_params);
- return NULL;
+ return PHP_to_XMLRPC(pData->return_data TSRMLS_CC);
}
/* }}} */
@@ -1101,34 +1115,17 @@ PHP_FUNCTION(xmlrpc_server_call_method)
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.
@@ -1138,7 +1135,7 @@ PHP_FUNCTION(xmlrpc_server_call_method)
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);
}