summaryrefslogtreecommitdiff
path: root/ext/xmlrpc
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2010-03-09 11:57:54 +0100
committerOndřej Surý <ondrej@sury.org>2010-03-09 11:57:54 +0100
commit855a09f4eded707941180c9d90acd17c25e29447 (patch)
treea40947efaa9876f31b6ee3956c3f3775768143bb /ext/xmlrpc
parentc852c28a88fccf6e34a2cb091fdfa72bce2b59c7 (diff)
downloadphp-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.h4
-rw-r--r--ext/xmlrpc/tests/bug50282.phpt43
-rw-r--r--ext/xmlrpc/tests/bug50285.phpt115
-rw-r--r--ext/xmlrpc/tests/bug50761.phpt62
-rw-r--r--ext/xmlrpc/xmlrpc-epi-php.c76
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);
}