From: Michael Niedermayer <mich...@niedermayer.cc> TODO: Docs TODO: version bump
Note to maintainers: update tools Note, testing and checking for missing changes is needed Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> --- ffmpeg_opt.c | 4 ++-- libavdevice/lavfi.c | 2 +- libavformat/async.c | 2 +- libavformat/avformat.h | 7 ++++++ libavformat/avio.c | 44 ++++++++++++++++++++++++++++++++++--- libavformat/avio.h | 4 ++++ libavformat/aviobuf.c | 16 ++++++++++---- libavformat/cache.c | 3 ++- libavformat/concat.c | 5 +++-- libavformat/crypto.c | 5 +++-- libavformat/dashenc.c | 9 ++++---- libavformat/ftp.c | 10 +++++---- libavformat/gopher.c | 4 ++-- libavformat/hdsenc.c | 12 +++++----- libavformat/hls.c | 8 ++++--- libavformat/hlsenc.c | 28 +++++++++++------------ libavformat/hlsproto.c | 10 +++++---- libavformat/http.c | 16 +++++++++----- libavformat/icecast.c | 3 ++- libavformat/md5proto.c | 5 +++-- libavformat/mmst.c | 5 +++-- libavformat/movenc.c | 2 +- libavformat/options_table.h | 1 + libavformat/rtmpcrypt.c | 5 +++-- libavformat/rtmpproto.c | 10 +++++---- libavformat/rtpproto.c | 10 ++++++--- libavformat/rtsp.c | 20 ++++++++--------- libavformat/rtspdec.c | 10 +++++---- libavformat/sapdec.c | 5 +++-- libavformat/sapenc.c | 9 +++++--- libavformat/segment.c | 16 +++++++------- libavformat/smoothstreamingenc.c | 18 ++++++++------- libavformat/srtpproto.c | 3 ++- libavformat/subfile.c | 3 ++- libavformat/tee.c | 4 +++- libavformat/tls.c | 5 +++-- libavformat/tls_securetransport.c | 5 +++-- libavformat/url.h | 5 +++++ libavformat/utils.c | 13 +++++++---- libavformat/webm_chunk.c | 7 +++--- 40 files changed, 230 insertions(+), 123 deletions(-) diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 9b341cf..54a7472 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -1129,12 +1129,12 @@ static int get_preset_file_2(const char *preset_name, const char *codec_name, AV if (codec_name) { snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i], i != 1 ? "" : "/.avconv", codec_name, preset_name); - ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL); + ret = avio_open_whitelist(s, filename, AVIO_FLAG_READ, &int_cb, NULL, "file"); } if (ret < 0) { snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i], i != 1 ? "" : "/.avconv", preset_name); - ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL); + ret = avio_open_whitelist(s, filename, AVIO_FLAG_READ, &int_cb, NULL, "file"); } } return ret; diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c index 077879e..85027da 100644 --- a/libavdevice/lavfi.c +++ b/libavdevice/lavfi.c @@ -144,7 +144,7 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx) if (lavfi->graph_filename) { AVBPrint graph_file_pb; AVIOContext *avio = NULL; - ret = avio_open(&avio, lavfi->graph_filename, AVIO_FLAG_READ); + ret = avio_open_whitelist(&avio, lavfi->graph_filename, AVIO_FLAG_READ, &avctx->interrupt_callback, NULL, avctx->protocol_whitelist); if (ret < 0) goto end; av_bprint_init(&graph_file_pb, 0, AV_BPRINT_SIZE_UNLIMITED); diff --git a/libavformat/async.c b/libavformat/async.c index 4308c4b..138ef13 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -251,7 +251,7 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** /* wrap interrupt callback */ c->interrupt_callback = h->interrupt_callback; - ret = ffurl_open(&c->inner, arg, flags, &interrupt_callback, options); + ret = ffurl_open_whitelist(&c->inner, arg, flags, &interrupt_callback, options, h->protocol_whitelist); if (ret != 0) { av_log(h, AV_LOG_ERROR, "ffurl_open failed : %s, %s\n", av_err2str(ret), arg); goto url_fail; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 4964263..2fb9130 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1815,6 +1815,13 @@ typedef struct AVFormatContext { * Demuxing: Set by user. */ int (*open_cb)(struct AVFormatContext *s, AVIOContext **p, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options); + + /** + * ',' separated list of allowed protocols. + * - encoding: unused + * - decoding: set by user through AVOptions (NO direct access) + */ + char *protocol_whitelist; } AVFormatContext; int av_format_get_probe_score(const AVFormatContext *s); diff --git a/libavformat/avio.c b/libavformat/avio.c index 05d0557..ad9712d 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -73,7 +73,13 @@ static const AVClass *urlcontext_child_class_next(const AVClass *prev) return NULL; } -static const AVOption options[] = { { NULL } }; +#define OFFSET(x) offsetof(URLContext,x) +#define E AV_OPT_FLAG_ENCODING_PARAM +#define D AV_OPT_FLAG_DECODING_PARAM +static const AVOption options[] = { + {"protocol_whitelist", "List of protocols that are allowed to be used", OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, + { NULL } +}; const AVClass ffurl_context_class = { .class_name = "URLContext", .item_name = urlcontext_to_name, @@ -296,18 +302,43 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags, return AVERROR_PROTOCOL_NOT_FOUND; } -int ffurl_open(URLContext **puc, const char *filename, int flags, - const AVIOInterruptCB *int_cb, AVDictionary **options) +int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist) { + AVDictionary *tmp_opts = NULL; + AVDictionaryEntry *e; int ret = ffurl_alloc(puc, filename, flags, int_cb); if (ret < 0) return ret; if (options && (*puc)->prot->priv_data_class && (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0) goto fail; + + if (!options) + options = &tmp_opts; + + av_assert0(!whitelist || + !(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) || + !strcmp(whitelist, e->value)); + + if ((ret = av_dict_set(options, "protocol_whitelist", whitelist, 0)) < 0) + goto fail; + if ((ret = av_opt_set_dict(*puc, options)) < 0) goto fail; + + whitelist = (*puc)->protocol_whitelist; + if (whitelist && av_match_list((*puc)->prot->name, whitelist, ',') <= 0) { + av_log(*puc, AV_LOG_ERROR, "Protocol not on whitelist!\n"); + ret = AVERROR(EINVAL); + goto fail; + } + if ((ret = av_dict_set(options, "protocol_whitelist", whitelist, 0)) < 0) + goto fail; + ret = ffurl_connect(*puc, options); + av_dict_set(options, "protocol_whitelist", NULL, 0); + if (!ret) return 0; fail: @@ -316,6 +347,13 @@ fail: return ret; } +int ffurl_open(URLContext **puc, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options) +{ + return ffurl_open_whitelist(puc, filename, flags, + int_cb, options, NULL); +} + static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf, int size, int size_min, int (*transfer_func)(URLContext *h, diff --git a/libavformat/avio.h b/libavformat/avio.h index c3c0b73..26c39b2 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -595,6 +595,10 @@ int avio_open(AVIOContext **s, const char *url, int flags); int avio_open2(AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options); +int avio_open_whitelist(AVIOContext **s, const char *url, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options, + const char *whitelist); + /** * Close the resource accessed by the AVIOContext s and free it. * This function can only be used if s was opened by avio_open(). diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index b56d113..041210a 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -919,13 +919,15 @@ int avio_open(AVIOContext **s, const char *filename, int flags) return avio_open2(s, filename, flags, NULL, NULL); } -int avio_open2(AVIOContext **s, const char *filename, int flags, - const AVIOInterruptCB *int_cb, AVDictionary **options) +int avio_open_whitelist(AVIOContext **s, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options, + const char *whitelist + ) { URLContext *h; int err; - err = ffurl_open(&h, filename, flags, int_cb, options); + err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist); if (err < 0) return err; err = ffio_fdopen(s, h); @@ -936,10 +938,16 @@ int avio_open2(AVIOContext **s, const char *filename, int flags, return 0; } +int avio_open2(AVIOContext **s, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options) +{ + return avio_open_whitelist(s, filename, flags, int_cb, options, NULL); +} + int ffio_open2_wrapper(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options) { - return avio_open2(pb, url, flags, int_cb, options); + return avio_open_whitelist(pb, url, flags, int_cb, options, s->protocol_whitelist); } int avio_close(AVIOContext *s) diff --git a/libavformat/cache.c b/libavformat/cache.c index d41161d..8e8b9e8 100644 --- a/libavformat/cache.c +++ b/libavformat/cache.c @@ -86,7 +86,8 @@ static int cache_open(URLContext *h, const char *arg, int flags, AVDictionary ** unlink(buffername); av_freep(&buffername); - return ffurl_open(&c->inner, arg, flags, &h->interrupt_callback, options); + return ffurl_open_whitelist(&c->inner, arg, flags, &h->interrupt_callback, + options, h->protocol_whitelist); } static int add_entry(URLContext *h, const unsigned char *buf, int size) diff --git a/libavformat/concat.c b/libavformat/concat.c index 7bcc279..b2fa30d 100644 --- a/libavformat/concat.c +++ b/libavformat/concat.c @@ -97,8 +97,9 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags) uri += len + strspn(uri + len, AV_CAT_SEPARATOR); /* creating URLContext */ - if ((err = ffurl_open(&uc, node_uri, flags, - &h->interrupt_callback, NULL)) < 0) + err = ffurl_open_whitelist(&uc, node_uri, flags, + &h->interrupt_callback, NULL, h->protocol_whitelist); + if (err < 0) break; /* creating size */ diff --git a/libavformat/crypto.c b/libavformat/crypto.c index f56ee4e..b1871fe 100644 --- a/libavformat/crypto.c +++ b/libavformat/crypto.c @@ -136,8 +136,9 @@ static int crypto_open2(URLContext *h, const char *uri, int flags, AVDictionary goto err; } - if ((ret = ffurl_open(&c->hd, nested_url, flags, - &h->interrupt_callback, options)) < 0) { + if ((ret = ffurl_open_whitelist(&c->hd, nested_url, flags, + &h->interrupt_callback, options, + h->protocol_whitelist)) < 0) { av_log(h, AV_LOG_ERROR, "Unable to open resource: %s\n", nested_url); goto err; } diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 4509ee4..734ac1f 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -448,7 +448,8 @@ static int write_manifest(AVFormatContext *s, int final) AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0); snprintf(temp_filename, sizeof(temp_filename), "%s.tmp", s->filename); - ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); + ret = avio_open_whitelist(&out, temp_filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename); return ret; @@ -648,7 +649,7 @@ static int dash_write_header(AVFormatContext *s) dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), c->init_seg_name, i, 0, os->bit_rate, 0); } snprintf(filename, sizeof(filename), "%s%s", c->dirname, os->initfile); - ret = ffurl_open(&os->out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); + ret = ffurl_open_whitelist(&os->out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) goto fail; os->init_start_pos = 0; @@ -755,7 +756,7 @@ static void find_index_range(AVFormatContext *s, const char *full_path, URLContext *fd; int ret; - ret = ffurl_open(&fd, full_path, AVIO_FLAG_READ, &s->interrupt_callback, NULL); + ret = ffurl_open_whitelist(&fd, full_path, AVIO_FLAG_READ, &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) return; if (ffurl_seek(fd, pos, SEEK_SET) != pos) { @@ -838,7 +839,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) dash_fill_tmpl_params(filename, sizeof(filename), c->media_seg_name, i, os->segment_index, os->bit_rate, os->start_pts); snprintf(full_path, sizeof(full_path), "%s%s", c->dirname, filename); snprintf(temp_path, sizeof(temp_path), "%s.tmp", full_path); - ret = ffurl_open(&os->out, temp_path, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); + ret = ffurl_open_whitelist(&os->out, temp_path, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) break; write_styp(os->ctx->pb); diff --git a/libavformat/ftp.c b/libavformat/ftp.c index 4526dd7..1370ced 100644 --- a/libavformat/ftp.c +++ b/libavformat/ftp.c @@ -537,8 +537,9 @@ static int ftp_connect_control_connection(URLContext *h) if (s->rw_timeout != -1) { av_dict_set_int(&opts, "timeout", s->rw_timeout, 0); } /* if option is not given, don't pass it and let tcp use its own default */ - err = ffurl_open(&s->conn_control, buf, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, &opts); + err = ffurl_open_whitelist(&s->conn_control, buf, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, &opts, + h->protocol_whitelist); av_dict_free(&opts); if (err < 0) { av_log(h, AV_LOG_ERROR, "Cannot open control connection\n"); @@ -590,8 +591,9 @@ static int ftp_connect_data_connection(URLContext *h) if (s->rw_timeout != -1) { av_dict_set_int(&opts, "timeout", s->rw_timeout, 0); } /* if option is not given, don't pass it and let tcp use its own default */ - err = ffurl_open(&s->conn_data, buf, h->flags, - &h->interrupt_callback, &opts); + err = ffurl_open_whitelist(&s->conn_data, buf, h->flags, + &h->interrupt_callback, &opts, + h->protocol_whitelist); av_dict_free(&opts); if (err < 0) return err; diff --git a/libavformat/gopher.c b/libavformat/gopher.c index a5340d2..835ad7f 100644 --- a/libavformat/gopher.c +++ b/libavformat/gopher.c @@ -93,8 +93,8 @@ static int gopher_open(URLContext *h, const char *uri, int flags) ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); s->hd = NULL; - err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, NULL); + err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, NULL, h->protocol_whitelist); if (err < 0) goto fail; diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c index 7670185..e9a03a8 100644 --- a/libavformat/hdsenc.c +++ b/libavformat/hdsenc.c @@ -169,8 +169,8 @@ static int write_manifest(AVFormatContext *s, int final) snprintf(filename, sizeof(filename), "%s/index.f4m", s->filename); snprintf(temp_filename, sizeof(temp_filename), "%s/index.f4m.tmp", s->filename); - ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL); + ret = avio_open_whitelist(&out, temp_filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename); return ret; @@ -238,8 +238,8 @@ static int write_abst(AVFormatContext *s, OutputStream *os, int final) "%s/stream%d.abst", s->filename, index); snprintf(temp_filename, sizeof(temp_filename), "%s/stream%d.abst.tmp", s->filename, index); - ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL); + ret = avio_open_whitelist(&out, temp_filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename); return ret; @@ -289,8 +289,8 @@ static int write_abst(AVFormatContext *s, OutputStream *os, int final) static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts) { int ret, i; - ret = avio_open2(&os->out, os->temp_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL); + ret = avio_open_whitelist(&os->out, os->temp_filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) return ret; avio_wb32(os->out, 0); diff --git a/libavformat/hls.c b/libavformat/hls.c index 846d884..a800cb0 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -180,6 +180,7 @@ struct variant { typedef struct HLSContext { AVClass *class; + AVFormatContext *avfmt; int n_variants; struct variant **variants; int n_playlists; @@ -626,7 +627,7 @@ static int open_url(HLSContext *c, URLContext **uc, const char *url, AVDictionar av_dict_copy(&tmp, c->avio_opts, 0); av_dict_copy(&tmp, opts, 0); - ret = ffurl_open(uc, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); + ret = ffurl_open_whitelist(uc, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp, c->avfmt->protocol_whitelist); if( ret >= 0) { // update cookies on http response with setcookies. URLContext *u = *uc; @@ -671,8 +672,8 @@ static int parse_playlist(HLSContext *c, const char *url, av_dict_set(&opts, "headers", c->headers, 0); av_dict_set(&opts, "http_proxy", c->http_proxy, 0); - ret = avio_open2(&in, url, AVIO_FLAG_READ, - c->interrupt_callback, &opts); + ret = avio_open_whitelist(&in, url, AVIO_FLAG_READ, + c->interrupt_callback, &opts, c->avfmt->protocol_whitelist); av_dict_free(&opts); if (ret < 0) return ret; @@ -1509,6 +1510,7 @@ static int hls_read_header(AVFormatContext *s) HLSContext *c = s->priv_data; int ret = 0, i, j, stream_offset = 0; + c->avfmt = s; c->interrupt_callback = &s->interrupt_callback; c->strict_std_compliance = s->strict_std_compliance; diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index f2d7a52..983db30 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -209,8 +209,8 @@ static int hls_encryption_start(AVFormatContext *s) AVIOContext *pb; uint8_t key[KEYSIZE]; - if ((ret = avio_open2(&pb, hls->key_info_file, AVIO_FLAG_READ, - &s->interrupt_callback, NULL)) < 0) { + if ((ret = avio_open_whitelist(&pb, hls->key_info_file, AVIO_FLAG_READ, + &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { av_log(hls, AV_LOG_ERROR, "error opening key info file %s\n", hls->key_info_file); return ret; @@ -237,8 +237,8 @@ static int hls_encryption_start(AVFormatContext *s) return AVERROR(EINVAL); } - if ((ret = avio_open2(&pb, hls->key_file, AVIO_FLAG_READ, - &s->interrupt_callback, NULL)) < 0) { + if ((ret = avio_open_whitelist(&pb, hls->key_file, AVIO_FLAG_READ, + &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", hls->key_file); return ret; } @@ -394,8 +394,8 @@ static int hls_window(AVFormatContext *s, int last) set_http_options(&options, hls); snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->filename); - if ((ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, &options)) < 0) + if ((ret = avio_open_whitelist(&out, temp_filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, &options, s->protocol_whitelist)) < 0) goto fail; for (en = hls->segments; en; en = en->next) { @@ -445,8 +445,8 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-ENDLIST\n"); if( hls->vtt_m3u8_name ) { - if ((ret = avio_open2(&sub_out, hls->vtt_m3u8_name, AVIO_FLAG_WRITE, - &s->interrupt_callback, &options)) < 0) + if ((ret = avio_open_whitelist(&sub_out, hls->vtt_m3u8_name, AVIO_FLAG_WRITE, + &s->interrupt_callback, &options, s->protocol_whitelist)) < 0) goto fail; avio_printf(sub_out, "#EXTM3U\n"); avio_printf(sub_out, "#EXT-X-VERSION:%d\n", version); @@ -542,20 +542,20 @@ static int hls_start(AVFormatContext *s) err = AVERROR(ENOMEM); goto fail; } - err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, &options); + err = avio_open_whitelist(&oc->pb, filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, &options, s->protocol_whitelist); av_free(filename); av_dict_free(&options); if (err < 0) return err; } else - if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, &options)) < 0) + if ((err = avio_open_whitelist(&oc->pb, oc->filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, &options, s->protocol_whitelist)) < 0) goto fail; if (c->vtt_basename) { set_http_options(&options, c); - if ((err = avio_open2(&vtt_oc->pb, vtt_oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, &options)) < 0) + if ((err = avio_open_whitelist(&vtt_oc->pb, vtt_oc->filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, &options, s->protocol_whitelist)) < 0) goto fail; } av_dict_free(&options); diff --git a/libavformat/hlsproto.c b/libavformat/hlsproto.c index 92843df..bb8f6db 100644 --- a/libavformat/hlsproto.c +++ b/libavformat/hlsproto.c @@ -116,8 +116,9 @@ static int parse_playlist(URLContext *h, const char *url) char line[1024]; const char *ptr; - if ((ret = avio_open2(&in, url, AVIO_FLAG_READ, - &h->interrupt_callback, NULL)) < 0) + if ((ret = avio_open_whitelist(&in, url, AVIO_FLAG_READ, + &h->interrupt_callback, NULL, + h->protocol_whitelist)) < 0) return ret; read_chomp_line(in, line, sizeof(line)); @@ -303,8 +304,9 @@ retry: } url = s->segments[s->cur_seq_no - s->start_seq_no]->url, av_log(h, AV_LOG_DEBUG, "opening %s\n", url); - ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ, - &h->interrupt_callback, NULL); + ret = ffurl_open_whitelist(&s->seg_hd, url, AVIO_FLAG_READ, + &h->interrupt_callback, NULL, + h->protocol_whitelist); if (ret < 0) { if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; diff --git a/libavformat/http.c b/libavformat/http.c index a1f1807..96561e4 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -219,8 +219,9 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL); if (!s->hd) { - err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, options); + err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, options, + h->protocol_whitelist); if (err < 0) return err; } @@ -453,8 +454,10 @@ static int http_listen(URLContext *h, const char *uri, int flags, NULL); if ((ret = av_dict_set_int(options, "listen", s->listen, 0)) < 0) goto fail; - if ((ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, options)) < 0) + if ((ret = ffurl_open_whitelist(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, options, + h->protocol_whitelist + )) < 0) goto fail; s->handshake_step = LOWER_PROTO; if (s->listen == HTTP_SINGLE) { /* single client */ @@ -1575,8 +1578,9 @@ static int http_proxy_open(URLContext *h, const char *uri, int flags) ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port, NULL); redo: - ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, NULL); + ret = ffurl_open_whitelist(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, NULL, + h->protocol_whitelist); if (ret < 0) return ret; diff --git a/libavformat/icecast.c b/libavformat/icecast.c index f4dca6f..a3b9a36 100644 --- a/libavformat/icecast.c +++ b/libavformat/icecast.c @@ -164,7 +164,8 @@ static int icecast_open(URLContext *h, const char *uri, int flags) // Build new URI for passing to http protocol ff_url_join(h_url, sizeof(h_url), "http", auth, host, port, "%s", path); // Finally open http proto handler - ret = ffurl_open(&s->hd, h_url, AVIO_FLAG_READ_WRITE, NULL, &opt_dict); + ret = ffurl_open_whitelist(&s->hd, h_url, AVIO_FLAG_READ_WRITE, NULL, + &opt_dict, h->protocol_whitelist); cleanup: av_freep(&user); diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c index 6af0a6e..9a092e4 100644 --- a/libavformat/md5proto.c +++ b/libavformat/md5proto.c @@ -69,8 +69,9 @@ static int md5_close(URLContext *h) av_strstart(filename, "md5:", &filename); if (*filename) { - err = ffurl_open(&out, filename, AVIO_FLAG_WRITE, - &h->interrupt_callback, NULL); + err = ffurl_open_whitelist(&out, filename, AVIO_FLAG_WRITE, + &h->interrupt_callback, NULL, + h->protocol_whitelist); if (err) return err; err = ffurl_write(out, buf, i*2+1); diff --git a/libavformat/mmst.c b/libavformat/mmst.c index aa245ea..21cf2a6 100644 --- a/libavformat/mmst.c +++ b/libavformat/mmst.c @@ -528,8 +528,9 @@ static int mms_open(URLContext *h, const char *uri, int flags) // establish tcp connection. ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL); - err = ffurl_open(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, NULL); + err = ffurl_open_whitelist(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, NULL, + h->protocol_whitelist); if (err) goto fail; diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 1aff5c5..41f9cca 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -5534,7 +5534,7 @@ static int shift_data(AVFormatContext *s) * writing, so we re-open the same output, but for reading. It also avoids * a read/seek/write/seek back and forth. */ avio_flush(s->pb); - ret = avio_open(&read_pb, s->filename, AVIO_FLAG_READ); + ret = avio_open_whitelist(&read_pb, s->filename, AVIO_FLAG_READ, &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for " "the second pass (faststart)\n", s->filename); diff --git a/libavformat/options_table.h b/libavformat/options_table.h index cc64bea..8926fe5 100644 --- a/libavformat/options_table.h +++ b/libavformat/options_table.h @@ -100,6 +100,7 @@ static const AVOption avformat_options[] = { {"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = ", "}, CHAR_MIN, CHAR_MAX, D|E}, {"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, {"format_whitelist", "List of demuxers that are allowed to be used", OFFSET(format_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, +{"protocol_whitelist", "List of protocols that are allowed to be used", OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, {NULL}, }; diff --git a/libavformat/rtmpcrypt.c b/libavformat/rtmpcrypt.c index a0c914f..811c74c 100644 --- a/libavformat/rtmpcrypt.c +++ b/libavformat/rtmpcrypt.c @@ -264,8 +264,9 @@ static int rtmpe_open(URLContext *h, const char *uri, int flags) } /* open the tcp or ffrtmphttp connection */ - if ((ret = ffurl_open(&rt->stream, url, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, NULL)) < 0) { + if ((ret = ffurl_open_whitelist(&rt->stream, url, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, NULL, + h->protocol_whitelist)) < 0) { rtmpe_close(h); return ret; } diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index bd1c38a..a5485ab 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1118,8 +1118,9 @@ static int rtmp_calc_swfhash(URLContext *s) int ret = 0; /* Get the SWF player file. */ - if ((ret = ffurl_open(&stream, rt->swfverify, AVIO_FLAG_READ, - &s->interrupt_callback, NULL)) < 0) { + if ((ret = ffurl_open_whitelist(&stream, rt->swfverify, AVIO_FLAG_READ, + &s->interrupt_callback, NULL, + s->protocol_whitelist)) < 0) { av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify); goto fail; } @@ -2647,8 +2648,9 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) } reconnect: - if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, &opts)) < 0) { + if ((ret = ffurl_open_whitelist(&rt->stream, buf, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, &opts, + s->protocol_whitelist)) < 0) { av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf); goto fail; } diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index e0aa23e..538a7b2 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -380,7 +380,8 @@ static int rtp_open(URLContext *h, const char *uri, int flags) build_udp_url(s, buf, sizeof(buf), hostname, rtp_port, s->local_rtpport, sources, block); - if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0) + if (ffurl_open_whitelist(&s->rtp_hd, buf, flags, &h->interrupt_callback, + NULL, h->protocol_whitelist) < 0) goto fail; s->local_rtpport = ff_udp_get_local_port(s->rtp_hd); if(s->local_rtpport == 65535) { @@ -392,7 +393,9 @@ static int rtp_open(URLContext *h, const char *uri, int flags) build_udp_url(s, buf, sizeof(buf), hostname, s->rtcp_port, s->local_rtcpport, sources, block); - if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0) { + if (ffurl_open_whitelist(&s->rtcp_hd, buf, flags, + &h->interrupt_callback, NULL, + h->protocol_whitelist) < 0) { s->local_rtpport = s->local_rtcpport = -1; continue; } @@ -401,7 +404,8 @@ static int rtp_open(URLContext *h, const char *uri, int flags) build_udp_url(s, buf, sizeof(buf), hostname, s->rtcp_port, s->local_rtcpport, sources, block); - if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0) + if (ffurl_open_whitelist(&s->rtcp_hd, buf, flags, &h->interrupt_callback, + NULL, h->protocol_whitelist) < 0) goto fail; break; } diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 39539e9..d710469 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1468,8 +1468,8 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, "?localport=%d", j); /* we will use two ports per rtp stream (rtp and rtcp) */ j += 2; - err = ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, &opts); + err = ffurl_open_whitelist(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, &opts, s->protocol_whitelist); av_dict_free(&opts); @@ -1611,8 +1611,8 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST); ff_url_join(url, sizeof(url), "rtp", NULL, namebuf, port, "%s", optbuf); - if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, NULL) < 0) { + if (ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist) < 0) { err = AVERROR_INVALIDDATA; goto fail; } @@ -1800,8 +1800,8 @@ redirect: ff_url_join(tcpname, sizeof(tcpname), lower_rtsp_proto, NULL, host, port, "?timeout=%d", rt->stimeout); - if ((ret = ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, NULL)) < 0) { + if ((ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { err = ret; goto fail; } @@ -2316,8 +2316,8 @@ static int sdp_read_header(AVFormatContext *s) append_source_addrs(url, sizeof(url), "block", rtsp_st->nb_exclude_source_addrs, rtsp_st->exclude_source_addrs); - err = ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, &opts); + err = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, &opts, s->protocol_whitelist); av_dict_free(&opts); @@ -2386,8 +2386,8 @@ static int rtp_read_header(AVFormatContext *s) if (!ff_network_init()) return AVERROR(EIO); - ret = ffurl_open(&in, s->filename, AVIO_FLAG_READ, - &s->interrupt_callback, NULL); + ret = ffurl_open_whitelist(&in, s->filename, AVIO_FLAG_READ, + &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret) goto fail; diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c index 77389b6..17f04c0 100644 --- a/libavformat/rtspdec.c +++ b/libavformat/rtspdec.c @@ -294,8 +294,9 @@ static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl) av_dict_set(&opts, "buffer_size", buf, 0); ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL); av_log(s, AV_LOG_TRACE, "Opening: %s", url); - ret = ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, &opts); + ret = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, &opts, + s->protocol_whitelist); av_dict_free(&opts); if (ret) localport += 2; @@ -662,8 +663,9 @@ static int rtsp_listen(AVFormatContext *s) ff_url_join(tcpname, sizeof(tcpname), lower_proto, NULL, host, port, "?listen&listen_timeout=%d", rt->initial_timeout * 1000); - if (ret = ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, NULL)) { + if (ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, NULL, + s->protocol_whitelist)) { av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n"); return ret; } diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c index 808ae14..926795b 100644 --- a/libavformat/sapdec.c +++ b/libavformat/sapdec.c @@ -85,8 +85,9 @@ static int sap_read_header(AVFormatContext *s) ff_url_join(url, sizeof(url), "udp", NULL, host, port, "?localport=%d", port); - ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_READ, - &s->interrupt_callback, NULL); + ret = ffurl_open_whitelist(&sap->ann_fd, url, AVIO_FLAG_READ, + &s->interrupt_callback, NULL, + s->protocol_whitelist); if (ret) goto fail; diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c index 07fbf48..b2f64b8 100644 --- a/libavformat/sapenc.c +++ b/libavformat/sapenc.c @@ -149,7 +149,9 @@ static int sap_write_header(AVFormatContext *s) "?ttl=%d", ttl); if (!same_port) base_port += 2; - ret = ffurl_open(&fd, url, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); + ret = ffurl_open_whitelist(&fd, url, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, + s->protocol_whitelist); if (ret) { ret = AVERROR(EIO); goto fail; @@ -167,8 +169,9 @@ static int sap_write_header(AVFormatContext *s) ff_url_join(url, sizeof(url), "udp", NULL, announce_addr, port, "?ttl=%d&connect=1", ttl); - ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL); + ret = ffurl_open_whitelist(&sap->ann_fd, url, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, + s->protocol_whitelist); if (ret) { ret = AVERROR(EIO); goto fail; diff --git a/libavformat/segment.c b/libavformat/segment.c index 0c1f633..c13b91c 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -237,8 +237,8 @@ static int segment_start(AVFormatContext *s, int write_header) if ((err = set_segment_filename(s)) < 0) return err; - if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL)) < 0) { + if ((err = avio_open_whitelist(&oc->pb, oc->filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename); return err; } @@ -263,8 +263,8 @@ static int segment_list_open(AVFormatContext *s) int ret; snprintf(seg->temp_list_filename, sizeof(seg->temp_list_filename), seg->use_rename ? "%s.tmp" : "%s", seg->list); - ret = avio_open2(&seg->list_pb, seg->temp_list_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL); + ret = avio_open_whitelist(&seg->list_pb, seg->temp_list_filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment list '%s'\n", seg->list); return ret; @@ -690,8 +690,8 @@ static int seg_write_header(AVFormatContext *s) goto fail; if (seg->write_header_trailer) { - if ((ret = avio_open2(&oc->pb, seg->header_filename ? seg->header_filename : oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL)) < 0) { + if ((ret = avio_open_whitelist(&oc->pb, seg->header_filename ? seg->header_filename : oc->filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename); goto fail; } @@ -734,8 +734,8 @@ static int seg_write_header(AVFormatContext *s) } else { close_null_ctxp(&oc->pb); } - if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL)) < 0) + if ((ret = avio_open_whitelist(&oc->pb, oc->filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) goto fail; if (!seg->individual_header_trailer) oc->pb->seekable = 0; diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index a26f8fe..9b890e0 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -121,7 +121,8 @@ static int64_t ism_seek(void *opaque, int64_t offset, int whence) AVDictionary *opts = NULL; os->tail_out = os->out; av_dict_set(&opts, "truncate", "0", 0); - ret = ffurl_open(&os->out, frag->file, AVIO_FLAG_READ_WRITE, &os->ctx->interrupt_callback, &opts); + ret = ffurl_open_whitelist(&os->out, frag->file, AVIO_FLAG_READ_WRITE, + &os->ctx->interrupt_callback, &opts, os->ctx->protocol_whitelist); av_dict_free(&opts); if (ret < 0) { os->out = os->tail_out; @@ -129,7 +130,8 @@ static int64_t ism_seek(void *opaque, int64_t offset, int whence) return ret; } av_dict_set(&opts, "truncate", "0", 0); - ffurl_open(&os->out2, frag->infofile, AVIO_FLAG_READ_WRITE, &os->ctx->interrupt_callback, &opts); + ffurl_open_whitelist(&os->out2, frag->infofile, AVIO_FLAG_READ_WRITE, + &os->ctx->interrupt_callback, &opts, os->ctx->protocol_whitelist); av_dict_free(&opts); ffurl_seek(os->out, offset - frag->start_pos, SEEK_SET); if (os->out2) @@ -220,7 +222,7 @@ static int write_manifest(AVFormatContext *s, int final) snprintf(filename, sizeof(filename), "%s/Manifest", s->filename); snprintf(temp_filename, sizeof(temp_filename), "%s/Manifest.tmp", s->filename); - ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); + ret = avio_open_whitelist(&out, temp_filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename); return ret; @@ -329,7 +331,7 @@ static int ism_write_header(AVFormatContext *s) } ctx = avformat_alloc_context(); - if (!ctx) { + if (!ctx || ff_copy_whitelists(ctx, s) < 0) { ret = AVERROR(ENOMEM); goto fail; } @@ -409,7 +411,7 @@ static int parse_fragment(AVFormatContext *s, const char *filename, int64_t *sta AVIOContext *in; int ret; uint32_t len; - if ((ret = avio_open2(&in, filename, AVIO_FLAG_READ, &s->interrupt_callback, NULL)) < 0) + if ((ret = avio_open_whitelist(&in, filename, AVIO_FLAG_READ, &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) return ret; ret = AVERROR(EIO); *moof_size = avio_rb32(in); @@ -486,9 +488,9 @@ static int copy_moof(AVFormatContext *s, const char* infile, const char *outfile { AVIOContext *in, *out; int ret = 0; - if ((ret = avio_open2(&in, infile, AVIO_FLAG_READ, &s->interrupt_callback, NULL)) < 0) + if ((ret = avio_open_whitelist(&in, infile, AVIO_FLAG_READ, &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) return ret; - if ((ret = avio_open2(&out, outfile, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL)) < 0) { + if ((ret = avio_open_whitelist(&out, outfile, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { avio_close(in); return ret; } @@ -523,7 +525,7 @@ static int ism_flush(AVFormatContext *s, int final) continue; snprintf(filename, sizeof(filename), "%s/temp", os->dirname); - ret = ffurl_open(&os->out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); + ret = ffurl_open_whitelist(&os->out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) break; os->cur_start_pos = os->tail_pos; diff --git a/libavformat/srtpproto.c b/libavformat/srtpproto.c index 0124696..460799a 100644 --- a/libavformat/srtpproto.c +++ b/libavformat/srtpproto.c @@ -80,7 +80,8 @@ static int srtp_open(URLContext *h, const char *uri, int flags) av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port, path, sizeof(path), uri); ff_url_join(buf, sizeof(buf), "rtp", NULL, hostname, rtp_port, "%s", path); - if ((ret = ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL)) < 0) + if ((ret = ffurl_open_whitelist(&s->rtp_hd, buf, flags, &h->interrupt_callback, + NULL, h->protocol_whitelist)) < 0) goto fail; h->max_packet_size = FFMIN(s->rtp_hd->max_packet_size, diff --git a/libavformat/subfile.c b/libavformat/subfile.c index 0e84384..a8baf14 100644 --- a/libavformat/subfile.c +++ b/libavformat/subfile.c @@ -77,7 +77,8 @@ static int subfile_open(URLContext *h, const char *filename, int flags, return AVERROR(EINVAL); } av_strstart(filename, "subfile:", &filename); - ret = ffurl_open(&c->h, filename, flags, &h->interrupt_callback, options); + ret = ffurl_open_whitelist(&c->h, filename, flags, &h->interrupt_callback, + options, h->protocol_whitelist); if (ret < 0) return ret; c->pos = c->start; diff --git a/libavformat/tee.c b/libavformat/tee.c index 8c54d32..0e9f097 100644 --- a/libavformat/tee.c +++ b/libavformat/tee.c @@ -226,7 +226,9 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) } if (!(avf2->oformat->flags & AVFMT_NOFILE)) { - if ((ret = avio_open(&avf2->pb, filename, AVIO_FLAG_WRITE)) < 0) { + if ((ret = avio_open_whitelist(&avf2->pb, filename, AVIO_FLAG_WRITE, + &avf->interrupt_callback, NULL, + avf->protocol_whitelist)) < 0) { av_log(avf, AV_LOG_ERROR, "Slave '%s': error opening: %s\n", slave, av_err2str(ret)); goto end; diff --git a/libavformat/tls.c b/libavformat/tls.c index 9802a70..c625983 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -104,6 +104,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV proxy_port, "/%s", dest); } - return ffurl_open(&c->tcp, buf, AVIO_FLAG_READ_WRITE, - &parent->interrupt_callback, options); + return ffurl_open_whitelist(&c->tcp, buf, AVIO_FLAG_READ_WRITE, + &parent->interrupt_callback, options, + parent->protocol_whitelist); } diff --git a/libavformat/tls_securetransport.c b/libavformat/tls_securetransport.c index 6ad266a..6e0d497 100644 --- a/libavformat/tls_securetransport.c +++ b/libavformat/tls_securetransport.c @@ -80,8 +80,9 @@ static int import_pem(URLContext *h, char *path, CFArrayRef *array) goto end; } - if ((ret = avio_open2(&s, path, AVIO_FLAG_READ, - &h->interrupt_callback, NULL)) < 0) + if ((ret = avio_open_whitelist(&s, path, AVIO_FLAG_READ, + &h->interrupt_callback, NULL, + h->protocol_whitelist)) < 0) goto end; if ((ret = avio_size(s)) < 0) diff --git a/libavformat/url.h b/libavformat/url.h index 391e3bc..6e5b218 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -47,6 +47,7 @@ typedef struct URLContext { int is_connected; AVIOInterruptCB interrupt_callback; int64_t rw_timeout; /**< maximum time to wait for (network) read/write operation completion, in mcs */ + char *protocol_whitelist; } URLContext; typedef struct URLProtocol { @@ -138,6 +139,10 @@ int ffurl_connect(URLContext *uc, AVDictionary **options); * @return >= 0 in case of success, a negative value corresponding to an * AVERROR code in case of failure */ +int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options, + const char *whitelist); + int ffurl_open(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options); diff --git a/libavformat/utils.c b/libavformat/utils.c index b6457b0..7f30829 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -139,11 +139,15 @@ void av_format_inject_global_side_data(AVFormatContext *s) int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src) { - av_assert0(!dst->codec_whitelist && !dst->format_whitelist); + av_assert0(!dst->codec_whitelist && + !dst->format_whitelist && + !dst->protocol_whitelist); dst-> codec_whitelist = av_strdup(src->codec_whitelist); dst->format_whitelist = av_strdup(src->format_whitelist); + dst->protocol_whitelist = av_strdup(src->protocol_whitelist); if ( (src-> codec_whitelist && !dst-> codec_whitelist) - || (src->format_whitelist && !dst->format_whitelist)) { + || (src-> format_whitelist && !dst-> format_whitelist) + || (src->protocol_whitelist && !dst->protocol_whitelist)) { av_log(dst, AV_LOG_ERROR, "Failed to duplicate whitelist\n"); return AVERROR(ENOMEM); } @@ -352,8 +356,9 @@ static int init_input(AVFormatContext *s, const char *filename, (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score)))) return score; - if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ | s->avio_flags, - &s->interrupt_callback, options)) < 0) + if ((ret = avio_open_whitelist(&s->pb, filename, AVIO_FLAG_READ | s->avio_flags, + &s->interrupt_callback, options, + s->protocol_whitelist)) < 0) return ret; if (s->iformat) return 0; diff --git a/libavformat/webm_chunk.c b/libavformat/webm_chunk.c index 3dfef4b..8188219 100644 --- a/libavformat/webm_chunk.c +++ b/libavformat/webm_chunk.c @@ -125,8 +125,8 @@ static int webm_chunk_write_header(AVFormatContext *s) ret = get_chunk_filename(s, 1, oc->filename); if (ret < 0) return ret; - ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL); + ret = avio_open_whitelist(&oc->pb, oc->filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) return ret; @@ -169,7 +169,8 @@ static int chunk_end(AVFormatContext *s) ret = get_chunk_filename(s, 0, filename); if (ret < 0) goto fail; - ret = avio_open2(&pb, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); + ret = avio_open_whitelist(&pb, filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) goto fail; avio_write(pb, buffer, buffer_size); -- 1.7.9.5 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel