[evolution-data-server] I#272 - WebDAV: Decode URI-s before comparing them
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] I#272 - WebDAV: Decode URI-s before comparing them
- Date: Thu, 19 Nov 2020 14:05:23 +0000 (UTC)
commit 8c5df2d15eaca42d126a928da0b12d7c324e17bb
Author: Milan Crha <mcrha redhat com>
Date: Thu Nov 19 15:04:12 2020 +0100
I#272 - WebDAV: Decode URI-s before comparing them
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/272
src/libedataserver/e-webdav-session.c | 71 ++++++++++++++++++++++++++++--
tests/libedataserver/libedataserver-test.c | 22 +++++++--
2 files changed, 86 insertions(+), 7 deletions(-)
---
diff --git a/src/libedataserver/e-webdav-session.c b/src/libedataserver/e-webdav-session.c
index ca95ec437..fbf8a0acb 100644
--- a/src/libedataserver/e-webdav-session.c
+++ b/src/libedataserver/e-webdav-session.c
@@ -5139,6 +5139,65 @@ e_webdav_session_util_free_privileges (GNode *privileges)
g_node_destroy (privileges);
}
+static gint
+e_webdav_session_uricmp (const gchar *str1,
+ const gchar *str2,
+ gint len,
+ gboolean case_sensitive)
+{
+ const gchar *p1, *p2;
+ gchar c1, c2;
+ gint len1, len2;
+
+ g_return_val_if_fail (len >= 0, -1);
+ g_return_val_if_fail (str1 != NULL, -1);
+ g_return_val_if_fail (str2 != NULL, -1);
+
+ if (!len)
+ return 0;
+
+ /* Decode %-encoded letters, if needed */
+ #define get_next_char(str, ll, cc) G_STMT_START { \
+ if (!*str) { \
+ cc = 0; \
+ } else if (*str == '%' && ll >= 2 && g_ascii_isxdigit (str[1]) && g_ascii_isxdigit (str[2]))
{ \
+ cc = ((str[1] >= '0' && str[1] <= '9') ? (str[1] - '0') : \
+ (str[1] >= 'a' && str[1] <= 'f') ? (str[1] - 'a' + 10) : \
+ (str[1] >= 'A' && str[1] <= 'F') ? (str[1] - 'A' + 10) : 0) * 16 + \
+ ((str[2] >= '0' && str[2] <= '9') ? (str[2] - '0') : \
+ (str[2] >= 'a' && str[2] <= 'f') ? (str[2] - 'a' + 10) : \
+ (str[2] >= 'A' && str[2] <= 'F') ? (str[2] - 'A' + 10) : 0); \
+ str += 3; \
+ ll -= 3; \
+ } else { \
+ cc = *str; \
+ str++; \
+ ll--; \
+ } \
+ } G_STMT_END
+
+ p1 = str1;
+ p2 = str2;
+
+ len1 = len;
+ len2 = len;
+
+ c1 = *p1;
+ c2 = *p2;
+
+ while (len1 > 0 && len2 > 0 && *p1 && *p2) {
+ get_next_char (p1, len1, c1);
+ get_next_char (p2, len2, c2);
+
+ if ((case_sensitive && c1 != c2) || (!case_sensitive && g_ascii_tolower (c1) !=
g_ascii_tolower (c2)))
+ break;
+ }
+
+ #undef get_next_char
+
+ return c1 - c2;
+}
+
/**
* e_webdav_session_util_item_href_equal:
* @href1: the first href
@@ -5200,18 +5259,22 @@ e_webdav_session_util_item_href_equal (const gchar *href1,
/* it's the hostname part */
if (from1 == href1) {
+ const gchar *dash;
+
/* ignore the username/password part */
ptr = strchr (from1, '@');
- if (ptr)
+ dash = strchr (from1, '/');
+ if (ptr && (!dash || dash > ptr))
from1 = ptr + 1;
ptr = strchr (from2, '@');
- if (ptr)
+ dash = strchr (from2, '/');
+ if (ptr && (!dash || dash > ptr))
from2 = ptr + 1;
- if (g_ascii_strncasecmp (from1, from2, len) != 0)
+ if (e_webdav_session_uricmp (from1, from2, len, FALSE) != 0)
return FALSE;
- } else if (strncmp (from1, from2, len) != 0) {
+ } else if (e_webdav_session_uricmp (from1, from2, len, TRUE) != 0) {
return FALSE;
}
}
diff --git a/tests/libedataserver/libedataserver-test.c b/tests/libedataserver/libedataserver-test.c
index 8ff11b999..c3c225b62 100644
--- a/tests/libedataserver/libedataserver-test.c
+++ b/tests/libedataserver/libedataserver-test.c
@@ -28,7 +28,7 @@ test_webdav_href_compare (ETestServerFixture *fixture,
const gchar *href2;
gboolean same;
} hrefs[] = {
- { "http://www.gnome.org/", "http://www.gnome.org/", TRUE },
+ /* 0 */ { "http://www.gnome.org/", "http://www.gnome.org/", TRUE },
{ "https://www.gnome.org/", "http://www.gnome.org/", TRUE },
{ "http://user www gnome org/", "https://www.gnome.org/", TRUE },
{ "http://www.gnome.org/index", "http://www.gnome.org/", FALSE },
@@ -38,7 +38,7 @@ test_webdav_href_compare (ETestServerFixture *fixture,
{ "http://www.gnome.org/path/collection/data.ext",
"http://www.gnome.org/path/collection/data.ext", TRUE },
{ "https://www.gnome.org/path/collection/data.ext",
"http://www.gnome.org/path/collection/data.ext", TRUE },
{ "http://user www gnome org/path/collection/data.ext",
"http://www.gnome.org/path/collection/data.ext", TRUE },
- { "http://www.gnome.org/Path/collection/data.ext",
"http://www.gnome.org/path/collection/data.ext", FALSE },
+ /* 10 */{ "http://www.gnome.org/Path/collection/data.ext",
"http://www.gnome.org/path/collection/data.ext", FALSE },
{ "http://www.gnome.org/path/Collection/data.ext",
"http://www.gnome.org/path/collection/data.ext", FALSE },
{ "http://www.gnome.org/path/collection/Data.ext",
"http://www.gnome.org/path/collection/data.ext", FALSE },
{ "http://www.GNOME.org/path/collection/data.ext",
"http://www.gnome.org/path/collection/data.ext", TRUE },
@@ -48,7 +48,23 @@ test_webdav_href_compare (ETestServerFixture *fixture,
{ "https://www.gnome.org/path", "https://www.gnome.org/path/collection/data.ext", FALSE },
{ "https://www.gnome.org/path/", "https://www.gnome.org/path/collection/data.ext", FALSE },
{ "https://www.gnome.org/path/collection", "https://www.gnome.org/path/collection/data.ext",
FALSE },
- { "https://www.gnome.org/path/collection/", "https://www.gnome.org/path/collection/data.ext",
FALSE }
+ /* 20 */{ "https://www.gnome.org/path/collection/", "https://www.gnome.org/path/collection/data.ext",
FALSE },
+ { "https://www.gnome.org/path/user@no.where/", "http://www.gnome.org/path/user@no.where/",
TRUE },
+ { "https://www.gnome.org/path/user%40no.where/", "http://www.gnome.org/path/user@no.where/",
TRUE },
+ { "https://www.gnome.org/path/user%40no.where/", "http://www.gnome.org/path/user@no.where",
FALSE },
+ { "https://www.gnome.org/user%40no.where/", "http://www.gnome.org/path/user@no.where", FALSE
},
+ { "https://www.gnome.org/user%40no.where", "http://www.gnome.org/user%40no%2Ewhere", TRUE },
+ { "https://www.gnome.org/user%40no.where", "http://www.gnome.org/user%40no%2ewhere", TRUE },
+ { "https://www.gnome.org/path/user%40no.where/path",
"http://www.gnome.org/path/user%40no%2Ewhere/path", TRUE },
+ { "https://user www gnome org/path/user%40no.where/path",
"http://www.gnome.org/path/user%40no%2Ewhere/path", TRUE },
+ { "https://user www gnome org/path/user%40no.where/path",
"http://www.gnome.org/path/user%40no%2Ewhere/path", TRUE },
+ /* 30 */{ "https://user www gnome org/path/user@no.where/path",
"http://www.gnome.org/path/user%40no%2Ewhere/path", TRUE },
+ { "https://user www gnome org/path/user@no.where/path", "http://no www gnome
org/path/user@no%2Ewhere/path", TRUE },
+ { "https://www.gnome.org/path%", "https://www.gnome.org/path%", TRUE },
+ { "https://www.gnome.org/path%g", "https://www.gnome.org/path%g", TRUE },
+ { "https://www.gnome.org/path%ah", "https://www.gnome.org/path%ah", TRUE },
+ { "https://www.gnome.org/path%32", "https://www.gnome.org/path%32", TRUE },
+ { "https://www.gnome.org/path%20%2e", "https://www.gnome.org/path .", TRUE }
};
gint ii;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]