mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 02:28:21 +00:00
Fix ambiguity between composite table index and record ctor expressions.
For tables of a composite index type with the first type being a record, membership checks with an inline index key could be misinterpreted as a record constructor instead of an expression list. E.g, if the table type is "global t = table[conn_id, bool] of count", then checking membership like "[c$id, is_orig] in t" now works. Addresses #80.
This commit is contained in:
parent
5508a5bb80
commit
56e359ca9d
3 changed files with 37 additions and 10 deletions
25
src/parse.y
25
src/parse.y
|
@ -456,17 +456,24 @@ expr:
|
|||
|
||||
| '[' expr_list ']'
|
||||
{
|
||||
// A little crufty: we peek at the type of
|
||||
// the first expression in the list. If it's
|
||||
// a record or a field assignment, then this
|
||||
// is a record constructor. If not, then this
|
||||
// is a list used for an initializer.
|
||||
|
||||
set_location(@1, @3);
|
||||
|
||||
Expr* e0 = $2->Exprs()[0];
|
||||
if ( e0->Tag() == EXPR_FIELD_ASSIGN ||
|
||||
e0->Type()->Tag() == TYPE_RECORD )
|
||||
bool is_record_ctor = true;
|
||||
|
||||
// If every expression in the list is a field assignment,
|
||||
// then treat it as a record constructor, else as a list
|
||||
// used for an initializer.
|
||||
|
||||
for ( int i = 0; i < $2->Exprs().length(); ++i )
|
||||
{
|
||||
if ( $2->Exprs()[i]->Tag() != EXPR_FIELD_ASSIGN )
|
||||
{
|
||||
is_record_ctor = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_record_ctor )
|
||||
$$ = new RecordConstructorExpr($2);
|
||||
else
|
||||
$$ = $2;
|
||||
|
|
|
@ -12,6 +12,7 @@ cardinality (PASS)
|
|||
cardinality (PASS)
|
||||
cardinality (PASS)
|
||||
cardinality (PASS)
|
||||
cardinality (PASS)
|
||||
iterate over table (PASS)
|
||||
iterate over table (PASS)
|
||||
iterate over table (PASS)
|
||||
|
@ -30,6 +31,11 @@ add element (PASS)
|
|||
in operator (PASS)
|
||||
add element (PASS)
|
||||
in operator (PASS)
|
||||
composite index add element (PASS)
|
||||
composite index in operator (PASS)
|
||||
composite index in operator (PASS)
|
||||
remove element (PASS)
|
||||
!in operator (PASS)
|
||||
remove element (PASS)
|
||||
!in operator (PASS)
|
||||
remove element (PASS)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# @TEST-EXEC: bro %INPUT >out
|
||||
# @TEST-EXEC: bro -b %INPUT >out
|
||||
# @TEST-EXEC: btest-diff out
|
||||
|
||||
function test_case(msg: string, expect: bool)
|
||||
|
@ -26,6 +26,9 @@ event bro_init()
|
|||
local t10: table[port, string, bool] of string = {
|
||||
[10/udp, "curly", F] = "first",
|
||||
[11/udp, "braces", T] = "second" };
|
||||
local t11: table[conn_id, bool] of count = {
|
||||
[ [$orig_h=1.1.1.1, $orig_p=1234/tcp,
|
||||
$resp_h=2.2.2.2, $resp_p=4321/tcp], T ] = 42 };
|
||||
|
||||
# Type inference tests
|
||||
|
||||
|
@ -45,6 +48,7 @@ event bro_init()
|
|||
test_case( "cardinality", |t8| == 0 );
|
||||
test_case( "cardinality", |t9| == 1 );
|
||||
test_case( "cardinality", |t10| == 2 );
|
||||
test_case( "cardinality", |t11| == 1 );
|
||||
test_case( "cardinality", |tg1| == 3 );
|
||||
|
||||
# Test iterating over each table
|
||||
|
@ -121,6 +125,13 @@ event bro_init()
|
|||
test_case( "add element", |t5| == 3 );
|
||||
test_case( "in operator", 10 in t5 );
|
||||
|
||||
local cid = [$orig_h=1.1.1.1, $orig_p=1234/tcp,
|
||||
$resp_h=2.2.2.2, $resp_p=4321/tcp];
|
||||
t11[[$orig_h=[::1], $orig_p=3/tcp, $resp_h=[::2], $resp_p=3/tcp], F] = 3;
|
||||
test_case( "composite index add element", |t11| == 2 );
|
||||
test_case( "composite index in operator", [cid, T] in t11 );
|
||||
test_case( "composite index in operator", [[$orig_h=[::1], $orig_p=3/tcp, $resp_h=[::2], $resp_p=3/tcp], F] in t11 );
|
||||
|
||||
# Test removing elements from each table (Note: cannot remove elements
|
||||
# from tables of multiple types)
|
||||
|
||||
|
@ -145,5 +156,8 @@ event bro_init()
|
|||
test_case( "remove element", |t5| == 2 );
|
||||
test_case( "!in operator", 1 !in t5 );
|
||||
|
||||
delete t11[cid, T];
|
||||
test_case( "remove element", |t11| == 1 );
|
||||
test_case( "!in operator", [cid, T] !in t11 );
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue