[libsoup] soup-xmlrpc: fix parsing of <methodCall> without <params>



commit 909850a4945fb9f37c8005a31f501861df9b3942
Author: Dan Winship <danw gnome org>
Date:   Mon Aug 6 14:28:00 2012 -0400

    soup-xmlrpc: fix parsing of <methodCall> without <params>
    
    If a method takes no parameters, you can leave out the <params>
    section of <methodCall>, but soup_xmlrpc_parse_method_call() was
    requiring it anyway.
    
    Fix that and add some tests of parameter-less methods.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=671661

 libsoup/soup-xmlrpc.c      |   33 ++++++++-------
 tests/xmlrpc-server-test.c |   12 ++++++
 tests/xmlrpc-server.php    |   17 ++++++--
 tests/xmlrpc-test.c        |   94 +++++++++++++++++++++++++++++++++++++-------
 4 files changed, 122 insertions(+), 34 deletions(-)
---
diff --git a/libsoup/soup-xmlrpc.c b/libsoup/soup-xmlrpc.c
index f790858..8d711d3 100644
--- a/libsoup/soup-xmlrpc.c
+++ b/libsoup/soup-xmlrpc.c
@@ -593,29 +593,32 @@ soup_xmlrpc_parse_method_call (const char *method_call, int length,
 	xmlMethodName = xmlNodeGetContent (node);
 
 	node = find_real_node (node->next);
-	if (!node || strcmp ((const char *)node->name, "params") != 0)
-		goto fail;
+	if (node) {
+		if (strcmp ((const char *)node->name, "params") != 0)
+			goto fail;
 
 #ifdef G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 #endif
-	*params = g_value_array_new (1);
-	param = find_real_node (node->children);
-	while (param && !strcmp ((const char *)param->name, "param")) {
-		xval = find_real_node (param->children);
-		if (!xval || strcmp ((const char *)xval->name, "value") != 0 ||
-		    !parse_value (xval, &value)) {
-			g_value_array_free (*params);
-			goto fail;
-		}
-		g_value_array_append (*params, &value);
-		g_value_unset (&value);
+		*params = soup_value_array_new ();
+		param = find_real_node (node->children);
+		while (param && !strcmp ((const char *)param->name, "param")) {
+			xval = find_real_node (param->children);
+			if (!xval || strcmp ((const char *)xval->name, "value") != 0 ||
+			    !parse_value (xval, &value)) {
+				g_value_array_free (*params);
+				goto fail;
+			}
+			g_value_array_append (*params, &value);
+			g_value_unset (&value);
 
-		param = find_real_node (param->next);
-	}
+			param = find_real_node (param->next);
+		}
 #ifdef G_GNUC_END_IGNORE_DEPRECATIONS
 G_GNUC_END_IGNORE_DEPRECATIONS
 #endif
+	} else
+		*params = soup_value_array_new ();
 
 	success = TRUE;
 	*method_name = g_strdup ((char *)xmlMethodName);
diff --git a/tests/xmlrpc-server-test.c b/tests/xmlrpc-server-test.c
index 8ad2187..75f6c91 100644
--- a/tests/xmlrpc-server-test.c
+++ b/tests/xmlrpc-server-test.c
@@ -180,7 +180,17 @@ do_echo (SoupMessage *msg, GValueArray *params)
 
 	soup_xmlrpc_set_response (msg, G_TYPE_VALUE_ARRAY, out);
 	g_value_array_free (out);
+}
+
+static void
+do_ping (SoupMessage *msg, GValueArray *params)
+{
+	if (params->n_values) {
+		args_error (msg, params, 0);
+		return;
+	}
 
+	soup_xmlrpc_set_response (msg, G_TYPE_STRING, "pong");
 }
 
 static void
