[vlc-commits] uri: try to encode brackets in fix-up (fixes #19594)

Rémi Denis-Courmont git at videolan.org
Sun Jul 8 16:57:46 CEST 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Jul  8 17:20:50 2018 +0300| [3ae477f9c998b0e4f2f6f99830aba2f8d3811ddd] | committer: Rémi Denis-Courmont

uri: try to encode brackets in fix-up (fixes #19594)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3ae477f9c998b0e4f2f6f99830aba2f8d3811ddd
---

 src/text/url.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 57 insertions(+), 5 deletions(-)

diff --git a/src/text/url.c b/src/text/url.c
index 6089c6802d..1b7d50fb61 100644
--- a/src/text/url.c
+++ b/src/text/url.c
@@ -863,15 +863,67 @@ static char *vlc_uri_fixup_inner(const char *str, const char *extras)
     return stream.ptr;
 }
 
+static void vlc_uri_putc(struct vlc_memstream *s, int c, const char *extras)
+{
+    if (isurisafe(c) || isurisubdelim(c) || (strchr(extras, c) != NULL))
+        vlc_memstream_putc(s, c);
+    else
+        vlc_memstream_printf(s, "%%%02hhX", c);
+}
+
 char *vlc_uri_fixup(const char *str)
 {
-    static const char extras[] = ":/?#[]@";
+    assert(str != NULL);
+
+    /* If percent sign is consistently followed by two hexadecimal digits,
+     * then URL encoding must be assumed.
+     * Otherwise, the percent sign itself must be URL-encoded.
+     */
+    bool encode_percent = false;
+
+    for (const char *p = str; *p != '\0'; p++)
+        if (p[0] == '%' && !(isurihex(p[1]) && isurihex(p[2])))
+        {
+            encode_percent = true;
+            break;
+        }
+
+    struct vlc_memstream stream;
+    vlc_memstream_open(&stream);
+
+    /* Handle URI scheme */
+    const char *p = str;
+    bool absolute = false;
+    bool encode_brackets = true;
+
+    while (isurialnum(*p) || memchr("+-.", *p, 3) != NULL)
+        vlc_memstream_putc(&stream, *(p++));
+
+    if (p > str && *p == ':')
+    {   /* There is an URI scheme, assume an absolute URI. */
+        vlc_memstream_putc(&stream, *(p++));
+        absolute = true;
+        encode_brackets = false;
+    }
+
+    /* Handle URI authority */
+    if ((absolute || p == str) && strncmp(p, "//", 2) == 0)
+    {
+        vlc_memstream_write(&stream, p, 2);
+        p += 2;
+        encode_brackets = true;
+
+        while (memchr("/?#", *p, 4) == NULL)
+            vlc_uri_putc(&stream, *(p++), "%:[]@" + encode_percent);
+    }
+
+    /* Handle URI path and what follows */
+    const char *extras = encode_brackets ? "%/?#@" : "%:/?#[]@";
 
-    /* Rule number one is do not change a (potentially) valid URI */
-    if (vlc_uri_component_validate(str, extras))
-        return strdup(str);
+    while (*p != '\0')
+        vlc_uri_putc(&stream, *(p++), extras + encode_percent);
 
-    return vlc_uri_fixup_inner(str, extras);
+    return vlc_memstream_close(&stream) ? NULL : stream.ptr;
 }
 
 #if defined (HAVE_IDN)



More information about the vlc-commits mailing list