stream_libarchive: seek source stream to 0 before probing

If p->mpa = NULL due to an error during a seek or fill_buffer, then when
archive_entry_seek(), if newpos != s->pos, reopen_archive() ->
mp_archive_new() -> mp_archive_probe(), which asserts stream_tell(src)
== 0. This won't be the case if the previous mpa left the source stream
seeked in the middle of the file.

For example, in samples in archives where avformat_find_stream_info
takes a long time, if playback is aborted while the demuxer is doing
that, reading from the source stream will stop working due to cancels
being triggered. When archive_entry_seek() and newpos != s->pos,
reopen_archive() -> mp_archive_new_raw() -> archive_read_open1() fails
and returns with mpa == NULL due to reads not working. Then when another
seek happens, reopen_archive() -> mp_archive_new() -> mp_archive_probe()
-> assertion failed.

One solution is to have reopen_archive return STREAM_ERROR if the stream
is cancelled, since nothing useful can happen in this case. But there
are other situations where p->mpa could become NULL (fatal errors), and
it is supposed to be possible to seek back to a working area of the
archive.

Fixes: https://github.com/mpv-player/mpv/issues/15174
This commit is contained in:
Attila Fidan authored and sfan5 committed 2025-08-12 18:38:50 +02:00
1 parent 01b7edcc71
commit 211c9cb7c9
1 file changed
+4 -1
+4 -1
View File
@@ -80,7 +80,10 @@ static bool probe_zip(struct stream *s)
static int mp_archive_probe(struct stream *src)
{
int flags = 0;
mp_assert(stream_tell(src) == 0);
stream_seek(src, 0);
if (stream_tell(src) != 0)
return flags;
if (probe_zip(src))
flags |= MP_ARCHIVE_FLAG_MAYBE_ZIP;