[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