soup_request_data_send: data URL decoding fix
authorSergio Villar Senin <svillar@igalia.com>
Wed, 6 Apr 2011 19:55:23 +0000 (21:55 +0200)
committerSergio Villar Senin <svillar@igalia.com>
Thu, 7 Apr 2011 18:44:39 +0000 (20:44 +0200)
SoupRequestData was not unescaping base64 URIs before trying to decode them.
This was incorrectly causing decoding errors with base64 data.

https://bugzilla.gnome.org/show_bug.cgi?id=646896

libsoup/Makefile.am
libsoup/soup-request-data.c
libsoup/soup-uri-private.h [new file with mode: 0644]
libsoup/soup-uri.c

index c4ec90e..14fd692 100644 (file)
@@ -175,6 +175,7 @@ libsoup_2_4_la_SOURCES =            \
        soup-ssl.c                      \
        soup-status.c                   \
        soup-uri.c                      \
+       soup-uri-private.h              \
        soup-value-utils.c              \
        soup-xmlrpc.c
 
index 8c97bf8..dd64cf2 100644 (file)
@@ -30,6 +30,7 @@
 #include "soup-request-data.h"
 
 #include "soup-requester.h"
+#include "soup-uri-private.h"
 #include <libsoup/soup.h>
 #include <glib/gi18n.h>
 
@@ -90,16 +91,8 @@ soup_request_data_send (SoupRequest   *request,
                } else
                        end = comma;
 
-               if (end != start) {
-                       char *encoded_content_type = g_strndup (start, end - start);
-
-                       if (base64)
-                               data->priv->content_type = encoded_content_type;
-                       else {
-                               data->priv->content_type = soup_uri_decode (encoded_content_type);
-                               g_free (encoded_content_type);
-                       }
-               }
+               if (end != start)
+                       data->priv->content_type = uri_decoded_copy (start, end - start);
        }
 
        memstream = g_memory_input_stream_new ();
@@ -108,25 +101,12 @@ soup_request_data_send (SoupRequest   *request,
                start = comma + 1;
 
        if (*start) {
-               guchar *buf;
-
-               if (base64) {
-                       int inlen, state = 0;
-                       guint save = 0;
-
-                       inlen = strlen (start);
-                       buf = g_malloc0 (inlen * 3 / 4 + 3);
-                       data->priv->content_length =
-                               g_base64_decode_step (start, inlen, buf,
-                                                     &state, &save);
-                       if (state != 0) {
-                               g_free (buf);
-                               goto fail;
-                       }
-               } else {
-                       buf = (guchar *) soup_uri_decode (start);
+               guchar *buf = (guchar *) soup_uri_decode (start);
+
+               if (base64)
+                       buf = g_base64_decode_inplace ((gchar*) buf, &data->priv->content_length);
+               else
                        data->priv->content_length = strlen ((const char *) buf);
-               }
 
                g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (memstream),
                                                buf, data->priv->content_length,
@@ -135,13 +115,6 @@ soup_request_data_send (SoupRequest   *request,
        g_free (uristr);
 
        return memstream;
-
- fail:
-       g_free (uristr);
-       g_set_error (error, SOUP_REQUESTER_ERROR, SOUP_REQUESTER_ERROR_BAD_URI,
-                    _("Unable to decode URI: %s"), start);
-       g_object_unref (memstream);
-       return NULL;
 }
 
 static goffset
diff --git a/libsoup/soup-uri-private.h b/libsoup/soup-uri-private.h
new file mode 100644 (file)
index 0000000..14cfd57
--- /dev/null
@@ -0,0 +1,11 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2011 Igalia, S.L.
+ */
+
+#ifndef SOUP_URI_PRIVATE_H
+#define SOUP_URI_PRIVATE_H 1
+
+char *uri_decoded_copy (const char *str, int length);
+
+#endif /* SOUP_URI_PRIVATE_H */
index dcffd33..539ff74 100644 (file)
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 
 #include "soup-uri.h"
+#include "soup-uri-private.h"
 #include "soup-form.h"
 #include "soup-misc.h"
 
@@ -92,7 +93,6 @@
  **/
 
 static void append_uri_encoded (GString *str, const char *in, const char *extra_enc_chars);
-static char *uri_decoded_copy (const char *str, int length);
 static char *uri_normalized_copy (const char *str, int length, const char *unescape_extra);
 
 gpointer _SOUP_URI_SCHEME_HTTP, _SOUP_URI_SCHEME_HTTPS;
@@ -599,7 +599,7 @@ soup_uri_encode (const char *part, const char *escape_extra)
 #define XDIGIT(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10)
 #define HEXCHAR(s) ((XDIGIT (s[1]) << 4) + XDIGIT (s[2]))
 
-static char *
+char *
 uri_decoded_copy (const char *part, int length)
 {
        unsigned char *s, *d;