X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fhls.c;h=fb8795431682fd4d7c4f8078c1acd091789cf432;hb=0c9490609d888ba384798777a3daaf012488ad89;hp=b7ef24290e5e8b782a3c53979dd017af884cadaf;hpb=79b1a24b7ddd20ba68b0bb7a5ad41fe0dd77ffc8;p=ffmpeg diff --git a/libavformat/hls.c b/libavformat/hls.c index b7ef24290e5..fb879543168 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -584,7 +584,7 @@ static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url static void update_options(char **dest, const char *name, void *src) { av_freep(dest); - av_opt_get(src, name, 0, (uint8_t**)dest); + av_opt_get(src, name, AV_OPT_SEARCH_CHILDREN, (uint8_t**)dest); if (*dest && !strlen(*dest)) av_freep(dest); } @@ -594,12 +594,20 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, { HLSContext *c = s->priv_data; AVDictionary *tmp = NULL; - const char *proto_name = avio_find_protocol_name(url); + const char *proto_name = NULL; int ret; av_dict_copy(&tmp, opts, 0); av_dict_copy(&tmp, opts2, 0); + if (av_strstart(url, "crypto", NULL)) { + if (url[6] == '+' || url[6] == ':') + proto_name = avio_find_protocol_name(url + 7); + } + + if (!proto_name) + proto_name = avio_find_protocol_name(url); + if (!proto_name) return AVERROR_INVALIDDATA; @@ -608,13 +616,15 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, return AVERROR_INVALIDDATA; if (!strncmp(proto_name, url, strlen(proto_name)) && url[strlen(proto_name)] == ':') ; + else if (av_strstart(url, "crypto", NULL) && !strncmp(proto_name, url + 7, strlen(proto_name)) && url[7 + strlen(proto_name)] == ':') + ; else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); if (ret >= 0) { // update cookies on http response with setcookies. - void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque; + void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb; update_options(&c->cookies, "cookies", u); av_dict_set(&opts, "cookies", c->cookies, 0); } @@ -1484,9 +1494,19 @@ static int save_avio_options(AVFormatContext *s) return ret; } +static int nested_io_open(AVFormatContext *s, AVIOContext **pb, const char *url, + int flags, AVDictionary **opts) +{ + av_log(s, AV_LOG_ERROR, + "A HLS playlist item '%s' referred to an external file '%s'. " + "Opening this file was forbidden for security reasons\n", + s->filename, url); + return AVERROR(EPERM); +} + static int hls_read_header(AVFormatContext *s) { - void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque; + void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb; HLSContext *c = s->priv_data; int ret = 0, i, j, stream_offset = 0; @@ -1604,9 +1624,10 @@ static int hls_read_header(AVFormatContext *s) goto fail; } pls->ctx->pb = &pls->pb; + pls->ctx->io_open = nested_io_open; pls->stream_offset = stream_offset; - if ((ret = ff_copy_whitelists(pls->ctx, s)) < 0) + if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0) goto fail; ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL);