summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-12-04 23:15:31 +0100
committerwm4 <wm4@nowhere>2016-12-04 23:15:31 +0100
commitceb2e1026d4295d3831d080dc18f8ca5db56bc5c (patch)
treeff0bc73ad982c1a1740aa8b1fb31b83fabbe7879
parent83c5f704e7d483e2db6df90dacd24896d45fe39a (diff)
downloadmpv-ceb2e1026d4295d3831d080dc18f8ca5db56bc5c.tar.bz2
mpv-ceb2e1026d4295d3831d080dc18f8ca5db56bc5c.tar.xz
demux, stream: add option to prevent opening referenced files
Quite irresponsibly hacked together. Sue me.
-rw-r--r--DOCS/man/options.rst20
-rw-r--r--demux/demux.c7
-rw-r--r--demux/demux.h1
-rw-r--r--demux/demux_cue.c3
-rw-r--r--demux/demux_edl.c3
-rw-r--r--demux/demux_lavf.c15
-rw-r--r--demux/demux_libarchive.c3
-rw-r--r--demux/demux_mkv_timeline.c2
-rw-r--r--demux/demux_playlist.c5
-rw-r--r--demux/demux_rar.c3
-rw-r--r--stream/stream.c6
-rw-r--r--stream/stream.h1
-rw-r--r--stream/stream_bluray.c3
-rw-r--r--stream/stream_dvd.c3
-rw-r--r--stream/stream_dvdnav.c3
-rw-r--r--wscript6
16 files changed, 81 insertions, 3 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 82c51fc503..d4cef55bf3 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -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
diff --git a/demux/demux.c b/demux/demux.c
index 8aa9989de3..18c9b3b5c1 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -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,
diff --git a/demux/demux.h b/demux/demux.h
index 18f52d463d..0e5a5e15c6 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -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;
diff --git a/demux/demux_cue.c b/demux/demux_cue.c
index 673e8b9f27..ba97ca0c1b 100644
--- a/demux/demux_cue.c
+++ b/demux/demux_cue.c
@@ -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);
diff --git a/demux/demux_edl.c b/demux/demux_edl.c
index 67a4290303..623cae35b3 100644
--- a/demux/demux_edl.c
+++ b/demux/demux_edl.c
@@ -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;
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index d5598a942b..94bcd3fff6 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -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) {
diff --git a/demux/demux_libarchive.c b/demux/demux_libarchive.c
index dcdbe65fc0..41b05368ca 100644
--- a/demux/demux_libarchive.c
+++ b/demux/demux_libarchive.c
@@ -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) {
diff --git a/demux/demux_mkv_timeline.c b/demux/demux_mkv_timeline.c
index 15f9a5d594..476551c58b 100644
--- a/demux/demux_mkv_timeline.c
+++ b/demux/demux_mkv_timeline.c
@@ -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);
diff --git a/demux/demux_playlist.c b/demux/demux_playlist.c
index 7479db149f..0f2ebedd76 100644
--- a/demux/demux_playlist.c
+++ b/demux/demux_playlist.c
@@ -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);
diff --git a/demux/demux_rar.c b/demux/demux_rar.c
index f35c2ccf66..7d9adfc28a 100644
--- a/demux/demux_rar.c
+++ b/demux/demux_rar.c
@@ -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;
diff --git a/stream/stream.c b/stream/stream.c
index c936c5c77e..4c7aa04844 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -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) {
diff --git a/stream/stream.h b/stream/stream.h
index 4444da8ed3..7d44e30eae 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -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;
diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c
index 26a78e5f21..5f083954c2 100644
--- a/stream/stream_bluray.c
+++ b/stream/stream_bluray.c
@@ -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;
diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c
index 4b423de630..338c23633c 100644
--- a/stream/stream_dvd.c
+++ b/stream/stream_dvd.c
@@ -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;
diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c
index ec15c83b20..1178f50857 100644
--- a/stream/stream_dvdnav.c
+++ b/stream/stream_dvdnav.c
@@ -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));
diff --git a/wscript b/wscript
index caa5570dd5..b098099cc1 100644
--- a/wscript
+++ b/wscript
@@ -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'),
}
]