ref: 8d153c572972830bbf71f98cef25c16a6ea733cc
parent: ec63ede671f9af57e1bde766586f923183ae99a0
author: Timothy B. Terriberry <tterribe@xiph.org>
date: Fri Apr 11 05:01:28 EDT 2025
Avoid rescanning invalid regions during file open. If there is a large region of invalid data in the middle of the file, avoid scanning it repeatedly during chain boundary enumeration. Because of the bisection, doing that would only be O(n*log(n)), not quadratic like op_get_last_page(), but still good to avoid.
--- a/src/opusfile.c
+++ b/src/opusfile.c
@@ -1189,6 +1189,7 @@
/*We guard against garbage separating the last and first pages of two
links below.*/
while(_searched<end_searched){
+ opus_int64 boundary;
opus_int32 next_bias;
/*If we don't have a better estimate, use simple bisection.*/
if(bisect==-1)bisect=_searched+(end_searched-_searched>>1);
@@ -1199,7 +1200,14 @@
else end_gp=-1;
ret=op_seek_helper(_of,bisect);
if(OP_UNLIKELY(ret<0))return ret;
- last=op_get_next_page(_of,&og,_sr[nsr-1].offset);
+ /*If there is a large region of invalid data in the middle of the file,
+ avoid scanning it repeatedly.
+ Because of the bisection, doing that would only be O(n*log(n)), not
+ quadratic like op_get_last_page(), but still good to avoid.*/
+ OP_ASSERT(end_searched<=_sr[nsr-1].search_start);
+ boundary=OP_MIN(_sr[nsr-1].offset,
+ OP_ADV_OFFSET(end_searched,OP_PAGE_SIZE_MAX-1));
+ last=op_get_next_page(_of,&og,boundary);
if(OP_UNLIKELY(last<OP_FALSE))return (int)last;
next_bias=0;
if(last==OP_FALSE)end_searched=bisect;
--
⑨