avformat/ftp: add support for escaped credentials

Properly fixes ticket #7816.

Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
Marton Balint 2020-02-06 00:11:05 +01:00
parent 3004ef1b1b
commit f204a38e08
2 changed files with 18 additions and 10 deletions

View File

@ -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

View File

@ -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);