summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-09-08 16:16:20 +0200
committerJan Ekström <jeebjp@gmail.com>2018-10-01 18:54:54 +0300
commite74ffab36ea3d8fce4408d9d2c75142187c594c3 (patch)
tree391fef046b9b0a6c31c8b2b8db2c58325b2fb1ec
parent4f47596043121c32d1e6724db28f21aaaf6303ff (diff)
downloadmpv-e74ffab36ea3d8fce4408d9d2c75142187c594c3.tar.bz2
mpv-e74ffab36ea3d8fce4408d9d2c75142187c594c3.tar.xz
stream_libarchive: fix hangs when demuxer does out of bound seeks
This happened with a .flac file inside an archive. It tried to seek beyond the end of the archive entry in a format where seeking isn't supported. stream_libarchive handles these situations by skipping data. But when the end of the archive is reached, archive_read_data() returns 0. While libarchive didn't bother to fucking document this, they do say it's supposed to work like read(), so I guess a return value of 0 really means EOF. So change the "< 0" to "<= 0". Also add some error logging. The same file actually worked without out of bounds reads when extracted, so there still might be something very wrong. (cherry picked from commit 7e85dc2167b7524308159915d5c1d3341464977f)
-rw-r--r--stream/stream_libarchive.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/stream/stream_libarchive.c b/stream/stream_libarchive.c
index bb25c6ad84..119af8eea4 100644
--- a/stream/stream_libarchive.c
+++ b/stream/stream_libarchive.c
@@ -432,8 +432,15 @@ static int archive_entry_seek(stream_t *s, int64_t newpos)
int size = MPMIN(newpos - s->pos, sizeof(buffer));
locale_t oldlocale = uselocale(p->mpa->locale);
int r = archive_read_data(p->mpa->arch, buffer, size);
- if (r < 0) {
- MP_ERR(s, "%s\n", archive_error_string(p->mpa->arch));
+ if (r <= 0) {
+ if (r == 0 && newpos > p->entry_size) {
+ MP_ERR(s, "demuxer trying to seek beyond end of archive "
+ "entry\n");
+ } else if (r == 0) {
+ MP_ERR(s, "end of archive entry reached while seeking\n");
+ } else {
+ MP_ERR(s, "%s\n", archive_error_string(p->mpa->arch));
+ }
uselocale(oldlocale);
if (mp_archive_check_fatal(p->mpa, r)) {
mp_archive_free(p->mpa);