From ba9809c8b83163098c097d4275ddc6e3b662c412 Mon Sep 17 00:00:00 2001 From: Thomas Guillem Date: Mon, 4 Dec 2017 13:56:41 +0100 Subject: [PATCH] url: add vlc_UrlParseFixup Refs #18991 --- include/vlc_url.h | 9 ++++++++ src/libvlccore.sym | 1 + src/text/url.c | 56 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/include/vlc_url.h b/include/vlc_url.h index 5a20c27edc..e13b7a5abb 100644 --- a/include/vlc_url.h +++ b/include/vlc_url.h @@ -153,6 +153,7 @@ struct vlc_url_t char *psz_option; char *psz_buffer; /* to be freed */ + char *psz_pathbuffer; /* to be freed */ }; /** @@ -191,6 +192,14 @@ struct vlc_url_t */ VLC_API int vlc_UrlParse(vlc_url_t *url, const char *str); +/** + * Parses an URI or IRI and fix up the path part. + * + * \see vlc_UrlParse + * \see vlc_uri_fixup + */ +VLC_API int vlc_UrlParseFixup(vlc_url_t *url, const char *str); + /** * Releases resources allocated by vlc_UrlParse(). */ diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 3e0d23fdf0..a15ba0d923 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -235,6 +235,7 @@ libvlc_MetadataRequest libvlc_MetadataCancel libvlc_ArtRequest vlc_UrlParse +vlc_UrlParseFixup vlc_UrlClean vlc_path2uri vlc_uri2path diff --git a/src/text/url.c b/src/text/url.c index dc983c8861..1c86bedb58 100644 --- a/src/text/url.c +++ b/src/text/url.c @@ -401,7 +401,7 @@ static bool vlc_uri_path_validate(const char *str) return vlc_uri_component_validate(str, "/@:"); } -int vlc_UrlParse(vlc_url_t *restrict url, const char *str) +static int vlc_UrlParseInner(vlc_url_t *restrict url, const char *str) { url->psz_protocol = NULL; url->psz_username = NULL; @@ -411,6 +411,7 @@ int vlc_UrlParse(vlc_url_t *restrict url, const char *str) url->psz_path = NULL; url->psz_option = NULL; url->psz_buffer = NULL; + url->psz_pathbuffer = NULL; if (str == NULL) { @@ -547,13 +548,46 @@ int vlc_UrlParse(vlc_url_t *restrict url, const char *str) url->psz_path = cur; } + return ret; +} + +int vlc_UrlParse(vlc_url_t *url, const char *str) +{ + int ret = vlc_UrlParseInner(url, str); + if (url->psz_path != NULL && !vlc_uri_path_validate(url->psz_path)) { url->psz_path = NULL; errno = EINVAL; ret = -1; } + return ret; +} +static char *vlc_uri_fixup_inner(const char *str, const char *extras); + +int vlc_UrlParseFixup(vlc_url_t *url, const char *str) +{ + int ret = vlc_UrlParseInner(url, str); + + static const char pathextras[] = "/@:"; + + if (url->psz_path != NULL + && !vlc_uri_component_validate(url->psz_path, pathextras)) + { + url->psz_pathbuffer = vlc_uri_fixup_inner(url->psz_path, pathextras); + if (url->psz_pathbuffer == NULL) + { + url->psz_path = NULL; + errno = ENOMEM; + ret = -1; + } + else + { + url->psz_path = url->psz_pathbuffer; + assert(vlc_uri_path_validate(url->psz_path)); + } + } return ret; } @@ -561,6 +595,7 @@ void vlc_UrlClean (vlc_url_t *restrict url) { free (url->psz_host); free (url->psz_buffer); + free (url->psz_pathbuffer); } /** @@ -793,11 +828,9 @@ error: return ret; } -char *vlc_uri_fixup(const char *str) +static char *vlc_uri_fixup_inner(const char *str, const char *extras) { - /* Rule number one is do not change a (potentially) valid URI */ - if (vlc_uri_component_validate(str, ":/?#[]@")) - return strdup(str); + assert(str && extras); bool encode_percent = false; for (size_t i = 0; str[i] != '\0'; i++) @@ -815,7 +848,7 @@ char *vlc_uri_fixup(const char *str) { unsigned char c = str[i]; - if (isurisafe(c) || isurisubdelim(c) || (strchr(":/?#[]@", c) != NULL) + if (isurisafe(c) || isurisubdelim(c) || (strchr(extras, c) != NULL) || (c == '%' && !encode_percent)) vlc_memstream_putc(&stream, c); else @@ -827,6 +860,17 @@ char *vlc_uri_fixup(const char *str) return stream.ptr; } +char *vlc_uri_fixup(const char *str) +{ + static const char extras[] = ":/?#[]@"; + + /* Rule number one is do not change a (potentially) valid URI */ + if (vlc_uri_component_validate(str, extras)) + return strdup(str); + + return vlc_uri_fixup_inner(str, extras); +} + #if defined (HAVE_IDN) # include #elif defined (_WIN32)