Commit 8535063f authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

url: allow vlc_UrlParse() to return an error

parent c6cb283f
...@@ -158,13 +158,36 @@ struct vlc_url_t ...@@ -158,13 +158,36 @@ struct vlc_url_t
/** /**
* Splits an URL into parts. * Splits an URL into parts.
* *
* Extracts the following parts from an URI string:
* - scheme (i.e. protocol),
* - user (deprecated),
* - password (also deprecated),
* - host name or IP address literal,
* - port number,
* - path (including the filename preceded by any and all directories)
* - request parameters (excluding the leading question mark '?').
*
* If the host name uses IDN, it is decoded to ASCII, as appropriate for DNS
* resolution. If the host is an IPv6 address literal, brackets are stripped.
*
* Any missing part is set to nul. For historical reasons, the target structure
* is always initialized, even if parsing the URI string fails.
*
* On error, errno is set to one of the following value:
* - ENOMEM in case of memory allocation failure,
* - EINVAL in case of syntax error in the input string.
*
* \bug The URI fragment is discarded if present.
*
* \note This function allocates memory. vlc_UrlClean() must be used free
* associated the allocations, even if the function fails.
*
* \param url structure of URL parts [OUT] * \param url structure of URL parts [OUT]
* \param str nul-terminated URL string to split * \param str nul-terminated URL string to split
* \note Use vlc_UrlClean() to free associated resources * \retval 0 success
* \bug Errors cannot be detected. * \retval -1 failure
* \return nothing
*/ */
VLC_API void vlc_UrlParse(vlc_url_t *url, const char *str); VLC_API int vlc_UrlParse(vlc_url_t *url, const char *str);
/** /**
* Releases resources allocated by vlc_UrlParse(). * Releases resources allocated by vlc_UrlParse().
......
...@@ -325,8 +325,7 @@ static char *vlc_idna_to_ascii (const char *); ...@@ -325,8 +325,7 @@ static char *vlc_idna_to_ascii (const char *);
static bool vlc_uri_component_validate(const char *str, const char *extras) static bool vlc_uri_component_validate(const char *str, const char *extras)
{ {
if (str == NULL) assert(str != NULL);
return false;
for (size_t i = 0; str[i] != '\0'; i++) for (size_t i = 0; str[i] != '\0'; i++)
{ {
...@@ -356,7 +355,7 @@ static bool vlc_uri_path_validate(const char *str) ...@@ -356,7 +355,7 @@ static bool vlc_uri_path_validate(const char *str)
return vlc_uri_component_validate(str, "/@:"); return vlc_uri_component_validate(str, "/@:");
} }
void vlc_UrlParse (vlc_url_t *restrict url, const char *str) int vlc_UrlParse(vlc_url_t *restrict url, const char *str)
{ {
url->psz_protocol = NULL; url->psz_protocol = NULL;
url->psz_username = NULL; url->psz_username = NULL;
...@@ -368,14 +367,18 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str) ...@@ -368,14 +367,18 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str)
url->psz_buffer = NULL; url->psz_buffer = NULL;
if (str == NULL) if (str == NULL)
return; {
errno = EINVAL;
return -1;
}
char *buf = strdup (str); char *buf = strdup (str);
if (unlikely(buf == NULL)) if (unlikely(buf == NULL))
abort (); return -1;
url->psz_buffer = buf; url->psz_buffer = buf;
char *cur = buf, *next; char *cur = buf, *next;
int ret = 0;
/* URI scheme */ /* URI scheme */
next = buf; next = buf;
...@@ -463,10 +466,16 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str) ...@@ -463,10 +466,16 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str)
url->psz_host = vlc_idna_to_ascii (cur); url->psz_host = vlc_idna_to_ascii (cur);
} }
if (url->psz_host == NULL)
ret = -1;
else
if (!vlc_uri_host_validate(url->psz_host)) if (!vlc_uri_host_validate(url->psz_host))
{ {
free(url->psz_host); free(url->psz_host);
url->psz_host = NULL; url->psz_host = NULL;
errno = EINVAL;
ret = -1;
} }
/* Port number */ /* Port number */
...@@ -481,8 +490,14 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str) ...@@ -481,8 +490,14 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str)
url->psz_path = cur; url->psz_path = cur;
} }
if (!vlc_uri_path_validate(url->psz_path)) if (url->psz_path != NULL && !vlc_uri_path_validate(url->psz_path))
{
url->psz_path = NULL; url->psz_path = NULL;
errno = EINVAL;
ret = -1;
}
return ret;
} }
void vlc_UrlClean (vlc_url_t *restrict url) void vlc_UrlClean (vlc_url_t *restrict url)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment