From d6fc439c21038718bcffdf317ddd17cd87f3ee1e Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 18 May 2018 10:00:35 -0500 Subject: [PATCH] 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. --- tools/binpac/src/pac_array.cc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/binpac/src/pac_array.cc b/tools/binpac/src/pac_array.cc index 7017389df9..71736b1a49 100644 --- a/tools/binpac/src/pac_array.cc +++ b/tools/binpac/src/pac_array.cc @@ -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);