[libsoup] soup_header_g_string_append_param: if @value is a token, don't quote it



commit 7dfc7855fc9e41fd542c0cef7a229fe2c2e959ca
Author: Dan Winship <danw gnome org>
Date:   Tue Apr 6 12:05:26 2010 -0400

    soup_header_g_string_append_param: if @value is a token, don't quote it
    
    also add soup_header_g_string_append_param_quoted(), for places that
    need to guarantee they're adding a quoted-string, not a token, even if
    a token would be syntactically correct. (eg, digest auth, where lots of
    implementations are very very picky)

 libsoup/soup-auth-digest.c        |   14 ++++----
 libsoup/soup-auth-domain-digest.c |    2 +-
 libsoup/soup-headers.c            |   59 ++++++++++++++++++++++++++++--------
 libsoup/soup-headers.h            |    3 ++
 tests/header-parsing.c            |    4 +-
 tests/sniffing-test.c             |    2 +-
 6 files changed, 60 insertions(+), 24 deletions(-)
---
diff --git a/libsoup/soup-auth-digest.c b/libsoup/soup-auth-digest.c
index f9c88bc..90718c6 100644
--- a/libsoup/soup-auth-digest.c
+++ b/libsoup/soup-auth-digest.c
@@ -436,30 +436,30 @@ get_authorization (SoupAuth *auth, SoupMessage *msg)
 
 	out = g_string_new ("Digest ");
 
-	soup_header_g_string_append_param (out, "username", priv->user);
+	soup_header_g_string_append_param_quoted (out, "username", priv->user);
 	g_string_append (out, ", ");
-	soup_header_g_string_append_param (out, "realm", auth->realm);
+	soup_header_g_string_append_param_quoted (out, "realm", auth->realm);
 	g_string_append (out, ", ");
-	soup_header_g_string_append_param (out, "nonce", priv->nonce);
+	soup_header_g_string_append_param_quoted (out, "nonce", priv->nonce);
 	g_string_append (out, ", ");
-	soup_header_g_string_append_param (out, "uri", url);
+	soup_header_g_string_append_param_quoted (out, "uri", url);
 	g_string_append (out, ", ");
 	algorithm = soup_auth_digest_get_algorithm (priv->algorithm);
 	g_string_append_printf (out, "algorithm=%s", algorithm);
 	g_free (algorithm);
 	g_string_append (out, ", ");
-	soup_header_g_string_append_param (out, "response", response);
+	soup_header_g_string_append_param_quoted (out, "response", response);
 
 	if (priv->opaque) {
 		g_string_append (out, ", ");
-		soup_header_g_string_append_param (out, "opaque", priv->opaque);
+		soup_header_g_string_append_param_quoted (out, "opaque", priv->opaque);
 	}
 
 	if (priv->qop) {
 		char *qop = soup_auth_digest_get_qop (priv->qop);
 
 		g_string_append (out, ", ");
-		soup_header_g_string_append_param (out, "cnonce", priv->cnonce);
+		soup_header_g_string_append_param_quoted (out, "cnonce", priv->cnonce);
 		g_string_append_printf (out, ", nc=%.8x, qop=%s",
 					priv->nc, qop);
 		g_free (qop);
diff --git a/libsoup/soup-auth-domain-digest.c b/libsoup/soup-auth-domain-digest.c
index f4a7f41..cee7745 100644
--- a/libsoup/soup-auth-domain-digest.c
+++ b/libsoup/soup-auth-domain-digest.c
@@ -374,7 +374,7 @@ challenge (SoupAuthDomain *domain, SoupMessage *msg)
 	GString *str;
 
 	str = g_string_new ("Digest ");
-	soup_header_g_string_append_param (str, "realm", soup_auth_domain_get_realm (domain));
+	soup_header_g_string_append_param_quoted (str, "realm", soup_auth_domain_get_realm (domain));
 	g_string_append_printf (str, ", nonce=\"%lu%lu\"", 
 				(unsigned long) msg,
 				(unsigned long) time (0));
diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c
index 9835392..5e73a3c 100644
--- a/libsoup/soup-headers.c
+++ b/libsoup/soup-headers.c
@@ -795,21 +795,42 @@ soup_header_free_param_list (GHashTable *param_list)
 }
 
 static void
-append_param_rfc2231 (GString *string, const char *value)
+append_param_rfc2231 (GString    *string,
+		      const char *name,
+		      const char *value)
 {
 	char *encoded;
 
+	g_string_append (string, name);
 	g_string_append (string, "*=UTF-8''");
 	encoded = soup_uri_encode (value, " *'%()<>@,;:\\\"/[]?=");
 	g_string_append (string, encoded);
 	g_free (encoded);
 }
 
