mirror of
https://github.com/zeek/zeek.git
synced 2025-10-13 03:58:20 +00:00
GH-927: Fix circumvention of evaluation order in 'when' conditions
Historically, a 'when' condition performed an AST-traversal to locate any index-expressions like `x[9]` and evaluated them so that it could register the associated value as something for which it needs to receive "modification" notifications. Evaluating arbitrary expressions during an AST-traversal like that ignores the typical order-of-evaluation/short-circuiting you'd expect if the condition was evaluated normally, from its root expression. Now, a new subclass of IndexExpr is used to keep track of all IndexExpr results in the context of evaluating a 'when' condition without having to do a secondary AST-traversal-and-eval. i.e. the first evaluation of the full 'when' condition follows the typical expression-evaluation semantics (as always), but additionally now captures all the values a Trigger needs to monitor for modifications.
This commit is contained in:
parent
0771dbcec6
commit
33ca675515
6 changed files with 141 additions and 29 deletions
27
src/parse.y
27
src/parse.y
|
@ -58,7 +58,7 @@
|
|||
%type <ic> init_class
|
||||
%type <expr> opt_init
|
||||
%type <val> TOK_CONSTANT
|
||||
%type <expr> expr opt_expr init anonymous_function lambda_body index_slice opt_deprecated
|
||||
%type <expr> expr opt_expr init anonymous_function lambda_body index_slice opt_deprecated when_condition
|
||||
%type <event_expr> event
|
||||
%type <stmt> stmt stmt_list func_body for_head
|
||||
%type <type> type opt_type enum_body
|
||||
|
@ -126,6 +126,7 @@ extern zeek::detail::Expr* g_curr_debug_expr;
|
|||
extern bool in_debug;
|
||||
extern const char* g_curr_debug_error;
|
||||
|
||||
static int in_when_cond = 0;
|
||||
static int in_hook = 0;
|
||||
int in_init = 0;
|
||||
int in_record = 0;
|
||||
|
@ -289,6 +290,11 @@ opt_expr:
|
|||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
when_condition:
|
||||
{ ++in_when_cond; } expr { --in_when_cond; }
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
expr:
|
||||
'(' expr ')'
|
||||
{
|
||||
|
@ -474,7 +480,10 @@ expr:
|
|||
| expr '[' expr_list ']'
|
||||
{
|
||||
zeek::detail::set_location(@1, @4);
|
||||
$$ = new zeek::detail::IndexExpr({zeek::AdoptRef{}, $1}, {zeek::AdoptRef{}, $3});
|
||||
if ( in_when_cond > 0 )
|
||||
$$ = new zeek::detail::IndexExprWhen({zeek::AdoptRef{}, $1}, {zeek::AdoptRef{}, $3});
|
||||
else
|
||||
$$ = new zeek::detail::IndexExpr({zeek::AdoptRef{}, $1}, {zeek::AdoptRef{}, $3});
|
||||
}
|
||||
|
||||
| index_slice
|
||||
|
@ -1328,7 +1337,11 @@ index_slice:
|
|||
|
||||
auto le = zeek::make_intrusive<zeek::detail::ListExpr>(std::move(low));
|
||||
le->Append(std::move(high));
|
||||
$$ = new zeek::detail::IndexExpr({zeek::AdoptRef{}, $1}, std::move(le), true);
|
||||
|
||||
if ( in_when_cond > 0 )
|
||||
$$ = new zeek::detail::IndexExprWhen({zeek::AdoptRef{}, $1}, std::move(le), true);
|
||||
else
|
||||
$$ = new zeek::detail::IndexExpr({zeek::AdoptRef{}, $1}, std::move(le), true);
|
||||
}
|
||||
|
||||
opt_attr:
|
||||
|
@ -1535,14 +1548,14 @@ stmt:
|
|||
zeek::detail::script_coverage_mgr.AddStmt($$);
|
||||
}
|
||||
|
||||
| TOK_WHEN '(' expr ')' stmt
|
||||
| TOK_WHEN '(' when_condition ')' stmt
|
||||
{
|
||||
zeek::detail::set_location(@3, @5);
|
||||
$$ = new zeek::detail::WhenStmt({zeek::AdoptRef{}, $3}, {zeek::AdoptRef{}, $5},
|
||||
nullptr, nullptr, false);
|
||||
}
|
||||
|
||||
| TOK_WHEN '(' expr ')' stmt TOK_TIMEOUT expr '{' opt_no_test_block stmt_list '}'
|
||||
| TOK_WHEN '(' when_condition ')' stmt TOK_TIMEOUT expr '{' opt_no_test_block stmt_list '}'
|
||||
{
|
||||
zeek::detail::set_location(@3, @9);
|
||||
$$ = new zeek::detail::WhenStmt({zeek::AdoptRef{}, $3}, {zeek::AdoptRef{}, $5},
|
||||
|
@ -1552,14 +1565,14 @@ stmt:
|
|||
}
|
||||
|
||||
|
||||
| TOK_RETURN TOK_WHEN '(' expr ')' stmt
|
||||
| TOK_RETURN TOK_WHEN '(' when_condition ')' stmt
|
||||
{
|
||||
zeek::detail::set_location(@4, @6);
|
||||
$$ = new zeek::detail::WhenStmt({zeek::AdoptRef{}, $4}, {zeek::AdoptRef{}, $6}, nullptr,
|
||||
nullptr, true);
|
||||
}
|
||||
|
||||
| TOK_RETURN TOK_WHEN '(' expr ')' stmt TOK_TIMEOUT expr '{' opt_no_test_block stmt_list '}'
|
||||
| TOK_RETURN TOK_WHEN '(' when_condition ')' stmt TOK_TIMEOUT expr '{' opt_no_test_block stmt_list '}'
|
||||
{
|
||||
zeek::detail::set_location(@4, @10);
|
||||
$$ = new zeek::detail::WhenStmt({zeek::AdoptRef{}, $4}, {zeek::AdoptRef{}, $6},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue