fseek() resets the EOF flag, even if seeking past the end of a read-only file.
This causes problems when stb_image tries to do this with stdio callbacks with a maliciously crafted file (or just an unfortunately corrupt one)... // calls fread(), sets EOF flag, sets s->read_from_callbacks = 0 stbi__refill_buffer(s); // calls fseek(), which resets the stream's EOF flag stbi__skip(some value we just read) // calls feof(), which always returns false because EOF flag was reset. while (!stbi__at_eof(s)) { // never calls fread() because s->read_from_callbacks==0 stbi__refill_buffer(s); // loop forever } To work around this, after seeking, we call fgetc(), which will set the EOF flag as appropriate, and if not at EOF, we ungetc the byte so future reads are correct. This fixes the infinite loop.
This commit is contained in:
parent
f54acd4e13
commit
00f3f01be3
@ -789,7 +789,12 @@ static int stbi__stdio_read(void *user, char *data, int size)
|
||||
|
||||
static void stbi__stdio_skip(void *user, int n)
|
||||
{
|
||||
int ch;
|
||||
fseek((FILE*) user, n, SEEK_CUR);
|
||||
ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */
|
||||
if (ch != EOF) {
|
||||
ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */
|
||||
}
|
||||
}
|
||||
|
||||
static int stbi__stdio_eof(void *user)
|
||||
|
Loading…
Reference in New Issue
Block a user