[vlc-commits] url: allow vlc_UrlParse() to return an error
Rémi Denis-Courmont
git at videolan.org
Sat Oct 15 12:38:01 CEST 2016
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Oct 15 13:16:59 2016 +0300| [8535063fe16b511041bef8e140efb421e1b3a8f3] | committer: Rémi Denis-Courmont
url: allow vlc_UrlParse() to return an error
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8535063fe16b511041bef8e140efb421e1b3a8f3
---
include/vlc_url.h | 31 +++++++++++++++++++++++++++----
src/text/url.c | 27 +++++++++++++++++++++------
2 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/include/vlc_url.h b/include/vlc_url.h
index e50685d..405fc4a 100644
--- a/include/vlc_url.h
+++ b/include/vlc_url.h
@@ -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().
diff --git a/src/text/url.c b/src/text/url.c
index 1ea39b4..df16092 100644
--- a/src/text/url.c
+++ b/src/text/url.c
@@ -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)
More information about the vlc-commits
mailing list