demux, stream: add option to prevent opening referenced files

Quite irresponsibly hacked together. Sue me.
This commit is contained in:
wm4 2016-12-04 23:15:31 +01:00
parent 83c5f704e7
commit ceb2e1026d
16 changed files with 81 additions and 3 deletions

View File

@ -267,6 +267,26 @@ Playback Control
Note that ``--playlist`` always loads all entries, so you use that instead
if you really have the need for this functionality.
``--access-references=<yes|no>``
Follow any references in the file being opened (default: yes). Disabling
this is helpful if the file is automatically scanned (e.g. thumbnail
generation). If the thumbnail scanner for example encounters a playlist
file, which contains network URLs, and the scanner should not open these,
enabling this option will prevent it. This option also disables ordered
chapters, mov reference files, opening of archives, and a number of other
features.
On older FFmpeg versions, this will not work in some cases. Some FFmpeg
demuxers might not respect this option.
This option does not prevent opening of paired subtitle files and such. Use
``--autoload-files=no`` to prevent this.
This option does not always work if you open non-files (for example using
``dvd://directory`` would open a whole bunch of files in the given
directory). Prefixing the filename with ``./`` if it doesn't start with
a ``/`` will avoid this.
``--loop-file=<N|inf|no>``
Loop a single file N times. ``inf`` means forever, ``no`` means normal
playback. For compatibility, ``--loop-file`` and ``--loop-file=yes`` are

View File

