url: add vlc_UrlParseFixup

Refs #18991
This commit is contained in:
Thomas Guillem 2017-12-04 13:56:41 +01:00
parent 5094c8e334
commit ba9809c8b8
3 changed files with 60 additions and 6 deletions

View File

@ -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().
*/

View File

@ -235,6 +235,7 @@ libvlc_MetadataRequest
libvlc_MetadataCancel
libvlc_ArtRequest
vlc_UrlParse
vlc_UrlParseFixup
vlc_UrlClean
vlc_path2uri
vlc_uri2path

View File

@ -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 <idna.h>
#elif defined (_WIN32)