mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
binpac: Improve parsing of known-length, static-size arrays
In this case, the bounds checking for individual elements can be optimized out of the parsing-loop in favor of a single, array-wide bounds check beforehand.
This commit is contained in:
parent
d6fc439c21
commit
0a05aa92fc
1 changed files with 28 additions and 0 deletions
|
@ -280,6 +280,12 @@ void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
|
||||||
|
|
||||||
// Check for overlong array length. We cap it at the
|
// Check for overlong array length. We cap it at the
|
||||||
// maximum data size as we won't store more elements.
|
// maximum data size as we won't store more elements.
|
||||||
|
// e.g. this helps prevent user-controlled length fields
|
||||||
|
// from causing an excessive memory-allocation (for
|
||||||
|
// the array we'll be parsing into) unless they actually
|
||||||
|
// sent enough data to go along with it. Note that this check
|
||||||
|
// is *not* looking for whether the contents of the array will
|
||||||
|
// extend past the end of the data buffer.
|
||||||
out_cc->println("if ( t_begin_of_data + %s > t_end_of_data + 1 || t_begin_of_data + %s < t_begin_of_data )",
|
out_cc->println("if ( t_begin_of_data + %s > t_end_of_data + 1 || t_begin_of_data + %s < t_begin_of_data )",
|
||||||
env->LValue(arraylength_var()), env->LValue(arraylength_var()));
|
env->LValue(arraylength_var()), env->LValue(arraylength_var()));
|
||||||
out_cc->inc_indent();
|
out_cc->inc_indent();
|
||||||
|
@ -298,6 +304,28 @@ void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
|
||||||
env->LValue(arraylength_var()));
|
env->LValue(arraylength_var()));
|
||||||
out_cc->println("}");
|
out_cc->println("}");
|
||||||
out_cc->dec_indent();
|
out_cc->dec_indent();
|
||||||
|
|
||||||
|
if ( elemtype_->StaticSize(env) != -1 )
|
||||||
|
{
|
||||||
|
// Boundary check the entire array if elements have static size.
|
||||||
|
string array_size = strfmt("((%d) * (%s))",
|
||||||
|
elemtype_->StaticSize(env),
|
||||||
|
env->RValue(arraylength_var()));
|
||||||
|
out_cc->println("// Check bounds for static-size array: %s",
|
||||||
|
data_id_str_.c_str());
|
||||||
|
out_cc->println("if ( t_begin_of_data + %s > t_end_of_data || "
|
||||||
|
"t_begin_of_data + %s < t_begin_of_data )",
|
||||||
|
array_size.c_str(), array_size.c_str());
|
||||||
|
out_cc->inc_indent();
|
||||||
|
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",",
|
||||||
|
data_id_str_.c_str());
|
||||||
|
out_cc->println(" %s, (%s) - (%s));",
|
||||||
|
array_size.c_str(),
|
||||||
|
env->RValue(end_of_data),
|
||||||
|
env->RValue(begin_of_data));
|
||||||
|
out_cc->dec_indent();
|
||||||
|
elemtype_->SetBoundaryChecked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( attr_restofdata_ )
|
else if ( attr_restofdata_ )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue