mirror of http://shamusworld.gotdns.org/git/rmac
Rewrote .incbin's parsing and checks for position and size to increase robustness
This commit is contained in:
parent
e6e125acd9
commit
78d0bcae46
77
direct.c
77
direct.c
|
@ -621,32 +621,40 @@ allright:
|
|||
|
||||
tok += 2;
|
||||
|
||||
size = lseek(fd, 0L, SEEK_END);
|
||||
pos = lseek(fd, 0L, SEEK_SET);
|
||||
|
||||
if (*tok != EOL)
|
||||
{
|
||||
// Check size parameter (can be omitted)
|
||||
if (*tok++ == ',')
|
||||
// Parse size and position parameters
|
||||
uint64_t requested_size = -1; // -1 means "not set" for these two
|
||||
if (*tok++ != ',')
|
||||
{
|
||||
close(fd);
|
||||
return error("expected comma after incbin filename");
|
||||
}
|
||||
if (tok != EOL)
|
||||
{
|
||||
if (*tok != ',')
|
||||
{
|
||||
if (abs_expr(&size) != OK)
|
||||
if (abs_expr(&requested_size) != OK)
|
||||
{
|
||||
close(fd);
|
||||
return ERROR;
|
||||
}
|
||||
if ((int64_t)size <= 0)
|
||||
if ((int64_t)requested_size <= 0 || requested_size > size)
|
||||
{
|
||||
close(fd);
|
||||
return error("invalid incbin size requested");
|
||||
}
|
||||
}
|
||||
else
|
||||
size = lseek(fd, 0L, SEEK_END);
|
||||
}
|
||||
|
||||
// Check offset parameter (can be omitted)
|
||||
if (*tok != EOL)
|
||||
{
|
||||
if (*tok++ == ',')
|
||||
if (*tok != EOL)
|
||||
{
|
||||
if (*tok++ != ',')
|
||||
{
|
||||
close(fd);
|
||||
return error("expected comma after size parameter");
|
||||
}
|
||||
if (*tok != EOL)
|
||||
{
|
||||
if (abs_expr(&pos) != OK)
|
||||
|
@ -654,30 +662,37 @@ allright:
|
|||
close(fd);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
lseek(fd, pos, SEEK_SET);
|
||||
if ((int64_t)(size - pos) < 0)
|
||||
if ((int64_t)pos <= 0 || pos > size)
|
||||
{
|
||||
return error("requested incbin size out of range");
|
||||
close(fd);
|
||||
return error("invalid incbin position requested");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// offset parameter omitted, so it's 0
|
||||
pos = lseek(fd, 0L, SEEK_SET);
|
||||
}
|
||||
}
|
||||
else
|
||||
return error(comma_error);
|
||||
|
||||
if (*tok != EOL)
|
||||
{
|
||||
close(fd);
|
||||
return error("extra characters following incbin");
|
||||
}
|
||||
}
|
||||
else
|
||||
pos = lseek(fd, 0L, SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
// size & pos not given, so assume offset of 0 and all of the binary
|
||||
size = lseek(fd, 0L, SEEK_END);
|
||||
pos = lseek(fd, 0L, SEEK_SET);
|
||||
|
||||
// Adjust size if the user didn't specify it via the parameter
|
||||
if (requested_size == -1)
|
||||
{
|
||||
requested_size = size - pos;
|
||||
}
|
||||
|
||||
// Are we going to read past the end of the file?
|
||||
if (pos + requested_size > size)
|
||||
{
|
||||
close(fd);
|
||||
return error("invalid combination of incbin position and size");
|
||||
}
|
||||
size = requested_size;
|
||||
|
||||
// All checks passed, let's seek to where the user requested, otherwise at file start
|
||||
lseek(fd, pos, SEEK_SET);
|
||||
}
|
||||
|
||||
chcheck(size);
|
||||
|
|
Loading…
Reference in New Issue