mirror of
https://github.com/mpv-player/mpv
synced 2025-01-03 13:32:16 +00:00
player: always load playlists
Until now, you had to use --load-unsafe-playlists or --playlist to get playlists loaded. Change this and always load playlists by default. This still attempts to reject unsafe URLs. For example, trying to invoke libavdevice pseudo-demuxer is explicitly prevented. Local paths and any http links (and some more) are always allowed.
This commit is contained in:
parent
fc0fa9a221
commit
866e0e1670
@ -198,20 +198,12 @@ Playback Control
|
||||
(i.e. not with stdin, pipe, etc).
|
||||
|
||||
``--load-unsafe-playlists``
|
||||
Normally, something like ``mpv playlist.m3u`` won't load the playlist. This
|
||||
is because the playlist code is unsafe. (This is the same in all other
|
||||
variations of MPlayer.)
|
||||
Load URLs from playlists which are considered unsafe (default: no). This
|
||||
includes special protocols and anything that doesn't refer to normal files.
|
||||
Local files and http links on the other hand are always considered safe.
|
||||
|
||||
See ``--playlist`` for details.
|
||||
|
||||
Note: this option will allow opening playlists using the ``playlist``
|
||||
special demuxer. The ``--playlist`` uses different code, and supports more
|
||||
playlist formats than the playlist demuxer. This means that for now, the
|
||||
``--playlist`` option should always be used if you intend to open playlists.
|
||||
Background: the special demuxer contains newly written code, while the
|
||||
``--playlist`` option uses the old MPlayer code. Adding support for more
|
||||
playlist formats to the special demuxer is work in progress, and eventually
|
||||
the old code should disappear.
|
||||
Note that ``--playlist`` always loads all entries, so you use that instead
|
||||
if you really have the need for this functionality.
|
||||
|
||||
``--loop-file``
|
||||
Loop a single file. The difference to ``--loop=inf`` is that this doesn't
|
||||
|
@ -41,6 +41,9 @@ struct playlist_entry {
|
||||
bool playback_short : 1;
|
||||
// Set to true if not at least 1 frame (audio or video) could be played.
|
||||
bool init_failed : 1;
|
||||
// If set, assume that this is e.g. from an external playlist, and needs an
|
||||
// additional safety check.
|
||||
bool unsafe_origin : 1;
|
||||
};
|
||||
|
||||
struct playlist {
|
||||
|
@ -1084,7 +1084,10 @@ static void play_current_file(struct MPContext *mpctx)
|
||||
}
|
||||
stream_filename = mpctx->resolve_result->url;
|
||||
}
|
||||
mpctx->stream = stream_open(stream_filename, mpctx->global);
|
||||
int stream_flags = STREAM_READ;
|
||||
if (mpctx->playlist->current->unsafe_origin && !opts->load_unsafe_playlists)
|
||||
stream_flags |= STREAM_SAFE_ONLY;
|
||||
mpctx->stream = stream_create(stream_filename, stream_flags, mpctx->global);
|
||||
if (!mpctx->stream) { // error...
|
||||
demux_was_interrupted(mpctx);
|
||||
goto terminate_playback;
|
||||
@ -1127,16 +1130,10 @@ goto_reopen_demuxer: ;
|
||||
mpctx->initialized_flags |= INITIALIZED_DEMUXER;
|
||||
|
||||
if (mpctx->demuxer->playlist) {
|
||||
if (mpctx->demuxer->stream->safe_origin || opts->load_unsafe_playlists) {
|
||||
transfer_playlist(mpctx, mpctx->demuxer->playlist);
|
||||
} else {
|
||||
MP_ERR(mpctx, "\nThis looks like a playlist, but playlist support "
|
||||
"will not be used automatically.\nThe main problem with "
|
||||
"playlist safety is that playlist entries can be arbitrary,\n"
|
||||
"and an attacker could make mpv poke around in your local "
|
||||
"filesystem or network.\nUse --playlist=file or the "
|
||||
"--load-unsafe-playlists option to load them anyway.\n");
|
||||
}
|
||||
struct playlist *pl = mpctx->demuxer->playlist;
|
||||
for (struct playlist_entry *e = pl->first; e; e = e->next)
|
||||
e->unsafe_origin |= !mpctx->demuxer->stream->safe_origin;
|
||||
transfer_playlist(mpctx, pl);
|
||||
goto terminate_playback;
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,7 @@ extern const stream_info_t stream_info_null;
|
||||
extern const stream_info_t stream_info_memory;
|
||||
extern const stream_info_t stream_info_mf;
|
||||
extern const stream_info_t stream_info_ffmpeg;
|
||||
extern const stream_info_t stream_info_ffmpeg_unsafe;
|
||||
extern const stream_info_t stream_info_avdevice;
|
||||
extern const stream_info_t stream_info_file;
|
||||
extern const stream_info_t stream_info_ifo;
|
||||
@ -77,6 +78,7 @@ static const stream_info_t *const stream_list[] = {
|
||||
&stream_info_cdda,
|
||||
#endif
|
||||
&stream_info_ffmpeg,
|
||||
&stream_info_ffmpeg_unsafe,
|
||||
&stream_info_avdevice,
|
||||
#if HAVE_DVBIN
|
||||
&stream_info_dvb,
|
||||
@ -257,6 +259,8 @@ static int open_internal(const stream_info_t *sinfo, struct stream *underlying,
|
||||
return STREAM_NO_MATCH;
|
||||
if (sinfo->stream_filter && (flags & STREAM_NO_FILTERS))
|
||||
return STREAM_NO_MATCH;
|
||||
if (!sinfo->is_safe && (flags & STREAM_SAFE_ONLY))
|
||||
return STREAM_UNSAFE;
|
||||
|
||||
const char *path = NULL;
|
||||
// Stream filters use the original URL, with no protocol matching at all.
|
||||
@ -335,18 +339,30 @@ struct stream *stream_create(const char *url, int flags, struct mpv_global *glob
|
||||
assert(url);
|
||||
|
||||
// Open stream proper
|
||||
bool unsafe = false;
|
||||
for (int i = 0; stream_list[i]; i++) {
|
||||
int r = open_internal(stream_list[i], NULL, url, flags, global, &s);
|
||||
if (r == STREAM_OK)
|
||||
break;
|
||||
if (r == STREAM_NO_MATCH || r == STREAM_UNSUPPORTED)
|
||||
continue;
|
||||
if (r == STREAM_UNSAFE) {
|
||||
unsafe = true;
|
||||
continue;
|
||||
}
|
||||
if (r != STREAM_OK) {
|
||||
mp_err(log, "Failed to open %s.\n", url);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!s && unsafe) {
|
||||
mp_err(log, "\nRefusing to load potentially unsafe URL from a playlist.\n"
|
||||
"Use --playlist=file or the --load-unsafe-playlists option to "
|
||||
"load it anyway.\n\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!s) {
|
||||
mp_err(log, "No stream found to handle url %s\n", url);
|
||||
goto done;
|
||||
|
@ -55,7 +55,9 @@ enum streamtype {
|
||||
|
||||
// flags for stream_open_ext (this includes STREAM_READ and STREAM_WRITE)
|
||||
#define STREAM_NO_FILTERS 2
|
||||
#define STREAM_SAFE_ONLY 4
|
||||
|
||||
#define STREAM_UNSAFE -3
|
||||
#define STREAM_NO_MATCH -2
|
||||
#define STREAM_UNSUPPORTED -1
|
||||
#define STREAM_ERROR 0
|
||||
@ -141,6 +143,7 @@ typedef struct stream_info_st {
|
||||
const char *const *url_options;
|
||||
bool stream_filter;
|
||||
bool can_write;
|
||||
bool is_safe;
|
||||
} stream_info_t;
|
||||
|
||||
typedef struct stream {
|
||||
|
@ -281,4 +281,5 @@ const stream_info_t stream_info_file = {
|
||||
.open = open_f,
|
||||
.protocols = (const char*const[]){ "file", "", NULL },
|
||||
.can_write = true,
|
||||
.is_safe = true,
|
||||
};
|
||||
|
@ -322,10 +322,24 @@ const stream_info_t stream_info_ffmpeg = {
|
||||
.name = "ffmpeg",
|
||||
.open = open_f,
|
||||
.protocols = (const char *const[]){
|
||||
"lavf", "ffmpeg", "rtmp", "rtsp", "http", "https", "mms", "mmst", "mmsh",
|
||||
"mmshttp", "udp", "ftp", "rtp", "httpproxy", "hls", "rtmpe", "rtmps",
|
||||
"rtmpt", "rtmpte", "rtmpts", "srtp", "tcp", "udp", "tls", "unix", "sftp",
|
||||
"rtmp", "rtsp", "http", "https", "mms", "mmst", "mmsh", "mmshttp", "rtp",
|
||||
"httpproxy", "hls", "rtmpe", "rtmps", "rtmpt", "rtmpte", "rtmpts", "srtp",
|
||||
"md5",
|
||||
NULL },
|
||||
.can_write = true,
|
||||
.is_safe = true,
|
||||
};
|
||||
|
||||
// Unlike above, this is not marked as safe, and can contain protocols which
|
||||
// may do insecure things. (Such as "ffmpeg", which can access the "lavfi"
|
||||
// pseudo-demuxer, which in turn gives access to filters that can access the
|
||||
// local filesystem.)
|
||||
const stream_info_t stream_info_ffmpeg_unsafe = {
|
||||
.name = "ffmpeg",
|
||||
.open = open_f,
|
||||
.protocols = (const char *const[]){
|
||||
"lavf", "ffmpeg", "udp", "ftp", "tcp", "tls", "unix", "sftp",
|
||||
NULL },
|
||||
.can_write = true,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user