[FFmpeg-devel] [PATCH v2 1/2] avformat/url: fix logic for removing ".." path components
Steven Liu
lingjiujianke at gmail.com
Mon Jul 27 16:09:54 EEST 2020
Josef Zlomek <josef at pex.com> 于2020年7月27日周一 下午8:15写道:
>
> 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 <josef at pex.com>
> ---
> 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);
> --
> 2.17.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
I have resubmit new patch v3 to the old thread, you can try that.
Thanks
Steven
More information about the ffmpeg-devel
mailing list