[vlc-commits] text: add function to fix-up syntactically broken URLs

Rémi Denis-Courmont git at videolan.org
Tue Jul 12 22:22:36 CEST 2016


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Jul 12 23:19:13 2016 +0300| [132aa9315aad4db3413006f88526064ff62954b1] | committer: Rémi Denis-Courmont

text: add function to fix-up syntactically broken URLs

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

 include/vlc_url.h  |   13 +++++++++++++
 src/libvlccore.sym |    1 +
 src/text/url.c     |   40 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

diff --git a/include/vlc_url.h b/include/vlc_url.h
index 4abe0da..8fdd959 100644
--- a/include/vlc_url.h
+++ b/include/vlc_url.h
@@ -100,6 +100,19 @@ VLC_API char *vlc_uri_decode_duplicate(const char *str) VLC_MALLOC;
  */
 VLC_API char *vlc_uri_encode(const char *str) VLC_MALLOC;
 
+/**
+ * Fixes up a URI string.
+ *
+ * Attempts to convert a nul-terminated string into a syntactically valid URI.
+ * If the string is, or may be, a syntactically valid URI, an exact copy is
+ * returned. In any case, the result will only contain URI-safe and URI
+ * delimiter characters (generic delimiters or sub-delimiters) and all percent
+ * signs will be followed by two hexadecimal characters.
+ *
+ * @return a heap-allocated string, or NULL if on out of memory.
+ */
+VLC_API char *vlc_uri_fixup(const char *) VLC_MALLOC;
+
 /** @} */
 
 struct vlc_url_t
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 89e74f8..249bb50 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -252,6 +252,7 @@ vlc_uri2path
 vlc_uri_decode
 vlc_uri_decode_duplicate
 vlc_uri_encode
+vlc_uri_fixup
 mdate
 module_config_free
 module_config_get
diff --git a/src/text/url.c b/src/text/url.c
index 7132463..d3f33b5 100644
--- a/src/text/url.c
+++ b/src/text/url.c
@@ -24,12 +24,16 @@
 #endif
 
 #include <errno.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 #ifdef _WIN32
 # include <io.h>
 #endif
+#ifndef HAVE_OPEN_MEMSTREAM
+# define open_memstream(b,l) (*(b) = NULL, *(l) = 0, NULL)
+#endif
 
 #include <vlc_common.h>
 #include <vlc_url.h>
@@ -482,6 +486,42 @@ void vlc_UrlClean (vlc_url_t *restrict url)
     free (url->psz_buffer);
 }
 
+char *vlc_uri_fixup(const char *str)
+{
+    /* Rule number one is do not change a (potentially) valid URI */
+    if (vlc_uri_component_validate(str, ":/?#[]@"))
+        return strdup(str);
+
+    bool encode_percent = false;
+    for (size_t i = 0; str[i] != '\0'; i++)
+        if (str[i] == '%' && !(isurihex(str[i+1]) && isurihex(str[i+2])))
+        {
+            encode_percent = true;
+            break;
+        }
+
+    char *buf;
+    size_t len;
+    FILE *stream = open_memstream(&buf, &len);
+    if (stream == NULL)
+        return NULL;
+
+    for (size_t i = 0; str[i] != '\0'; i++)
+    {
+        unsigned char c = str[i];
+
+        if (isurisafe(c) || isurisubdelim(c) || (strchr(":/?#[]@", c) != NULL)
+         || (c == '%' && !encode_percent))
+            fputc(c, stream);
+        else
+            fprintf(stream, "%%%02hhX", c);
+    }
+
+    if (fclose(stream))
+        buf = NULL;
+    return buf;
+}
+
 #if defined (HAVE_IDN)
 # include <idna.h>
 #elif defined (_WIN32)



More information about the vlc-commits mailing list