[FFmpeg-devel] [PATCH v3 1/2] avformat/url: fix logic for removing ".." path components
Zlomek, Josef
josef at pex.com
Tue Jul 28 14:04:01 EEST 2020
I have removed tmp_path from function trim_double_dot_url
I did not change the function ff_make_absolute_url much, as I wanted to
just fix handling of "..".
Josef
On Tue, Jul 28, 2020 at 12:59 PM Steven Liu <lingjiujianke at gmail.com> wrote:
> Zlomek, Josef <josef at pex.com> 于2020年7月28日周二 下午6:58写道:
> >
> > see version 3
> Isn't this version? or maybe your mean is version 4?
> >
> > On Tue, Jul 28, 2020 at 12:37 PM Steven Liu <lingjiujianke at gmail.com>
> wrote:
> >
> > > Josef Zlomek <josef at pex.com> 于2020年7月28日周二 下午12:11写道:
> > > >
> > > > 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 output buffer
> is
> > > removed
> > > > - if the component is not empty, it is added to the output buffer
> > > > No temporary buffers are used anymore.
> > > >
> > > > Also the path containing no '/' after '://' is returned as it is.
> > > >
> > > > The duplicate logic was removed from ff_make_absolute_url.
> > > >
> > > > Signed-off-by: Josef Zlomek <josef at pex.com>
> > > > ---
> > > > libavformat/url.c | 101
> +++++++++++++++++++++++-----------------------
> > > > 1 file changed, 50 insertions(+), 51 deletions(-)
> > > >
> > > > diff --git a/libavformat/url.c b/libavformat/url.c
> > > > index 20463a6674..46a08e88e3 100644
> > > > --- a/libavformat/url.c
> > > > +++ b/libavformat/url.c
> > > > @@ -82,41 +82,62 @@ 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;
> > > > + char *dst;
> > > > + int dst_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, "://"))) {
> > > > sep += 3;
> > > > root = strchr(sep, '/');
> > > > - if (!root)
> > > > + if (!root) {
> > > > + av_strlcpy(buf, rel, size);
> > > > return;
> > > > + }
> > > > }
> > > > + if (*root == '/')
> > > > + ++root;
> > > >
> > > > - /* 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 (!av_stristart(p, "/", NULL) && root != rel)
> > > > - av_strlcat(tmp_path, "/", size);
> > > > -
> > > > - av_strlcat(tmp_path, p, size);
> > > > - /* start set buf after temp path process. */
> > > > + /* Copy the root to the output buffer */
> > > > av_strlcpy(buf, rel, root - rel + 1);
> > > > + size -= root - rel;
> > > > + dst = &buf[root - rel];
> > > > +
> > > > + /* 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;
> > > > + }
> > > >
> > > > - if (!av_stristart(tmp_path, "/", NULL) && root != rel)
> > > > - av_strlcat(buf, "/", size);
> > > > + if (next - p == 2 && !strncmp(p, "..", 2)) {
> > > > + /* remove the last directory from dst */
> > > > + while (dst_len > 0 && dst[--dst_len] != '/')
> > > > + ;
> > > > + dst[dst_len] = '\0';
> > > > + last_is_dir = 1;
> > > > + } else if (next > p) {
> > > > + int len_including_zero;
> > > > + /* copy the current path component to dst (including
> '/') */
> > > > + if (dst_len) {
> > > > + av_strlcpy(dst + dst_len, "/", size - dst_len);
> > > > + ++dst_len;
> > > > + }
> > > > + len_including_zero = FFMIN(size - dst_len, next - p +
> 1);
> > > > + av_strlcpy(dst + dst_len, p, len_including_zero);
> > > > + dst_len += len_including_zero - 1;
> > > > + }
> > > >
> > > > - av_strlcat(buf, tmp_path, size);
> > > > + /* skip "/" */
> > > > + while (*next == '/')
> > > > + ++next;
> > > > + }
> > > > + if (last_is_dir && dst_len)
> > > > + av_strlcpy(dst + dst_len, "/", size - dst_len);
> > > > }
> > > >
> > > > void ff_make_absolute_url(char *buf, int size, const char *base,
> > > > @@ -175,14 +196,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 +212,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);
> > > As Marton said, tmp_path should remove too.
> > >
> > > > 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".
> > > _______________________________________________
> > > 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".
> >
> >
> >
> > --
> > Josef Zlomek
> > _______________________________________________
> > 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".
> _______________________________________________
> 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".
--
Josef Zlomek
More information about the ffmpeg-devel
mailing list