binpac: GH-4: fix premature loop termination when parsing known-length arrays

For arrays with a length expression (e.g. uint16[size] instead of
uint16[]), the parsing loop would consider reaching the end of the
data buffer as a successful loop termination condition even if it's
not yet parsed the required number of elements.

Now, for such arrays, the loop will only terminate based on the loop
counter (derived from the length expression) or else it will throw an
OOB exception when trying to parse an element and finding not enough
data in the buffer.

Credit to Tomas Bortoli for reporting the problem and proposing
patches.
This commit is contained in:
Jon Siwek 2018-05-18 10:00:35 -05:00 committed by Tim Wojtulewicz
parent 9c61eefe0d
commit d6fc439c21

View file

@ -527,7 +527,22 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
GenUntilCheck(out_cc, env, attr_generic_until_expr_, true);
if ( elem_dataptr_var() )
GenUntilCheck(out_cc, env, elem_dataptr_until_expr_, false);
{
if ( length_ )
{
// Array has a known-length expression like uint16[4] vs. uint16[].
// Here, arriving at the end of the data buffer should not be a
// valid loop-termination condition (which is what the
// GenUntilCheck() call produces). Instead, rely on the loop
// counter to terminate iteration or else the parsing code
// generated for each element should throw an OOB exception if
// there's insufficient data in the buffer.
}
else
{
GenUntilCheck(out_cc, env, elem_dataptr_until_expr_, false);
}
}
elemtype_->GenPreParsing(out_cc, env);
elemtype_->GenParseCode(out_cc, env, elem_data, flags);