diff options
| author | Ondřej Surý <ondrej@sury.org> | 2010-03-09 11:57:54 +0100 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2010-03-09 11:57:54 +0100 |
| commit | 855a09f4eded707941180c9d90acd17c25e29447 (patch) | |
| tree | a40947efaa9876f31b6ee3956c3f3775768143bb /ext/xmlrpc | |
| parent | c852c28a88fccf6e34a2cb091fdfa72bce2b59c7 (diff) | |
| download | php-upstream/5.3.2.tar.gz | |
Imported Upstream version 5.3.2upstream/5.3.2
Diffstat (limited to 'ext/xmlrpc')
| -rw-r--r-- | ext/xmlrpc/php_xmlrpc.h | 4 | ||||
| -rw-r--r-- | ext/xmlrpc/tests/bug50282.phpt | 43 | ||||
| -rw-r--r-- | ext/xmlrpc/tests/bug50285.phpt | 115 | ||||
| -rw-r--r-- | ext/xmlrpc/tests/bug50761.phpt | 62 | ||||
| -rw-r--r-- | ext/xmlrpc/xmlrpc-epi-php.c | 76 |
5 files changed, 268 insertions, 32 deletions
diff --git a/ext/xmlrpc/php_xmlrpc.h b/ext/xmlrpc/php_xmlrpc.h index ce18b53a8..d1bc19cd5 100644 --- a/ext/xmlrpc/php_xmlrpc.h +++ b/ext/xmlrpc/php_xmlrpc.h @@ -37,7 +37,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | + | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -51,7 +51,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xmlrpc.h 272370 2008-12-31 11:15:49Z sebastian $ */ +/* $Id: php_xmlrpc.h 293036 2010-01-03 09:23:27Z sebastian $ */ #ifndef _PHP_XMLRPC_H #define _PHP_XMLRPC_H diff --git a/ext/xmlrpc/tests/bug50282.phpt b/ext/xmlrpc/tests/bug50282.phpt new file mode 100644 index 000000000..eb35fe3f2 --- /dev/null +++ b/ext/xmlrpc/tests/bug50282.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #50282 (xmlrpc_encode_request() changes object into array in calling function) +--SKIPIF-- +<?php if (!extension_loaded("xmlrpc")) print "skip"; ?> +--FILE-- +<?php + +class One { var $x = 10; } + +$o = new One(); +var_dump($o); +var_dump(xmlrpc_encode_request('test', $o)); +var_dump($o); + +?> +--EXPECTF-- +object(One)#%d (1) { + ["x"]=> + int(10) +} +string(279) "<?xml version="1.0" encoding="iso-8859-1"?> +<methodCall> +<methodName>test</methodName> +<params> + <param> + <value> + <struct> + <member> + <name>x</name> + <value> + <int>10</int> + </value> + </member> + </struct> + </value> + </param> +</params> +</methodCall> +" +object(One)#%d (1) { + ["x"]=> + int(10) +} diff --git a/ext/xmlrpc/tests/bug50285.phpt b/ext/xmlrpc/tests/bug50285.phpt new file mode 100644 index 000000000..cf766fc40 --- /dev/null +++ b/ext/xmlrpc/tests/bug50285.phpt @@ -0,0 +1,115 @@ +--TEST-- +Bug #50285 (xmlrpc does not preserve keys in encoded indexed arrays) +--FILE-- +<?php + +function test1($func, $params) { + return array(1=>'One', 3=>'Three', 5=>'Five'); +} + +function test2($func, $params) { + return array('One', 'Three', 'Five', 5); +} + +function test3($func, $params) { + return array('One', 3 => 'Three', b'Five' => 5, 'Six'); +} + +function test4($func, $params) { + return array('One', 'Three', 'Five', b'Six' => 6); +} + +$server = xmlrpc_server_create(); +$result = xmlrpc_server_register_method($server, 'test1', 'test1'); +$HTTP_RAW_POST_DATA = <<<EOD +<?xml version="1.0" encoding="UTF-8"?> +<methodCall> +<methodName>test1</methodName> +<params /> +</methodCall> +EOD; +$response = xmlrpc_server_call_method($server, $HTTP_RAW_POST_DATA, null); +var_dump(xmlrpc_decode($response)); + +// ------------ + +$server = xmlrpc_server_create(); +$result = xmlrpc_server_register_method($server, 'test2', 'test2'); +$HTTP_RAW_POST_DATA = <<<EOD +<?xml version="1.0" encoding="UTF-8"?> +<methodCall> +<methodName>test2</methodName> +<params /> +</methodCall> +EOD; +$response = xmlrpc_server_call_method($server, $HTTP_RAW_POST_DATA, null); +var_dump(xmlrpc_decode($response)); + +// ------------ + +$server = xmlrpc_server_create(); +$result = xmlrpc_server_register_method($server, 'test3', 'test3'); +$HTTP_RAW_POST_DATA = <<<EOD +<?xml version="1.0" encoding="UTF-8"?> +<methodCall> +<methodName>test3</methodName> +<params /> +</methodCall> +EOD; +$response = xmlrpc_server_call_method($server, $HTTP_RAW_POST_DATA, null); +var_dump(xmlrpc_decode($response)); + +// ------------ + +$server = xmlrpc_server_create(); +$result = xmlrpc_server_register_method($server, 'test4', 'test4'); +$HTTP_RAW_POST_DATA = <<<EOD +<?xml version="1.0" encoding="UTF-8"?> +<methodCall> +<methodName>test4</methodName> +<params /> +</methodCall> +EOD; +$response = xmlrpc_server_call_method($server, $HTTP_RAW_POST_DATA, null); +var_dump(xmlrpc_decode($response)); + +?> +--EXPECT-- +array(3) { + [1]=> + string(3) "One" + [3]=> + string(5) "Three" + [5]=> + string(4) "Five" +} +array(4) { + [0]=> + string(3) "One" + [1]=> + string(5) "Three" + [2]=> + string(4) "Five" + [3]=> + int(5) +} +array(4) { + [0]=> + string(3) "One" + [3]=> + string(5) "Three" + ["Five"]=> + int(5) + [4]=> + string(3) "Six" +} +array(4) { + [0]=> + string(3) "One" + [1]=> + string(5) "Three" + [2]=> + string(4) "Five" + ["Six"]=> + int(6) +} diff --git a/ext/xmlrpc/tests/bug50761.phpt b/ext/xmlrpc/tests/bug50761.phpt new file mode 100644 index 000000000..653d8502f --- /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 77ec4ecbf..054ea2f2a 100644 --- a/ext/xmlrpc/xmlrpc-epi-php.c +++ b/ext/xmlrpc/xmlrpc-epi-php.c @@ -37,7 +37,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | + | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -51,7 +51,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xmlrpc-epi-php.c 287434 2009-08-18 00:41:43Z stas $ */ +/* $Id: xmlrpc-epi-php.c 294452 2010-02-03 20:19:05Z pajoye $ */ /********************************************************************** * BUGS: * @@ -484,7 +484,7 @@ static void set_output_options(php_output_options* options, zval* output_opts) static XMLRPC_VECTOR_TYPE determine_vector_type (HashTable *ht) { int bArray = 0, bStruct = 0, bMixed = 0; - unsigned long num_index; + unsigned long num_index, last_num = 0; char* my_key; zend_hash_internal_pointer_reset(ht); @@ -495,8 +495,12 @@ static XMLRPC_VECTOR_TYPE determine_vector_type (HashTable *ht) if (bStruct) { bMixed = 1; break; + } else if (last_num > 0 && last_num != num_index-1) { + bStruct = 1; + break; } bArray = 1; + last_num = num_index; } else if (res == HASH_KEY_NON_EXISTANT) { break; } else if (res == HASH_KEY_IS_STRING) { @@ -556,6 +560,8 @@ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int dep zval** pIter; char* my_key; HashTable *ht = NULL; + zval *val_arr; + XMLRPC_VECTOR_TYPE vtype; ht = HASH_OF(val); if (ht && ht->nApplyCount > 1) { @@ -563,12 +569,16 @@ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int dep return NULL; } - convert_to_array(val); - xReturn = XMLRPC_CreateVector(key, determine_vector_type(Z_ARRVAL_P(val))); + MAKE_STD_ZVAL(val_arr); + MAKE_COPY_ZVAL(&val, val_arr); + convert_to_array(val_arr); + + vtype = determine_vector_type(Z_ARRVAL_P(val_arr)); + xReturn = XMLRPC_CreateVector(key, vtype); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(val)); - while(zend_hash_get_current_data(Z_ARRVAL_P(val), (void**)&pIter) == SUCCESS) { - int res = my_zend_hash_get_current_key(Z_ARRVAL_P(val), &my_key, &num_index); + zend_hash_internal_pointer_reset(Z_ARRVAL_P(val_arr)); + while(zend_hash_get_current_data(Z_ARRVAL_P(val_arr), (void**)&pIter) == SUCCESS) { + int res = my_zend_hash_get_current_key(Z_ARRVAL_P(val_arr), &my_key, &num_index); switch (res) { case HASH_KEY_NON_EXISTANT: @@ -580,7 +590,15 @@ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int dep ht->nApplyCount++; } if (res == HASH_KEY_IS_LONG) { - XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(0, *pIter, depth++ TSRMLS_CC)); + char *num_str = NULL; + + if (vtype != xmlrpc_vector_array) { + spprintf(&num_str, 0, "%ld", num_index); + } + XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(num_str, *pIter, depth++ TSRMLS_CC)); + if (num_str) { + efree(num_str); + } } else { XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(my_key, *pIter, depth++ TSRMLS_CC)); } @@ -589,8 +607,9 @@ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int dep } break; } - zend_hash_move_forward(Z_ARRVAL_P(val)); - } + zend_hash_move_forward(Z_ARRVAL_P(val_arr)); + } + zval_ptr_dtor(&val_arr); } break; default: @@ -892,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; @@ -913,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); } /* }}} */ @@ -1082,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. @@ -1119,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); } |
