summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/encode_lavc.c4
-rw-r--r--common/playlist.c6
-rw-r--r--common/playlist.h7
-rw-r--r--demux/demux.c7
-rw-r--r--demux/demux.h1
-rw-r--r--demux/demux_cue.c8
-rw-r--r--demux/demux_disc.c1
-rw-r--r--demux/demux_edl.c5
-rw-r--r--demux/demux_libarchive.c6
-rw-r--r--demux/demux_mf.c6
-rw-r--r--demux/demux_mkv_timeline.c1
-rw-r--r--demux/demux_playlist.c2
-rw-r--r--demux/demux_timeline.c1
-rw-r--r--demux/timeline.c1
-rw-r--r--demux/timeline.h1
-rw-r--r--input/input.c2
-rw-r--r--options/options.c1
-rw-r--r--options/options.h1
-rw-r--r--player/loadfile.c14
-rw-r--r--player/misc.c4
-rw-r--r--stream/stream.c61
-rw-r--r--stream/stream.h29
-rw-r--r--stream/stream_avdevice.c1
-rw-r--r--stream/stream_bluray.c3
-rw-r--r--stream/stream_cb.c1
-rw-r--r--stream/stream_cdda.c1
-rw-r--r--stream/stream_concat.c2
-rw-r--r--stream/stream_dvb.c1
-rw-r--r--stream/stream_dvdnav.c4
-rw-r--r--stream/stream_file.c2
-rw-r--r--stream/stream_lavf.c6
-rw-r--r--stream/stream_libarchive.c10
-rw-r--r--stream/stream_memory.c2
-rw-r--r--stream/stream_smb.c1
34 files changed, 133 insertions, 70 deletions
diff --git a/common/encode_lavc.c b/common/encode_lavc.c
index 2b9bdb4a66..b64232fb87 100644
--- a/common/encode_lavc.c
+++ b/common/encode_lavc.c
@@ -830,7 +830,9 @@ static void encoder_2pass_prepare(struct encoder_context *p)
if (p->encoder->flags & AV_CODEC_FLAG_PASS2) {
MP_INFO(p, "Reading 2-pass log: %s\n", filename);
- struct stream *s = stream_open(filename, p->global);
+ struct stream *s = stream_create(filename,
+ STREAM_ORIGIN_DIRECT | STREAM_READ,
+ NULL, p->global);
if (s) {
struct bstr content = stream_read_complete(s, p, 1000000000);
if (content.start) {
diff --git a/common/playlist.c b/common/playlist.c
index 7572e67780..b5d6ca15c2 100644
--- a/common/playlist.c
+++ b/common/playlist.c
@@ -32,6 +32,7 @@ struct playlist_entry *playlist_entry_new(const char *filename)
struct playlist_entry *e = talloc_zero(NULL, struct playlist_entry);
char *local_filename = mp_file_url_to_filename(e, bstr0(filename));
e->filename = local_filename ? local_filename : talloc_strdup(e, filename);
+ e->stream_flags = STREAM_ORIGIN_DIRECT;
return e;
}
@@ -281,7 +282,10 @@ struct playlist *playlist_parse_file(const char *file, struct mp_cancel *cancel,
struct mp_log *log = mp_log_new(NULL, global->log, "!playlist_parser");
mp_verbose(log, "Parsing playlist file %s...\n", file);
- struct demuxer_params p = {.force_format = "playlist"};
+ struct demuxer_params p = {
+ .force_format = "playlist",
+ .stream_flags = STREAM_ORIGIN_DIRECT,
+ };
struct demuxer *d = demux_open_url(file, &p, cancel, global);
if (!d) {
talloc_free(log);
diff --git a/common/playlist.h b/common/playlist.h
index a37c516519..bbf6821428 100644
--- a/common/playlist.h
+++ b/common/playlist.h
@@ -53,11 +53,8 @@ struct playlist_entry {
// Additional refcount. Normally (reserved==0), the entry is owned by the
// playlist, and this can be used to keep the entry alive.
int reserved;
+ // Any flags from STREAM_ORIGIN_FLAGS. 0 if unknown.
// Used to reject loading of unsafe entries from external playlists.
- // Can have any of the following bit flags set:
- // STREAM_SAFE_ONLY: only allow streams marked with is_safe
- // STREAM_NETWORK_ONLY: only allow streams marked with is_network
- // The value 0 allows everything.
int stream_flags;
};
@@ -69,8 +66,6 @@ struct playlist {
// current_was_replaced is set to true.
struct playlist_entry *current;
bool current_was_replaced;
-
- bool disable_safety;
};
void playlist_entry_add_param(struct playlist_entry *e, bstr name, bstr value);
diff --git a/demux/demux.c b/demux/demux.c
index 813cb1aa23..21ad3383c1 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -2894,6 +2894,7 @@ static void demux_copy(struct demuxer *dst, struct demuxer *src)
dst->duration = src->duration;
dst->is_network = src->is_network;
dst->is_streaming = src->is_streaming;
+ dst->stream_origin = src->stream_origin;
dst->priv = src->priv;
dst->metadata = mp_tags_dup(dst, src->metadata);
}
@@ -3145,6 +3146,7 @@ struct parent_stream_info {
bool seekable;
bool is_network;
bool is_streaming;
+ int stream_origin;
struct mp_cancel *cancel;
char *filename;
};
@@ -3176,6 +3178,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
.filename = talloc_strdup(demuxer, sinfo->filename),
.is_network = sinfo->is_network,
.is_streaming = sinfo->is_streaming,
+ .stream_origin = sinfo->stream_origin,
.access_references = opts->access_references,
.events = DEMUX_EVENT_ALL,
.duration = -1,
@@ -3309,6 +3312,7 @@ static struct demuxer *demux_open(struct stream *stream,
.seekable = stream->seekable,
.is_network = stream->is_network,
.is_streaming = stream->streaming,
+ .stream_origin = stream->stream_origin,
.cancel = cancel,
.filename = talloc_strdup(NULL, stream->url),
};
@@ -3364,9 +3368,8 @@ struct demuxer *demux_open_url(const char *url,
struct mp_cancel *cancel,
struct mpv_global *global)
{
- struct demuxer_params dummy = {0};
if (!params)
- params = &dummy;
+ return NULL;
struct mp_cancel *priv_cancel = mp_cancel_new(NULL);
if (cancel)
mp_cancel_set_parent(priv_cancel, cancel);
diff --git a/demux/demux.h b/demux/demux.h
index 235744c6f7..4c15e074c2 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -197,6 +197,7 @@ typedef struct demuxer {
bool fully_read;
bool is_network; // opened directly from a network stream
bool is_streaming; // implies a "slow" input, such as network or FUSE
+ int stream_origin; // any STREAM_ORIGIN_* (set from source stream)
bool access_references; // allow opening other files/URLs
// Bitmask of DEMUX_EVENT_*
diff --git a/demux/demux_cue.c b/demux/demux_cue.c
index 35874972b9..edd1a97d1b 100644
--- a/demux/demux_cue.c
+++ b/demux/demux_cue.c
@@ -78,7 +78,11 @@ static bool try_open(struct timeline *tl, char *filename)
|| bstrcasecmp(bstr0(tl->demuxer->filename), bfilename) == 0)
return false;
- struct demuxer *d = demux_open_url(filename, NULL, tl->cancel, tl->global);
+ struct demuxer_params p = {
+ .stream_flags = tl->stream_origin,
+ };
+
+ struct demuxer *d = demux_open_url(filename, &p, tl->cancel, tl->global);
// Since .bin files are raw PCM data with no headers, we have to explicitly
// open them. Also, try to avoid to open files that are most likely not .bin
// files, as that would only play noise. Checking the file extension is
@@ -87,7 +91,7 @@ static bool try_open(struct timeline *tl, char *filename)
// CD sector size (2352 bytes)
if (!d && bstr_case_endswith(bfilename, bstr0(".bin"))) {
MP_WARN(tl, "CUE: Opening as BIN file!\n");
- struct demuxer_params p = {.force_format = "rawaudio"};
+ p.force_format = "rawaudio";
d = demux_open_url(filename, &p, tl->cancel, tl->global);
}
if (d) {
diff --git a/demux/demux_disc.c b/demux/demux_disc.c
index 919360d074..3dfff45403 100644
--- a/demux/demux_disc.c
+++ b/demux/demux_disc.c
@@ -296,6 +296,7 @@ static int d_open(demuxer_t *demuxer, enum demux_check check)
struct demuxer_params params = {
.force_format = "+lavf",
.external_stream = demuxer->stream,
+ .stream_flags = demuxer->stream_origin,
};
struct stream *cur = demuxer->stream;
diff --git a/demux/demux_edl.c b/demux/demux_edl.c
index 1ac912888f..b1f268ad8b 100644
--- a/demux/demux_edl.c
+++ b/demux/demux_edl.c
@@ -203,6 +203,7 @@ static struct demuxer *open_source(struct timeline *root,
}
struct demuxer_params params = {
.init_fragment = tl->init_fragment,
+ .stream_flags = root->stream_origin,
};
struct demuxer *d = demux_open_url(filename, &params, root->cancel,
root->global);
@@ -268,7 +269,8 @@ static struct timeline_par *build_timeline(struct timeline *root,
if (parts->init_fragment_url && parts->init_fragment_url[0]) {
MP_VERBOSE(root, "Opening init fragment...\n");
- stream_t *s = stream_create(parts->init_fragment_url, STREAM_READ,
+ stream_t *s = stream_create(parts->init_fragment_url,
+ STREAM_READ | root->stream_origin,
root->cancel, root->global);
if (s) {
root->is_network |= s->is_network;
@@ -282,6 +284,7 @@ static struct timeline_par *build_timeline(struct timeline *root,
}
struct demuxer_params params = {
.init_fragment = tl->init_fragment,
+ .stream_flags = root->stream_origin,
};
tl->track_layout = demux_open_url("memory://", &params, root->cancel,
root->global);
diff --git a/demux/demux_libarchive.c b/demux/demux_libarchive.c
index 80bd3e240e..f2e669aa72 100644
--- a/demux/demux_libarchive.c
+++ b/demux/demux_libarchive.c
@@ -64,9 +64,6 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
struct playlist *pl = talloc_zero(demuxer, struct playlist);
demuxer->playlist = pl;
- // make it load archive://
- pl->disable_safety = true;
-
char *prefix = mp_url_escape(mpa, demuxer->stream->url, "~|");
char **files = NULL;
@@ -85,6 +82,9 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
for (int n = 0; n < num_files; n++)
playlist_add_file(pl, files[n]);
+ for (struct playlist_entry *e = pl->first; e; e = e->next)
+ e->stream_flags = demuxer->stream_origin;
+
demuxer->filetype = "archive";
demuxer->fully_read = true;
diff --git a/demux/demux_mf.c b/demux/demux_mf.c
index 6698ef8c62..2f46d356f3 100644
--- a/demux/demux_mf.c
+++ b/demux/demux_mf.c
@@ -188,8 +188,10 @@ static bool demux_mf_read_packet(struct demuxer *demuxer,
struct stream *stream = entry_stream;
if (!stream) {
char *filename = mf->names[mf->curr_frame];
- if (filename)
- stream = stream_open(filename, demuxer->global);
+ if (filename) {
+ stream = stream_create(filename, demuxer->stream_origin | STREAM_READ,
+ demuxer->cancel, demuxer->global);
+ }
}
if (stream) {
diff --git a/demux/demux_mkv_timeline.c b/demux/demux_mkv_timeline.c
index 5bbadc0781..22d859c75c 100644
--- a/demux/demux_mkv_timeline.c
+++ b/demux/demux_mkv_timeline.c
@@ -172,6 +172,7 @@ static bool check_file_seg(struct tl_ctx *ctx, char *filename, int segment)
.matroska_wanted_segment = segment,
.matroska_was_valid = &was_valid,
.disable_timeline = true,
+ .stream_flags = ctx->tl->stream_origin,
};
struct mp_cancel *cancel = ctx->tl->cancel;
if (mp_cancel_test(cancel))
diff --git a/demux/demux_playlist.c b/demux/demux_playlist.c
index 00db544b30..b40beda980 100644
--- a/demux/demux_playlist.c
+++ b/demux/demux_playlist.c
@@ -462,6 +462,8 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
bool ok = fmt->parse(p) >= 0 && !p->error;
if (p->add_base)
playlist_add_base_path(p->pl, mp_dirname(demuxer->filename));
+ for (struct playlist_entry *e = p->pl->first; e; e = e->next)
+ e->stream_flags = demuxer->stream_origin;
demuxer->playlist = talloc_steal(demuxer, p->pl);
demuxer->filetype = p->format ? p->format : fmt->name;
demuxer->fully_read = true;
diff --git a/demux/demux_timeline.c b/demux/demux_timeline.c
index f8f096c464..ecce06bcb2 100644
--- a/demux/demux_timeline.c
+++ b/demux/demux_timeline.c
@@ -212,6 +212,7 @@ static void reopen_lazy_segments(struct demuxer *demuxer,
struct demuxer_params params = {
.init_fragment = src->tl->init_fragment,
.skip_lavf_probing = true,
+ .stream_flags = demuxer->stream_origin,
};
src->current->d = demux_open_url(src->current->url, &params,
demuxer->cancel, demuxer->global);
diff --git a/demux/timeline.c b/demux/timeline.c
index 967c20da01..0e5ff75192 100644
--- a/demux/timeline.c
+++ b/demux/timeline.c
@@ -17,6 +17,7 @@ struct timeline *timeline_load(struct mpv_global *global, struct mp_log *log,
.cancel = demuxer->cancel,
.demuxer = demuxer,
.format = "unknown",
+ .stream_origin = demuxer->stream_origin,
};
demuxer->desc->load_timeline(tl);
diff --git a/demux/timeline.h b/demux/timeline.h
index e64b2f96c9..c8151a0606 100644
--- a/demux/timeline.h
+++ b/demux/timeline.h
@@ -36,6 +36,7 @@ struct timeline {
struct mp_cancel *cancel;
bool is_network, is_streaming;
+ int stream_origin;
const char *format;
// main source, and all other sources (this usually only has special meaning
diff --git a/input/input.c b/input/input.c
index 1bc8e303f6..f9475648b0 100644
--- a/input/input.c
+++ b/input/input.c
@@ -1276,7 +1276,7 @@ static int parse_config_file(struct input_ctx *ictx, char *file, bool warn)
file = mp_get_user_path(tmp, ictx->global, file);
- s = stream_open(file, ictx->global);
+ s = stream_create(file, STREAM_ORIGIN_DIRECT | STREAM_READ, NULL, ictx->global);
if (!s) {
MP_ERR(ictx, "Can't open input config file %s.\n", file);
goto done;
diff --git a/options/options.c b/options/options.c
index a874e95483..312354d988 100644
--- a/options/options.c
+++ b/options/options.c
@@ -649,7 +649,6 @@ static const m_option_t mp_opts[] = {
OPT_STRING("chapters-file", chapter_file, M_OPT_FILE),
- OPT_FLAG("load-unsafe-playlists", load_unsafe_playlists, 0),
OPT_FLAG("merge-files", merge_files, 0),
// a-v sync stuff:
diff --git a/options/options.h b/options/options.h
index 588b897e57..c87a4f2d36 100644
--- a/options/options.h
+++ b/options/options.h
@@ -194,7 +194,6 @@ typedef struct MPOpts {
int chapter_merge_threshold;
double chapter_seek_threshold;
char *chapter_file;
- int load_unsafe_playlists;
int merge_files;
int quiet;
int load_config;
diff --git a/player/loadfile.c b/player/loadfile.c
index 2535e75617..462355f60e 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -746,6 +746,7 @@ int mp_add_external_file(struct MPContext *mpctx, char *filename,
struct demuxer_params params = {
.is_top_level = true,
+ .stream_flags = STREAM_ORIGIN_DIRECT,
};
switch (filter) {
@@ -949,7 +950,8 @@ static void load_chapters(struct MPContext *mpctx)
if (chapter_file && chapter_file[0]) {
chapter_file = talloc_strdup(NULL, chapter_file);
mp_core_unlock(mpctx);
- struct demuxer *demux = demux_open_url(chapter_file, NULL,
+ struct demuxer_params p = {.stream_flags = STREAM_ORIGIN_DIRECT};
+ struct demuxer *demux = demux_open_url(chapter_file, &p,
mpctx->playback_abort,
mpctx->global);
mp_core_lock(mpctx);
@@ -1065,8 +1067,6 @@ static void start_open(struct MPContext *mpctx, char *url, int url_flags,
mpctx->open_format = talloc_strdup(NULL, mpctx->opts->demuxer_name);
mpctx->open_url_flags = url_flags;
mpctx->open_for_prefetch = for_prefetch && mpctx->opts->demuxer_thread;
- if (mpctx->opts->load_unsafe_playlists)
- mpctx->open_url_flags = 0;
if (pthread_create(&mpctx->open_thread, NULL, open_demux_thread, mpctx)) {
cancel_open(mpctx);
@@ -1473,14 +1473,6 @@ static void play_current_file(struct MPContext *mpctx)
if (mpctx->demuxer->playlist) {
struct playlist *pl = mpctx->demuxer->playlist;
- int entry_stream_flags = 0;
- if (!pl->disable_safety && !mpctx->opts->load_unsafe_playlists) {
- entry_stream_flags = STREAM_SAFE_ONLY;
- if (mpctx->demuxer->is_network)
- entry_stream_flags |= STREAM_NETWORK_ONLY;
- }
- for (struct playlist_entry *e = pl->first; e; e = e->next)
- e->stream_flags |= entry_stream_flags;
transfer_playlist(mpctx, pl);
mp_notify_property(mpctx, "playlist");
mpctx->error_playing = 2;
diff --git a/player/misc.c b/player/misc.c
index ae4550fec5..5a96d6cc25 100644
--- a/player/misc.c
+++ b/player/misc.c
@@ -238,7 +238,9 @@ void error_on_track(struct MPContext *mpctx, struct track *track)
int stream_dump(struct MPContext *mpctx, const char *source_filename)
{
struct MPOpts *opts = mpctx->opts;
- stream_t *stream = stream_open(source_filename, mpctx->global);
+ stream_t *stream = stream_create(source_filename,
+ STREAM_ORIGIN_DIRECT | STREAM_READ,
+ mpctx->playback_abort, mpctx->global);
if (!stream)
return -1;
diff --git a/stream/stream.c b/stream/stream.c
index 271e268a1c..157776cd87 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -101,6 +101,7 @@ static const stream_info_t *const stream_list[] = {
struct stream_opts {
int64_t buffer_size;
+ int load_unsafe_playlists;
};
#define OPT_BASE_STRUCT struct stream_opts
@@ -109,6 +110,7 @@ const struct m_sub_options stream_conf = {
.opts = (const struct m_option[]){
OPT_BYTE_SIZE("stream-buffer-size", buffer_size, 0,
STREAM_MIN_BUFFER_SIZE, 512 * 1024 * 1024),
+ OPT_FLAG("load-unsafe-playlists", load_unsafe_playlists, 0),
{0}
},
.size = sizeof(struct stream_opts),
@@ -202,6 +204,30 @@ static const char *match_proto(const char *url, const char *proto)
return NULL;
}
+// src and new are both STREAM_ORIGIN_* values. This checks whether a stream
+// with flags "new" can be opened from the "src". On success, return
+// new origin, on incompatibility return 0.
+static int check_origin(int src, int new)
+{
+ switch (src) {
+ case STREAM_ORIGIN_DIRECT:
+ case STREAM_ORIGIN_UNSAFE:
+ // Allow anything, but constrain it to the new origin.
+ return new;
+ case STREAM_ORIGIN_FS:
+ // From unix FS, allow all but unsafe.
+ if (new == STREAM_ORIGIN_FS || new == STREAM_ORIGIN_NET)
+ return new;
+ break;
+ case STREAM_ORIGIN_NET:
+ // Allow only other network links.
+ if (new == STREAM_ORIGIN_NET)
+ return new;
+ break;
+ }
+ return 0;
+}
+
// Read len bytes from the start position, and wrap around as needed. Limit the
// actually read data to the size of the buffer. Return amount of copied bytes.
// len: max bytes to copy to dst
@@ -289,11 +315,6 @@ static int stream_create_instance(const stream_info_t *sinfo,
*ret = NULL;
- if (!sinfo->is_safe && (flags & STREAM_SAFE_ONLY))
- return STREAM_UNSAFE;
- if (!sinfo->is_network && (flags & STREAM_NETWORK_ONLY))
- return STREAM_UNSAFE;
-
const char *path = url;
for (int n = 0; sinfo->protocols && sinfo->protocols[n]; n++) {
path = match_proto(url, sinfo->protocols[n]);
@@ -304,11 +325,9 @@ static int stream_create_instance(const stream_info_t *sinfo,
if (!path)
return STREAM_NO_MATCH;
- struct stream_opts *opts =
- mp_get_config_group(NULL, args->global, &stream_conf);
-
stream_t *s = talloc_zero(NULL, stream_t);
s->global = args->global;
+ struct stream_opts *opts = mp_get_config_group(s, s->global, &stream_conf);
if (flags & STREAM_SILENT) {
s->log = mp_null_log;
} else {
@@ -318,7 +337,6 @@ static int stream_create_instance(const stream_info_t *sinfo,
s->cancel = args->cancel;
s->url = talloc_strdup(s, url);
s->path = talloc_strdup(s, path);
- s->is_network = sinfo->is_network;
s->mode = flags & (STREAM_READ | STREAM_WRITE);
s->requested_buffer_size = opts->buffer_size;
@@ -326,8 +344,6 @@ static int stream_create_instance(const stream_info_t *sinfo,
mp_read_option_raw(s->global, "access-references", &m_option_type_flag, &opt);
s->access_references = opt;
- talloc_free(opts);
-
MP_VERBOSE(s, "Opening %s\n", url);
if (strlen(url) > INT_MAX / 8) {
@@ -342,6 +358,18 @@ static int stream_create_instance(const stream_info_t *sinfo,
return STREAM_NO_MATCH;
}
+ s->stream_origin = flags & STREAM_ORIGIN_MASK; // pass through by default
+ if (opts->load_unsafe_playlists) {
+ s->stream_origin = STREAM_ORIGIN_DIRECT;
+ } else if (sinfo->stream_origin) {
+ s->stream_origin = check_origin(s->stream_origin, sinfo->stream_origin);
+ }
+
+ if (!s->stream_origin) {
+ talloc_free(s);
+ return STREAM_UNSAFE;
+ }
+
int r = STREAM_UNSUPPORTED;
if (sinfo->open2) {
r = sinfo->open2(s, args);
@@ -429,14 +457,10 @@ struct stream *stream_create(const char *url, int flags,
return s;
}
-struct stream *stream_open(const char *filename, struct mpv_global *global)
-{
- return stream_create(filename, STREAM_READ, NULL, global);
-}
-
stream_t *open_output_stream(const char *filename, struct mpv_global *global)
{
- return stream_create(filename, STREAM_WRITE, NULL, global);
+ return stream_create(filename, STREAM_ORIGIN_DIRECT | STREAM_WRITE,
+ NULL, global);
}
// Read function bypassing the local stream buffer. This will not write into
@@ -787,7 +811,8 @@ struct bstr stream_read_file(const char *filename, void *talloc_ctx,
{
struct bstr res = {0};
char *fname = mp_get_user_path(NULL, global, filename);
- stream_t *s = stream_open(fname, global);
+ stream_t *s =
+ stream_create(fname, STREAM_ORIGIN_DIRECT | STREAM_READ, NULL, global);
if (s) {
res = stream_read_complete(s, talloc_ctx, max_size);
free_stream(s);
diff --git a/stream/stream.h b/stream/stream.h
index aa764818b7..c85aeffd73 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -32,14 +32,23 @@
// it's guaranteed that you can seek back by <= of this size again.
#define STREAM_BUFFER_SIZE 2048
+// flags for stream_open_ext (this includes STREAM_READ and STREAM_WRITE)
+
// stream->mode
-#define STREAM_READ 0
-#define STREAM_WRITE 1
+#define STREAM_READ 0
+#define STREAM_WRITE (1 << 0)
-// flags for stream_open_ext (this includes STREAM_READ and STREAM_WRITE)
-#define STREAM_SAFE_ONLY 4
-#define STREAM_NETWORK_ONLY 8
-#define STREAM_SILENT 16
+#define STREAM_SILENT (1 << 1)
+
+// Origin value for "security". This is an integer within the flags bit-field.
+#define STREAM_ORIGIN_DIRECT (1 << 2) // passed from cmdline or loadfile
+#define STREAM_ORIGIN_FS (2 << 2) // referenced from playlist on unix FS
+#define STREAM_ORIGIN_NET (3 << 2) // referenced from playlist on network
+#define STREAM_ORIGIN_UNSAFE (4 << 2) // from a grotesque source
+
+#define STREAM_ORIGIN_MASK (7 << 2) // for extracting origin value from flags
+
+// end flags for stream_open_ext (the naming convention sucks)
#define STREAM_UNSAFE -3
#define STREAM_NO_MATCH -2
@@ -100,8 +109,8 @@ typedef struct stream_info_st {
int (*open2)(struct stream *st, struct stream_open_args *args);
const char *const *protocols;
bool can_write; // correctly checks for READ/WRITE modes
- bool is_safe; // opening is no security issue, even with remote provided URLs
- bool is_network; // used to restrict remote playlist entries to remote URLs
+ int stream_origin; // 0 or set of STREAM_ORIGIN_*; if 0, the same origin
+ // is set, or the stream's open() function handles it
} stream_info_t;
typedef struct stream {
@@ -123,6 +132,7 @@ typedef struct stream {
int64_t pos;
int eof; // valid only after read calls that returned a short result
int mode; //STREAM_READ or STREAM_WRITE
+ int stream_origin; // any STREAM_ORIGIN_*
void *priv; // used for DVD, TV, RTSP etc
char *url; // filename/url (possibly including protocol prefix)
char *path; // filename (url without protocol prefix)
@@ -132,7 +142,7 @@ typedef struct stream {
bool streaming : 1; // known to be a network stream if true
bool seekable : 1; // presence of general byte seeking support
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 is_network : 1; // I really don't know what this is for
bool is_local_file : 1; // from the filesystem
bool is_directory : 1; // directory on the filesystem
bool access_references : 1; // open other streams
@@ -223,7 +233,6 @@ struct stream_open_args {
int stream_create_with_args(struct stream_open_args *args, struct stream **ret);
struct stream *stream_create(const char *url, int flags,
struct mp_cancel *c, struct mpv_global *global);
-struct stream *stream_open(const char *filename, struct mpv_global *global);
stream_t *open_output_stream(const char *filename, struct mpv_global *global);
void mp_url_unescape_inplace(char *buf);
diff --git a/stream/stream_avdevice.c b/stream/stream_avdevice.c
index 5185b7a844..3cfdfe1a53 100644
--- a/stream/stream_avdevice.c
+++ b/stream/stream_avdevice.c
@@ -30,4 +30,5 @@ const stream_info_t stream_info_avdevice = {
.name = "avdevice",
.open = open_f,
.protocols = (const char*const[]){ "avdevice", "av", NULL },
+ .stream_origin = STREAM_ORIGIN_UNSAFE,
};
diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c
index 1d57730539..19e99a458b 100644
--- a/stream/stream_bluray.c
+++ b/stream/stream_bluray.c
@@ -512,12 +512,14 @@ const stream_info_t stream_info_bluray = {
.name = "bd",
.open = bluray_stream_open,
.protocols = (const char*const[]){ "bd", "br", "bluray", NULL },
+ .stream_origin = STREAM_ORIGIN_UNSAFE,
};
const stream_info_t stream_info_bdnav = {
.name = "bdnav",
.open = bluray_stream_open,
.protocols = (const char*const[]){ "bdnav", "brnav", "bluraynav", NULL },
+ .stream_origin = STREAM_ORIGIN_UNSAFE,
};
static bool check_bdmv(const char *path)
@@ -605,4 +607,5 @@ const stream_info_t stream_info_bdmv_dir = {
.name = "bdmv/bluray",
.open = bdmv_dir_stream_open,
.protocols = (const char*const[]){ "file", "", NULL },
+ .stream_origin = STREAM_ORIGIN_UNSAFE,
};
diff --git a/stream/stream_cb.c b/stream/stream_cb.c
index ba0b3e5da3..238dd1ac1c 100644
--- a/stream/stream_cb.c
+++ b/stream/stream_cb.c
@@ -106,4 +106,5 @@ static int open_cb(stream_t *stream)
const stream_info_t stream_info_cb = {
.name = "stream_callback",
.open = open_cb,
+ .stream_origin = STREAM_ORIGIN_UNSAFE,
};
diff --git a/stream/stream_cdda.c b/stream/stream_cdda.c
index 158cfd0646..87be426992 100644
--- a/stream/stream_cdda.c
+++ b/stream/stream_cdda.c
@@ -401,4 +401,5 @@ const stream_info_t stream_info_cdda = {
.name = "cdda",
.open = open_cdda,
.protocols = (const char*const[]){"cdda", NULL },
+ .stream_origin = STREAM_ORIGIN_UNSAFE,
};
diff --git a/stream/stream_concat.c b/stream/stream_concat.c
index a10fee7912..060583a604 100644
--- a/stream/stream_concat.c
+++ b/stream/stream_concat.c
@@ -151,7 +151,7 @@ struct stream *stream_concat_open(struct mpv_global *global, struct mp_cancel *c
.global = global,
.cancel = c,
.url = "concat://",
- .flags = STREAM_READ | STREAM_SILENT,
+ .flags = STREAM_READ | STREAM_SILENT | STREAM_ORIGIN_DIRECT,
.sinfo = &stream_info_concat,
.special_arg = &arg,
};
diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c
index d6907cb792..c14cce8420 100644
--- a/stream/stream_dvb.c
+++ b/stream/stream_dvb.c
@@ -1267,4 +1267,5 @@ const stream_info_t stream_info_dvb = {
.name = "dvbin",