ref: 85f7aa22733e412a91f29555c502610bbc797e9f
parent: 836104b143ed839abe871a74df3df9ff64eb4c7c
author: Timothy B. Terriberry <[email protected]>
date: Fri Apr 24 09:51:43 EDT 2020
Fix handling of holes again. It is possible for us to buffer multiple out-of-sequence pages with no packets on them before getting one that does have packets. In this case, libogg will report each hole in the page sequence numbers separately. Since we were only checking for the actual packets once after encountering a hole, if the total number of holes was even, we could exit op_fetch_and_process_page() with valid packets still in the libogg buffer. Then, if the next page had a lot of packets, we might wind up with a total of more than 255 of them, overflowing our stack buffer for their durations. That's bad. Instead, make sure we always drain all hole reports from libogg any time we encounter one, to ensure we get the actual packets behind it. Thanks to Felicia Lim for the report.
--- a/src/opusfile.c
+++ b/src/opusfile.c
@@ -1990,9 +1990,12 @@
Drain the packets from the page anyway.
If we don't, they'll still be there when we fetch the next page.
Then, when we go to pull out packets, we might get more than 255,
- which would overrun our packet buffer.*/
- total_duration=op_collect_audio_packets(_of,durations);
- OP_ASSERT(total_duration>=0);
+ which would overrun our packet buffer.
+ We repeat this call until we get any actual packets, since we might
+ have buffered multiple out-of-sequence pages with no packets on
+ them.*/
+ do total_duration=op_collect_audio_packets(_of,durations);
+ while(total_duration<0);
if(!_ignore_holes){
/*Report the hole to the caller after we finish timestamping the
packets.*/