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

Reply via email to