mirror of https://github.com/mpv-player/mpv
stream: make stream_read_file() more robust
Change it to strictly accept local paths only. No more http://, no more $HOME expansion with "~/" or mpv config path expansion with "~~/". This should behave as if passing a path directly to open(). Reduce annoying log noise to further facilitate it using as open() replacement.
This commit is contained in:
parent
a600d152d2
commit
ad9f3bfe96
|
@ -319,6 +319,11 @@ static int stream_create_instance(const stream_info_t *sinfo,
|
|||
*ret = NULL;
|
||||
|
||||
const char *path = url;
|
||||
|
||||
if (flags & STREAM_LOCAL_FS_ONLY) {
|
||||
if (!sinfo->local_fs)
|
||||
return STREAM_NO_MATCH;
|
||||
} else {
|
||||
for (int n = 0; sinfo->protocols && sinfo->protocols[n]; n++) {
|
||||
path = match_proto(url, sinfo->protocols[n]);
|
||||
if (path)
|
||||
|
@ -327,6 +332,7 @@ static int stream_create_instance(const stream_info_t *sinfo,
|
|||
|
||||
if (!path)
|
||||
return STREAM_NO_MATCH;
|
||||
}
|
||||
|
||||
stream_t *s = talloc_zero(NULL, stream_t);
|
||||
s->global = args->global;
|
||||
|
@ -343,6 +349,9 @@ static int stream_create_instance(const stream_info_t *sinfo,
|
|||
s->mode = flags & (STREAM_READ | STREAM_WRITE);
|
||||
s->requested_buffer_size = opts->buffer_size;
|
||||
|
||||
if (flags & STREAM_LESS_NOISE)
|
||||
mp_msg_set_max_level(s->log, MSGL_WARN);
|
||||
|
||||
int opt;
|
||||
mp_read_option_raw(s->global, "access-references", &m_option_type_flag, &opt);
|
||||
s->access_references = opt;
|
||||
|
@ -820,14 +829,13 @@ struct bstr stream_read_file(const char *filename, void *talloc_ctx,
|
|||
struct mpv_global *global, int max_size)
|
||||
{
|
||||
struct bstr res = {0};
|
||||
char *fname = mp_get_user_path(NULL, global, filename);
|
||||
stream_t *s =
|
||||
stream_create(fname, STREAM_ORIGIN_DIRECT | STREAM_READ, NULL, global);
|
||||
int flags = STREAM_ORIGIN_DIRECT | STREAM_READ | STREAM_LOCAL_FS_ONLY |
|
||||
STREAM_LESS_NOISE;
|
||||
stream_t *s = stream_create(filename, flags, NULL, global);
|
||||
if (s) {
|
||||
res = stream_read_complete(s, talloc_ctx, max_size);
|
||||
free_stream(s);
|
||||
}
|
||||
talloc_free(fname);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@
|
|||
|
||||
#define STREAM_ORIGIN_MASK (7 << 2) // for extracting origin value from flags
|
||||
|
||||
#define STREAM_LOCAL_FS_ONLY (1 << 5) // stream_file only, no URLs
|
||||
#define STREAM_LESS_NOISE (1 << 6) // try to log errors only
|
||||
|
||||
// end flags for stream_open_ext (the naming convention sucks)
|
||||
|
||||
#define STREAM_UNSAFE -3
|
||||
|
@ -109,6 +112,7 @@ 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 local_fs; // supports STREAM_LOCAL_FS_ONLY
|
||||
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;
|
||||
|
@ -218,6 +222,7 @@ struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
|
|||
int max_size);
|
||||
struct bstr stream_read_file(const char *filename, void *talloc_ctx,
|
||||
struct mpv_global *global, int max_size);
|
||||
|
||||
int stream_control(stream_t *s, int cmd, void *arg);
|
||||
void free_stream(stream_t *s);
|
||||
|
||||
|
|
|
@ -246,7 +246,7 @@ static bool check_stream_network(int fd)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int open_f(stream_t *stream)
|
||||
static int open_f(stream_t *stream, struct stream_open_args *args)
|
||||
{
|
||||
struct priv *p = talloc_ptrtype(stream, p);
|
||||
*p = (struct priv) {
|
||||
|
@ -255,18 +255,21 @@ static int open_f(stream_t *stream)
|
|||
stream->priv = p;
|
||||
stream->is_local_file = true;
|
||||
|
||||
bool strict_fs = args->flags & STREAM_LOCAL_FS_ONLY;
|
||||
bool write = stream->mode == STREAM_WRITE;
|
||||
int m = O_CLOEXEC | (write ? O_RDWR | O_CREAT | O_TRUNC : O_RDONLY);
|
||||
|
||||
char *filename = mp_file_url_to_filename(stream, bstr0(stream->url));
|
||||
if (filename) {
|
||||
stream->path = filename;
|
||||
} else {
|
||||
filename = stream->path;
|
||||
char *filename = stream->path;
|
||||
char *url = "";
|
||||
if (!strict_fs) {
|
||||
char *fn = mp_file_url_to_filename(stream, bstr0(stream->url));
|
||||
if (fn)
|
||||
filename = stream->path = fn;
|
||||
url = stream->url;
|
||||
}
|
||||
|
||||
bool is_fdclose = strncmp(stream->url, "fdclose://", 10) == 0;
|
||||
if (strncmp(stream->url, "fd://", 5) == 0 || is_fdclose) {
|
||||
bool is_fdclose = strncmp(url, "fdclose://", 10) == 0;
|
||||
if (strncmp(url, "fd://", 5) == 0 || is_fdclose) {
|
||||
char *begin = strstr(stream->url, "://") + 3, *end = NULL;
|
||||
p->fd = strtol(begin, &end, 0);
|
||||
if (!end || end == begin || end[0]) {
|
||||
|
@ -275,7 +278,7 @@ static int open_f(stream_t *stream)
|
|||
}
|
||||
if (is_fdclose)
|
||||
p->close = true;
|
||||
} else if (!strcmp(filename, "-")) {
|
||||
} else if (!strict_fs && !strcmp(filename, "-")) {
|
||||
if (!write) {
|
||||
MP_INFO(stream, "Reading from stdin...\n");
|
||||
p->fd = 0;
|
||||
|
@ -306,6 +309,7 @@ static int open_f(stream_t *stream)
|
|||
if (fstat(p->fd, &st) == 0) {
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
stream->is_directory = true;
|
||||
if (!(args->flags & STREAM_LESS_NOISE))
|
||||
MP_INFO(stream, "This is a directory - adding to playlist.\n");
|
||||
} else if (S_ISREG(st.st_mode)) {
|
||||
p->regular_file = true;
|
||||
|
@ -350,15 +354,16 @@ static int open_f(stream_t *stream)
|
|||
|
||||
const stream_info_t stream_info_file = {
|
||||
.name = "file",
|
||||
.open = open_f,
|
||||
.open2 = open_f,
|
||||
.protocols = (const char*const[]){ "file", "", "appending", NULL },
|
||||
.can_write = true,
|
||||
.local_fs = true,
|
||||
.stream_origin = STREAM_ORIGIN_FS,
|
||||
};
|
||||
|
||||
const stream_info_t stream_info_fd = {
|
||||
.name = "fd",
|
||||
.open = open_f,
|
||||
.open2 = open_f,
|
||||
.protocols = (const char*const[]){ "fd", "fdclose", NULL },
|
||||
.can_write = true,
|
||||
.stream_origin = STREAM_ORIGIN_UNSAFE,
|
||||
|
|
Loading…
Reference in New Issue