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 ']'
|
| '[' 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);
|
set_location(@1, @3);
|
||||||
|
|
||||||
Expr* e0 = $2->Exprs()[0];
|
bool is_record_ctor = true;
|
||||||
if ( e0->Tag() == EXPR_FIELD_ASSIGN ||
|
|
||||||
e0->Type()->Tag() == TYPE_RECORD )
|
// 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);
|
$$ = new RecordConstructorExpr($2);
|
||||||
else
|
else
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
|
|
|
@ -12,6 +12,7 @@ cardinality (PASS)
|
||||||
cardinality (PASS)
|
cardinality (PASS)
|
||||||
cardinality (PASS)
|
cardinality (PASS)
|
||||||
cardinality (PASS)
|
cardinality (PASS)
|
||||||
|
cardinality (PASS)
|
||||||
iterate over table (PASS)
|
iterate over table (PASS)
|
||||||
iterate over table (PASS)
|
iterate over table (PASS)
|
||||||
iterate over table (PASS)
|
iterate over table (PASS)
|
||||||
|
@ -30,6 +31,11 @@ add element (PASS)
|
||||||
in operator (PASS)
|
in operator (PASS)
|
||||||
add element (PASS)
|
add element (PASS)
|
||||||
in operator (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)
|
remove element (PASS)
|
||||||
!in operator (PASS)
|
!in operator (PASS)
|
||||||
remove element (PASS)
|
remove element (PASS)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# @TEST-EXEC: bro %INPUT >out
|
# @TEST-EXEC: bro -b %INPUT >out
|
||||||
# @TEST-EXEC: btest-diff out
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
function test_case(msg: string, expect: bool)
|
function test_case(msg: string, expect: bool)
|
||||||
|
@ -26,6 +26,9 @@ event bro_init()
|
||||||
local t10: table[port, string, bool] of string = {
|
local t10: table[port, string, bool] of string = {
|
||||||
[10/udp, "curly", F] = "first",
|
[10/udp, "curly", F] = "first",
|
||||||
[11/udp, "braces", T] = "second" };
|
[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
|
# Type inference tests
|
||||||
|
|
||||||
|
@ -45,6 +48,7 @@ event bro_init()
|
||||||
test_case( "cardinality", |t8| == 0 );
|
test_case( "cardinality", |t8| == 0 );
|
||||||
test_case( "cardinality", |t9| == 1 );
|
test_case( "cardinality", |t9| == 1 );
|
||||||
test_case( "cardinality", |t10| == 2 );
|
test_case( "cardinality", |t10| == 2 );
|
||||||
|
test_case( "cardinality", |t11| == 1 );
|
||||||
test_case( "cardinality", |tg1| == 3 );
|
test_case( "cardinality", |tg1| == 3 );
|
||||||
|
|
||||||
# Test iterating over each table
|
# Test iterating over each table
|
||||||
|
@ -121,6 +125,13 @@ event bro_init()
|
||||||
test_case( "add element", |t5| == 3 );
|
test_case( "add element", |t5| == 3 );
|
||||||
test_case( "in operator", 10 in t5 );
|
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
|
# Test removing elements from each table (Note: cannot remove elements
|
||||||
# from tables of multiple types)
|
# from tables of multiple types)
|
||||||
|
|
||||||
|
@ -145,5 +156,8 @@ event bro_init()
|
||||||
test_case( "remove element", |t5| == 2 );
|
test_case( "remove element", |t5| == 2 );
|
||||||
test_case( "!in operator", 1 !in t5 );
|
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