-static void
-append_param_quoted (GString *string, const char *value)
+/**
+ * soup_header_g_string_append_param_quoted:
+ * @string: a #GString being used to construct an HTTP header value
+ * @name: a parameter name
+ * @value: a parameter value
+ *
+ * Appends something like <literal>@name="@value"</literal> to
+ * @string, taking care to escape any quotes or backslashes in @value.
+ *
+ * Since: 2.32
+ **/
+void
+soup_header_g_string_append_param_quoted (GString    *string,
+					  const char *name,
+					  const char *value)
 {
 	int len;
 
+	g_return_if_fail (string != NULL);
+	g_return_if_fail (name != NULL);
+	g_return_if_fail (value != NULL);
+
+	g_string_append (string, name);
 	g_string_append (string, "=\"");
 	while (*value) {
 		while (*value == '\\' || *value == '"') {
@@ -829,9 +850,9 @@ append_param_quoted (GString *string, const char *value)
  * @name: a parameter name
  * @value: a parameter value, or %NULL
  *
- * Appends something like <literal>@name="@value"</literal> to
- * @string, taking care to appropriately escape any quotes or
- * backslashes in @value.
+ * Appends something like <literal>@name= value</literal> to @string,
+ * taking care to quote @value if needed, and if so, to escape any
+ * quotes or backslashes in @value.
  *
  * Alternatively, if @value is a non-ASCII UTF-8 string, it will be
  * appended using RFC2231 syntax. Although in theory this is supposed
@@ -844,26 +865,38 @@ append_param_quoted (GString *string, const char *value)
  * Since: 2.26
  **/
 void
-soup_header_g_string_append_param (GString *string, const char *name,
+soup_header_g_string_append_param (GString    *string,
+				   const char *name,
 				   const char *value)
 {
 	const char *v;
+	gboolean token = TRUE;
 
 	g_return_if_fail (string != NULL);
 	g_return_if_fail (name != NULL);
 
-	g_string_append (string, name);
-	if (!value)
+	if (!value) {
+		g_string_append (string, name);
 		return;
+	}
 
 	for (v = value; *v; v++) {
 		if (*v & 0x80) {
 			if (g_utf8_validate (value, -1, NULL)) {
-				append_param_rfc2231 (string, value);
+				append_param_rfc2231 (string, name, value);
 				return;
-			} else
+			} else {
+				token = FALSE;
 				break;
-		}
+			}
+		} else if (!soup_char_is_token (*v))
+			token = FALSE;
 	}
-	append_param_quoted (string, value);
+
+	if (token) {
+		g_string_append (string, name);
+		g_string_append_c (string, '=');
+		g_string_append (string, value);
+	} else
+		soup_header_g_string_append_param_quoted (string, name, value);
 }
diff --git a/libsoup/soup-headers.h b/libsoup/soup-headers.h
index 59f0e78..cc542c3 100644
--- a/libsoup/soup-headers.h
+++ b/libsoup/soup-headers.h
@@ -53,6 +53,9 @@ void        soup_header_free_param_list       (GHashTable       *param_list);
 void        soup_header_g_string_append_param (GString          *string,
 					       const char       *name,
 					       const char       *value);
+void        soup_header_g_string_append_param_quoted (GString    *string,
+						      const char *name,
+						      const char *value);
 
 G_END_DECLS
 
diff --git a/tests/header-parsing.c b/tests/header-parsing.c
index e8799b3..bc1b8cf 100644
--- a/tests/header-parsing.c
+++ b/tests/header-parsing.c
@@ -882,7 +882,7 @@ do_rfc2231_tests (void)
 #define CONTENT_TYPE_TEST_MIME_TYPE "text/plain"
 #define CONTENT_TYPE_TEST_ATTRIBUTE "charset"
 #define CONTENT_TYPE_TEST_VALUE     "US-ASCII"
-#define CONTENT_TYPE_TEST_HEADER    "text/plain; charset=\"US-ASCII\""
+#define CONTENT_TYPE_TEST_HEADER    "text/plain; charset=US-ASCII"
 
 #define CONTENT_TYPE_BAD_HEADER     "plain text, not text/html"
 
@@ -963,7 +963,7 @@ struct {
 	{ "five", "test with \xC3\xA1\xC3\xA7\xC4\x89\xC3\xA8\xC3\xB1\xC5\xA3\xC5\xA1" }
 };
 
-#define TEST_PARAMS_RESULT "one=\"foo\", two=\"test with spaces\", three=\"test with \\\"quotes\\\" and \\\\s\", four, five*=UTF-8''test%20with%20%C3%A1%C3%A7%C4%89%C3%A8%C3%B1%C5%A3%C5%A1"
+#define TEST_PARAMS_RESULT "one=foo, two=\"test with spaces\", three=\"test with \\\"quotes\\\" and \\\\s\", four, five*=UTF-8''test%20with%20%C3%A1%C3%A7%C4%89%C3%A8%C3%B1%C5%A3%C5%A1"
 
 static void
 do_append_param_tests (void)
diff --git a/tests/sniffing-test.c b/tests/sniffing-test.c
index 9aca27b..b2296be 100644
--- a/tests/sniffing-test.c
+++ b/tests/sniffing-test.c
@@ -540,7 +540,7 @@ main (int argc, char **argv)
 	test_sniffing ("/multiple_headers/home.gif", "image/gif");
 
 	/* Test that we keep the parameters when sniffing */
-	test_sniffing ("/type/text_html; charset=\"UTF-8\"/test.html", "text/html; charset=\"UTF-8\"");
+	test_sniffing ("/type/text_html; charset=UTF-8/test.html", "text/html; charset=UTF-8");
 
 	/* Test that disabling the sniffer works correctly */
 



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