@ -89,6 +89,7 @@ struct demux_opts {
double min_secs;
int force_seekable;
double min_secs_cache;
int access_references;
};
#define OPT_BASE_STRUCT struct demux_opts
@ -100,6 +101,7 @@ const struct m_sub_options demux_conf = {
OPT_INTRANGE("demuxer-max-bytes", max_bytes, 0, 0, INT_MAX),
OPT_FLAG("force-seekable", force_seekable, 0),
OPT_DOUBLE("cache-secs", min_secs_cache, M_OPT_MIN, .min = 0),
OPT_FLAG("access-references", access_references, 0),
{0}
},
.size = sizeof(struct demux_opts),
@ -108,6 +110,7 @@ const struct m_sub_options demux_conf = {
.max_bytes = 400 * 1024 * 1024,
.min_secs = 1.0,
.min_secs_cache = 10.0,
.access_references = 1,
},
};
@ -1213,6 +1216,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
return NULL;
struct demuxer *demuxer = talloc_ptrtype(NULL, demuxer);
struct demux_opts *opts = mp_get_config_group(demuxer, global, &demux_conf);
*demuxer = (struct demuxer) {
.desc = desc,
.stream = stream,
@ -1223,6 +1227,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
.glog = log,
.filename = talloc_strdup(demuxer, stream->url),
.is_network = stream->is_network,
.access_references = opts->access_references,
.events = DEMUX_EVENT_ALL,
};
demuxer->seekable = stream->seekable;
@ -1230,8 +1235,6 @@ static struct demuxer *open_given_type(struct mpv_global *global,
!demuxer->stream->uncached_stream->seekable)
demuxer->seekable = false;
struct demux_opts *opts = mp_get_config_group(demuxer, global, &demux_conf);
struct demux_internal *in = demuxer->in = talloc_ptrtype(demuxer, in);
*in = (struct demux_internal){
.log = demuxer->log,

View File

@ -186,6 +186,7 @@ typedef struct demuxer {
// Typical examples: text subtitles, playlists
bool fully_read;
bool is_network; // opened directly from a network stream
bool access_references; // allow opening other files/URLs
// Bitmask of DEMUX_EVENT_*
int events;

View File

@ -253,6 +253,9 @@ out:
static int try_open_file(struct demuxer *demuxer, enum demux_check check)
{
if (!demuxer->access_references)
return -1;
struct stream *s = demuxer->stream;
if (check >= DEMUX_CHECK_UNSAFE) {
bstr d = stream_peek(s, PROBE_SIZE);

View File

@ -295,6 +295,9 @@ static void build_mpv_edl_timeline(struct timeline *tl)
static int try_open_file(struct demuxer *demuxer, enum demux_check check)
{
if (!demuxer->access_references)
return -1;
struct priv *p = talloc_zero(demuxer, struct priv);
demuxer->priv = p;
demuxer->fully_read = true;

View File

@ -22,6 +22,7 @@
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <assert.h>
#include "config.h"
@ -754,6 +755,14 @@ static int interrupt_cb(void *ctx)
return mp_cancel_test(priv->stream->cancel);
}
static int block_io_open(struct AVFormatContext *s, AVIOContext **pb,
const char *url, int flags, AVDictionary **options)
{
struct demuxer *demuxer = s->opaque;
MP_ERR(demuxer, "Not opening '%s' due to --access-references=no.\n", url);
return AVERROR(EACCES);
}
static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
{
AVFormatContext *avfc;
@ -855,6 +864,12 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
.opaque = demuxer,
};
#if HAVE_AVFORMAT_IOOPEN
avfc->opaque = demuxer;
if (!demuxer->access_references)
avfc->io_open = block_io_open;
#endif
mp_set_avdict(&dopts, lavfdopts->avopts);
if (avformat_open_input(&avfc, priv->filename, priv->avif, &dopts) < 0) {

View File

@ -32,6 +32,9 @@ static int cmp_filename(const void *a, const void *b)
static int open_file(struct demuxer *demuxer, enum demux_check check)
{
if (!demuxer->access_references)
return -1;
int flags = 0;
int probe_size = STREAM_BUFFER_SIZE;
if (check <= DEMUX_CHECK_REQUEST) {

View File

@ -519,7 +519,7 @@ void build_ordered_chapter_timeline(struct timeline *tl)
.opts = mp_get_config_group(ctx, tl->global, NULL),
};
if (!ctx->opts->ordered_chapters) {
if (!ctx->opts->ordered_chapters || !demuxer->access_references) {
MP_INFO(demuxer, "File uses ordered chapters, but "
"you have disabled support for them. Ignoring.\n");
talloc_free(ctx);

View File

@ -283,6 +283,8 @@ static int parse_dir(struct pl_parser *p)
return 0;
char *path = mp_file_get_path(p, bstr0(p->real_stream->url));
if (!path)
return -1;
char **files = NULL;
int num_files = 0;
@ -339,6 +341,9 @@ static const struct pl_format *probe_pl(struct pl_parser *p)
static int open_file(struct demuxer *demuxer, enum demux_check check)
{
if (!demuxer->access_references)
return -1;
bool force = check < DEMUX_CHECK_UNSAFE || check == DEMUX_CHECK_REQUEST;
struct pl_parser *p = talloc_zero(NULL, struct pl_parser);

View File

@ -23,6 +23,9 @@
static int open_file(struct demuxer *demuxer, enum demux_check check)
{
if (!demuxer->access_references)
return -1;
if (RarProbe(demuxer->stream))
return -1;

View File

@ -230,6 +230,12 @@ static int open_internal(const stream_info_t *sinfo, const char *url, int flags,
s->is_network = sinfo->is_network;
s->mode = flags & (STREAM_READ | STREAM_WRITE);
if (global->config) {
int opt;
mp_read_option_raw(global, "access-references", &m_option_type_flag, &opt);
s->access_references = opt;
}
MP_VERBOSE(s, "Opening %s\n", url);
if ((s->mode & STREAM_WRITE) && !sinfo->can_write) {

View File

@ -197,6 +197,7 @@ typedef struct stream {
bool fast_skip : 1; // consider stream fast enough to fw-seek by skipping
bool is_network : 1; // original stream_info_t.is_network flag
bool allow_caching : 1; // stream cache makes sense
bool access_references : 1; // open other streams
struct mp_log *log;
struct mpv_global *global;

View File

@ -569,6 +569,9 @@ static int bdmv_dir_stream_open(stream_t *stream)
.cfg_title = BLURAY_DEFAULT_TITLE,
};
if (!stream->access_references)
goto unsupported;
char *path = mp_file_get_path(priv, bstr0(stream->url));
if (!path)
goto unsupported;

View File

@ -951,6 +951,9 @@ static int ifo_stream_open(stream_t *stream)
dvd_priv_t *priv = talloc_zero(stream, dvd_priv_t);
stream->priv = priv;
if (!stream->access_references)
goto unsupported;
char *path = mp_file_get_path(priv, bstr0(stream->url));
if (!path)
goto unsupported;

View File

@ -562,6 +562,9 @@ static int ifo_dvdnav_stream_open(stream_t *stream)
struct priv *priv = talloc_zero(stream, struct priv);
stream->priv = priv;
if (!stream->access_references)
goto unsupported;
priv->track = TITLE_LONGEST;
char *path = mp_file_get_path(priv, bstr0(stream->url));

View File

@ -528,6 +528,12 @@ FFmpeg/Libav libraries. You need at least {0}. Aborting.".format(libav_versions_
'func': check_statement('libavutil/frame.h',
'AV_FRAME_DATA_MASTERING_DISPLAY_METADATA',
use='libav'),
}, {
'name': 'avformat-ioopen',
'desc': 'libavformat io_open callback',
'func': check_statement('libavformat/avformat.h',
'offsetof(AVFormatContext, io_open)',
use='libav'),
}
]