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
/**
* 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 str nul-terminated URL string to split
* \note Use vlc_UrlClean() to free associated resources
* \bug Errors cannot be detected.
* \return nothing
* \retval 0 success
* \retval -1 failure
*/
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().
......
......@@ -325,8 +325,7 @@ static char *vlc_idna_to_ascii (const char *);
static bool vlc_uri_component_validate(const char *str, const char *extras)
{
if (str == NULL)
return false;
assert(str != NULL);
for (size_t i = 0; str[i] != '\0'; i++)
{
......@@ -356,7 +355,7 @@ static bool vlc_uri_path_validate(const char *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_username = NULL;
......@@ -368,14 +367,18 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str)
url->psz_buffer = NULL;
if (str == NULL)
return;
{
errno = EINVAL;
return -1;
}
char *buf = strdup (str);
if (unlikely(buf == NULL))
abort ();
return -1;
url->psz_buffer = buf;
char *cur = buf, *next;
int ret = 0;
/* URI scheme */
next = buf;
......@@ -463,10 +466,16 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str)
url->psz_host = vlc_idna_to_ascii (cur);
}
if (url->psz_host == NULL)
ret = -1;
else
if (!vlc_uri_host_validate(url->psz_host))
{
free(url->psz_host);
url->psz_host = NULL;
errno = EINVAL;
ret = -1;
}
/* Port number */
......@@ -481,8 +490,14 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str)
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;
errno = EINVAL;
ret = -1;
}
return ret;
}
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