[libsoup/cache] Don't crash when a request is redirected to an invalid/non-http URI



commit c43e910755189d34c65ab59e505a90f15927bc50
Author: Dan Winship <danw gnome org>
Date:   Mon Jul 27 21:27:27 2009 -0400

    Don't crash when a request is redirected to an invalid/non-http URI
    
    Make redirect_handler() reject such responses, and also make soup-uri
    g_return_if_fail rather than crashing. Add a regression test.
    
    http://bugzilla.gnome.org/show_bug.cgi?id=528882

 libsoup/soup-session.c |    2 +-
 libsoup/soup-uri.c     |    5 +++
 tests/redirect-test.c  |   68 +++++++++++++++++++++++++++++------------------
 3 files changed, 48 insertions(+), 27 deletions(-)
---
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 992e305..8c9ccc8 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -889,7 +889,7 @@ redirect_handler (SoupMessage *msg, gpointer user_data)
 	 * are lame, so we use soup_uri_new_with_base().
 	 */
 	new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), new_loc);
-	if (!new_uri) {
+	if (!new_uri || !new_uri->host) {
 		soup_message_set_status_full (msg,
 					      SOUP_STATUS_MALFORMED,
 					      "Invalid Redirect URL");
diff --git a/libsoup/soup-uri.c b/libsoup/soup-uri.c
index 72a900d..876b175 100644
--- a/libsoup/soup-uri.c
+++ b/libsoup/soup-uri.c
@@ -965,6 +965,8 @@ soup_uri_host_hash (gconstpointer key)
 {
 	const SoupURI *uri = key;
 
+	g_return_val_if_fail (uri != NULL && uri->host != NULL, 0);
+
 	return GPOINTER_TO_UINT (uri->scheme) + uri->port +
 		soup_str_case_hash (uri->host);
 }
@@ -987,6 +989,9 @@ soup_uri_host_equal (gconstpointer v1, gconstpointer v2)
 	const SoupURI *one = v1;
 	const SoupURI *two = v2;
 
+	g_return_val_if_fail (one != NULL && two != NULL, one == two);
+	g_return_val_if_fail (one->host != NULL && two->host != NULL, one->host == two->host);
+
 	if (one->scheme != two->scheme)
 		return FALSE;
 	if (one->port != two->port)
diff --git a/tests/redirect-test.c b/tests/redirect-test.c
index 9e21bd1..20e9d48 100644
--- a/tests/redirect-test.c
+++ b/tests/redirect-test.c
@@ -22,85 +22,89 @@ typedef struct {
 
 static struct {
 	TestRequest requests[3];
+	guint final_status;
 } tests[] = {
 	/* A redirecty response to a GET or HEAD should cause a redirect */
 
 	{ { { "GET", "/301", 301 },
 	    { "GET", "/", 200 },
-	    { NULL } } },
+	    { NULL } }, 200 },
 	{ { { "GET", "/302", 302 },
 	    { "GET", "/", 200 },
-	    { NULL } } },
+	    { NULL } }, 200 },
 	{ { { "GET", "/303", 303 },
 	    { "GET", "/", 200 },
-	    { NULL } } },
+	    { NULL } }, 200 },
 	{ { { "GET", "/307", 307 },
 	    { "GET", "/", 200 },
-	    { NULL } } },
+	    { NULL } }, 200 },
 	{ { { "HEAD", "/301", 301 },
 	    { "HEAD", "/", 200 },
-	    { NULL } } },
+	    { NULL } }, 200 },
 	{ { { "HEAD", "/302", 302 },
 	    { "HEAD", "/", 200 },
-	    { NULL } } },
+	    { NULL } }, 200 },
 	/* 303 is a nonsensical response to HEAD, so we don't care
 	 * what happens there.
 	 */
 	{ { { "HEAD", "/307", 307 },
 	    { "HEAD", "/", 200 },
-	    { NULL } } },
+	    { NULL } }, 200 },
 
 	/* A non-redirecty response to a GET or HEAD should not */
 
 	{ { { "GET", "/300", 300 },
-	    { NULL } } },
+	    { NULL } }, 300 },
 	{ { { "GET", "/304", 304 },
-	    { NULL } } },
+	    { NULL } }, 304 },
 	{ { { "GET", "/305", 305 },
-	    { NULL } } },
+	    { NULL } }, 305 },
 	{ { { "GET", "/306", 306 },
-	    { NULL } } },
+	    { NULL } }, 306 },
 	{ { { "GET", "/308", 308 },
-	    { NULL } } },
+	    { NULL } }, 308 },
 	{ { { "HEAD", "/300", 300 },
-	    { NULL } } },
+	    { NULL } }, 300 },
 	{ { { "HEAD", "/304", 304 },
-	    { NULL } } },
+	    { NULL } }, 304 },
 	{ { { "HEAD", "/305", 305 },
-	    { NULL } } },
+	    { NULL } }, 305 },
 	{ { { "HEAD", "/306", 306 },
-	    { NULL } } },
+	    { NULL } }, 306 },
 	{ { { "HEAD", "/308", 308 },
-	    { NULL } } },
+	    { NULL } }, 308 },
 	
 	/* Test double-redirect */
 
 	{ { { "GET", "/301/302", 301 },
 	    { "GET", "/302", 302 },
-	    { "GET", "/", 200 } } },
+	    { "GET", "/", 200 } }, 200 },
 	{ { { "HEAD", "/301/302", 301 },
 	    { "HEAD", "/302", 302 },
-	    { "HEAD", "/", 200 } } },
+	    { "HEAD", "/", 200 } }, 200 },
 
 	/* POST should only automatically redirect on 301, 302 and 303 */
 
 	{ { { "POST", "/301", 301 },
 	    { "GET", "/", 200 },
-	    { NULL } } },
+	    { NULL } }, 200 },
 	{ { { "POST", "/302", 302 },
 	    { "GET", "/", 200 },
-	    { NULL } } },
+	    { NULL } }, 200 },
 	{ { { "POST", "/303", 303 },
 	    { "GET", "/", 200 },
-	    { NULL } } },
+	    { NULL } }, 200 },
 	{ { { "POST", "/307", 307 },
-	    { NULL } } },
+	    { NULL } }, 307 },
 
-	/* Test behavior with recoverably-bad Location header
-	 */
+	/* Test behavior with recoverably-bad Location header */
 	{ { { "GET", "/bad", 302 },
 	    { "GET", "/bad%20with%20spaces", 200 },
-	    { NULL } } }
+	    { NULL } }, 200 },
+
+	/* Test behavior with irrecoverably-bad Location header */
+	{ { { "GET", "/bad-no-host", 302 },
+	    { NULL } }, SOUP_STATUS_MALFORMED }
 };
 static const int n_tests = G_N_ELEMENTS (tests);
 
@@ -183,6 +187,13 @@ do_test (SoupSession *session, SoupURI *base_uri, int n)
 			  G_CALLBACK (restarted), &req);
 
 	soup_session_send_message (session, msg);
+
+	if (msg->status_code != tests[n].final_status) {
+		debug_printf (1, "    - Expected final status of %d, got %d !\n",
+			      tests[n].final_status, msg->status_code);
+		errors++;
+	}
+
 	g_object_unref (msg);
 	debug_printf (2, "\n");
 }
@@ -220,6 +231,11 @@ server_callback (SoupServer *server, SoupMessage *msg,
 			soup_message_headers_replace (msg->response_headers,
 						      "Location",
 						      "/bad with spaces");
+		} else if (!strcmp (path, "/bad-no-host")) {
+			soup_message_set_status (msg, SOUP_STATUS_FOUND);
+			soup_message_headers_replace (msg->response_headers,
+						      "Location",
+						      "about:blank");
 		} else if (!strcmp (path, "/bad with spaces"))
 			soup_message_set_status (msg, SOUP_STATUS_OK);
 		else



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