summaryrefslogtreecommitdiffstats
path: root/demux/demux_libarchive.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-08-24 22:21:36 +0200
committerwm4 <wm4@nowhere>2015-08-24 22:26:07 +0200
commita48a8a746eea66cae66056cfd46d1a1693afc1c3 (patch)
tree5b3a763f0bab0cc0083d07903351a9618e922367 /demux/demux_libarchive.c
parent3bbcbc15a5be6f174baf5783785c8d070fa037cf (diff)
downloadmpv-a48a8a746eea66cae66056cfd46d1a1693afc1c3.tar.bz2
mpv-a48a8a746eea66cae66056cfd46d1a1693afc1c3.tar.xz
demux_libarchive: don't allow probing to read unlimited data
Instead, allow reading 2KB only. This seems to be sufficient for libarchive to recognize zip, 7z, rar, tar. Good enough. This is implemented by creating an in-memory stream with a copy of the file header. If libarchive succeeds opening this, the actual stream is opened. Allowing unlimited reading could break unseekable streams, such as playing from http servers with no range request support or pipes. Also, we try not to read too much data in the first probe pass. Some slow network streams like shoutcast services could make probing much slower if we allow it to read too much. In the second probing pass, actually allow 200KB.
Diffstat (limited to 'demux/demux_libarchive.c')
-rw-r--r--demux/demux_libarchive.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/demux/demux_libarchive.c b/demux/demux_libarchive.c
index d0afb624c5..1ce8b32244 100644
--- a/demux/demux_libarchive.c
+++ b/demux/demux_libarchive.c
@@ -32,13 +32,25 @@ static int cmp_filename(const void *a, const void *b)
static int open_file(struct demuxer *demuxer, enum demux_check check)
{
- if (stream_get_size(demuxer->stream) == 0)
- return -1;
-
int flags = 0;
- if (check <= DEMUX_CHECK_REQUEST)
+ int probe_size = STREAM_BUFFER_SIZE;
+ if (check <= DEMUX_CHECK_REQUEST) {
flags |= MP_ARCHIVE_FLAG_UNSAFE;
- struct mp_archive *mpa = mp_archive_new(demuxer->log, demuxer->stream, flags);
+ probe_size *= 100;
+ }
+
+ bstr probe = stream_peek(demuxer->stream, probe_size);
+ if (probe.len == 0)
+ return -1;
+ struct stream *probe_stream = open_memory_stream(probe.start, probe.len);
+ struct mp_archive *mpa = mp_archive_new(mp_null_log, probe_stream, flags);
+ bool ok = !!mpa;
+ free_stream(probe_stream);
+ mp_archive_free(mpa);
+ if (!ok)
+ return -1;
+
+ mpa = mp_archive_new(demuxer->log, demuxer->stream, flags);
if (!mpa)
return -1;