From patchwork Mon Jul 27 12:14:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zlomek, Josef" X-Patchwork-Id: 21286 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id A6174447F6E for ; Mon, 27 Jul 2020 15:15:06 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 91B1468B862; Mon, 27 Jul 2020 15:15:06 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from vps.zlomek.net (vps.zlomek.net [195.181.211.90]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BE1EB68B854 for ; Mon, 27 Jul 2020 15:14:59 +0300 (EEST) Received: by vps.zlomek.net (Postfix, from userid 1000) id 2F54E5FE38; Mon, 27 Jul 2020 14:14:59 +0200 (CEST) From: Josef Zlomek To: ffmpeg-devel@ffmpeg.org Date: Mon, 27 Jul 2020 14:14:56 +0200 Message-Id: <20200727121457.7500-1-josef@pex.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH v2 1/2] avformat/url: fix logic for removing ".." path components X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Josef Zlomek MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Fixes: 8814 The logic for removing ".." path components and their corresponding upper directories was reworked. Now, the function trim_double_dot_url splits the path by "/" into components, and processes the components one ny one: - if the component is "..", the last path component in tmp_path is removed - if the component is not empty, it is added to tmp_path The duplicate logic was removed from ff_make_absolute_url. Signed-off-by: Josef Zlomek --- libavformat/url.c | 90 ++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/libavformat/url.c b/libavformat/url.c index 20463a6674..343cbca9b9 100644 --- a/libavformat/url.c +++ b/libavformat/url.c @@ -83,8 +83,10 @@ static void trim_double_dot_url(char *buf, const char *rel, int size) const char *p = rel; const char *root = rel; char tmp_path[MAX_URL_SIZE] = {0, }; - char *sep; - char *node; + int tmp_len = 0; + const char *sep; + const char *next; + int last_is_dir; /* Get the path root of the url which start by "://" */ if (p && (sep = strstr(p, "://"))) { @@ -93,29 +95,45 @@ static void trim_double_dot_url(char *buf, const char *rel, int size) if (!root) return; } + if (*root == '/') + ++root; + + /* Split the path by "/" and remove ".." and its corresponding directory. */ + last_is_dir = 1; + for (p = root; *p; p = next) { + next = strchr(p, '/'); + if (!next) { + next = p + strlen(p); + last_is_dir = 0; + } - /* set new current position if the root node is changed */ - p = root; - while (p && (node = strstr(p, ".."))) { - av_strlcat(tmp_path, p, node - p + strlen(tmp_path)); - p = node + 3; - sep = strrchr(tmp_path, '/'); - if (sep) - sep[0] = '\0'; - else - tmp_path[0] = '\0'; - } + if (next - p == 2 && !strncmp(p, "..", 2)) { + /* remove the last directory from tmp_path */ + while (tmp_len > 0 && tmp_path[--tmp_len] != '/') + ; + tmp_path[tmp_len] = '\0'; + last_is_dir = 1; + } else if (next > p) { + /* copy the current path component to tmp_path (including '/') */ + if (tmp_len) { + av_strlcpy(tmp_path + tmp_len, "/", sizeof(tmp_path) - tmp_len); + ++tmp_len; + } + av_strlcpy(tmp_path + tmp_len, p, FFMIN(sizeof(tmp_path) - tmp_len, + next - p + 1)); + tmp_len += next - p; + tmp_path[tmp_len] = '\0'; + } - if (!av_stristart(p, "/", NULL) && root != rel) - av_strlcat(tmp_path, "/", size); + /* skip "/" */ + while (*next == '/') + ++next; + } + if (last_is_dir && tmp_len) + av_strlcpy(tmp_path + tmp_len, "/", sizeof(tmp_path) - tmp_len); - av_strlcat(tmp_path, p, size); /* start set buf after temp path process. */ av_strlcpy(buf, rel, root - rel + 1); - - if (!av_stristart(tmp_path, "/", NULL) && root != rel) - av_strlcat(buf, "/", size); - av_strlcat(buf, tmp_path, size); } @@ -175,14 +193,11 @@ void ff_make_absolute_url(char *buf, int size, const char *base, root = p = buf; /* Get the path root of the url which start by "://" */ - if (p && strstr(p, "://")) { - sep = strstr(p, "://"); - if (sep) { - sep += 3; - root = strchr(sep, '/'); - if (!root) - return; - } + if (p && (sep = strstr(p, "://"))) { + sep += 3; + root = strchr(sep, '/'); + if (!root) + return; } /* Remove the file name from the base url */ @@ -194,26 +209,7 @@ void ff_make_absolute_url(char *buf, int size, const char *base, sep[1] = '\0'; else buf[0] = '\0'; - while (av_strstart(rel, "..", NULL) && sep) { - /* Remove the path delimiter at the end */ - if (sep > root) { - sep[0] = '\0'; - sep = strrchr(buf, '/'); - } - /* If the next directory name to pop off is "..", break here */ - if (!strcmp(sep ? &sep[1] : buf, "..")) { - /* Readd the slash we just removed */ - av_strlcat(buf, "/", size); - break; - } - /* Cut off the directory name */ - if (sep) - sep[1] = '\0'; - else - buf[0] = '\0'; - rel += 3; - } av_strlcat(buf, rel, size); trim_double_dot_url(tmp_path, buf, size); memset(buf, 0, size); From patchwork Mon Jul 27 12:14:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zlomek, Josef" X-Patchwork-Id: 21285 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id EB426447F6E for ; Mon, 27 Jul 2020 15:15:05 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CCF9468B833; Mon, 27 Jul 2020 15:15:05 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from vps.zlomek.net (vps.zlomek.net [195.181.211.90]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BA17768B7CF for ; Mon, 27 Jul 2020 15:14:59 +0300 (EEST) Received: by vps.zlomek.net (Postfix, from userid 1000) id 3B2F65FE59; Mon, 27 Jul 2020 14:14:59 +0200 (CEST) From: Josef Zlomek To: ffmpeg-devel@ffmpeg.org Date: Mon, 27 Jul 2020 14:14:57 +0200 Message-Id: <20200727121457.7500-2-josef@pex.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200727121457.7500-1-josef@pex.com> References: <20200727121457.7500-1-josef@pex.com> Subject: [FFmpeg-devel] [PATCH v2 2/2] avformat/tests/url: add test cases for handling of double dot X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Josef Zlomek MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Josef Zlomek --- libavformat/tests/url.c | 6 ++++++ tests/ref/fate/url | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/libavformat/tests/url.c b/libavformat/tests/url.c index 1d961a1b43..a27a875892 100644 --- a/libavformat/tests/url.c +++ b/libavformat/tests/url.c @@ -57,6 +57,8 @@ int main(void) test("/foo/bar", "../baz"); test("/foo/bar", "/baz"); test("/foo/bar", "../../../baz"); + test("/foo/bar", ".."); + test("/foo/bar/baz", ".."); test("http://server/foo/", "baz"); test("http://server/foo/bar", "baz"); test("http://server/foo/", "../baz"); @@ -67,6 +69,10 @@ int main(void) test("http://server/foo/bar?param&otherparam", "?someparam"); test("http://server/foo/bar", "//other/url"); test("http://server/foo/bar", "../../../../../other/url"); + test("http://server/foo/bar", "a/b/../c/d/../e../..f/.../other/url/test..mp3"); + test("http://server/foo/bar", "/a/b/../c/d/../e../..f/.../other/url/test..mp3"); + test("http://server/foo/bar", "a/b/../c/d/../e../..f/.../other/url/.."); + test("http://server/foo/bar", "a/b/../c/d/../e../..f/.../other/url/"); test("http://server/foo/bar", "/../../../../../other/url"); test("http://server/foo/bar", "/test/../../../../../other/url"); test("http://server/foo/bar", "/test/../../test/../../../other/url"); diff --git a/tests/ref/fate/url b/tests/ref/fate/url index 533ba2cb1e..aa53e09fab 100644 --- a/tests/ref/fate/url +++ b/tests/ref/fate/url @@ -4,6 +4,8 @@ Testing ff_make_absolute_url: /foo/bar ../baz => /baz /foo/bar /baz => /baz /foo/bar ../../../baz => /baz + /foo/bar .. => / + /foo/bar/baz .. => /foo/ http://server/foo/ baz => http://server/foo/baz http://server/foo/bar baz => http://server/foo/baz http://server/foo/ ../baz => http://server/baz @@ -14,6 +16,10 @@ Testing ff_make_absolute_url: http://server/foo/bar?param&otherparam ?someparam => http://server/foo/bar?someparam http://server/foo/bar //other/url => http://other/url http://server/foo/bar ../../../../../other/url => http://server/other/url + http://server/foo/bar a/b/../c/d/../e../..f/.../other/url/test..mp3 => http://server/foo/a/c/e../..f/.../other/url/test..mp3 + http://server/foo/bar /a/b/../c/d/../e../..f/.../other/url/test..mp3 => http://server/a/c/e../..f/.../other/url/test..mp3 + http://server/foo/bar a/b/../c/d/../e../..f/.../other/url/.. => http://server/foo/a/c/e../..f/.../other/ + http://server/foo/bar a/b/../c/d/../e../..f/.../other/url/ => http://server/foo/a/c/e../..f/.../other/url/ http://server/foo/bar /../../../../../other/url => http://server/other/url http://server/foo/bar /test/../../../../../other/url => http://server/other/url http://server/foo/bar /test/../../test/../../../other/url => http://server/other/url