vlc | branch: master | Rémi Denis-Courmont <[email protected]> | 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) _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