@@ -216,6 +226,8 @@ server_callback (SoupServer *server, SoupMessage *msg,
 		do_dateChange (msg, params);
 	else if (!strcmp (method_name, "echo"))
 		do_echo (msg, params);
+	else if (!strcmp (method_name, "ping"))
+		do_ping (msg, params);
 	else {
 		soup_xmlrpc_set_fault (msg, SOUP_XMLRPC_FAULT_SERVER_ERROR_REQUESTED_METHOD_NOT_FOUND,
 				       "Unknown method %s", method_name);
diff --git a/tests/xmlrpc-server.php b/tests/xmlrpc-server.php
index 2e3dd38..66cb2be 100644
--- a/tests/xmlrpc-server.php
+++ b/tests/xmlrpc-server.php
@@ -2,13 +2,13 @@
 
 function paramfault ()
 {
-	# xmlrpc-epi-php translates this into a real <fault>
+	# xmlrpc-php translates this into a real <fault>
 	$fault["faultCode"] = -32602;
 	$fault["faultString"] = "bad parameter";
 	return $fault;
 }
 
-# We only check the params in sum(), because that's the one that
+# We only check the params in sum(), because that is the one that
 # xmlrpc-test tests will fail if given bad args
 
 function sum ($method_name, $params, $app_data)
@@ -69,8 +69,16 @@ function echo_ ($method_name, $params, $app_data)
 	return $params[0];
 }
 
-# Work around xmlrpc-epi-php lossage; otherwise the datetime values
-# we return will sometimes get a DST adjustment we don't want.
+function ping ($method_name, $params, $app_data)
+{
+	if (count ($params) == 0)
+		return "pong";
+	else
+		return paramfault ();
+}
+
+# Work around xmlrpc-php lossage; otherwise the datetime values
+# we return will sometimes get a DST adjustment we do not want.
 putenv ("TZ=");
 
 $xmlrpc_server = xmlrpc_server_create ();
@@ -79,6 +87,7 @@ xmlrpc_server_register_method($xmlrpc_server, "countBools", "countBools");
 xmlrpc_server_register_method($xmlrpc_server, "md5sum", "md5sum");
 xmlrpc_server_register_method($xmlrpc_server, "dateChange", "dateChange");
 xmlrpc_server_register_method($xmlrpc_server, "echo", "echo_");
+xmlrpc_server_register_method($xmlrpc_server, "ping", "ping");
 
 $response = xmlrpc_server_call_method ($xmlrpc_server,
 				       implode("\r\n", file('php://input')),
diff --git a/tests/xmlrpc-test.c b/tests/xmlrpc-test.c
index ec67e4d..7a29d0e 100644
--- a/tests/xmlrpc-test.c
+++ b/tests/xmlrpc-test.c
@@ -27,26 +27,13 @@ static const char *const value_type[] = {
 };
 
 static gboolean
-do_xmlrpc (const char *method, GValue *retval, ...)
+send_xmlrpc (const char *body, GValue *retval)
 {
 	SoupMessage *msg;
-	va_list args;
-	GValueArray *params;
 	GError *err = NULL;
-	char *body;
-
-	va_start (args, retval);
-	params = soup_value_array_from_args (args);
-	va_end (args);
-
-	body = soup_xmlrpc_build_method_call (method, params->values,
-					      params->n_values);
-	g_value_array_free (params);
-	if (!body)
-		return FALSE;
 
 	msg = soup_message_new ("POST", uri);
-	soup_message_set_request (msg, "text/xml", SOUP_MEMORY_TAKE,
+	soup_message_set_request (msg, "text/xml", SOUP_MEMORY_COPY,
 				  body, strlen (body));
 	soup_session_send_message (session, msg);
 
@@ -74,6 +61,30 @@ do_xmlrpc (const char *method, GValue *retval, ...)
 }
 
 static gboolean
+do_xmlrpc (const char *method, GValue *retval, ...)
+{
+	va_list args;
+	GValueArray *params;
+	char *body;
+	gboolean ret;
+
+	va_start (args, retval);
+	params = soup_value_array_from_args (args);
+	va_end (args);
+
+	body = soup_xmlrpc_build_method_call (method, params->values,
+					      params->n_values);
+	g_value_array_free (params);
+	if (!body)
+		return FALSE;
+
+	ret = send_xmlrpc (body, retval);
+	g_free (body);
+
+	return ret;
+}
+
+static gboolean
 check_xmlrpc (GValue *value, GType type, ...)
 {
 	va_list args;
@@ -386,6 +397,55 @@ test_echo (void)
 }
 
 static gboolean
+test_ping (gboolean include_params)
+{
+	GValueArray *params;
+	GValue retval;
+	char *request;
+	char *out;
+	gboolean ret;
+
+	debug_printf (1, "ping (void (%s) -> string): ",
+		      include_params ? "empty <params>" : "no <params>");
+
+	params = soup_value_array_new ();
+	request = soup_xmlrpc_build_method_call ("ping", params->values,
+						 params->n_values);
+	g_value_array_free (params);
+	if (!request)
+		return FALSE;
+
+	if (!include_params) {
+		char *params, *end;
+
+		params = strstr (request, "<params/>");
+		if (!params) {
+			debug_printf (1, "ERROR: XML did not contain <params/>!");
+			return FALSE;
+		}
+		end = params + strlen ("<params/>");
+		memmove (params, end, strlen (end) + 1);
+	}
+
+	ret = send_xmlrpc (request, &retval);
+	g_free (request);
+
+	if (!ret || !check_xmlrpc (&retval, G_TYPE_STRING, &out))
+		return FALSE;
+
+	if (!strcmp (out, "pong")) {
+		debug_printf (1, "OK!\n");
+		ret = TRUE;
+	} else {
+		debug_printf (1, "WRONG! Bad response '%s'", out);
+		ret = FALSE;
+	}
+
+	g_free (out);
+	return ret;
+}
+
+static gboolean
 do_bad_xmlrpc (const char *body)
 {
 	SoupMessage *msg;
@@ -476,6 +536,10 @@ main (int argc, char **argv)
 		errors++;
 	if (!test_echo ())
 		errors++;
+	if (!test_ping (TRUE))
+		errors++;
+	if (!test_ping (FALSE))
+		errors++;
 	if (!test_fault_malformed ())
 		errors++;
 	if (!test_fault_method ())



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]