[vlc-commits] HLS: resolve relative URLs (/a/b/../c -> /a/c)

Rafaël Carré git at videolan.org
Tue May 21 01:10:06 CEST 2013


vlc | branch: master | Rafaël Carré <funman at videolan.org> | Tue May 21 01:09:34 2013 +0200| [4548301142f5cc33273bf41a3b5b13e9fb2e2ba8] | committer: Rafaël Carré

HLS: resolve relative URLs (/a/b/../c -> /a/c)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4548301142f5cc33273bf41a3b5b13e9fb2e2ba8
---

 modules/stream_filter/httplive.c |   43 ++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 11 deletions(-)

diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
index 5f85e2f..a58baf3 100644
--- a/modules/stream_filter/httplive.c
+++ b/modules/stream_filter/httplive.c
@@ -542,28 +542,49 @@ static int string_to_IV(char *string_hexa, uint8_t iv[AES_BLOCK_SIZE])
 
 static char *relative_URI(const char *psz_url, const char *psz_path)
 {
+    char *ret = NULL;
     assert(psz_url != NULL && psz_path != NULL);
+
+
     //If the path is actually an absolute URL, don't do anything.
     if (strncmp(psz_path, "http", 4) == 0)
         return NULL;
 
-    char *path_separator=NULL;
+    size_t len = strlen(psz_path);
+
+    char *new_url = strdup(psz_url);
+    if (unlikely(!new_url))
+        return NULL;
+
     if( psz_path[0] == '/' ) //Relative URL with absolute path
     {
         //Try to find separator for name and path, try to skip
         //access and first ://
-        path_separator = strchr( &psz_url[8], '/');
+        char *slash = strchr(&new_url[8], '/');
+        if (unlikely(slash == NULL))
+            goto end;
+        *slash = '\0';
     } else {
-        path_separator = strrchr(psz_url, '/');
+        int levels = 0;
+        while(len >= 3 && !strncmp(psz_path, "../", 3)) {
+            psz_path += 3;
+            len -= 3;
+            levels++;
+        }
+        do {
+            char *slash = strrchr(new_url, '/');
+            if (unlikely(slash == NULL))
+                goto end;
+            *slash = '\0';
+        } while (levels--);
     }
-    if ( unlikely( path_separator == NULL ) )
-        return NULL;
-    const size_t url_length = path_separator - psz_url + 1;
-    char    *psz_res = malloc(url_length + strlen(psz_path) + 1);
-    strncpy(psz_res, psz_url, url_length);
-    psz_res[url_length] = 0;
-    strcat(psz_res, psz_path);
-    return psz_res;
+
+    if (asprintf(&ret, "%s/%s", new_url, psz_path) < 0)
+        ret = NULL;
+
+end:
+    free(new_url);
+    return ret;
 }
 
 static int parse_SegmentInformation(hls_stream_t *hls, char *p_read, int *duration)



More information about the vlc-commits mailing list