diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/xmlrpc/tests/bug50285.phpt | 115 | ||||
-rw-r--r-- | ext/xmlrpc/xmlrpc-epi-php.c | 20 |
3 files changed, 134 insertions, 3 deletions
@@ -26,6 +26,8 @@ PHP NEWS - Fixed memory leak in extension loading when an error occurs on Windows. (Pierre) +- Fixed bug #50285 (xmlrpc does not preserve keys in encoded indexed arrays). + (Felipe) - Fixed bug #50282 (xmlrpc_encode_request() changes object into array in calling function). (Felipe) - Fixed bug #50267 (get_browser(null) does not use HTTP_USER_AGENT). (Jani) diff --git a/ext/xmlrpc/tests/bug50285.phpt b/ext/xmlrpc/tests/bug50285.phpt new file mode 100644 index 0000000000..cf766fc40f --- /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/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c index df63759dcb..01de63fec2 100644 --- a/ext/xmlrpc/xmlrpc-epi-php.c +++ b/ext/xmlrpc/xmlrpc-epi-php.c @@ -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) { @@ -557,6 +561,7 @@ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int dep char* my_key; HashTable *ht = NULL; zval *val_arr; + XMLRPC_VECTOR_TYPE vtype; ht = HASH_OF(val); if (ht && ht->nApplyCount > 1) { @@ -570,7 +575,8 @@ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int dep INIT_PZVAL(val_arr); convert_to_array(val_arr); - xReturn = XMLRPC_CreateVector(key, determine_vector_type(Z_ARRVAL_P(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_arr)); while(zend_hash_get_current_data(Z_ARRVAL_P(val_arr), (void**)&pIter) == SUCCESS) { @@ -586,7 +592,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)); } |