Expr: Fix folding of pattern values to support == and !=

The fatal error is actually triggered at runtime, so it's a bit
dangerous for users, but not sure there's many use-cases to
compare vectors of patterns.

Closes #4084
This commit is contained in:
Arne Welzel 2024-12-16 10:55:38 +01:00
parent 9a4791f9e9
commit cd8adb3da5
3 changed files with 21 additions and 4 deletions

View file

@ -925,12 +925,20 @@ ValPtr BinaryExpr::PatternFold(Val* v1, Val* v2) const {
const RE_Matcher* re1 = v1->AsPattern(); const RE_Matcher* re1 = v1->AsPattern();
const RE_Matcher* re2 = v2->AsPattern(); const RE_Matcher* re2 = v2->AsPattern();
if ( tag != EXPR_AND && tag != EXPR_OR ) ValPtr res;
if ( tag == EXPR_AND || tag == EXPR_OR ) {
RE_Matcher* matcher = tag == EXPR_AND ? RE_Matcher_conjunction(re1, re2) : RE_Matcher_disjunction(re1, re2);
res = make_intrusive<PatternVal>(matcher);
}
else if ( tag == EXPR_EQ || tag == EXPR_NE ) {
bool cmp = strcmp(re1->PatternText(), re2->PatternText());
res = val_mgr->Bool(tag == EXPR_EQ ? cmp == 0 : cmp != 0);
}
else {
BadTag("BinaryExpr::PatternFold"); BadTag("BinaryExpr::PatternFold");
}
RE_Matcher* res = tag == EXPR_AND ? RE_Matcher_conjunction(re1, re2) : RE_Matcher_disjunction(re1, re2); return res;
return make_intrusive<PatternVal>(res);
} }
ValPtr BinaryExpr::SetFold(Val* v1, Val* v2) const { ValPtr BinaryExpr::SetFold(Val* v1, Val* v2) const {

View file

@ -84,3 +84,5 @@ negative index (PASS)
negative index (PASS) negative index (PASS)
+= of empty vector (PASS) += of empty vector (PASS)
+= of empty vector (PASS) += of empty vector (PASS)
pv1 == pv2 -> [T, F] (PASS)
pv1 != pv2 -> [F, T] (PASS)

View file

@ -241,4 +241,11 @@ event zeek_init()
v26 += vector(); v26 += vector();
test_case( "+= of empty vector", |v26| == 0 ); test_case( "+= of empty vector", |v26| == 0 );
# Pattern vectors
local pv1 = vector(/a/, /b/);
local pv2 = vector(/a/, /c/);
local pv_eq = pv1 == pv2;
local pv_ne = pv1 != pv2;
test_case( fmt("pv1 == pv2 -> %s", pv_eq), (pv_eq[0] == T) && (pv_eq[1] == F) );
test_case( fmt("pv1 != pv2 -> %s", pv_ne), (pv_ne[0] == F) && (pv_ne[1] == T) );
} }