[evolution-data-server] I#232 - ESoupSession: Ensure request URI is properly encoded



commit 5801d11720c8c17831eb68670af7e47416e8ca53
Author: Milan Crha <mcrha redhat com>
Date:   Thu Sep 3 11:15:23 2020 +0200

    I#232 - ESoupSession: Ensure request URI is properly encoded
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/232

 src/libedataserver/e-soup-session.c | 86 +++++++++++++++++++++++++++++++++++++
 src/libedataserver/e-soup-session.h |  1 +
 2 files changed, 87 insertions(+)
---
diff --git a/src/libedataserver/e-soup-session.c b/src/libedataserver/e-soup-session.c
index 9cbf5d156d..b6467f75d8 100644
--- a/src/libedataserver/e-soup-session.c
+++ b/src/libedataserver/e-soup-session.c
@@ -767,6 +767,8 @@ e_soup_session_preset_request (SoupRequestHTTP *request)
 
        message = soup_request_http_get_message (request);
        if (message) {
+               e_soup_session_util_normalize_uri_path (soup_message_get_uri (message));
+
                soup_message_headers_append (message->request_headers, "User-Agent", "Evolution/" VERSION);
                soup_message_headers_append (message->request_headers, "Connection", "close");
 
@@ -1227,3 +1229,87 @@ e_soup_session_util_status_to_string (guint status_code,
 
        return _("Unknown error");
 }
+
+static gboolean
+part_needs_encoding (const gchar *part)
+{
+       const gchar *pp;
+
+       if (!part || !*part)
+               return FALSE;
+
+       for (pp = part; *pp; pp++) {
+               if (!strchr ("/!()+-*~';,.$&_", *pp) &&
+                   !g_ascii_isalnum (*pp) &&
+                   (*pp != '%' || pp[1] != '4' || pp[2] != '0') && /* cover '%40', aka '@', as a common 
case, to avoid unnecessary allocations */
+                   (*pp != '%' || pp[1] != '2' || pp[2] != '0')) { /* '%20', aka ' ' */
+                       break;
+               }
+       }
+
+       return *pp;
+}
+
+/**
+ * e_soup_session_util_normalize_uri_path:
+ * @suri: a #SoupURI to normalize the path for
+ *
+ * Normalizes the path of the @suri, aka encodes characters, which should
+ * be encoded, if needed. Returns, whether any change had been made to the path.
+ * It doesn't touch other parts of the @suri.
+ *
+ * Returns: whether made any changes
+ *
+ * Since: 3.38
+ **/
+gboolean
+e_soup_session_util_normalize_uri_path (SoupURI *suri)
+{
+       const gchar *path;
+       gchar **parts, *tmp;
+       gboolean did_change = FALSE;
+       gint ii;
+
+       if (!suri)
+               return FALSE;
+
+       path = soup_uri_get_path (suri);
+
+       if (!path || !*path || g_strcmp0 (path, "/") == 0)
+               return FALSE;
+
+       if (!part_needs_encoding (path))
+               return FALSE;
+
+       parts = g_strsplit (path, "/", -1);
+
+       if (!parts)
+               return FALSE;
+
+       for (ii = 0; parts[ii]; ii++) {
+               gchar *part = parts[ii];
+
+               if (part_needs_encoding (part)) {
+                       if (strchr (part, '%')) {
+                               tmp = soup_uri_decode (part);
+                               g_free (part);
+                               part = tmp;
+                       }
+
+                       tmp = soup_uri_encode (part, NULL);
+                       g_free (part);
+                       parts[ii] = tmp;
+               }
+       }
+
+       tmp = g_strjoinv ("/", parts);
+       if (g_strcmp0 (path, tmp) != 0) {
+               soup_uri_set_path (suri, tmp);
+               did_change = TRUE;
+       }
+
+       g_free (tmp);
+       g_strfreev (parts);
+
+       return did_change;
+}
diff --git a/src/libedataserver/e-soup-session.h b/src/libedataserver/e-soup-session.h
index 9ea18a926e..78a75f41f5 100644
--- a/src/libedataserver/e-soup-session.h
+++ b/src/libedataserver/e-soup-session.h
@@ -116,6 +116,7 @@ GByteArray *        e_soup_session_send_request_simple_sync (ESoupSession *session,
                                                         GError **error);
 const gchar *  e_soup_session_util_status_to_string    (guint status_code,
                                                         const gchar *reason_phrase);
+gboolean       e_soup_session_util_normalize_uri_path  (SoupURI *suri);
 
 G_END_DECLS
 


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