diff options
Diffstat (limited to 'stream')
-rw-r--r-- | stream/stream.c | 4 | ||||
-rw-r--r-- | stream/stream_lavf.c | 25 |
2 files changed, 24 insertions, 5 deletions
diff --git a/stream/stream.c b/stream/stream.c index de362a6ee1..1e1c5eee4e 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -157,7 +157,7 @@ void mp_url_unescape_inplace(char *buf) // ok[0] != '~': additional characters that are not escaped // ok[0] == '~': do not escape anything but these characters // (can't override the unreserved characters, which are -// never escaped, and '%', which is always escaped) +// never escaped) char *mp_url_escape(void *talloc_ctx, const char *s, const char *ok) { int len = strlen(s); @@ -167,7 +167,7 @@ char *mp_url_escape(void *talloc_ctx, const char *s, const char *ok) unsigned char c = s[i]; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || strchr("-._~", c) || - (ok && ((ok[0] != '~') == !!strchr(ok, c)) && c != '%')) + (ok && ((ok[0] != '~') == !!strchr(ok, c)))) { buf[o++] = c; } else { diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c index 286f9effcc..fd83202632 100644 --- a/stream/stream_lavf.c +++ b/stream/stream_lavf.c @@ -20,7 +20,6 @@ #include <libavformat/avio.h> #include <libavutil/opt.h> -#include "config.h" #include "options/options.h" #include "options/path.h" #include "common/msg.h" @@ -34,8 +33,6 @@ #include "misc/bstr.h" #include "talloc.h" -struct stream_lavf_params *stream_lavf_opts; - #define OPT_BASE_STRUCT struct stream_lavf_params struct stream_lavf_params { char **avopts; @@ -49,6 +46,8 @@ const struct m_sub_options stream_lavf_conf = { .size = sizeof(struct stream_lavf_params), }; +static const char *const http_like[]; + static int open_f(stream_t *stream); static struct mp_tags *read_icy(stream_t *stream); @@ -188,6 +187,21 @@ void mp_setup_av_network_options(AVDictionary **dict, struct mpv_global *global, talloc_free(temp); } +// Escape http URLs with unescaped, invalid characters in them. +// libavformat's http protocol does not do this, and a patch to add this +// in a 100% safe case (spaces only) was rejected. +static char *normalize_url(void *ta_parent, const char *filename) +{ + bstr proto = mp_split_proto(bstr0(filename), NULL); + for (int n = 0; http_like[n]; n++) { + if (bstr_equals0(proto, http_like[n])) + // Escape everything but reserved characters. + // Also don't double-scape, so include '%'. + return mp_url_escape(ta_parent, filename, ":/?#[]@!$&'()*+,;=%"); + } + return (char *)filename; +} + static int open_f(stream_t *stream) { struct MPOpts *opts = stream->opts; @@ -238,6 +252,8 @@ static int open_f(stream_t *stream) .opaque = stream, }; + filename = normalize_url(stream, filename); + int err = avio_open2(&avio, filename, flags, &cb, &dict); if (err < 0) { if (err == AVERROR_PROTOCOL_NOT_FOUND) @@ -335,6 +351,9 @@ done: return res; } +static const char *const http_like[] = + {"http", "https", "mmsh", "mmshttp", "httproxy", NULL}; + const stream_info_t stream_info_ffmpeg = { .name = "ffmpeg", .open = open_f, |