diff --git a/Fix-short-circuit-test-when-seeking-in-short-files.patch b/Fix-short-circuit-test-when-seeking-in-short-files.patch new file mode 100644 index 0000000..1d591a6 --- /dev/null +++ b/Fix-short-circuit-test-when-seeking-in-short-files.patch @@ -0,0 +1,50 @@ +From 4174c26e0aaab19d01afdea0a46f7f95fdc6b3e6 Mon Sep 17 00:00:00 2001 +From: "Timothy B. Terriberry" +Date: Tue, 13 Oct 2020 12:30:41 -0700 +Subject: [PATCH] Fix short-circuit test when seeking in short files + +When a file is very, very short (i.e., only one packet) and uses + end-trimming, the apparent granule position preceding the first + sample in the first packet can underflow. +We were computing this value by subtracting the packet duration + from the computed per-packet granule position and expecting this + computation to always succeed. +Because it could fail in the presence of end-trimming on the first + packet (ironically, exactly the situation where the short-circuit + is helpful), it would leave the value uninitialized, and then use + it in a comparison, which is undefined behavior. +The correct solution is to check for failure and force the previous + page's granule position to 0 in this case. +--- + src/opusfile.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/src/opusfile.c b/src/opusfile.c +index 0d09e97..5bf9f91 100644 +--- a/src/opusfile.c ++++ b/src/opusfile.c +@@ -2358,8 +2358,19 @@ static int op_pcm_seek_page(OggOpusFile *_of, + For very small files (with all of the data in a single page, + generally 1 second or less), we can loop them continuously + without seeking at all.*/ +- OP_ALWAYS_TRUE(!op_granpos_add(&prev_page_gp,_of->op[0].granulepos, +- -op_get_packet_duration(_of->op[0].packet,_of->op[0].bytes))); ++ if(op_granpos_add(&prev_page_gp,_of->op[0].granulepos, ++ -op_get_packet_duration(_of->op[0].packet,_of->op[0].bytes))<0) { ++ /*We validate/sanitize the per-packet timestamps, so the only way ++ we should fail to calculate a granule position for the ++ previous page is if the first page with completed packets in ++ the stream is also the last, and end-trimming causes the ++ apparent granule position preceding the first sample in the ++ first packet to underflow. ++ The starting PCM offset is then 0 by spec mandate (see also: ++ op_find_initial_pcm_offset()).*/ ++ OP_ASSERT(_of->op[0].e_o_s); ++ prev_page_gp=0; ++ } + if(op_granpos_cmp(prev_page_gp,_target_gp)<=0){ + /*Don't call op_decode_clear(), because it will dump our + packets.*/ +-- +2.30.0 + diff --git a/opusfile.spec b/opusfile.spec index 90394ea..f67090e 100644 --- a/opusfile.spec +++ b/opusfile.spec @@ -1,11 +1,12 @@ Name: opusfile Version: 0.11 -Release: 3 +Release: 4 Summary: A high-level API provides seeking, decode, and playback of Opus streams License: BSD URL: http://www.opus-codec.org/ Source0: http://downloads.xiph.org/releases/opus/%{name}-%{version}.tar.gz Patch0000: 0001-fix-MemorySanitizer-use-of-uninitialized-value.patch +Patch0001: Fix-short-circuit-test-when-seeking-in-short-files.patch BuildRequires: libogg-devel openssl-devel opus-devel @@ -50,6 +51,9 @@ Development package for opusfile package. %{_libdir}/{libopusfile.so,libopusurl.so} %changelog +* Tue Dec 14 2021 chenchen - 0.11-4 +- Fix short-circuit test when seeking in short files + * Thu Dec 03 2020 maminjie - 0.11-3 - fix MemorySanitizer: use-of-uninitialized-value