From: Marton Balint Date: Wed, 5 Feb 2020 23:11:05 +0000 (+0100) Subject: avformat/ftp: add support for escaped credentials X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=f204a38e08f937f6204bb21a3d95a23089679fe0;p=ffmpeg avformat/ftp: add support for escaped credentials Properly fixes ticket #7816. Signed-off-by: Marton Balint --- diff --git a/libavformat/Makefile b/libavformat/Makefile index 710cc4d0884..a9972fd99a9 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -592,7 +592,7 @@ OBJS-$(CONFIG_DATA_PROTOCOL) += data_uri.o OBJS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpcrypt.o rtmpdigest.o rtmpdh.o OBJS-$(CONFIG_FFRTMPHTTP_PROTOCOL) += rtmphttp.o OBJS-$(CONFIG_FILE_PROTOCOL) += file.o -OBJS-$(CONFIG_FTP_PROTOCOL) += ftp.o +OBJS-$(CONFIG_FTP_PROTOCOL) += ftp.o urldecode.o OBJS-$(CONFIG_GOPHER_PROTOCOL) += gopher.o OBJS-$(CONFIG_HLS_PROTOCOL) += hlsproto.o OBJS-$(CONFIG_HTTP_PROTOCOL) += http.o httpauth.o urldecode.o diff --git a/libavformat/ftp.c b/libavformat/ftp.c index 97ad80de0ba..860dd7d8dc6 100644 --- a/libavformat/ftp.c +++ b/libavformat/ftp.c @@ -24,6 +24,7 @@ #include "avformat.h" #include "internal.h" #include "url.h" +#include "urldecode.h" #include "libavutil/opt.h" #include "libavutil/bprint.h" @@ -658,7 +659,7 @@ static int ftp_connect(URLContext *h, const char *url) { char proto[10], path[MAX_URL_SIZE], credentials[MAX_URL_SIZE], hostname[MAX_URL_SIZE]; const char *tok_user = NULL, *tok_pass = NULL; - char *end = NULL, *newpath = NULL; + char *newpath = NULL; int err; FTPContext *s = h->priv_data; @@ -675,21 +676,28 @@ static int ftp_connect(URLContext *h, const char *url) path, sizeof(path), url); - tok_user = av_strtok(credentials, ":", &end); - tok_pass = av_strtok(end, ":", &end); - if (!tok_user) { + if (!*credentials) { if (!s->option_user) { tok_user = "anonymous"; tok_pass = av_x_if_null(s->anonymous_password, "nopassword"); } else { tok_user = s->option_user; + tok_pass = s->option_password; } + s->user = av_strdup(tok_user); + s->password = av_strdup(tok_pass); + } else { + char *pass = strchr(credentials, ':'); + if (pass) { + *pass++ = '\0'; + tok_pass = pass; + s->password = ff_urldecode(pass, 0); + } else { + tok_pass = s->option_password; + s->password = av_strdup(tok_pass); + } + s->user = ff_urldecode(credentials, 0); } - if (!tok_pass) { - tok_pass = s->option_password; - } - s->user = av_strdup(tok_user); - s->password = av_strdup(tok_pass); s->hostname = av_strdup(hostname); if (!s->hostname || !s->user || (tok_pass && !s->password)) { return AVERROR(ENOMEM);