From 21614cd30d0f23f2535a6e7ffa8dce6dd008eaff Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Wed, 20 Jun 2018 09:49:29 -0700 Subject: [PATCH 01/16] basic code implemented, but there's a memory problem somehwere :-( --- src/Expr.cc | 47 ++++++++++++++++++++++++++++------------------- src/Expr.h | 3 +++ src/parse.y | 36 ++++++++++-------------------------- 3 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index f5c8e66b50..d895e811ab 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -665,6 +665,9 @@ Val* BinaryExpr::Fold(Val* v1, Val* v2) const if ( it == TYPE_INTERNAL_STRING ) return StringFold(v1, v2); + if ( v1->Type()->Tag() == TYPE_PATTERN ) + return PatternFold(v1, v2); + if ( it == TYPE_INTERNAL_ADDR ) return AddrFold(v1, v2); @@ -851,6 +854,21 @@ Val* BinaryExpr::StringFold(Val* v1, Val* v2) const return new Val(result, TYPE_BOOL); } +Val* 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 ) + BadTag("BinaryExpr::PatternFold"); + + RE_Matcher* res = tag == EXPR_AND ? + RE_Matcher_conjunction(re1, re2) : + RE_Matcher_disjunction(re1, re2); + + return new PatternVal(res); + } + Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const { IPAddr a1 = v1->AsAddr(); @@ -1696,9 +1714,6 @@ BoolExpr::BoolExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) SetType(base_type(TYPE_BOOL)); } - else if ( bt1 == TYPE_PATTERN && bt2 == bt1 ) - SetType(base_type(TYPE_PATTERN)); - else ExprError("requires boolean operands"); } @@ -1708,22 +1723,6 @@ Val* BoolExpr::DoSingleEval(Frame* f, Val* v1, Expr* op2) const if ( ! v1 ) return 0; - if ( Type()->Tag() == TYPE_PATTERN ) - { - Val* v2 = op2->Eval(f); - if ( ! v2 ) - return 0; - - RE_Matcher* re1 = v1->AsPattern(); - RE_Matcher* re2 = v2->AsPattern(); - - RE_Matcher* res = tag == EXPR_AND_AND ? - RE_Matcher_conjunction(re1, re2) : - RE_Matcher_disjunction(re1, re2); - - return new PatternVal(res); - } - if ( tag == EXPR_AND_AND ) { if ( v1->IsZero() ) @@ -1885,6 +1884,16 @@ BitExpr::BitExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) SetType(base_type(TYPE_COUNT)); } + if ( bt1 == TYPE_PATTERN ) + { + if ( bt2 != TYPE_PATTERN ) + ExprError("cannot mix pattern and non-pattern operands"); + else if ( tag == EXPR_XOR ) + ExprError("'^' operator does not apply to patterns"); + else + SetType(base_type(TYPE_PATTERN)); + } + else ExprError("requires \"count\" operands"); } diff --git a/src/Expr.h b/src/Expr.h index 8e8b6cc96b..4229750fb1 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -327,6 +327,9 @@ protected: // Same for when the constants are strings. virtual Val* StringFold(Val* v1, Val* v2) const; + // Same for when the constants are patterns. + virtual Val* PatternFold(Val* v1, Val* v2) const; + // Same for when the constants are addresses or subnets. virtual Val* AddrFold(Val* v1, Val* v2) const; virtual Val* SubNetFold(Val* v1, Val* v2) const; diff --git a/src/parse.y b/src/parse.y index 6f7a43ae7f..b8f82aa1fb 100644 --- a/src/parse.y +++ b/src/parse.y @@ -2,7 +2,7 @@ // See the file "COPYING" in the main distribution directory for copyright. %} -%expect 78 +%expect 77 %token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY %token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF @@ -49,13 +49,12 @@ %left '$' '[' ']' '(' ')' TOK_HAS_FIELD TOK_HAS_ATTR %type opt_no_test opt_no_test_block opt_deprecated -%type TOK_ID TOK_PATTERN_TEXT single_pattern +%type TOK_ID TOK_PATTERN_TEXT %type local_id global_id def_global_id event_id global_or_event_id resolve_id begin_func %type local_id_list %type init_class %type opt_init %type TOK_CONSTANT -%type pattern %type expr opt_expr init anonymous_function %type event %type stmt stmt_list func_body for_head @@ -720,11 +719,15 @@ expr: $$ = new ConstExpr($1); } - | pattern + | '/' { begin_RE(); } TOK_PATTERN_TEXT { end_RE(); } '/' { - set_location(@1); - $1->Compile(); - $$ = new ConstExpr(new PatternVal($1)); + set_location(@3); + + RE_Matcher* re = new RE_Matcher($3); + delete [] $3; + + re->Compile(); + $$ = new ConstExpr(new PatternVal(re)); } | '|' expr '|' %prec '(' @@ -754,25 +757,6 @@ opt_expr_list: { $$ = new ListExpr(); } ; -pattern: - pattern '|' single_pattern - { - $1->AddPat($3); - delete [] $3; - } - - | single_pattern - { - $$ = new RE_Matcher($1); - delete [] $1; - } - ; - -single_pattern: - '/' { begin_RE(); } TOK_PATTERN_TEXT { end_RE(); } '/' - { $$ = $3; } - ; - enum_body: enum_body_list { From b864772e8ac18df273afeb8d2ce471422591fc73 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 21 Jun 2018 15:15:05 -0700 Subject: [PATCH 02/16] fixed typos in NEWS --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 93a28cb200..445305ea59 100644 --- a/NEWS +++ b/NEWS @@ -16,7 +16,7 @@ New Functionality to the version in 2.5), and much of its implementation has been redone. There's a new script-level "broker" framework that supersedes the old "communication" framework, which is now - depracated. The "cluster" and "control" frameworks have been ported + deprecated. The "cluster" and "control" frameworks have been ported to Broker; same for BroControl. For more about the new Broker framework, see doc/frameworks/broker.rst (there's also guide there for porting existing Bro scripts to Broker). For more about Broker @@ -252,7 +252,7 @@ New Functionality Changed Functionality --------------------- - - ALl communication is now handled through Broker, requiring changes + - All communication is now handled through Broker, requiring changes to existing scripts to port them over to the new API. The Broker framework documentation comes with a porting guide. From 6c8562bbdd45d4e5499d4b6e6dc1eca1ca8a9d77 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 21 Jun 2018 15:50:56 -0700 Subject: [PATCH 03/16] deprecate && / || operators for patterns --- src/Expr.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Expr.cc b/src/Expr.cc index 1ab82853c3..0c890eaea2 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -1695,7 +1695,10 @@ BoolExpr::BoolExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) } else if ( bt1 == TYPE_PATTERN && bt2 == bt1 ) + { + reporter->Warning("&& and || operators deprecated for pattern operands"); SetType(base_type(TYPE_PATTERN)); + } else ExprError("requires boolean operands"); From cff68b437152c2117e3ac8a0565e040b29ad92cc Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 22 Jun 2018 10:03:13 -0700 Subject: [PATCH 04/16] deprecate mixing scalars and vectors --- NEWS | 7 +++++++ src/Expr.cc | 13 +++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 445305ea59..8542d7853b 100644 --- a/NEWS +++ b/NEWS @@ -356,6 +356,13 @@ Deprecated Functionality removal with the next Bro release. Bro's new configuration framework is taking its place. +- Mixing of scalars and vectors, such as "v + e" yielding a vector + corresponding to the vector v with the scalar e added to each of + its elements, has been deprecated. + +- The undocumented feature of using "&&" and "||" operators for patterns + has been deprecated. + Bro 2.5.1 ========= diff --git a/src/Expr.cc b/src/Expr.cc index 0c890eaea2..be4b05d6a2 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -909,11 +909,17 @@ void BinaryExpr::PromoteOps(TypeTag t) TypeTag bt1 = op1->Type()->Tag(); TypeTag bt2 = op2->Type()->Tag(); - if ( IsVector(bt1) ) + bool is_vec1 = IsVector(bt1); + bool is_vec2 = IsVector(bt2); + + if ( is_vec1 ) bt1 = op1->Type()->AsVectorType()->YieldType()->Tag(); - if ( IsVector(bt2) ) + if ( is_vec2 ) bt2 = op2->Type()->AsVectorType()->YieldType()->Tag(); + if ( (is_vec1 || is_vec2) && ! (is_vec1 && is_vec2) ) + reporter->Warning("mixing vector and scalar operands is deprecated"); + if ( bt1 != t ) op1 = new ArithCoerceExpr(op1, t); if ( bt2 != t ) @@ -1003,7 +1009,10 @@ IncrExpr::IncrExpr(BroExprTag arg_tag, Expr* arg_op) if ( ! IsIntegral(t->AsVectorType()->YieldType()->Tag()) ) ExprError("vector elements must be integral for increment operator"); else + { + reporter->Warning("increment/decrement operations for vectors deprecated"); SetType(t->Ref()); + } } else { From b811a8e7a6fa4d2b56b60937fadbe144cdc4ed51 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 22 Jun 2018 13:40:53 -0700 Subject: [PATCH 05/16] bug fix (and typo fix) for vector+scalar boolean operations --- src/Expr.cc | 2 +- src/Val.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index be4b05d6a2..cd431fdca1 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -1798,7 +1798,7 @@ Val* BoolExpr::Eval(Frame* f) const VectorVal* result = 0; - // It's either and EXPR_AND_AND or an EXPR_OR_OR. + // It's either an EXPR_AND_AND or an EXPR_OR_OR. bool is_and = (tag == EXPR_AND_AND); if ( scalar_v->IsZero() == is_and ) diff --git a/src/Val.cc b/src/Val.cc index 4da4a35d48..61cca185df 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -3226,7 +3226,7 @@ bool VectorVal::AssignRepeat(unsigned int index, unsigned int how_many, ResizeAtLeast(index + how_many); for ( unsigned int i = index; i < index + how_many; ++i ) - if ( ! Assign(i, element ) ) + if ( ! Assign(i, element->Ref() ) ) return false; return true; From 89b7b88e75f7662fc655d73ef81827290941f1db Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 22 Jun 2018 13:43:51 -0700 Subject: [PATCH 06/16] deprecate boolean scalar+vector operations --- src/Expr.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Expr.cc b/src/Expr.cc index cd431fdca1..ef8da8edbb 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -1698,7 +1698,11 @@ BoolExpr::BoolExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) if ( BothBool(bt1, bt2) ) { if ( is_vector(op1) || is_vector(op2) ) + { + if ( ! (is_vector(op1) && is_vector(op2)) ) + reporter->Warning("mixing vector and scalar operands is deprecated"); SetType(new VectorType(base_type(TYPE_BOOL))); + } else SetType(base_type(TYPE_BOOL)); } From 9e2c70b90b79db440873bdbe55ed735f6d04033b Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 22 Jun 2018 14:17:15 -0700 Subject: [PATCH 07/16] deprecate merge_patterns() --- NEWS | 3 +++ src/bro.bif | 2 ++ 2 files changed, 5 insertions(+) diff --git a/NEWS b/NEWS index 8542d7853b..8cd4f3c201 100644 --- a/NEWS +++ b/NEWS @@ -360,6 +360,9 @@ Deprecated Functionality corresponding to the vector v with the scalar e added to each of its elements, has been deprecated. +- The built-in function merge_pattern() has been deprecated. It will + be replaced by the '&' operator for patterns. + - The undocumented feature of using "&&" and "||" operators for patterns has been deprecated. diff --git a/src/bro.bif b/src/bro.bif index 652b8cdd07..f0641104c9 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2966,6 +2966,8 @@ function merge_pattern%(p1: pattern, p2: pattern%): pattern return 0; } + reporter->Warning("merge_pattern() builtin-function has been deprecated"); + RE_Matcher* re = new RE_Matcher(); re->AddPat(p1->PatternText()); re->AddPat(p2->PatternText()); From 04b7f8276c3b85409326b5405937e1dc37e5f008 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 22 Jun 2018 15:12:22 -0700 Subject: [PATCH 08/16] side-porting changes for supporting &/| pattern ops --- src/Expr.cc | 44 ++++++++++++++++++++++++++++---------------- src/Expr.h | 3 +++ src/NFA.cc | 3 +++ src/parse.y | 36 ++++++++++-------------------------- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index ef8da8edbb..b979a3638b 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -663,6 +663,9 @@ Val* BinaryExpr::Fold(Val* v1, Val* v2) const if ( it == TYPE_INTERNAL_STRING ) return StringFold(v1, v2); + if ( v1->Type()->Tag() == TYPE_PATTERN ) + return PatternFold(v1, v2); + if ( it == TYPE_INTERNAL_ADDR ) return AddrFold(v1, v2); @@ -849,6 +852,21 @@ Val* BinaryExpr::StringFold(Val* v1, Val* v2) const return new Val(result, TYPE_BOOL); } +Val* 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 ) + BadTag("BinaryExpr::PatternFold"); + + RE_Matcher* res = tag == EXPR_AND ? + RE_Matcher_conjunction(re1, re2) : + RE_Matcher_disjunction(re1, re2); + + return new PatternVal(res); + } + Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const { IPAddr a1 = v1->AsAddr(); @@ -1722,22 +1740,6 @@ Val* BoolExpr::DoSingleEval(Frame* f, Val* v1, Expr* op2) const if ( ! v1 ) return 0; - if ( Type()->Tag() == TYPE_PATTERN ) - { - Val* v2 = op2->Eval(f); - if ( ! v2 ) - return 0; - - RE_Matcher* re1 = v1->AsPattern(); - RE_Matcher* re2 = v2->AsPattern(); - - RE_Matcher* res = tag == EXPR_AND_AND ? - RE_Matcher_conjunction(re1, re2) : - RE_Matcher_disjunction(re1, re2); - - return new PatternVal(res); - } - if ( tag == EXPR_AND_AND ) { if ( v1->IsZero() ) @@ -1899,6 +1901,16 @@ BitExpr::BitExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) SetType(base_type(TYPE_COUNT)); } + if ( bt1 == TYPE_PATTERN ) + { + if ( bt2 != TYPE_PATTERN ) + ExprError("cannot mix pattern and non-pattern operands"); + else if ( tag == EXPR_XOR ) + ExprError("'^' operator does not apply to patterns"); + else + SetType(base_type(TYPE_PATTERN)); + } + else ExprError("requires \"count\" operands"); } diff --git a/src/Expr.h b/src/Expr.h index 9fc9aa15ed..c21547d91c 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -329,6 +329,9 @@ protected: // Same for when the constants are strings. virtual Val* StringFold(Val* v1, Val* v2) const; + // Same for when the constants are patterns. + virtual Val* PatternFold(Val* v1, Val* v2) const; + // Same for when the constants are addresses or subnets. virtual Val* AddrFold(Val* v1, Val* v2) const; virtual Val* SubNetFold(Val* v1, Val* v2) const; diff --git a/src/NFA.cc b/src/NFA.cc index 43ec3d2a90..8fb78a7131 100644 --- a/src/NFA.cc +++ b/src/NFA.cc @@ -55,7 +55,10 @@ void NFA_State::AddXtionsTo(NFA_state_list* ns) NFA_State* NFA_State::DeepCopy() { if ( mark ) + { + Ref(mark); return mark; + } NFA_State* copy = ccl ? new NFA_State(ccl) : new NFA_State(sym, 0); SetMark(copy); diff --git a/src/parse.y b/src/parse.y index 8145b66809..34d6f31373 100644 --- a/src/parse.y +++ b/src/parse.y @@ -5,7 +5,7 @@ // Switching parser table type fixes ambiguity problems. %define lr.type ielr -%expect 142 +%expect 141 %token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY %token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF @@ -53,13 +53,12 @@ %nonassoc TOK_AS TOK_IS %type opt_no_test opt_no_test_block opt_deprecated -%type TOK_ID TOK_PATTERN_TEXT single_pattern +%type TOK_ID TOK_PATTERN_TEXT %type local_id global_id def_global_id event_id global_or_event_id resolve_id begin_func case_type %type local_id_list case_type_list %type init_class %type opt_init %type TOK_CONSTANT -%type pattern %type expr opt_expr init anonymous_function %type event %type stmt stmt_list func_body for_head @@ -724,11 +723,15 @@ expr: $$ = new ConstExpr($1); } - | pattern + | '/' { begin_RE(); } TOK_PATTERN_TEXT { end_RE(); } '/' { - set_location(@1); - $1->Compile(); - $$ = new ConstExpr(new PatternVal($1)); + set_location(@3); + + RE_Matcher* re = new RE_Matcher($3); + delete [] $3; + + re->Compile(); + $$ = new ConstExpr(new PatternVal(re)); } | '|' expr '|' %prec '(' @@ -770,25 +773,6 @@ opt_expr_list: { $$ = new ListExpr(); } ; -pattern: - pattern '|' single_pattern - { - $1->AddPat($3); - delete [] $3; - } - - | single_pattern - { - $$ = new RE_Matcher($1); - delete [] $1; - } - ; - -single_pattern: - '/' { begin_RE(); } TOK_PATTERN_TEXT { end_RE(); } '/' - { $$ = $3; } - ; - enum_body: enum_body_list { From f340707e2c725fef54efa0eaa259b85b0d634df4 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 22 Jun 2018 15:23:06 -0700 Subject: [PATCH 09/16] documentation for &/| for patterns --- NEWS | 6 ++++++ doc/script-reference/types.rst | 12 +++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 8cd4f3c201..f594207f58 100644 --- a/NEWS +++ b/NEWS @@ -249,6 +249,12 @@ New Functionality '^' are binary "and", "or" and "xor" operators, and '~' is a unary ones-complement operator. +- The '&' and '|' operators can apply to patterns, too. p1 & p2 yields + a pattern that represents matching p1 followed by p2, and p1 | p2 yields + a pattern representing matching p1 or p2. The p1 | p2 functionality was + semi-present in previous versions of Bro, but required constants as as + its operands; now you can use any pattern-valued expressions. + Changed Functionality --------------------- diff --git a/doc/script-reference/types.rst b/doc/script-reference/types.rst index 44dcbbdfb8..438706c425 100644 --- a/doc/script-reference/types.rst +++ b/doc/script-reference/types.rst @@ -237,13 +237,19 @@ Here is a more detailed description of each type: is false since "oob" does not appear at the start of "foobar". The ``!in`` operator would yield the negation of ``in``. - Finally, you can create a disjunction (either-or) of two literal patterns + You can create a disjunction (either-or) of two patterns using the ``|`` operator. For example:: /foo/ | /bar/ in "foobar" - yields true, like in the similar example above. (This does not presently - work for variables whose values are patterns, however.) + yields true, like in the similar example above. You can also + create the conjunction (concatenation) of patterns using the ``&`` + operator. For example: + + /foo/ & /bar/ in "foobar" + + will yield true because the pattern /(foo)(bar)/ appears in + the string "foobar". .. bro:type:: port From 762048cb414fc10a492c19a1dd05930c518f1134 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 22 Jun 2018 15:29:10 -0700 Subject: [PATCH 10/16] test suite updates for &/| pattern operators --- testing/btest/Baseline/language.pattern/out | 4 ++++ testing/btest/language/pattern.bro | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/testing/btest/Baseline/language.pattern/out b/testing/btest/Baseline/language.pattern/out index 4a5b8de670..9c801eb60b 100644 --- a/testing/btest/Baseline/language.pattern/out +++ b/testing/btest/Baseline/language.pattern/out @@ -6,3 +6,7 @@ inequality operator (order of operands) (PASS) in operator (PASS) in operator (PASS) !in operator (PASS) +& operator (PASS) +& operator (FAIL) +| operator (PASS) +| operator (FAIL) diff --git a/testing/btest/language/pattern.bro b/testing/btest/language/pattern.bro index b904fe8737..1c137969eb 100644 --- a/testing/btest/language/pattern.bro +++ b/testing/btest/language/pattern.bro @@ -27,6 +27,10 @@ event bro_init() test_case( "in operator", p1 in "foobar" ); test_case( "in operator", p2 in "foobar" ); test_case( "!in operator", p3 !in "foobar" ); + test_case( "& operator", p1 & p2 in "baroob" ); + test_case( "& operator", p2 & p1 in "baroob" ); + test_case( "| operator", p1 | p2 in "lazybarlazy" ); + test_case( "| operator", p3 | p4 in "xoob" ); } From 610d1ae40762f11f4b55d46792c3234454c130d9 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 22 Jun 2018 22:01:42 -0700 Subject: [PATCH 11/16] Update submodules to correct checkouts. --- aux/binpac | 2 +- aux/bro-aux | 2 +- aux/broccoli | 2 +- aux/broctl | 2 +- aux/broker | 2 +- aux/btest | 2 +- aux/netcontrol-connectors | 2 +- cmake | 2 +- src/3rdparty | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/aux/binpac b/aux/binpac index afb2aa5d3c..951aeae8e4 160000 --- a/aux/binpac +++ b/aux/binpac @@ -1 +1 @@ -Subproject commit afb2aa5d3c485212230c68a4eade120be288953e +Subproject commit 951aeae8e4a08c598203cf61387f015ec4e0849d diff --git a/aux/bro-aux b/aux/bro-aux index f7cc11d97b..eeb677ff69 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit f7cc11d97b3298bbfc5d01ff544e871b67f0fc5a +Subproject commit eeb677ff696f8ea3eaa43a765fe40da07ed5281d diff --git a/aux/broccoli b/aux/broccoli index 22a35f3378..d9041cc95d 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 22a35f33786b2ede5f3efe7e2b24237a4fe974fb +Subproject commit d9041cc95d2232dbbcf36647f34537da22e360ff diff --git a/aux/broctl b/aux/broctl index 60eeea9f98..c5dd2ba83d 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 60eeea9f98455ea613bcfc02e09f2c9665c97f58 +Subproject commit c5dd2ba83dda185d2008731a5cd25b2b8131ac78 diff --git a/aux/broker b/aux/broker index 066fb75d1e..08f41ccc24 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 066fb75d1ea46e919a2d9c56faff1e605c64756c +Subproject commit 08f41ccc2497f4c6567da0b95488593c39a12a01 diff --git a/aux/btest b/aux/btest index 3d76371f89..99ec0e1ea8 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit 3d76371f896b714520d0796a1f3f781ee8561c47 +Subproject commit 99ec0e1ea89e166af4cb6ebc2d923d123424123d diff --git a/aux/netcontrol-connectors b/aux/netcontrol-connectors index 9f3d6fce49..a432ae2f9a 160000 --- a/aux/netcontrol-connectors +++ b/aux/netcontrol-connectors @@ -1 +1 @@ -Subproject commit 9f3d6fce49cad3b45b5ddd0fe1f3c79186e1d2e7 +Subproject commit a432ae2f9a06e7b1664df5fc4ce1b694acb7b099 diff --git a/cmake b/cmake index c40d8f9831..1600554d1d 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit c40d8f9831b69259bfa930a64662d91cfdbf97bf +Subproject commit 1600554d1d907f4f252f19cf1f55e13d368a936f diff --git a/src/3rdparty b/src/3rdparty index 3107bd0398..c78abc8454 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit 3107bd039828c47ebae399d0f0c9220595bf6cf2 +Subproject commit c78abc8454932019f030045340348560a8ac9b23 From 2fa1ea77e4e861a9e27e89a1cff07396d3fefd26 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 26 Jun 2018 10:43:06 -0700 Subject: [PATCH 12/16] fixed 3 leaks in creating pattern values --- src/NFA.cc | 17 +++++++++++++++-- src/NFA.h | 8 ++++++++ src/RE.cc | 20 ++++++++++++++++++-- src/re-scan.l | 9 ++++++++- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/NFA.cc b/src/NFA.cc index 8fb78a7131..c53aa4304b 100644 --- a/src/NFA.cc +++ b/src/NFA.cc @@ -12,6 +12,7 @@ NFA_State::NFA_State(int arg_sym, EquivClass* ec) sym = arg_sym; ccl = 0; accept = NO_ACCEPT; + first_trans_is_back_ref = false; mark = 0; epsclosure = 0; id = ++nfa_state_id; @@ -33,6 +34,7 @@ NFA_State::NFA_State(CCL* arg_ccl) sym = SYM_CCL; ccl = arg_ccl; accept = NO_ACCEPT; + first_trans_is_back_ref = false; mark = 0; id = ++nfa_state_id; epsclosure = 0; @@ -41,7 +43,8 @@ NFA_State::NFA_State(CCL* arg_ccl) NFA_State::~NFA_State() { for ( int i = 0; i < xtions.length(); ++i ) - Unref(xtions[i]); + if ( i > 0 || ! first_trans_is_back_ref ) + Unref(xtions[i]); delete epsclosure; } @@ -247,7 +250,10 @@ void NFA_Machine::MakePositiveClosure() { AppendEpsilon(); final_state->AddXtion(first_state); - Ref(first_state); + + // Don't Ref the state the final epsilon points to, otherwise we'll + // have reference cycles that lead to leaks. + final_state->SetFirstTransIsBackRef(); } void NFA_Machine::MakeRepl(int lower, int upper) @@ -307,6 +313,13 @@ NFA_Machine* make_alternate(NFA_Machine* m1, NFA_Machine* m2) m2->AppendState(last); Ref(last); + // Keep these around. + Ref(m1->FirstState()); + Ref(m2->FirstState()); + + Unref(m1); + Unref(m2); + return new NFA_Machine(first, last); } diff --git a/src/NFA.h b/src/NFA.h index 560f0930b4..79c3961dd5 100644 --- a/src/NFA.h +++ b/src/NFA.h @@ -46,6 +46,8 @@ public: NFA_State* Mark() const { return mark; } void ClearMarks(); + void SetFirstTransIsBackRef() { first_trans_is_back_ref = true; } + int TransSym() const { return sym; } CCL* TransCCL() const { return ccl; } int ID() const { return id; } @@ -62,7 +64,13 @@ protected: int sym; // if SYM_CCL, then use ccl CCL* ccl; // if nil, then use sym int accept; + + // Whether the first transition points backwards. Used + // to avoid reference-counting loops. + bool first_trans_is_back_ref; + int id; // number that uniquely identifies this state + NFA_state_list xtions; NFA_state_list* epsclosure; NFA_State* mark; diff --git a/src/RE.cc b/src/RE.cc index a4294e064d..4d26ce2423 100644 --- a/src/RE.cc +++ b/src/RE.cc @@ -19,6 +19,7 @@ int case_insensitive = 0; extern int RE_parse(void); extern void RE_set_input(const char* str); +extern void RE_done_with_scan(); Specific_RE_Matcher::Specific_RE_Matcher(match_type arg_mt, int arg_multiline) : equiv_class(NUM_SYM) @@ -108,9 +109,15 @@ int Specific_RE_Matcher::Compile(int lazy) rem = this; RE_set_input(pattern_text); - if ( RE_parse() ) + + int parse_status = RE_parse(); + RE_done_with_scan(); + + if ( parse_status ) { reporter->Error("error compiling pattern /%s/", pattern_text); + Unref(nfa); + nfa = 0; return 0; } @@ -139,9 +146,18 @@ int Specific_RE_Matcher::CompileSet(const string_list& set, const int_list& idx) loop_over_list(set, i) { RE_set_input(set[i]); - if ( RE_parse() ) + int parse_status = RE_parse(); + RE_done_with_scan(); + + if ( parse_status ) { reporter->Error("error compiling pattern /%s/", set[i]); + + if ( set_nfa != nfa ) + Unref(set_nfa); + Unref(nfa); + nfa = 0; + return 0; } diff --git a/src/re-scan.l b/src/re-scan.l index 0d737f08a6..8bd00c8bba 100644 --- a/src/re-scan.l +++ b/src/re-scan.l @@ -196,8 +196,15 @@ CCL_EXPR ("[:"[[:alpha:]]+":]") %% +YY_BUFFER_STATE RE_buf; + void RE_set_input(const char* str) { RE_parse_input = str; - yy_scan_string(str); + RE_buf = yy_scan_string(str); + } + +void RE_done_with_scan() + { + yy_delete_buffer(RE_buf); } From bd5414d8d5ed0a678c230d9e6e2b81b2499db899 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 26 Jun 2018 10:57:24 -0700 Subject: [PATCH 13/16] whoops - patterns ops broke count bitwise ops --- src/Expr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Expr.cc b/src/Expr.cc index b979a3638b..4c3c7a536a 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -1901,7 +1901,7 @@ BitExpr::BitExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) SetType(base_type(TYPE_COUNT)); } - if ( bt1 == TYPE_PATTERN ) + else if ( bt1 == TYPE_PATTERN ) { if ( bt2 != TYPE_PATTERN ) ExprError("cannot mix pattern and non-pattern operands"); From ac495e729bc29323027aa4dc17dce59de93013d9 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 26 Jun 2018 15:05:23 -0500 Subject: [PATCH 14/16] Fix deprecated actor_system_config field usages --- CHANGES | 4 ++++ VERSION | 2 +- aux/broker | 2 +- src/3rdparty | 2 +- src/broker/Manager.cc | 10 +++++----- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 206a804ab7..78c8dbf629 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +2.5-690 | 2018-06-26 15:05:23 -0500 + + * Fix deprecated actor_system_config field usages (Corelight) + 2.5-689 | 2018-06-26 11:45:52 -0500 * Remove header self-inclusions (Corelight) diff --git a/VERSION b/VERSION index b34c5c7be1..c546c8150b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.5-689 +2.5-690 diff --git a/aux/broker b/aux/broker index 17fcb73a30..6d5b3c785c 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 17fcb73a30388862f0a921040a605ac38f47ff74 +Subproject commit 6d5b3c785c3c1e517c4c7596beda23e411edeff2 diff --git a/src/3rdparty b/src/3rdparty index c78abc8454..0b10bb2943 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit c78abc8454932019f030045340348560a8ac9b23 +Subproject commit 0b10bb2943beaf972ddc494ba34699ed37ef3dbf diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index f31537f3b7..6f5e09e611 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -185,7 +185,7 @@ void Manager::InitPostScript() auto max_sleep = get_option("Broker::max_sleep")->AsCount(); if ( max_threads ) - config.scheduler_max_threads = max_threads; + config.set("scheduler.max-threads", max_threads); else { // On high-core-count systems, spawning one thread per core @@ -193,7 +193,7 @@ void Manager::InitPostScript() // threads are under-utilized. Related: // https://github.com/actor-framework/actor-framework/issues/699 if ( reading_pcaps ) - config.scheduler_max_threads = 2u; + config.set("scheduler.max-threads", 2u); else { auto hc = std::thread::hardware_concurrency(); @@ -203,18 +203,18 @@ void Manager::InitPostScript() else if ( hc < 4u) hc = 4u; - config.scheduler_max_threads = hc; + config.set("scheduler.max-threads", hc); } } if ( max_sleep ) - config.work_stealing_relaxed_sleep_duration_us = max_sleep; + config.set("work-stealing.relaxed-sleep-duration-us", max_sleep); else // 64ms is just an arbitrary amount derived from testing // the overhead of a unused CAF actor system on a 32-core system. // Performance was within 2% of baseline timings (w/o CAF) // when using this sleep duration. - config.work_stealing_relaxed_sleep_duration_us = 64000; + config.set("work-stealing.relaxed-sleep-duration-us", 64000); bstate = std::make_shared(std::move(config)); } From a97567ef389578a08de9a00f62700624ebfec5a6 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 26 Jun 2018 18:00:51 -0500 Subject: [PATCH 15/16] Add memory leak unit test for pattern operations --- testing/btest/core/leaks/pattern.bro | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 testing/btest/core/leaks/pattern.bro diff --git a/testing/btest/core/leaks/pattern.bro b/testing/btest/core/leaks/pattern.bro new file mode 100644 index 0000000000..3119ad12af --- /dev/null +++ b/testing/btest/core/leaks/pattern.bro @@ -0,0 +1,38 @@ +# @TEST-GROUP: leaks +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks + +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run bro bro -m -b -r $TRACES/http/get.trace %INPUT +# @TEST-EXEC: btest-bg-wait 60 + +function test_case(msg: string, expect: bool) + { + print fmt("%s (%s)", msg, expect ? "PASS" : "FAIL"); + } + +event new_connection(c: connection) + { + print "new connection"; + + local p1: pattern = /foo|bar/; + local p2: pattern = /oob/; + local p3: pattern = /^oob/; + local p4 = /foo/; + + # Type inference tests + + test_case( "type inference", type_name(p4) == "pattern" ); + + # Operator tests + + test_case( "equality operator", "foo" == p1 ); + test_case( "equality operator (order of operands)", p1 == "foo" ); + test_case( "inequality operator", "foobar" != p1 ); + test_case( "inequality operator (order of operands)", p1 != "foobar" ); + test_case( "in operator", p1 in "foobar" ); + test_case( "in operator", p2 in "foobar" ); + test_case( "!in operator", p3 !in "foobar" ); + test_case( "& operator", p1 & p2 in "baroob" ); + test_case( "& operator", p2 & p1 in "baroob" ); + test_case( "| operator", p1 | p2 in "lazybarlazy" ); + test_case( "| operator", p3 | p4 in "xoob" ); + } From e33a3a9c0298dec00474c1e4b79dce2b57dafaa5 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 26 Jun 2018 18:06:07 -0500 Subject: [PATCH 16/16] Fix typo in NEWS --- CHANGES | 16 ++++++++++++++++ NEWS | 2 +- VERSION | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 78c8dbf629..f8ca072f83 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,20 @@ +2.5-710 | 2018-06-26 18:06:22 -0500 + + * Add memory leak unit test for pattern operations (Corelight) + + * fixed 3 leaks in creating pattern values (Vern Paxson) + + * add & and | operators for patterns (Vern Paxson) + + * deprecate merge_patterns() (Vern Paxson) + + * deprecate boolean scalar+vector operations (Vern Paxson) + + * deprecate mixing scalars and vectors (Vern Paxson) + + * deprecate && / || operators for patterns (Vern Paxson) + 2.5-690 | 2018-06-26 15:05:23 -0500 * Fix deprecated actor_system_config field usages (Corelight) diff --git a/NEWS b/NEWS index f594207f58..a4f233a116 100644 --- a/NEWS +++ b/NEWS @@ -252,7 +252,7 @@ New Functionality - The '&' and '|' operators can apply to patterns, too. p1 & p2 yields a pattern that represents matching p1 followed by p2, and p1 | p2 yields a pattern representing matching p1 or p2. The p1 | p2 functionality was - semi-present in previous versions of Bro, but required constants as as + semi-present in previous versions of Bro, but required constants as its operands; now you can use any pattern-valued expressions. Changed Functionality diff --git a/VERSION b/VERSION index c546c8150b..ca1bc4e12b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.5-690 +2.5-710