From 211c9cb7c98cf182c288f646af615501f3546077 Mon Sep 17 00:00:00 2001 From: Attila Fidan Date: Sat, 9 Aug 2025 07:18:09 +0000 Subject: [PATCH] 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 --- stream/stream_libarchive.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stream/stream_libarchive.c b/stream/stream_libarchive.c index 15294ca066..89d1e82075 100644 --- a/stream/stream_libarchive.c +++ b/stream/stream_libarchive.c @@ -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;