Skip to content

Commit 4e18f01

Browse files
committed
Validate seek offsets in cfseek
Invalid values previously corrupted the internal position counter which caused crashes on some platforms because the position counter would overflow in the next read operation. I added some assertions to track the position counter corruption and it's probably a good idea to leave them in to catch possible future errors early. The actual fix was to just ensure that the seek position it always valid for the file. This fixes #1059.
1 parent f67a42d commit 4e18f01

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

code/cfile/cfilearchive.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,15 @@ int cfseek( CFILE *cfile, int offset, int where )
161161
default:
162162
Int3();
163163
return 1;
164-
}
164+
}
165+
166+
// Make sure we don't seek beyond the end of the file
167+
CAP(goal_position, cb->lib_offset, cb->lib_offset + cb->size);
165168

166169
int result = fseek(cb->fp, (long)goal_position, SEEK_SET );
170+
Assertion(goal_position >= cb->lib_offset, "Invalid offset values detected while seeking! Goal was " SIZE_T_ARG ", lib_offset is " SIZE_T_ARG ".", goal_position, cb->lib_offset);
167171
cb->raw_position = goal_position - cb->lib_offset;
172+
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
168173

169174
#if defined(CHECK_POSITION) && !defined(NDEBUG)
170175
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;
@@ -200,6 +205,7 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
200205
}
201206

202207
if ( (cb->raw_position+size) > cb->size ) {
208+
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
203209
size = cb->size - cb->raw_position;
204210
if ( size < 1 ) {
205211
return 0;
@@ -219,6 +225,7 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
219225
size_t bytes_read = fread( buf, 1, size, cb->fp );
220226
if ( bytes_read > 0 ) {
221227
cb->raw_position += bytes_read;
228+
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
222229
}
223230

224231
#if defined(CHECK_POSITION) && !defined(NDEBUG)
@@ -249,7 +256,8 @@ int cfread_lua_number(double *buf, CFILE *cfile)
249256

250257
long orig_pos = ftell(cb->fp);
251258
int items_read = fscanf(cb->fp, LUA_NUMBER_SCAN, buf);
252-
cb->raw_position += ftell(cb->fp)-orig_pos;
259+
cb->raw_position += ftell(cb->fp)-orig_pos;
260+
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
253261

254262
#if defined(CHECK_POSITION) && !defined(NDEBUG)
255263
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;

code/libs/ffmpeg/FFmpegContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ int64_t cfileSeek(void* ptr, int64_t offset, int whence) {
4343

4444
auto ret = cfseek(cfile, intOff, op);
4545

46-
if (ret < 0) {
46+
if (ret != 0) {
4747
// Error
4848
return -1;
4949
}

0 commit comments

Comments
 (0)