Commit 34f945bb authored by Timothy B. Terriberry's avatar Timothy B. Terriberry
Browse files

Fix SEEK_END usage in seek implementations.

When seeking using SEEK_END, the win32-specific implementation of
 op_fseek() would add the offset to the file size to get the
 absolute seek position.
However, op_mem_seek() and op_http_stream_seek() would subtract the
 offset instead.
The documentation of fseek() is not at all clear which behavior is
 correct, but I believe that the op_fseek() behavior is.

This inconsistency didn't matter for opusfile in practice, because
 we only ever use SEEK_END with an offset of 0.
However, the user can also open files with our API and use the
 resulting callbacks for their own purposes, so it would be good to
 be consistent for them.

Thanks to a person who did not wish to be credited for the report.
parent d2577d7f
......@@ -3151,8 +3151,10 @@ static int op_http_stream_seek(void *_stream,opus_int64 _offset,int _whence){
}break;
case SEEK_END:{
/*Check for overflow:*/
if(_offset>content_length||_offset<content_length-OP_INT64_MAX)return -1;
pos=content_length-_offset;
if(_offset<-content_length||_offset>OP_INT64_MAX-content_length){
return -1;
}
pos=content_length+_offset;
}break;
default:return -1;
}
......
......@@ -72,7 +72,7 @@ static int op_fseek(void *_stream,opus_int64 _offset,int _whence){
other libraries (that don't use MSVCRT80 from MSVC 2005 by default).
i686-w64-mingw32 does have fseeko() and respects _FILE_OFFSET_BITS, but I
don't know how to detect that at compile time.
We could just use fseeko64() (which is available in both), but its
We could just use fseeko64() (which is available in both), but it's
implemented using fgetpos()/fsetpos() just like this code, except without
the overflow checking, so we prefer our version.*/
opus_int64 pos;
......@@ -322,8 +322,8 @@ static int op_mem_seek(void *_stream,opus_int64 _offset,int _whence){
size=stream->size;
OP_ASSERT(size>=0);
/*Check for overflow:*/
if(_offset>size||_offset<size-OP_MEM_DIFF_MAX)return -1;
pos=(ptrdiff_t)(size-_offset);
if(_offset<-size||_offset>OP_MEM_DIFF_MAX-size)return -1;
pos=(ptrdiff_t)(size+_offset);
}break;
default:return -1;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment