diff --git a/CHANGES b/CHANGES index 8fe262c0a4..4fbe8c7095 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,16 @@ +7.1.0-rc1.1 | 2024-12-16 13:02:12 -0700 + + * ZAM/relexpr-op NE for patterns (Vern Paxson, Corelight) + + (cherry picked from commit 33eaa5ccda4157a34feb5ffc466f7371dc6d8eff) + + * Expr: Fix folding of pattern values to support == and != (Arne Welzel, Corelight) + 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. + + (cherry picked from commit 33eaa5ccda4157a34feb5ffc466f7371dc6d8eff) + 7.1.0-rc1 | 2024-12-16 11:01:50 -0700 * Update docs submodule [nomail] [skip ci] (Tim Wojtulewicz) diff --git a/VERSION b/VERSION index db45bc9329..490966df74 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.1.0-rc1 +7.1.0-rc1.1 diff --git a/src/Expr.cc b/src/Expr.cc index cd1c98ebd3..88c2bbd759 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -925,12 +925,20 @@ ValPtr BinaryExpr::PatternFold(Val* v1, Val* v2) const { const RE_Matcher* re1 = v1->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(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"); + } - RE_Matcher* res = tag == EXPR_AND ? RE_Matcher_conjunction(re1, re2) : RE_Matcher_disjunction(re1, re2); - - return make_intrusive(res); + return res; } ValPtr BinaryExpr::SetFold(Val* v1, Val* v2) const { diff --git a/src/script_opt/ZAM/OPs/rel-exprs.op b/src/script_opt/ZAM/OPs/rel-exprs.op index 92c35b7ce6..f4ed1a023f 100644 --- a/src/script_opt/ZAM/OPs/rel-exprs.op +++ b/src/script_opt/ZAM/OPs/rel-exprs.op @@ -29,7 +29,7 @@ eval-type P strcmp($1->Get()->PatternText(), $2->Get()->PatternText()) == 0 eval-mixed P S $1->MatchExactly($2->AsString()) rel-expr-op NE -op-type I U D S T A N F +op-type I U D S T A N F P vector eval $1 != $2 eval-type S Bstr_cmp($1->AsString(), $2->AsString()) != 0 @@ -37,6 +37,7 @@ eval-type T ! $1->EqualTo(*$2) eval-type A $1->AsAddr() != $2->AsAddr() eval-type N $1->AsSubNet() != $2->AsSubNet() eval-type F $1->GetName() != $2->GetName() +eval-type P strcmp($1->Get()->PatternText(), $2->Get()->PatternText()) != 0 eval-mixed P S ! $1->MatchExactly($2->AsString()) # Note, canonicalization means that GE and GT shouldn't occur diff --git a/testing/btest/Baseline/language.vector/out b/testing/btest/Baseline/language.vector/out index 5887d66595..03d2d0c894 100644 --- a/testing/btest/Baseline/language.vector/out +++ b/testing/btest/Baseline/language.vector/out @@ -84,3 +84,5 @@ negative index (PASS) negative index (PASS) += of empty vector (PASS) += of empty vector (PASS) +pv1 == pv2 -> [T, F] (PASS) +pv1 != pv2 -> [F, T] (PASS) diff --git a/testing/btest/Baseline/opt.validate-ZAM/output b/testing/btest/Baseline/opt.validate-ZAM/output index 2f91ef7f21..e99ede3a6b 100644 --- a/testing/btest/Baseline/opt.validate-ZAM/output +++ b/testing/btest/Baseline/opt.validate-ZAM/output @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -1248 valid, 1890 tested, 437 skipped +1255 valid, 1908 tested, 440 skipped diff --git a/testing/btest/language/vector.zeek b/testing/btest/language/vector.zeek index 820261e0e8..60f4178358 100644 --- a/testing/btest/language/vector.zeek +++ b/testing/btest/language/vector.zeek @@ -241,4 +241,11 @@ event zeek_init() v26 += vector(); 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) ); }