iliaa Sun, 17 Jan 2010 17:19:38 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=293655
Log: Fixed bug #50761 (system.multiCall crashes in xmlrpc extension). Bug: http://bugs.php.net/50761 (Verified) system.multiCall crashes Changed paths: U php/php-src/branches/PHP_5_2/NEWS A php/php-src/branches/PHP_5_2/ext/xmlrpc/tests/bug50761.phpt U php/php-src/branches/PHP_5_2/ext/xmlrpc/xmlrpc-epi-php.c U php/php-src/branches/PHP_5_3/NEWS A php/php-src/branches/PHP_5_3/ext/xmlrpc/tests/bug50761.phpt U php/php-src/branches/PHP_5_3/ext/xmlrpc/xmlrpc-epi-php.c A php/php-src/trunk/ext/xmlrpc/tests/bug50761.phpt U php/php-src/trunk/ext/xmlrpc/xmlrpc-epi-php.c
Modified: php/php-src/branches/PHP_5_2/NEWS =================================================================== --- php/php-src/branches/PHP_5_2/NEWS 2010-01-17 17:05:38 UTC (rev 293654) +++ php/php-src/branches/PHP_5_2/NEWS 2010-01-17 17:19:38 UTC (rev 293655) @@ -13,6 +13,8 @@ - Fixed build of mysqli with MySQL 5.5.0-m2. (Andrey) +- Fixed bug #50761 (system.multiCall crashes in xmlrpc extension). (hiroaki + dot kawai at gmail dot com, Ilia) - Fixed bug #50732 (exec() adds single byte twice to $output array). (Ilia) - Fixed bug #50728 (All PDOExceptions hardcode 'code' property to 0). (Joey, Ilia) Added: php/php-src/branches/PHP_5_2/ext/xmlrpc/tests/bug50761.phpt =================================================================== --- php/php-src/branches/PHP_5_2/ext/xmlrpc/tests/bug50761.phpt (rev 0) +++ php/php-src/branches/PHP_5_2/ext/xmlrpc/tests/bug50761.phpt 2010-01-17 17:19:38 UTC (rev 293655) @@ -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> Modified: php/php-src/branches/PHP_5_2/ext/xmlrpc/xmlrpc-epi-php.c =================================================================== --- php/php-src/branches/PHP_5_2/ext/xmlrpc/xmlrpc-epi-php.c 2010-01-17 17:05:38 UTC (rev 293654) +++ php/php-src/branches/PHP_5_2/ext/xmlrpc/xmlrpc-epi-php.c 2010-01-17 17:19:38 UTC (rev 293655) @@ -870,13 +870,27 @@ 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; callback_params[1] = xmlrpc_params; @@ -891,7 +905,7 @@ zval_ptr_dtor(&xmlrpc_params); - return NULL; + return PHP_to_XMLRPC(pData->return_data TSRMLS_CC); } /* called by the C server when it first receives an introspection request. We pass this on to @@ -1059,34 +1073,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. @@ -1096,7 +1093,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); } Modified: php/php-src/branches/PHP_5_3/NEWS =================================================================== --- php/php-src/branches/PHP_5_3/NEWS 2010-01-17 17:05:38 UTC (rev 293654) +++ php/php-src/branches/PHP_5_3/NEWS 2010-01-17 17:19:38 UTC (rev 293655) @@ -13,6 +13,8 @@ - Added stream filter support to mcrypt extension (ported from mcrypt_filter). (Stas) +- Fixed bug #50761 (system.multiCall crashes in xmlrpc extension). (hiroaki + dot kawai at gmail dot com, Ilia) - Fixed bug #50732 (exec() adds single byte twice to $output array). (Ilia) - Fixed bug #50728 (All PDOExceptions hardcode 'code' property to 0). (Joey, Ilia) Added: php/php-src/branches/PHP_5_3/ext/xmlrpc/tests/bug50761.phpt =================================================================== --- php/php-src/branches/PHP_5_3/ext/xmlrpc/tests/bug50761.phpt (rev 0) +++ php/php-src/branches/PHP_5_3/ext/xmlrpc/tests/bug50761.phpt 2010-01-17 17:19:38 UTC (rev 293655) @@ -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> Modified: php/php-src/branches/PHP_5_3/ext/xmlrpc/xmlrpc-epi-php.c =================================================================== --- php/php-src/branches/PHP_5_3/ext/xmlrpc/xmlrpc-epi-php.c 2010-01-17 17:05:38 UTC (rev 293654) +++ php/php-src/branches/PHP_5_3/ext/xmlrpc/xmlrpc-epi-php.c 2010-01-17 17:19:38 UTC (rev 293655) @@ -911,13 +911,27 @@ 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; callback_params[1] = xmlrpc_params; @@ -932,7 +946,7 @@ zval_ptr_dtor(&xmlrpc_params); - return NULL; + return PHP_to_XMLRPC(pData->return_data TSRMLS_CC); } /* }}} */ @@ -1101,34 +1115,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. @@ -1138,7 +1135,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); } Added: php/php-src/trunk/ext/xmlrpc/tests/bug50761.phpt =================================================================== --- php/php-src/trunk/ext/xmlrpc/tests/bug50761.phpt (rev 0) +++ php/php-src/trunk/ext/xmlrpc/tests/bug50761.phpt 2010-01-17 17:19:38 UTC (rev 293655) @@ -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> Modified: php/php-src/trunk/ext/xmlrpc/xmlrpc-epi-php.c =================================================================== --- php/php-src/trunk/ext/xmlrpc/xmlrpc-epi-php.c 2010-01-17 17:05:38 UTC (rev 293654) +++ php/php-src/trunk/ext/xmlrpc/xmlrpc-epi-php.c 2010-01-17 17:19:38 UTC (rev 293655) @@ -917,13 +917,27 @@ 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; callback_params[1] = xmlrpc_params; @@ -938,7 +952,7 @@ zval_ptr_dtor(&xmlrpc_params); - return NULL; + return PHP_to_XMLRPC(pData->return_data TSRMLS_CC); } /* }}} */ @@ -1107,34 +1121,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. @@ -1144,7 +1141,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); }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php