diff --git a/CHANGES b/CHANGES index fcad200e12..9ff294055c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,101 @@ +2.1-195 | 2012-12-03 14:50:33 -0800 + + * Catching out-of-memory in patricia tree code. (Bill Parker) + +2.1-194 | 2012-12-03 14:36:26 -0800 + + * Renaming ASCII writer filter option 'only_single_header_row' to + 'tsv'. Also clarifying usage. Closes #912. (Robin Sommer) + +2.1-193 | 2012-12-03 14:11:14 -0800 + + * Fix a set of bugs with table/set attributes. (Jon Siwek) + + - Identifiers that are initialized with set()/table() constructor + expressions now inherit attributes from the expression. Before, + statements like + + const i: set[string] = set() &redef; + + associated the attribute with the set() constructor, but not the + "i" identifier, preventing redefinition. Addresses #866. + + - Allow &default attribute to apply to tables initialized as empty + (via either "{ }" or "table()") or if the expression supplied to it + can evaluate to a type that's promotable to the same yield type as + the table. + +2.1-191 | 2012-12-03 14:08:56 -0800 + + * Add test of record() constructor to table initializer unit test. + (Jon Siwek) + + * Fix table(), set(), vector() constructors in table initializer + lists. Also adds type checking of yield values to table() + constructor and fixes the type checking of yield values in + vector() constructor. Addresses #5. (Jon Siwek) + +2.1-188 | 2012-12-03 14:04:29 -0800 + + * Hook functions now callable with "hook" expression (i.e., hook is + no longer a statement). The return value of the call is an + implicit boolean value of T if all hook handlers ran, or F if one + hook handler exited as a result of a break statement and + potentially prevented other handlers from running. + + Scripts don't need to declare hooks with an explicit return type of bool + (internally, that's assumed), and any values given to (optional) return + statements in handler definitions are just ignored. + + Addresses #918. (Jon Siwek) + + * Clarification in hook documentation. (Jon Siwek) + +2.1-184 | 2012-12-03 13:59:50 -0800 + + * Slightly fix up file name extraction from Content-Disposition + headers. (Seth Hall) + + * Adding -b flag to bro in unit tests so they run faster. + + * Fixed a DNS attribute issue. Reported by Matt Thompson. (Seth + Hall) + + * Adding NEWS placeholder for hooks and CSV mode. (Robin Sommer) + +2.1-178 | 2012-11-23 19:35:32 -0800 + + * The ASCII writer now supports a new filter config option + "only_single_header_row" that turns the output into CSV format + when set to "T". (Carsten Langer) + + * Add new function flavor called a "hook". This new flavor of + function behaves like a "synchronous event". See + doc/scripts/builtins.rst more details on usage. (Jon Siwek) + + * Improve auto-generated enum documentation. The names of enum types + are tracked so that variables holding a value of a given enum type + can generate a reference to it instead of just listing the type as + a generic "enum". (Jon Siwek) + +2.1-171 | 2012-11-23 18:24:15 -0800 + + * Fix ambiguity between composite table index and record ctor + expressions. If a 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. (Jon Siwek) + +2.1-169 | 2012-11-23 18:21:32 -0800 + + * Fix some warnings from sphinx when building docs. (Jon Siwek) + +2.1-167 | 2012-11-14 13:19:17 -0800 + + * Add a new BIF "bytestring_to_double" for converting from a binary + representation of a double. Addresses #908. (Carsten Langer/Daniel + Thayer) + 2.1-162 | 2012-11-13 17:29:00 -0800 * Fix modbus register array parsing. (Jon Siwek) diff --git a/NEWS b/NEWS index 26dcf0e8cd..63c4d5d6f7 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,11 @@ New Functionality - ssl.log now also records the subject client and issuer certificates. +- Hooks: TODO: Briefly summarize the documention from + doc/scripts/builtins.rst here. + +- The ASCII writer can now output CSV files on a per filter basis. + Changed Functionality ~~~~~~~~~~~~~~~~~~~~~ diff --git a/VERSION b/VERSION index 39a178f6fb..5f2036da97 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1-162 +2.1-195 diff --git a/aux/broccoli b/aux/broccoli index 907210ce14..a8846fc5b0 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 907210ce1470724fb386f939cc1b10a4caa2ae39 +Subproject commit a8846fc5b004ffe4e3d00e826d0077ba19518192 diff --git a/doc/scripts/builtins.rst b/doc/scripts/builtins.rst index 507a4b96e3..9e14e72a0d 100644 --- a/doc/scripts/builtins.rst +++ b/doc/scripts/builtins.rst @@ -524,10 +524,6 @@ The Bro scripting language supports the following built-in types. Writing to files like this for logging usually isn't recommended, for better logging support see :doc:`/logging`. -.. bro:type:: func - - See :bro:type:`function`. - .. bro:type:: function Function types in Bro are declared using:: @@ -611,6 +607,87 @@ The Bro scripting language supports the following built-in types. identifier and the body of each will be executed in turn. Ordering of execution can be influenced with :bro:attr:`&priority`. +.. bro:type:: hook + + A hook is another flavor of function that shares characteristics of + both a :bro:type:`function` and a :bro:type:`event`. They are like + events in that many handler bodies can be defined for the same hook + identifier and the order of execution can be enforced with + :bro:attr:`&priority`. They are more like functions in the way they + are invoked/called, because, unlike events, their execution is + immediate and they do not get scheduled through an event queue. + Also, a unique feature of a hook is that a given hook handler body + can short-circuit the execution of remaining hook handlers simply by + exiting from the body as a result of a ``break`` statement (as + opposed to a ``return`` or just reaching the end of the body). + + A hook type is declared like:: + + hook( argument* ) + + where *argument* is a (possibly empty) comma-separated list of + arguments. For example: + + .. code:: bro + + global myhook: hook(s: string) + + Here ``myhook`` is the hook type identifier and no hook handler + bodies have been defined for it yet. To define some hook handler + bodies the syntax looks like: + + .. code:: bro + + hook myhook(s: string) &priority=10 + { + print "priority 10 myhook handler", s; + s = "bye"; + } + + hook myhook(s: string) + { + print "break out of myhook handling", s; + break; + } + + hook myhook(s: string) &priority=-5 + { + print "not going to happen", s; + } + + Note that the first (forward) declaration of ``myhook`` as a hook + type isn't strictly required. Argument types must match for all + hook handlers and any forward declaration of a given hook. + + To invoke immediate execution of all hook handler bodies, they + are called similarly to a function, except preceded by the ``hook`` + keyword: + + .. code:: bro + + hook myhook("hi"); + + or + + .. code:: bro + + if ( hook myhook("hi") ) + print "all handlers ran"; + + And the output would look like:: + + priority 10 myhook handler, hi + break out of myhook handling, bye + + Note how the modification to arguments can be seen by remaining + hook handlers. + + The return value of a hook call is an implicit :bro:type:`bool` + value with ``T`` meaning that all handlers for the hook were + executed and ``F`` meaning that only some of the handlers may have + executed due to one handler body exiting as a result of a ``break`` + statement. + Attributes ---------- diff --git a/scripts/base/frameworks/intel/main.bro b/scripts/base/frameworks/intel/main.bro index d66990e611..aeb7bf4bfc 100644 --- a/scripts/base/frameworks/intel/main.bro +++ b/scripts/base/frameworks/intel/main.bro @@ -59,7 +59,7 @@ export { }; ## Enum to represent where data came from when it was discovered. - ## The convenction is to prefix the name with "IN_". + ## The convention is to prefix the name with ``IN_``. type Where: enum { ## A catchall value to represent data of unknown provenance. IN_ANYWHERE, @@ -342,4 +342,4 @@ function insert(item: Item) else event Intel::new_item(item); } - \ No newline at end of file + diff --git a/scripts/base/frameworks/logging/writers/ascii.bro b/scripts/base/frameworks/logging/writers/ascii.bro index bacb0996d0..352006666b 100644 --- a/scripts/base/frameworks/logging/writers/ascii.bro +++ b/scripts/base/frameworks/logging/writers/ascii.bro @@ -1,5 +1,16 @@ ##! Interface for the ASCII log writer. Redefinable options are available ##! to tweak the output format of ASCII logs. +##! +##! The ASCII writer supports currently one writer-specific filter option via +##! ``config``: setting ``tsv`` to the string ``T`` turns the output into into +##! "tab-separated-value" mode where only a single header row with the column names +##! is printed out as meta information, with no "# fields" prepended; no other meta +##! data gets included in that mode. +##! +##! Example filter using this:: +##! +##! local my_filter: Log::Filter = [$name = "my-filter", $writer = Log::WRITER_ASCII, $config = table(["tsv"] = "T")]; +##! module LogAscii; diff --git a/scripts/base/protocols/dns/main.bro b/scripts/base/protocols/dns/main.bro index 8ae3806ab6..ee0e4166da 100644 --- a/scripts/base/protocols/dns/main.bro +++ b/scripts/base/protocols/dns/main.bro @@ -67,7 +67,7 @@ export { ready: bool &default=F; ## The total number of resource records in a reply message's answer ## section. - total_answers: count &default=0; + total_answers: count &optional; ## The total number of resource records in a reply message's answer, ## authority, and additional sections. total_replies: count &optional; @@ -231,6 +231,7 @@ event DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string) Log::write(DNS::LOG, c$dns); # This record is logged and no longer pending. delete c$dns_state$pending[c$dns$trans_id]; + delete c$dns; } } diff --git a/scripts/base/utils/files.bro b/scripts/base/utils/files.bro index ccd03df0e6..e1e599b0b6 100644 --- a/scripts/base/utils/files.bro +++ b/scripts/base/utils/files.bro @@ -19,7 +19,7 @@ function generate_extraction_filename(prefix: string, c: connection, suffix: str ## the filename. function extract_filename_from_content_disposition(data: string): string { - local filename = sub(data, /^.*[fF][iI][lL][eE][nN][aA][mM][eE]=/, ""); + local filename = sub(data, /^.*[fF][iI][lL][eE][nN][aA][mM][eE][[:blank:]]*=[[:blank:]]*/, ""); # Remove quotes around the filename if they are there. if ( /^\"/ in filename ) filename = split_n(filename, /\"/, F, 2)[2]; diff --git a/scripts/policy/integration/collective-intel/README b/scripts/policy/integration/collective-intel/README index 550eb96962..17d534c8dd 100644 --- a/scripts/policy/integration/collective-intel/README +++ b/scripts/policy/integration/collective-intel/README @@ -1,6 +1,4 @@ -Collective Intelligence Framework Integration -============================================= - -The scripts in this module are for deeper integration with the Collective Intelligence -Framework (CIF) since Bro's Intel framework doesn't natively behave the same as CIF nor -does it store and maintain the same data in all cases. \ No newline at end of file +The scripts in this module are for deeper integration with the +Collective Intelligence Framework (CIF) since Bro's Intel framework +doesn't natively behave the same as CIF nor does it store and maintain +the same data in all cases. diff --git a/scripts/policy/protocols/modbus/track-memmap.bro b/scripts/policy/protocols/modbus/track-memmap.bro index fc02d9b274..e2001e66bf 100644 --- a/scripts/policy/protocols/modbus/track-memmap.bro +++ b/scripts/policy/protocols/modbus/track-memmap.bro @@ -2,11 +2,12 @@ ##! changes as they are discovered. ##! ##! .. todo: Not all register reads and write functions are being supported yet. -module Modbus; @load base/protocols/modbus @load base/utils/directions-and-hosts +module Modbus; + export { redef enum Log::ID += { Modbus::REGISTER_CHANGE_LOG }; diff --git a/src/Attr.cc b/src/Attr.cc index bdf247b4f5..6cc582f053 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -71,7 +71,9 @@ void Attr::DescribeReST(ODesc* d) const else if ( expr->Type()->Tag() == TYPE_FUNC ) { - d->Add(":bro:type:`func`"); + d->Add(":bro:type:`"); + d->Add(expr->Type()->AsFuncType()->FlavorString()); + d->Add("`"); } else @@ -258,6 +260,11 @@ void Attributes::CheckAttr(Attr* a) // Ok. break; + if ( type->Tag() == TYPE_TABLE && + type->AsTableType()->IsUnspecifiedTable() ) + // Ok. + break; + a->AttrExpr()->Error("&default value has inconsistent type", type); } @@ -288,6 +295,11 @@ void Attributes::CheckAttr(Attr* a) // Ok. break; + Expr* e = a->AttrExpr(); + if ( check_and_promote_expr(e, ytype) ) + // Ok. + break; + Error("&default value has inconsistent type 2"); } @@ -401,13 +413,13 @@ void Attributes::CheckAttr(Attr* a) case ATTR_GROUP: if ( type->Tag() != TYPE_FUNC || - ! type->AsFuncType()->IsEvent() ) + type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT ) Error("&group only applicable to events"); break; case ATTR_ERROR_HANDLER: if ( type->Tag() != TYPE_FUNC || - ! type->AsFuncType()->IsEvent() ) + type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT ) Error("&error_handler only applicable to events"); break; diff --git a/src/BroDoc.cc b/src/BroDoc.cc index 1e2d7d52ea..23b1f56aaa 100644 --- a/src/BroDoc.cc +++ b/src/BroDoc.cc @@ -271,6 +271,7 @@ void BroDoc::WriteInterface(const char* heading, char underline, WriteBroDocObjList(state_vars, isPublic, "State Variables", sub, isShort); WriteBroDocObjList(types, isPublic, "Types", sub, isShort); WriteBroDocObjList(events, isPublic, "Events", sub, isShort); + WriteBroDocObjList(hooks, isPublic, "Hooks", sub, isShort); WriteBroDocObjList(functions, isPublic, "Functions", sub, isShort); WriteBroDocObjList(redefs, isPublic, "Redefinitions", sub, isShort); } diff --git a/src/BroDoc.h b/src/BroDoc.h index ac6ff0a59b..79f02b7110 100644 --- a/src/BroDoc.h +++ b/src/BroDoc.h @@ -179,6 +179,30 @@ public: all.push_back(o); } + /** + * Schedules documentation of a hook declared by the script. + * @param o A pointer to a BroDocObj which contains the internal + * Bro language representation of the script hook and + * also any associated comments about it. + */ + void AddHook(const BroDocObj* o) + { + hooks.push_back(o); + all.push_back(o); + } + + /** + * Schedules documentation of a hook handler declared by the script. + * @param o A pointer to a BroDocObj which contains the internal + * Bro language representation of the script hook handler and + * also any associated comments about it. + */ + void AddHookHandler(const BroDocObj* o) + { + hook_handlers.push_back(o); + all.push_back(o); + } + /** * Schedules documentation of a function declared by the script. * @param o A pointer to a BroDocObj which contains the internal @@ -241,6 +265,8 @@ protected: BroDocObjList notices; BroDocObjList events; BroDocObjList event_handlers; + BroDocObjList hooks; + BroDocObjList hook_handlers; BroDocObjMap functions; BroDocObjList redefs; diff --git a/src/Expr.cc b/src/Expr.cc index e6936267d8..07ee4eb1e1 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -2663,7 +2663,7 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const TableVal* tv = aggr->AsTableVal(); Val* index = op1->Eval(f); - Val* v = op2->Eval(f); + Val* v = check_and_promote(op2->Eval(f), t->YieldType(), 1); if ( ! index || ! v ) return; @@ -3386,7 +3386,14 @@ Val* TableConstructorExpr::InitVal(const BroType* t, Val* aggr) const if ( IsError() ) return 0; - return op->InitVal(t, aggr); + TableType* tt = Type()->AsTableType(); + TableVal* tval = aggr ? aggr->AsTableVal() : new TableVal(tt, attrs); + const expr_list& exprs = op->AsListExpr()->Exprs(); + + loop_over_list(exprs, i) + exprs[i]->EvalIntoAggregate(t, tval, 0); + + return tval; } void TableConstructorExpr::ExprDescribe(ODesc* d) const @@ -3438,7 +3445,7 @@ Val* SetConstructorExpr::Eval(Frame* f) const if ( IsError() ) return 0; - TableVal* aggr = new TableVal(type->AsTableType(), 0); + TableVal* aggr = new TableVal(type->AsTableType(), attrs); const expr_list& exprs = op->AsListExpr()->Exprs(); loop_over_list(exprs, i) @@ -3456,7 +3463,26 @@ Val* SetConstructorExpr::InitVal(const BroType* t, Val* aggr) const if ( IsError() ) return 0; - return op->InitVal(t, aggr); + const BroType* index_type = t->AsTableType()->Indices(); + TableType* tt = Type()->AsTableType(); + TableVal* tval = aggr ? aggr->AsTableVal() : new TableVal(tt, attrs); + const expr_list& exprs = op->AsListExpr()->Exprs(); + + loop_over_list(exprs, i) + { + Expr* e = exprs[i]; + Val* element = check_and_promote(e->Eval(0), index_type, 1); + + if ( ! element || ! tval->Assign(element, 0) ) + { + Error(fmt("initialization type mismatch in set"), e); + return 0; + } + + Unref(element); + } + + return tval; } void SetConstructorExpr::ExprDescribe(ODesc* d) const @@ -3536,14 +3562,14 @@ Val* VectorConstructorExpr::InitVal(const BroType* t, Val* aggr) const if ( IsError() ) return 0; - VectorVal* vec = aggr->AsVectorVal(); - const BroType* vt = vec->Type()->AsVectorType()->YieldType(); + VectorType* vt = Type()->AsVectorType(); + VectorVal* vec = aggr ? aggr->AsVectorVal() : new VectorVal(vt); const expr_list& exprs = op->AsListExpr()->Exprs(); loop_over_list(exprs, i) { Expr* e = exprs[i]; - Val* v = check_and_promote(e->Eval(0), vt, 1); + Val* v = check_and_promote(e->Eval(0), t->YieldType(), 1); if ( ! v || ! vec->Assign(i, v, e) ) { @@ -4374,7 +4400,7 @@ bool InExpr::DoUnserialize(UnserialInfo* info) return true; } -CallExpr::CallExpr(Expr* arg_func, ListExpr* arg_args) +CallExpr::CallExpr(Expr* arg_func, ListExpr* arg_args, bool in_hook) : Expr(EXPR_CALL) { func = arg_func; @@ -4394,6 +4420,13 @@ CallExpr::CallExpr(Expr* arg_func, ListExpr* arg_args) return; } + if ( func_type->AsFuncType()->Flavor() == FUNC_FLAVOR_HOOK && ! in_hook ) + { + func->Error("hook cannot be called directly, use hook operator"); + SetError(); + return; + } + if ( ! func_type->MatchesIndex(args) ) SetError("argument type mismatch in function call"); else @@ -4402,8 +4435,28 @@ CallExpr::CallExpr(Expr* arg_func, ListExpr* arg_args) if ( ! yield ) { - Error("event called in expression"); - SetError(); + switch ( func_type->AsFuncType()->Flavor() ) { + + case FUNC_FLAVOR_FUNCTION: + Error("function has no yield type"); + SetError(); + break; + + case FUNC_FLAVOR_EVENT: + Error("event called in expression, use event statement instead"); + SetError(); + break; + + case FUNC_FLAVOR_HOOK: + Error("hook has no yield type"); + SetError(); + break; + + default: + Error("invalid function flavor"); + SetError(); + break; + } } else SetType(yield->Ref()); diff --git a/src/Expr.h b/src/Expr.h index c16cf86612..afdf02c124 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -747,6 +747,8 @@ public: TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs); ~TableConstructorExpr() { Unref(attrs); } + Attributes* Attrs() { return attrs; } + Val* Eval(Frame* f) const; protected: @@ -767,6 +769,8 @@ public: SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs); ~SetConstructorExpr() { Unref(attrs); } + Attributes* Attrs() { return attrs; } + Val* Eval(Frame* f) const; protected: @@ -959,7 +963,7 @@ protected: class CallExpr : public Expr { public: - CallExpr(Expr* func, ListExpr* args); + CallExpr(Expr* func, ListExpr* args, bool in_hook = false); ~CallExpr(); Expr* Func() const { return func; } diff --git a/src/Func.cc b/src/Func.cc index 582de1d9bb..cf548b2d95 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -284,8 +284,8 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const #endif if ( ! bodies.size() ) { - // Can only happen for events. - assert(IsEvent()); + // Can only happen for events and hooks. + assert(Flavor() == FUNC_FLAVOR_EVENT || Flavor() == FUNC_FLAVOR_HOOK); loop_over_list(*args, i) Unref((*args)[i]); return 0 ; @@ -309,7 +309,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const DescribeDebug(&d, args); g_trace_state.LogTrace("%s called: %s\n", - IsEvent() ? "event" : "function", d.Description()); + FType()->FlavorString().c_str(), d.Description()); } loop_over_list(*args, i) @@ -348,11 +348,32 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const parent->SetDelayed(); break; } + + if ( Flavor() == FUNC_FLAVOR_HOOK ) + { + // Ignore any return values of hook bodies, final return value + // depends on whether a body returns as a result of break statement. + Unref(result); + result = 0; + + if ( flow == FLOW_BREAK ) + { + // Short-circuit execution of remaining hook handler bodies. + result = new Val(false, TYPE_BOOL); + break; + } + } + } + + if ( Flavor() == FUNC_FLAVOR_HOOK ) + { + if ( ! result ) + result = new Val(true, TYPE_BOOL); } // Warn if the function returns something, but we returned from // the function without an explicit return, or without a value. - if ( FType()->YieldType() && FType()->YieldType()->Tag() != TYPE_VOID && + else if ( FType()->YieldType() && FType()->YieldType()->Tag() != TYPE_VOID && (flow != FLOW_RETURN /* we fell off the end */ || ! result /* explicit return with no result */) && ! f->HasDelayed() ) @@ -380,7 +401,7 @@ void BroFunc::AddBody(Stmt* new_body, id_list* new_inits, int new_frame_size, new_body = AddInits(new_body, new_inits); - if ( ! IsEvent() ) + if ( Flavor() == FUNC_FLAVOR_FUNCTION ) { // For functions, we replace the old body with the new one. assert(bodies.size() <= 1); diff --git a/src/Func.h b/src/Func.h index 909b2a9802..7f9627b66d 100644 --- a/src/Func.h +++ b/src/Func.h @@ -25,7 +25,7 @@ public: virtual ~Func(); virtual int IsPure() const = 0; - int IsEvent() const { return FType()->IsEvent(); } + function_flavor Flavor() const { return FType()->Flavor(); } struct Body { Stmt* stmts; diff --git a/src/ID.cc b/src/ID.cc index a70aa3fd0e..959ad9b07d 100644 --- a/src/ID.cc +++ b/src/ID.cc @@ -107,7 +107,8 @@ void ID::SetVal(Val* v, Opcode op, bool arg_weak_ref) #endif if ( type && val && - type->Tag() == TYPE_FUNC && type->AsFuncType()->IsEvent() ) + type->Tag() == TYPE_FUNC && + type->AsFuncType()->Flavor() == FUNC_FLAVOR_EVENT ) { EventHandler* handler = event_registry->Lookup(name); if ( ! handler ) @@ -657,11 +658,19 @@ void ID::DescribeReSTShort(ODesc* d) const break; case TYPE_FUNC: - d->Add(type->AsFuncType()->IsEvent() ? "event" : type_name(t)); + d->Add(type->AsFuncType()->FlavorString()); + break; + + case TYPE_ENUM: + if ( is_type ) + d->Add(type_name(t)); + else + d->Add(type->AsEnumType()->Name().c_str()); break; default: d->Add(type_name(t)); + break; } } diff --git a/src/Serializer.cc b/src/Serializer.cc index fc6d00d06c..3dea7ee9e4 100644 --- a/src/Serializer.cc +++ b/src/Serializer.cc @@ -389,23 +389,35 @@ bool Serializer::UnserializeCall(UnserialInfo* info) { if ( info->print ) fprintf(info->print, "%s [%.06f] %s(%s)\n", - functype->IsEvent() ? "Event" : "Function call", + functype->FlavorString().c_str(), time, name, types ? d.Description() : ""); - if ( functype->IsEvent() ) + switch ( functype->Flavor() ) { + + case FUNC_FLAVOR_EVENT: { EventHandler* handler = event_registry->Lookup(name); assert(handler); + if ( ! info->ignore_callbacks ) GotEvent(name, time, handler, args); + + break; } - else + + case FUNC_FLAVOR_FUNCTION: + case FUNC_FLAVOR_HOOK: if ( ! info->ignore_callbacks ) GotFunctionCall(name, time, id->ID_Val()->AsFunc(), args); + break; + + default: + reporter->InternalError("invalid function flavor"); + break; + } if ( info->ignore_callbacks ) delete_vals(args); - } else delete_vals(args); diff --git a/src/Serializer.h b/src/Serializer.h index e7396cb7f8..72e0723880 100644 --- a/src/Serializer.h +++ b/src/Serializer.h @@ -125,7 +125,7 @@ protected: // This will be increased whenever there is an incompatible change // in the data format. - static const uint32 DATA_FORMAT_VERSION = 22; + static const uint32 DATA_FORMAT_VERSION = 23; ChunkedIO* io; diff --git a/src/Stmt.cc b/src/Stmt.cc index 7d754d8e72..c65b44a9bd 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -1332,7 +1332,10 @@ ReturnStmt::ReturnStmt(Expr* arg_e) : ExprStmt(STMT_RETURN, arg_e) } else if ( ! e ) - Error("return statement needs expression"); + { + if ( ft->Flavor() != FUNC_FLAVOR_HOOK ) + Error("return statement needs expression"); + } else (void) check_and_promote_expr(e, yt); diff --git a/src/Type.cc b/src/Type.cc index 414c07d3d7..e9b0949d13 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -651,12 +651,12 @@ bool SetType::DoUnserialize(UnserialInfo* info) return true; } -FuncType::FuncType(RecordType* arg_args, BroType* arg_yield, int arg_is_event) +FuncType::FuncType(RecordType* arg_args, BroType* arg_yield, function_flavor arg_flavor) : BroType(TYPE_FUNC) { args = arg_args; yield = arg_yield; - is_event = arg_is_event; + flavor = arg_flavor; arg_types = new TypeList(); @@ -664,6 +664,25 @@ FuncType::FuncType(RecordType* arg_args, BroType* arg_yield, int arg_is_event) arg_types->Append(args->FieldType(i)->Ref()); } +string FuncType::FlavorString() const + { + switch ( flavor ) { + + case FUNC_FLAVOR_FUNCTION: + return "function"; + + case FUNC_FLAVOR_EVENT: + return "event"; + + case FUNC_FLAVOR_HOOK: + return "hook"; + + default: + reporter->InternalError("Invalid function flavor"); + return "invalid_func_flavor"; + } + } + FuncType::~FuncType() { Unref(arg_types); @@ -698,7 +717,7 @@ void FuncType::Describe(ODesc* d) const { if ( d->IsReadable() ) { - d->Add(is_event ? "event" : "function"); + d->Add(FlavorString()); d->Add("("); args->DescribeFields(d); d->Add(")"); @@ -712,7 +731,7 @@ void FuncType::Describe(ODesc* d) const else { d->Add(int(Tag())); - d->Add(is_event); + d->Add(flavor); d->Add(yield != 0); args->DescribeFields(d); if ( yield ) @@ -723,7 +742,7 @@ void FuncType::Describe(ODesc* d) const void FuncType::DescribeReST(ODesc* d) const { d->Add(":bro:type:`"); - d->Add(is_event ? "event" : "function"); + d->Add(FlavorString()); d->Add("`"); d->Add(" ("); args->DescribeFieldsReST(d, true); @@ -755,9 +774,30 @@ bool FuncType::DoSerialize(SerialInfo* info) const SERIALIZE_OPTIONAL(yield); + int ser_flavor = 0; + + switch ( flavor ) { + + case FUNC_FLAVOR_FUNCTION: + ser_flavor = 0; + break; + + case FUNC_FLAVOR_EVENT: + ser_flavor = 1; + break; + + case FUNC_FLAVOR_HOOK: + ser_flavor = 2; + break; + + default: + reporter->InternalError("Invalid function flavor serialization"); + break; + } + return args->Serialize(info) && arg_types->Serialize(info) && - SERIALIZE(is_event); + SERIALIZE(ser_flavor); } bool FuncType::DoUnserialize(UnserialInfo* info) @@ -774,7 +814,27 @@ bool FuncType::DoUnserialize(UnserialInfo* info) if ( ! arg_types ) return false; - return UNSERIALIZE(&is_event); + int ser_flavor = 0; + + if ( ! UNSERIALIZE(&ser_flavor) ) + return false; + + switch ( ser_flavor ) { + case 0: + flavor = FUNC_FLAVOR_FUNCTION; + break; + case 1: + flavor = FUNC_FLAVOR_EVENT; + break; + case 2: + flavor = FUNC_FLAVOR_HOOK; + break; + default: + reporter->InternalError("Invalid function flavor unserialization"); + break; + } + + return true; } TypeDecl::TypeDecl(BroType* t, const char* i, attr_list* arg_attrs, bool in_record) @@ -1202,9 +1262,10 @@ bool FileType::DoUnserialize(UnserialInfo* info) return yield != 0; } -EnumType::EnumType() +EnumType::EnumType(const string& arg_name) : BroType(TYPE_ENUM) { + name = arg_name; counter = 0; } @@ -1327,6 +1388,13 @@ const char* EnumType::Lookup(bro_int_t value) return 0; } +void EnumType::DescribeReST(ODesc* d) const + { + d->Add(":bro:type:`"); + d->Add(name.c_str()); + d->Add("`"); + } + void CommentedEnumType::DescribeReST(ODesc* d) const { // create temporary, reverse name map so that enums can be documented @@ -1595,7 +1663,7 @@ int same_type(const BroType* t1, const BroType* t2, int is_init) const FuncType* ft1 = (const FuncType*) t1; const FuncType* ft2 = (const FuncType*) t2; - if ( ft1->IsEvent() != ft2->IsEvent() ) + if ( ft1->Flavor() != ft2->Flavor() ) return 0; if ( t1->YieldType() || t2->YieldType() ) @@ -1882,7 +1950,7 @@ BroType* merge_types(const BroType* t1, const BroType* t2) BroType* yield = t1->YieldType() ? merge_types(t1->YieldType(), t2->YieldType()) : 0; - return new FuncType(args->AsRecordType(), yield, ft1->IsEvent()); + return new FuncType(args->AsRecordType(), yield, ft1->Flavor()); } case TYPE_RECORD: diff --git a/src/Type.h b/src/Type.h index efe15e6188..8e2bb099d8 100644 --- a/src/Type.h +++ b/src/Type.h @@ -35,7 +35,11 @@ typedef enum { #define NUM_TYPES (int(TYPE_ERROR) + 1) } TypeTag; -typedef enum { FUNC_FLAVOR_FUNCTION, FUNC_FLAVOR_EVENT } function_flavor; +typedef enum { + FUNC_FLAVOR_FUNCTION, + FUNC_FLAVOR_EVENT, + FUNC_FLAVOR_HOOK +} function_flavor; typedef enum { TYPE_INTERNAL_VOID, @@ -350,18 +354,19 @@ protected: class FuncType : public BroType { public: - FuncType(RecordType* args, BroType* yield, int is_event); + FuncType(RecordType* args, BroType* yield, function_flavor f); ~FuncType(); RecordType* Args() const { return args; } BroType* YieldType(); void SetYieldType(BroType* arg_yield) { yield = arg_yield; } - int IsEvent() const { return is_event; } + function_flavor Flavor() const { return flavor; } + string FlavorString() const; - // Used to convert a function type to an event type. - void ClearYieldType() - { Unref(yield); yield = 0; is_event = 1; } + // Used to convert a function type to an event or hook type. + void ClearYieldType(function_flavor arg_flav) + { Unref(yield); yield = 0; flavor = arg_flav; } int MatchesIndex(ListExpr*& index) const; int CheckArgs(const type_list* args) const; @@ -374,14 +379,13 @@ public: void DescribeReST(ODesc* d) const; protected: - FuncType() { args = 0; arg_types = 0; yield = 0; return_value = 0; } + FuncType() { args = 0; arg_types = 0; yield = 0; flavor = FUNC_FLAVOR_FUNCTION; } DECLARE_SERIAL(FuncType) RecordType* args; TypeList* arg_types; BroType* yield; - int is_event; - ID* return_value; + function_flavor flavor; }; class TypeType : public BroType { @@ -497,7 +501,7 @@ protected: class EnumType : public BroType { public: - EnumType(); + EnumType(const string& arg_name); ~EnumType(); // The value of this name is next internal counter value, starting @@ -513,7 +517,12 @@ public: bro_int_t Lookup(const string& module_name, const char* name); const char* Lookup(bro_int_t value); // Returns 0 if not found + string Name() const { return name; } + + void DescribeReST(ODesc* d) const; + protected: + EnumType() { counter = 0; } DECLARE_SERIAL(EnumType) virtual void AddNameInternal(const string& module_name, @@ -529,11 +538,14 @@ protected: // as a flag to prevent mixing of auto-increment and explicit // enumerator specifications. bro_int_t counter; + + // The name of the enum type is stored for documentation purposes. + string name; }; class CommentedEnumType: public EnumType { public: - CommentedEnumType() {} + CommentedEnumType(const string& arg_name) : EnumType(arg_name) {} ~CommentedEnumType(); void DescribeReST(ODesc* d) const; diff --git a/src/Val.cc b/src/Val.cc index 79fa8a0c69..3e60fffc82 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -3117,6 +3117,9 @@ void VectorVal::ValDescribe(ODesc* d) const Val* check_and_promote(Val* v, const BroType* t, int is_init) { + if ( ! v ) + return 0; + BroType* vt = v->Type(); vt = flatten_type(vt); diff --git a/src/Var.cc b/src/Var.cc index d54d94a078..2e9fdbe946 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -109,6 +109,36 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init, if ( attr ) id->AddAttrs(new Attributes(attr, t, false)); + if ( init ) + { + switch ( init->Tag() ) { + case EXPR_TABLE_CONSTRUCTOR: + { + TableConstructorExpr* ctor = (TableConstructorExpr*) init; + if ( ctor->Attrs() ) + { + ::Ref(ctor->Attrs()); + id->AddAttrs(ctor->Attrs()); + } + } + break; + + case EXPR_SET_CONSTRUCTOR: + { + SetConstructorExpr* ctor = (SetConstructorExpr*) init; + if ( ctor->Attrs() ) + { + ::Ref(ctor->Attrs()); + id->AddAttrs(ctor->Attrs()); + } + } + break; + + default: + break; + } + } + if ( id->FindAttr(ATTR_PERSISTENT) || id->FindAttr(ATTR_SYNCHRONIZED) ) { if ( dt == VAR_CONST ) @@ -171,7 +201,9 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init, id->UpdateValAttrs(); - if ( t && t->Tag() == TYPE_FUNC && t->AsFuncType()->IsEvent() ) + if ( t && t->Tag() == TYPE_FUNC && + (t->AsFuncType()->Flavor() == FUNC_FLAVOR_EVENT || + t->AsFuncType()->Flavor() == FUNC_FLAVOR_HOOK) ) { // For events, add a function value (without any body) here so that // we can later access the ID even if no implementations have been @@ -258,7 +290,7 @@ void add_type(ID* id, BroType* t, attr_list* attr, int /* is_event */) case TYPE_FUNC: tnew = new FuncType(t->AsFuncType()->Args(), t->AsFuncType()->YieldType(), - t->AsFuncType()->IsEvent()); + t->AsFuncType()->Flavor()); break; default: SerializationFormat* form = new BinarySerializationFormat(); @@ -299,7 +331,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor, if ( yt && yt->Tag() != TYPE_VOID ) id->Error("event cannot yield a value", t); - t->ClearYieldType(); + t->ClearYieldType(flavor); } if ( id->Type() ) @@ -313,21 +345,29 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor, if ( id->HasVal() ) { - int id_is_event = id->ID_Val()->AsFunc()->IsEvent(); + function_flavor id_flavor = id->ID_Val()->AsFunc()->Flavor(); - if ( id_is_event != (flavor == FUNC_FLAVOR_EVENT) ) - id->Error("inconsistency between event and function", t); - if ( id_is_event ) - { + if ( id_flavor != flavor ) + id->Error("inconsistent function flavor", t); + + switch ( id_flavor ) { + + case FUNC_FLAVOR_EVENT: + case FUNC_FLAVOR_HOOK: if ( is_redef ) // Clear out value so it will be replaced. id->SetVal(0); - } - else - { + break; + + case FUNC_FLAVOR_FUNCTION: if ( ! id->IsRedefinable() ) id->Error("already defined"); - } + break; + + default: + reporter->InternalError("invalid function flavor"); + break; + } } else id->SetType(t); diff --git a/src/bro.bif b/src/bro.bif index 87bf5b0e93..d945e54ef4 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2701,6 +2701,27 @@ function to_port%(s: string%): port return new PortVal(port, TRANSPORT_UNKNOWN); %} +## Converts a string of bytes (in network byte order) to a :bro:type:`double`. +## +## s: A string of bytes containing the binary representation of a double value. +## +## Returns: The double value contained in *s*, or 0 if the conversion +## failed. +## +function bytestring_to_double%(s: string%): double + %{ + if ( s->Len() != sizeof(double) ) + { + builtin_error("bad conversion to double"); + return new Val(0.0, TYPE_DOUBLE); + } + + // See #908 for a discussion of portability. + double d; + memcpy(&d, s->Bytes(), sizeof(double)); + return new Val(ntohd(d), TYPE_DOUBLE); + %} + ## Converts a reverse pointer name to an address. For example, ## ``1.0.168.192.in-addr.arpa`` to ``192.168.0.1``. ## diff --git a/src/input/Manager.cc b/src/input/Manager.cc index 43ac63200f..33f612cddd 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -393,7 +393,7 @@ bool Manager::CreateEventStream(RecordVal* fval) bool allow_file_func = false; - if ( ! etype->IsEvent() ) + if ( etype->Flavor() != FUNC_FLAVOR_EVENT ) { reporter->Error("stream event is a function, not an event"); return false; @@ -566,7 +566,7 @@ bool Manager::CreateTableStream(RecordVal* fval) { FuncType* etype = event->FType()->AsFuncType(); - if ( ! etype->IsEvent() ) + if ( etype->Flavor() != FUNC_FLAVOR_EVENT ) { reporter->Error("stream event is a function, not an event"); return false; diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index 4c6d2e92fd..f62cd1685d 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -327,7 +327,7 @@ bool Manager::CreateStream(EnumVal* id, RecordVal* sval) // Make sure the event is prototyped as expected. FuncType* etype = event->FType()->AsFuncType(); - if ( ! etype->IsEvent() ) + if ( etype->Flavor() != FUNC_FLAVOR_EVENT ) { reporter->Error("stream event is a function, not an event"); return false; diff --git a/src/logging/writers/Ascii.cc b/src/logging/writers/Ascii.cc index 11b322f5a3..15b50344d5 100644 --- a/src/logging/writers/Ascii.cc +++ b/src/logging/writers/Ascii.cc @@ -19,6 +19,7 @@ Ascii::Ascii(WriterFrontend* frontend) : WriterBackend(frontend) { fd = 0; ascii_done = false; + tsv = false; output_to_stdout = BifConst::LogAscii::output_to_stdout; include_meta = BifConst::LogAscii::include_meta; @@ -80,7 +81,7 @@ void Ascii::CloseFile(double t) if ( ! fd ) return; - if ( include_meta ) + if ( include_meta && ! tsv ) WriteHeaderField("close", Timestamp(0)); safe_close(fd); @@ -108,29 +109,29 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const Field* const * return false; } + for ( WriterInfo::config_map::const_iterator i = info.config.begin(); i != info.config.end(); i++ ) + { + if ( strcmp(i->first, "tsv") == 0 ) + { + if ( strcmp(i->second, "T") == 0 ) + tsv = true; + + else if ( strcmp(i->second, "F") == 0 ) + tsv = false; + + else + { + Error("invalid value for 'tsv', must be a string and either \"T\" or \"F\""); + return false; + } + } + } + if ( include_meta ) { string names; string types; - string str = string(meta_prefix, meta_prefix_len) - + "separator " // Always use space as separator here. - + get_escaped_string(string(separator, separator_len), false) - + "\n"; - - if ( ! safe_write(fd, str.c_str(), str.length()) ) - goto write_error; - - if ( ! (WriteHeaderField("set_separator", get_escaped_string( - string(set_separator, set_separator_len), false)) && - WriteHeaderField("empty_field", get_escaped_string( - string(empty_field, empty_field_len), false)) && - WriteHeaderField("unset_field", get_escaped_string( - string(unset_field, unset_field_len), false)) && - WriteHeaderField("path", get_escaped_string(path, false)) && - WriteHeaderField("open", Timestamp(0))) ) - goto write_error; - for ( int i = 0; i < num_fields; ++i ) { if ( i > 0 ) @@ -143,11 +144,39 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const Field* const * types += fields[i]->TypeName().c_str(); } + if ( tsv ) + { + // A single TSV-style line is all we need. + string str = names + "\n"; + if ( ! safe_write(fd, str.c_str(), str.length()) ) + goto write_error; + + return true; + } + + string str = string(meta_prefix, meta_prefix_len) + + "separator " // Always use space as separator here. + + get_escaped_string(string(separator, separator_len), false) + + "\n"; + + if ( ! safe_write(fd, str.c_str(), str.length()) ) + goto write_error; + + if ( ! (WriteHeaderField("set_separator", get_escaped_string( + string(set_separator, set_separator_len), false)) && + WriteHeaderField("empty_field", get_escaped_string( + string(empty_field, empty_field_len), false)) && + WriteHeaderField("unset_field", get_escaped_string( + string(unset_field, unset_field_len), false)) && + WriteHeaderField("path", get_escaped_string(path, false)) && + WriteHeaderField("open", Timestamp(0))) ) + goto write_error; + if ( ! (WriteHeaderField("fields", names) && WriteHeaderField("types", types)) ) goto write_error; } - + return true; write_error: diff --git a/src/logging/writers/Ascii.h b/src/logging/writers/Ascii.h index cf0190aa80..9fff5aae30 100644 --- a/src/logging/writers/Ascii.h +++ b/src/logging/writers/Ascii.h @@ -45,6 +45,7 @@ private: // Options set from the script-level. bool output_to_stdout; bool include_meta; + bool tsv; char* separator; int separator_len; diff --git a/src/parse.y b/src/parse.y index c1f6ddd96e..0385c1c4e1 100644 --- a/src/parse.y +++ b/src/parse.y @@ -2,14 +2,14 @@ // See the file "COPYING" in the main distribution directory for copyright. %} -%expect 87 +%expect 88 %token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY %token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF %token TOK_BOOL TOK_BREAK TOK_CASE TOK_CONST %token TOK_CONSTANT TOK_COPY TOK_COUNT TOK_COUNTER TOK_DEFAULT TOK_DELETE %token TOK_DOUBLE TOK_ELSE TOK_ENUM TOK_EVENT TOK_EXPORT TOK_FILE TOK_FOR -%token TOK_FUNCTION TOK_GLOBAL TOK_ID TOK_IF TOK_INT +%token TOK_FUNCTION TOK_GLOBAL TOK_HOOK TOK_ID TOK_IF TOK_INT %token TOK_INTERVAL TOK_LIST TOK_LOCAL TOK_MODULE %token TOK_NEXT TOK_OF TOK_PATTERN TOK_PATTERN_TEXT %token TOK_PORT TOK_PRINT TOK_RECORD TOK_REDEF @@ -32,6 +32,7 @@ %token TOK_NO_TEST +%nonassoc TOK_HOOK %left ',' '|' %right '=' TOK_ADD_TO TOK_REMOVE_FROM %right '?' ':' @@ -118,6 +119,7 @@ extern const char* g_curr_debug_error; #define YYLTYPE yyltype +static int in_hook = 0; int in_init = 0; int in_record = 0; bool resolving_global_ID = false; @@ -131,16 +133,18 @@ const char* cur_enum_elem_id = 0; type_decl_list* fake_type_decl_list = 0; TypeDecl* last_fake_type_decl = 0; +static ID* cur_decl_type_id = 0; + static void parser_new_enum (void) { /* Starting a new enum definition. */ assert(cur_enum_type == NULL); - cur_enum_type = new EnumType(); + cur_enum_type = new EnumType(cur_decl_type_id->Name()); // For documentation purposes, a separate type object is created // in order to avoid overlap that can be caused by redefs. if ( generate_documentation ) - cur_enum_type_doc = new CommentedEnumType(); + cur_enum_type_doc = new CommentedEnumType(cur_decl_type_id->Name()); } static void parser_redef_enum (ID *id) @@ -158,7 +162,7 @@ static void parser_redef_enum (ID *id) } if ( generate_documentation ) - cur_enum_type_doc = new CommentedEnumType(); + cur_enum_type_doc = new CommentedEnumType(id->Name()); } static void add_enum_comment (std::list* comments) @@ -209,7 +213,6 @@ static std::list* concat_opt_docs (std::list* pre, Val* val; RE_Matcher* re; Expr* expr; - CallExpr* call_expr; EventExpr* event_expr; Stmt* stmt; ListExpr* list; @@ -456,17 +459,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; @@ -507,7 +517,16 @@ expr: | expr '(' opt_expr_list ')' { set_location(@1, @4); - $$ = new CallExpr($1, $3); + $$ = new CallExpr($1, $3, in_hook > 0); + } + + | TOK_HOOK { ++in_hook; } expr + { + --in_hook; + set_location(@1, @3); + if ( $3->Tag() != EXPR_CALL ) + $3->Error("not a valid hook call expression"); + $$ = $3; } | expr TOK_HAS_FIELD TOK_ID @@ -859,7 +878,13 @@ type: | TOK_EVENT '(' formal_args ')' { set_location(@1, @3); - $$ = new FuncType($3, 0, 1); + $$ = new FuncType($3, 0, FUNC_FLAVOR_EVENT); + } + + | TOK_HOOK '(' formal_args ')' + { + set_location(@1, @3); + $$ = new FuncType($3, base_type(TYPE_BOOL), FUNC_FLAVOR_HOOK); } | TOK_FILE TOK_OF type @@ -991,12 +1016,27 @@ decl: ID* id = $2; if ( id->Type()->Tag() == TYPE_FUNC ) { - if ( id->Type()->AsFuncType()->IsEvent() ) - current_reST_doc->AddEvent( - new BroDocObj(id, reST_doc_comments)); - else + switch ( id->Type()->AsFuncType()->Flavor() ) { + + case FUNC_FLAVOR_FUNCTION: current_reST_doc->AddFunction( new BroDocObj(id, reST_doc_comments)); + break; + + case FUNC_FLAVOR_EVENT: + current_reST_doc->AddEvent( + new BroDocObj(id, reST_doc_comments)); + break; + + case FUNC_FLAVOR_HOOK: + current_reST_doc->AddHook( + new BroDocObj(id, reST_doc_comments)); + break; + + default: + reporter->InternalError("invalid function flavor"); + break; + } } else @@ -1098,9 +1138,10 @@ decl: } } - | TOK_TYPE global_id ':' type opt_attr ';' + | TOK_TYPE global_id ':' { cur_decl_type_id = $2; } type opt_attr ';' { - add_type($2, $4, $5, 0); + cur_decl_type_id = 0; + add_type($2, $5, $6, 0); if ( generate_documentation ) { @@ -1175,6 +1216,17 @@ func_hdr: current_reST_doc->AddEventHandler( new BroDocObj($2, reST_doc_comments)); } + | TOK_HOOK def_global_id func_params + { + $3->ClearYieldType(FUNC_FLAVOR_HOOK); + $3->SetYieldType(base_type(TYPE_BOOL)); + begin_func($2, current_module.c_str(), + FUNC_FLAVOR_HOOK, 0, $3); + $$ = $3; + if ( generate_documentation ) + current_reST_doc->AddHookHandler( + new BroDocObj($2, reST_doc_comments)); + } | TOK_REDEF TOK_EVENT event_id func_params { begin_func($3, current_module.c_str(), @@ -1209,9 +1261,9 @@ begin_func: func_params: '(' formal_args ')' ':' type - { $$ = new FuncType($2, $5, 0); } + { $$ = new FuncType($2, $5, FUNC_FLAVOR_FUNCTION); } | '(' formal_args ')' - { $$ = new FuncType($2, base_type(TYPE_VOID), 0); } + { $$ = new FuncType($2, base_type(TYPE_VOID), FUNC_FLAVOR_FUNCTION); } ; opt_type: diff --git a/src/patricia.c b/src/patricia.c index 1dbc795ab7..6998576fdb 100644 --- a/src/patricia.c +++ b/src/patricia.c @@ -2,7 +2,7 @@ * Dave Plonka * * This product includes software developed by the University of Michigan, - * Merit Network, Inc., and their contributors. + * Merit Network, Inc., and their contributors. * * This file had been called "radix.c" in the MRT sources. * @@ -12,28 +12,28 @@ */ /* From copyright.txt: - * + * * Copyright (c) 1997, 1998, 1999 - * - * + * + * * The Regents of the University of Michigan ("The Regents") and Merit Network, * Inc. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the * following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other * materials provided with the distribution. - * 3. All advertising materials mentioning features or use of - * this software must display the following acknowledgement: + * 3. All advertising materials mentioning features or use of + * this software must display the following acknowledgement: * This product includes software developed by the University of Michigan, Merit - * Network, Inc., and their contributors. + * Network, Inc., and their contributors. * 4. Neither the name of the University, Merit Network, nor the - * names of their contributors may be used to endorse or - * promote products derived from this software without + * names of their contributors may be used to endorse or + * promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -44,7 +44,7 @@ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ static char copyright[] = @@ -66,6 +66,9 @@ static char copyright[] = #define Delete free +// From Bro for reporting memory exhaustion. +extern void out_of_memory(const char* where); + /* { from prefix.c */ /* prefix_tochar @@ -80,7 +83,7 @@ prefix_tochar (prefix_t * prefix) return ((u_char *) & prefix->add.sin); } -int +int comp_with_mask (void *addr, void *dest, u_int mask) { @@ -95,15 +98,15 @@ comp_with_mask (void *addr, void *dest, u_int mask) } /* inet_pton substitute implementation - * Uses inet_addr to convert an IP address in dotted decimal notation into + * Uses inet_addr to convert an IP address in dotted decimal notation into * unsigned long and copies the result to dst. - * Only supports AF_INET. Follows standard error return conventions of + * Only supports AF_INET. Follows standard error return conventions of * inet_pton. */ int local_inet_pton (int af, const char *src, void *dst) { - u_long result; + u_long result; if (af == AF_INET) { result = inet_addr(src); @@ -166,7 +169,7 @@ my_inet_pton (int af, const char *src, void *dst) } } -/* +/* * convert prefix information to ascii string with length * thread safe and (almost) re-entrant implementation */ @@ -251,6 +254,9 @@ New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix) default_bitlen = 128; if (prefix == NULL) { prefix = calloc(1, sizeof (prefix_t)); + if (prefix == NULL) + out_of_memory("patrica/new_prefix2: unable to allocate memory"); + dynamic_allocated++; } memcpy (&prefix->add.sin6, dest, 16); @@ -260,12 +266,16 @@ New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix) if (prefix == NULL) { #ifndef NT prefix = calloc(1, sizeof (prefix4_t)); + if (prefix == NULL) + out_of_memory("patrica/new_prefix2: unable to allocate memory"); #else //for some reason, compiler is getting //prefix4_t size incorrect on NT - prefix = calloc(1, sizeof (prefix_t)); + prefix = calloc(1, sizeof (prefix_t)); + if (prefix == NULL) + out_of_memory("patrica/new_prefix2: unable to allocate memory"); #endif /* NT */ - + dynamic_allocated++; } memcpy (&prefix->add.sin, dest, 4); @@ -368,7 +378,7 @@ Ref_Prefix (prefix_t * prefix) return (prefix); } -void +void Deref_Prefix (prefix_t * prefix) { if (prefix == NULL) @@ -396,6 +406,8 @@ patricia_tree_t * New_Patricia (int maxbits) { patricia_tree_t *patricia = calloc(1, sizeof *patricia); + if (patricia == NULL) + out_of_memory("patrica/new_patricia: unable to allocate memory"); patricia->maxbits = maxbits; patricia->head = NULL; @@ -503,10 +515,10 @@ patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix) if (BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { #ifdef PATRICIA_DEBUG if (node->prefix) - fprintf (stderr, "patricia_search_exact: take right %s/%d\n", + fprintf (stderr, "patricia_search_exact: take right %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); else - fprintf (stderr, "patricia_search_exact: take right at %d\n", + fprintf (stderr, "patricia_search_exact: take right at %d\n", node->bit); #endif /* PATRICIA_DEBUG */ node = node->r; @@ -514,10 +526,10 @@ patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix) else { #ifdef PATRICIA_DEBUG if (node->prefix) - fprintf (stderr, "patricia_search_exact: take left %s/%d\n", + fprintf (stderr, "patricia_search_exact: take left %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); else - fprintf (stderr, "patricia_search_exact: take left at %d\n", + fprintf (stderr, "patricia_search_exact: take left at %d\n", node->bit); #endif /* PATRICIA_DEBUG */ node = node->l; @@ -529,7 +541,7 @@ patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix) #ifdef PATRICIA_DEBUG if (node->prefix) - fprintf (stderr, "patricia_search_exact: stop at %s/%d\n", + fprintf (stderr, "patricia_search_exact: stop at %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); else fprintf (stderr, "patricia_search_exact: stop at %d\n", node->bit); @@ -541,7 +553,7 @@ patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix) if (comp_with_mask (prefix_tochar (node->prefix), prefix_tochar (prefix), bitlen)) { #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_search_exact: found %s/%d\n", + fprintf (stderr, "patricia_search_exact: found %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); #endif /* PATRICIA_DEBUG */ return (node); @@ -575,7 +587,7 @@ patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inclusiv if (node->prefix) { #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_search_best: push %s/%d\n", + fprintf (stderr, "patricia_search_best: push %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); #endif /* PATRICIA_DEBUG */ stack[cnt++] = node; @@ -584,10 +596,10 @@ patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inclusiv if (BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { #ifdef PATRICIA_DEBUG if (node->prefix) - fprintf (stderr, "patricia_search_best: take right %s/%d\n", + fprintf (stderr, "patricia_search_best: take right %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); else - fprintf (stderr, "patricia_search_best: take right at %d\n", + fprintf (stderr, "patricia_search_best: take right at %d\n", node->bit); #endif /* PATRICIA_DEBUG */ node = node->r; @@ -595,10 +607,10 @@ patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inclusiv else { #ifdef PATRICIA_DEBUG if (node->prefix) - fprintf (stderr, "patricia_search_best: take left %s/%d\n", + fprintf (stderr, "patricia_search_best: take left %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); else - fprintf (stderr, "patricia_search_best: take left at %d\n", + fprintf (stderr, "patricia_search_best: take left at %d\n", node->bit); #endif /* PATRICIA_DEBUG */ node = node->l; @@ -615,7 +627,7 @@ patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inclusiv if (node == NULL) fprintf (stderr, "patricia_search_best: stop at null\n"); else if (node->prefix) - fprintf (stderr, "patricia_search_best: stop at %s/%d\n", + fprintf (stderr, "patricia_search_best: stop at %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); else fprintf (stderr, "patricia_search_best: stop at %d\n", node->bit); @@ -627,14 +639,14 @@ patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inclusiv while (--cnt >= 0) { node = stack[cnt]; #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_search_best: pop %s/%d\n", + fprintf (stderr, "patricia_search_best: pop %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); #endif /* PATRICIA_DEBUG */ - if (comp_with_mask (prefix_tochar (node->prefix), + if (comp_with_mask (prefix_tochar (node->prefix), prefix_tochar (prefix), node->prefix->bitlen)) { #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_search_best: found %s/%d\n", + fprintf (stderr, "patricia_search_best: found %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); #endif /* PATRICIA_DEBUG */ return (node); @@ -665,6 +677,9 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) if (patricia->head == NULL) { node = calloc(1, sizeof *node); + if (node == NULL) + out_of_memory("patrica/patrica_lookup: unable to allocate memory"); + node->bit = prefix->bitlen; node->prefix = Ref_Prefix (prefix); node->parent = NULL; @@ -672,7 +687,7 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) node->data = NULL; patricia->head = node; #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_lookup: new_node #0 %s/%d (head)\n", + fprintf (stderr, "patricia_lookup: new_node #0 %s/%d (head)\n", prefix_toa (prefix), prefix->bitlen); #endif /* PATRICIA_DEBUG */ patricia->num_active_node++; @@ -691,7 +706,7 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) break; #ifdef PATRICIA_DEBUG if (node->prefix) - fprintf (stderr, "patricia_lookup: take right %s/%d\n", + fprintf (stderr, "patricia_lookup: take right %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); else fprintf (stderr, "patricia_lookup: take right at %d\n", node->bit); @@ -703,7 +718,7 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) break; #ifdef PATRICIA_DEBUG if (node->prefix) - fprintf (stderr, "patricia_lookup: take left %s/%d\n", + fprintf (stderr, "patricia_lookup: take left %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); else fprintf (stderr, "patricia_lookup: take left at %d\n", node->bit); @@ -716,7 +731,7 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) assert (node->prefix); #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_lookup: stop at %s/%d\n", + fprintf (stderr, "patricia_lookup: stop at %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); #endif /* PATRICIA_DEBUG */ @@ -751,7 +766,7 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) parent = node->parent; #ifdef PATRICIA_DEBUG if (node->prefix) - fprintf (stderr, "patricia_lookup: up to %s/%d\n", + fprintf (stderr, "patricia_lookup: up to %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); else fprintf (stderr, "patricia_lookup: up to %d\n", node->bit); @@ -760,8 +775,8 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) if (differ_bit == bitlen && node->bit == bitlen) { if (node->prefix) { -#ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_lookup: found %s/%d\n", +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_lookup: found %s/%d\n", prefix_toa (node->prefix), node->prefix->bitlen); #endif /* PATRICIA_DEBUG */ return (node); @@ -776,6 +791,9 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) } new_node = calloc(1, sizeof *new_node); + if (new_node == NULL) + out_of_memory("patrica/patrica_lookup: unable to allocate memory"); + new_node->bit = prefix->bitlen; new_node->prefix = Ref_Prefix (prefix); new_node->parent = NULL; @@ -795,7 +813,7 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) node->l = new_node; } #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_lookup: new_node #2 %s/%d (child)\n", + fprintf (stderr, "patricia_lookup: new_node #2 %s/%d (child)\n", prefix_toa (prefix), prefix->bitlen); #endif /* PATRICIA_DEBUG */ return (new_node); @@ -822,12 +840,15 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) } node->parent = new_node; #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_lookup: new_node #3 %s/%d (parent)\n", + fprintf (stderr, "patricia_lookup: new_node #3 %s/%d (parent)\n", prefix_toa (prefix), prefix->bitlen); #endif /* PATRICIA_DEBUG */ } else { glue = calloc(1, sizeof *glue); + if (glue == NULL) + out_of_memory("patrica/patrica_lookup: unable to allocate memory"); + glue->bit = differ_bit; glue->prefix = NULL; glue->parent = node->parent; @@ -856,7 +877,7 @@ patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix) } node->parent = glue; #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_lookup: new_node #4 %s/%d (glue+node)\n", + fprintf (stderr, "patricia_lookup: new_node #4 %s/%d (glue+node)\n", prefix_toa (prefix), prefix->bitlen); #endif /* PATRICIA_DEBUG */ } @@ -874,13 +895,13 @@ patricia_remove (patricia_tree_t *patricia, patricia_node_t *node) if (node->r && node->l) { #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_remove: #0 %s/%d (r & l)\n", + fprintf (stderr, "patricia_remove: #0 %s/%d (r & l)\n", prefix_toa (node->prefix), node->prefix->bitlen); #endif /* PATRICIA_DEBUG */ - + /* this might be a placeholder node -- have to check and make sure * there is a prefix aossciated with it ! */ - if (node->prefix != NULL) + if (node->prefix != NULL) Deref_Prefix (node->prefix); node->prefix = NULL; /* Also I needed to clear data pointer -- masaki */ @@ -890,7 +911,7 @@ patricia_remove (patricia_tree_t *patricia, patricia_node_t *node) if (node->r == NULL && node->l == NULL) { #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_remove: #1 %s/%d (!r & !l)\n", + fprintf (stderr, "patricia_remove: #1 %s/%d (!r & !l)\n", prefix_toa (node->prefix), node->prefix->bitlen); #endif /* PATRICIA_DEBUG */ parent = node->parent; @@ -937,7 +958,7 @@ patricia_remove (patricia_tree_t *patricia, patricia_node_t *node) } #ifdef PATRICIA_DEBUG - fprintf (stderr, "patricia_remove: #2 %s/%d (r ^ l)\n", + fprintf (stderr, "patricia_remove: #2 %s/%d (r ^ l)\n", prefix_toa (node->prefix), node->prefix->bitlen); #endif /* PATRICIA_DEBUG */ if (node->r) { @@ -996,7 +1017,7 @@ try_search_exact (patricia_tree_t *tree, char *string) printf ("try_search_exact: not found\n"); } else { - printf ("try_search_exact: %s/%d found\n", + printf ("try_search_exact: %s/%d found\n", prefix_toa (node->prefix), node->prefix->bitlen); } Deref_Prefix (prefix); @@ -1023,7 +1044,7 @@ try_search_best (patricia_tree_t *tree, char *string) if ((node = patricia_search_best (tree, prefix)) == NULL) printf ("try_search_best: not found\n"); else - printf ("try_search_best: %s/%d found\n", + printf ("try_search_best: %s/%d found\n", prefix_toa (node->prefix), node->prefix->bitlen); Deref_Prefix (prefix); return 0; // [RS] What is supposed to be returned here? diff --git a/src/scan.l b/src/scan.l index 8ff33e7d24..4e1a66144e 100644 --- a/src/scan.l +++ b/src/scan.l @@ -287,6 +287,7 @@ for return TOK_FOR; function return TOK_FUNCTION; global return TOK_GLOBAL; "?$" return TOK_HAS_FIELD; +hook return TOK_HOOK; if return TOK_IF; in return TOK_IN; "!"{OWS}in/[^A-Za-z0-9] return TOK_NOT_IN; /* don't confuse w "! infoo"! */ diff --git a/src/util.cc b/src/util.cc index 80cd3a0685..c36ff6a31c 100644 --- a/src/util.cc +++ b/src/util.cc @@ -1416,7 +1416,7 @@ void safe_close(int fd) } } -void out_of_memory(const char* where) +extern "C" void out_of_memory(const char* where) { fprintf(stderr, "out of memory in %s.\n", where); diff --git a/src/util.h b/src/util.h index 71b9c494e8..7d65f42fa8 100644 --- a/src/util.h +++ b/src/util.h @@ -303,7 +303,7 @@ extern bool safe_write(int fd, const char* data, int len); // Wraps close(2) to emit error messages and abort on unrecoverable errors. extern void safe_close(int fd); -extern void out_of_memory(const char* where); +extern "C" void out_of_memory(const char* where); inline void* safe_realloc(void* ptr, size_t size) { diff --git a/testing/btest/Baseline/bifs.bytestring_to_double/out b/testing/btest/Baseline/bifs.bytestring_to_double/out new file mode 100644 index 0000000000..5927de2b7e --- /dev/null +++ b/testing/btest/Baseline/bifs.bytestring_to_double/out @@ -0,0 +1,9 @@ +3.140000e+15 +-3.140000e+15 +4.000000e-308 +0.000000e+00 +-0.000000e+00 +inf +-inf +nan +4.94e-324 diff --git a/testing/btest/Baseline/bifs.strptime/.stdout b/testing/btest/Baseline/bifs.strptime/.stdout deleted file mode 100644 index 179612d4c4..0000000000 --- a/testing/btest/Baseline/bifs.strptime/.stdout +++ /dev/null @@ -1,2 +0,0 @@ -1350604800.0 -0.0 diff --git a/testing/btest/Baseline/bifs.strptime/out b/testing/btest/Baseline/bifs.strptime/out new file mode 100644 index 0000000000..5fad7cd8e6 --- /dev/null +++ b/testing/btest/Baseline/bifs.strptime/out @@ -0,0 +1,3 @@ +warning: strptime conversion failed: fmt:%m d:1980-10-24 +1350604800.0 +0.0 diff --git a/testing/btest/Baseline/bifs.strptime/reporter.log b/testing/btest/Baseline/bifs.strptime/reporter.log deleted file mode 100644 index 367dbd63c1..0000000000 --- a/testing/btest/Baseline/bifs.strptime/reporter.log +++ /dev/null @@ -1,10 +0,0 @@ -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path reporter -#open 2012-10-19-06-06-36 -#fields ts level message location -#types time enum string string -0.000000 Reporter::WARNING strptime conversion failed: fmt:%m d:1980-10-24 (empty) -#close 2012-10-19-06-06-36 diff --git a/testing/btest/Baseline/doc.autogen-reST-enums/autogen-reST-enums.rst b/testing/btest/Baseline/doc.autogen-reST-enums/autogen-reST-enums.rst index 8bd6286c24..7ee7d86e66 100644 --- a/testing/btest/Baseline/doc.autogen-reST-enums/autogen-reST-enums.rst +++ b/testing/btest/Baseline/doc.autogen-reST-enums/autogen-reST-enums.rst @@ -12,6 +12,12 @@ autogen-reST-enums.bro Summary ~~~~~~~ +Options +####### +==================================================================== ====================================================================== +:bro:id:`test_enum_option`: :bro:type:`TestEnum1` :bro:attr:`&redef` this should reference the TestEnum1 type and not a generic "enum" type +==================================================================== ====================================================================== + Types ##### ======================================= ====================================== @@ -30,6 +36,16 @@ Redefinitions Detailed Interface ~~~~~~~~~~~~~~~~~~ +Options +####### +.. bro:id:: test_enum_option + + :Type: :bro:type:`TestEnum1` + :Attributes: :bro:attr:`&redef` + :Default: ``ONE`` + + this should reference the TestEnum1 type and not a generic "enum" type + Types ##### .. bro:type:: TestEnum1 diff --git a/testing/btest/Baseline/doc.autogen-reST-example/example.rst b/testing/btest/Baseline/doc.autogen-reST-example/example.rst index bee8658e14..1f60efe70b 100644 --- a/testing/btest/Baseline/doc.autogen-reST-example/example.rst +++ b/testing/btest/Baseline/doc.autogen-reST-example/example.rst @@ -73,9 +73,9 @@ Events Functions ######### -=============================================== ======================================= -:bro:id:`Example::a_function`: :bro:type:`func` Summarize purpose of "a_function" here. -=============================================== ======================================= +=================================================== ======================================= +:bro:id:`Example::a_function`: :bro:type:`function` Summarize purpose of "a_function" here. +=================================================== ======================================= Redefinitions ############# diff --git a/testing/btest/Baseline/doc.autogen-reST-func-params/autogen-reST-func-params.rst b/testing/btest/Baseline/doc.autogen-reST-func-params/autogen-reST-func-params.rst index 15526f12c7..9739d024e3 100644 --- a/testing/btest/Baseline/doc.autogen-reST-func-params/autogen-reST-func-params.rst +++ b/testing/btest/Baseline/doc.autogen-reST-func-params/autogen-reST-func-params.rst @@ -20,9 +20,9 @@ Types Functions ######### -===================================== ====================================== -:bro:id:`test_func`: :bro:type:`func` This is a global function declaration. -===================================== ====================================== +========================================= ====================================== +:bro:id:`test_func`: :bro:type:`function` This is a global function declaration. +========================================= ====================================== Detailed Interface ~~~~~~~~~~~~~~~~~~ diff --git a/testing/btest/Baseline/language.hook/out b/testing/btest/Baseline/language.hook/out new file mode 100644 index 0000000000..bef25193b8 --- /dev/null +++ b/testing/btest/Baseline/language.hook/out @@ -0,0 +1,18 @@ +myhook, &priority=10, [a=1156, b=hello world] +myhook return F +myhook return T +myhook, &priority=5, [a=37, b=goobye world] +F +myhook3, 8 +T +myhook4, 2 +myhook4, 1 +T +myhook4, 2 +myhook4, 1 +myhook4 all handlers ran +myhook, &priority=10, [a=2, b=it works] +myhook return F +myhook return T +myhook, &priority=5, [a=37, b=goobye world] +F diff --git a/testing/btest/Baseline/language.hook_calls/invalid.out b/testing/btest/Baseline/language.hook_calls/invalid.out new file mode 100644 index 0000000000..3412c1900e --- /dev/null +++ b/testing/btest/Baseline/language.hook_calls/invalid.out @@ -0,0 +1,10 @@ +error in ./invalid.bro, line 9: hook cannot be called directly, use hook operator (myhook) +warning in ./invalid.bro, line 9: expression value ignored (myhook(3)) +error in ./invalid.bro, line 10: hook cannot be called directly, use hook operator (myhook) +error in ./invalid.bro, line 11: hook cannot be called directly, use hook operator (myhook) +error in ./invalid.bro, line 12: not a valid hook call expression (2 + 2) +warning in ./invalid.bro, line 12: expression value ignored (2 + 2) +error in ./invalid.bro, line 13: not a valid hook call expression (2 + 2) +error in ./invalid.bro, line 15: hook cannot be called directly, use hook operator (h) +warning in ./invalid.bro, line 15: expression value ignored (h(3)) +error in ./invalid.bro, line 16: hook cannot be called directly, use hook operator (h) diff --git a/testing/btest/Baseline/language.hook_calls/valid.out b/testing/btest/Baseline/language.hook_calls/valid.out new file mode 100644 index 0000000000..c711115315 --- /dev/null +++ b/testing/btest/Baseline/language.hook_calls/valid.out @@ -0,0 +1,42 @@ +myhook(), 3 +other myhook(), 3 +myhook(), 3 +other myhook(), 3 +T +myhook(), 0 +F +----------- +indirect() +myhook(), 3 +other myhook(), 3 +indirect() +myhook(), 3 +other myhook(), 3 +T +----------- +really_indirect() +indirect() +myhook(), 3 +other myhook(), 3 +really_indirect() +indirect() +myhook(), 3 +other myhook(), 3 +T +----------- +myhook(), 3 +other myhook(), 3 +myhook(), 3 +other myhook(), 3 +T +myhook(), 3 +other myhook(), 3 +yes +myhook(), 0 +double yes +----------- +myhook(), 3 +other myhook(), 3 +myhook(), 3 +other myhook(), 3 +T diff --git a/testing/btest/Baseline/language.table-init-attrs/output b/testing/btest/Baseline/language.table-init-attrs/output new file mode 100644 index 0000000000..55df002ed0 --- /dev/null +++ b/testing/btest/Baseline/language.table-init-attrs/output @@ -0,0 +1,91 @@ +my_set_ctor_init +{ +test2, +test3, +test4, +test1 +} + +my_table_ctor_init +{ +[2] = test2, +[1] = test1, +[3] = test3 +} +nope + +my_set_init +{ +test2, +test3, +test4, +test1 +} + +my_table_init +{ +[2] = test2, +[4] = test4, +[1] = test1, +[3] = test3 +} +nope + +inception +{ +[0] = { +[13] = bar +} +} +{ +[13] = bar +} +bar +forty-two +{ + +} +we need to go deeper +{ +[0] = { +[13] = bar +} +} +{ +[13] = bar +} +bar +forty-two +{ + +} +we need to go deeper + +local table t1 +{ +[1] = foo +} +foo +nope + +local table t2 +{ +[1] = foo +} +foo +nope + +local table t3 +{ + +} +nope +nope + +local table t4 +{ + +} +nope +nope + diff --git a/testing/btest/Baseline/language.table-init-container-ctors/output b/testing/btest/Baseline/language.table-init-container-ctors/output new file mode 100644 index 0000000000..27774a660a --- /dev/null +++ b/testing/btest/Baseline/language.table-init-container-ctors/output @@ -0,0 +1,50 @@ +table of set +{ +[13] = { +[bar, 2] , +[foo, 1] +}, +[5] = { +[bah, 3] , +[baz, 4] +} +} + +table of vector +{ +[13] = [1, 2], +[5] = [3, 4] +} + +table of table +{ +[13] = { +[bar, 2] = 2, +[foo, 1] = 1 +}, +[5] = { +[bah, 3] = 3, +[baz, 4] = 4 +} +} + +table of record +{ +[13] = [a=1, b=foo], +[5] = [a=2, b=bar] +} + +T +T +T +T +T +T +T +T +T +T +T +T +T +T diff --git a/testing/btest/Baseline/language.table/out b/testing/btest/Baseline/language.table/out index 514cb6b02d..0d746ded2b 100644 --- a/testing/btest/Baseline/language.table/out +++ b/testing/btest/Baseline/language.table/out @@ -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) diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.ascii-tsv/ssh-filtered.log b/testing/btest/Baseline/scripts.base.frameworks.logging.ascii-tsv/ssh-filtered.log new file mode 100644 index 0000000000..f59c7c8f54 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.ascii-tsv/ssh-filtered.log @@ -0,0 +1,6 @@ +t id.orig_h id.orig_p id.resp_h id.resp_p status country b +1353727995.082217 1.2.3.4 1234 2.3.4.5 80 success unknown - +1353727995.082217 1.2.3.4 1234 2.3.4.5 80 - US - +1353727995.082217 1.2.3.4 1234 2.3.4.5 80 failure UK - +1353727995.082217 1.2.3.4 1234 2.3.4.5 80 - BR - +1353727995.082217 1.2.3.4 1234 2.3.4.5 80 failure (empty) T diff --git a/testing/btest/bifs/addr_count_conversion.bro b/testing/btest/bifs/addr_count_conversion.bro index 360994a8e5..fb87a0c6a3 100644 --- a/testing/btest/bifs/addr_count_conversion.bro +++ b/testing/btest/bifs/addr_count_conversion.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output global v: index_vec; diff --git a/testing/btest/bifs/addr_to_ptr_name.bro b/testing/btest/bifs/addr_to_ptr_name.bro index b9c831d061..ac2391cf9b 100644 --- a/testing/btest/bifs/addr_to_ptr_name.bro +++ b/testing/btest/bifs/addr_to_ptr_name.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output print addr_to_ptr_name([2607:f8b0:4009:802::1012]); diff --git a/testing/btest/bifs/addr_version.bro b/testing/btest/bifs/addr_version.bro index 3e0123ef42..bf96c0d1f3 100644 --- a/testing/btest/bifs/addr_version.bro +++ b/testing/btest/bifs/addr_version.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out print is_v4_addr(1.2.3.4); diff --git a/testing/btest/bifs/all_set.bro b/testing/btest/bifs/all_set.bro index 31544eb31e..67ae36622b 100644 --- a/testing/btest/bifs/all_set.bro +++ b/testing/btest/bifs/all_set.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/analyzer_name.bro b/testing/btest/bifs/analyzer_name.bro index 034344f5c4..9297d2ca27 100644 --- a/testing/btest/bifs/analyzer_name.bro +++ b/testing/btest/bifs/analyzer_name.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/any_set.bro b/testing/btest/bifs/any_set.bro index 5fe046cdf4..9f3f364556 100644 --- a/testing/btest/bifs/any_set.bro +++ b/testing/btest/bifs/any_set.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/bro_version.bro b/testing/btest/bifs/bro_version.bro index 7465cbc0f5..35975559a5 100644 --- a/testing/btest/bifs/bro_version.bro +++ b/testing/btest/bifs/bro_version.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT event bro_init() { diff --git a/testing/btest/bifs/byte_len.bro b/testing/btest/bifs/byte_len.bro index 25191fd173..bd15b0c390 100644 --- a/testing/btest/bifs/byte_len.bro +++ b/testing/btest/bifs/byte_len.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/bytestring_to_double.bro b/testing/btest/bifs/bytestring_to_double.bro new file mode 100644 index 0000000000..78820b207c --- /dev/null +++ b/testing/btest/bifs/bytestring_to_double.bro @@ -0,0 +1,26 @@ +# +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + +event bro_init() + { + local s1 = "\x43\x26\x4f\xa0\x71\x30\x80\x00"; # 3.14e15 + local s2 = "\xc3\x26\x4f\xa0\x71\x30\x80\x00"; #-3.14e15 + local s3 = "\x00\x1c\xc3\x59\xe0\x67\xa3\x49"; # 4e-308 + local s4 = "\x00\x00\x00\x00\x00\x00\x00\x00"; # 0.0 + local s5 = "\x80\x00\x00\x00\x00\x00\x00\x00"; #-0.0 + local s6 = "\x7f\xf0\x00\x00\x00\x00\x00\x00"; # Inf + local s7 = "\xff\xf0\x00\x00\x00\x00\x00\x00"; #-Inf + local s8 = "\x7f\xf8\x00\x00\x00\x00\x00\x00"; # NaN + local s9 = "\x00\x00\x00\x00\x00\x00\x00\x01"; # subnormal + + print bytestring_to_double(s1); + print bytestring_to_double(s2); + print fmt("%e", bytestring_to_double(s3)); + print fmt("%e", bytestring_to_double(s4)); + print fmt("%e", bytestring_to_double(s5)); + print bytestring_to_double(s6); + print bytestring_to_double(s7); + print bytestring_to_double(s8); + print fmt("%.2e", bytestring_to_double(s9)); + } diff --git a/testing/btest/bifs/bytestring_to_hexstr.bro b/testing/btest/bifs/bytestring_to_hexstr.bro index 976a4ccf71..4087047f40 100644 --- a/testing/btest/bifs/bytestring_to_hexstr.bro +++ b/testing/btest/bifs/bytestring_to_hexstr.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/capture_state_updates.bro b/testing/btest/bifs/capture_state_updates.bro index 3abfdffdc1..6a44e0f86f 100644 --- a/testing/btest/bifs/capture_state_updates.bro +++ b/testing/btest/bifs/capture_state_updates.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out # @TEST-EXEC: test -f testfile diff --git a/testing/btest/bifs/cat.bro b/testing/btest/bifs/cat.bro index b85b3af550..e923d5d066 100644 --- a/testing/btest/bifs/cat.bro +++ b/testing/btest/bifs/cat.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/cat_string_array.bro b/testing/btest/bifs/cat_string_array.bro index d2c2242411..e799f4b282 100644 --- a/testing/btest/bifs/cat_string_array.bro +++ b/testing/btest/bifs/cat_string_array.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/checkpoint_state.bro b/testing/btest/bifs/checkpoint_state.bro index 2a66bd1729..7a46516ba0 100644 --- a/testing/btest/bifs/checkpoint_state.bro +++ b/testing/btest/bifs/checkpoint_state.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT # @TEST-EXEC: test -f .state/state.bst event bro_init() diff --git a/testing/btest/bifs/clear_table.bro b/testing/btest/bifs/clear_table.bro index 94779285af..9485eba1f5 100644 --- a/testing/btest/bifs/clear_table.bro +++ b/testing/btest/bifs/clear_table.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT > out +# @TEST-EXEC: bro -b %INPUT > out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/convert_for_pattern.bro b/testing/btest/bifs/convert_for_pattern.bro index 11533cd49b..b99b010f97 100644 --- a/testing/btest/bifs/convert_for_pattern.bro +++ b/testing/btest/bifs/convert_for_pattern.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/count_to_addr.bro b/testing/btest/bifs/count_to_addr.bro index ffb2d975bf..993a701bc8 100644 --- a/testing/btest/bifs/count_to_addr.bro +++ b/testing/btest/bifs/count_to_addr.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/create_file.bro b/testing/btest/bifs/create_file.bro index 8f3d6cfdcd..af2cfb4979 100644 --- a/testing/btest/bifs/create_file.bro +++ b/testing/btest/bifs/create_file.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out # @TEST-EXEC: btest-diff testfile # @TEST-EXEC: btest-diff testfile2 diff --git a/testing/btest/bifs/current_analyzer.bro b/testing/btest/bifs/current_analyzer.bro index 45b495c046..e221d7aed0 100644 --- a/testing/btest/bifs/current_analyzer.bro +++ b/testing/btest/bifs/current_analyzer.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT event bro_init() { diff --git a/testing/btest/bifs/current_time.bro b/testing/btest/bifs/current_time.bro index 5d16df396d..9d4899aa06 100644 --- a/testing/btest/bifs/current_time.bro +++ b/testing/btest/bifs/current_time.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT event bro_init() { diff --git a/testing/btest/bifs/edit.bro b/testing/btest/bifs/edit.bro index c9a73d17f1..346c0bdbf7 100644 --- a/testing/btest/bifs/edit.bro +++ b/testing/btest/bifs/edit.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/enable_raw_output.test b/testing/btest/bifs/enable_raw_output.test index 92e0037a04..ebaff36c8f 100644 --- a/testing/btest/bifs/enable_raw_output.test +++ b/testing/btest/bifs/enable_raw_output.test @@ -1,7 +1,7 @@ # Files which enable raw output via the BiF shouldn't interpret NUL characters # in strings that are `print`ed to it. -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT # @TEST-EXEC: tr '\000' 'X' output # @TEST-EXEC: btest-diff output # @TEST-EXEC: cmp myfile hookfile diff --git a/testing/btest/bifs/entropy_test.bro b/testing/btest/bifs/entropy_test.bro index ca01c79ed7..8dc54e09b2 100644 --- a/testing/btest/bifs/entropy_test.bro +++ b/testing/btest/bifs/entropy_test.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/escape_string.bro b/testing/btest/bifs/escape_string.bro index 92b7b535d8..fd796497be 100644 --- a/testing/btest/bifs/escape_string.bro +++ b/testing/btest/bifs/escape_string.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/exit.bro b/testing/btest/bifs/exit.bro index e551144caa..b942a5e81c 100644 --- a/testing/btest/bifs/exit.bro +++ b/testing/btest/bifs/exit.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out || test $? -eq 7 +# @TEST-EXEC: bro -b %INPUT >out || test $? -eq 7 # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/file_mode.bro b/testing/btest/bifs/file_mode.bro index c63a2fa188..62bee05c6c 100644 --- a/testing/btest/bifs/file_mode.bro +++ b/testing/btest/bifs/file_mode.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/find_all.bro b/testing/btest/bifs/find_all.bro index edf3530c8a..4fe451a9d4 100644 --- a/testing/btest/bifs/find_all.bro +++ b/testing/btest/bifs/find_all.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/find_entropy.bro b/testing/btest/bifs/find_entropy.bro index 24f1c0ed84..2eb24fe118 100644 --- a/testing/btest/bifs/find_entropy.bro +++ b/testing/btest/bifs/find_entropy.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/find_last.bro b/testing/btest/bifs/find_last.bro index b1a567f73a..00ae2a874d 100644 --- a/testing/btest/bifs/find_last.bro +++ b/testing/btest/bifs/find_last.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/fmt.bro b/testing/btest/bifs/fmt.bro index 53b5f2235d..93607c2740 100644 --- a/testing/btest/bifs/fmt.bro +++ b/testing/btest/bifs/fmt.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out type color: enum { Red, Blue }; diff --git a/testing/btest/bifs/fmt_ftp_port.bro b/testing/btest/bifs/fmt_ftp_port.bro index 09ec5369e2..6a7b4d20c7 100644 --- a/testing/btest/bifs/fmt_ftp_port.bro +++ b/testing/btest/bifs/fmt_ftp_port.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/get_matcher_stats.bro b/testing/btest/bifs/get_matcher_stats.bro index baee49fe1e..eeaa8cb86a 100644 --- a/testing/btest/bifs/get_matcher_stats.bro +++ b/testing/btest/bifs/get_matcher_stats.bro @@ -1,5 +1,14 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b -s mysig %INPUT + +@TEST-START-FILE mysig.sig +signature my_ftp_client { + ip-proto == tcp + payload /(|.*[\n\r]) *[uU][sS][eE][rR] / + tcp-state originator + event "matched my_ftp_client" +} +@TEST-END-FILE event bro_init() { diff --git a/testing/btest/bifs/get_port_transport_proto.bro b/testing/btest/bifs/get_port_transport_proto.bro index c9b5e626ec..ae3c496d88 100644 --- a/testing/btest/bifs/get_port_transport_proto.bro +++ b/testing/btest/bifs/get_port_transport_proto.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/gethostname.bro b/testing/btest/bifs/gethostname.bro index 97af719745..1d760525cb 100644 --- a/testing/btest/bifs/gethostname.bro +++ b/testing/btest/bifs/gethostname.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT event bro_init() { diff --git a/testing/btest/bifs/getpid.bro b/testing/btest/bifs/getpid.bro index 98edc19a44..1852b1287e 100644 --- a/testing/btest/bifs/getpid.bro +++ b/testing/btest/bifs/getpid.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT event bro_init() { diff --git a/testing/btest/bifs/getsetenv.bro b/testing/btest/bifs/getsetenv.bro index b4ee9a0931..d217a14ea9 100644 --- a/testing/btest/bifs/getsetenv.bro +++ b/testing/btest/bifs/getsetenv.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: TESTBRO=testvalue bro %INPUT >out +# @TEST-EXEC: TESTBRO=testvalue bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/global_ids.bro b/testing/btest/bifs/global_ids.bro index 65f8944ed4..2dcb6e844d 100644 --- a/testing/btest/bifs/global_ids.bro +++ b/testing/btest/bifs/global_ids.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/global_sizes.bro b/testing/btest/bifs/global_sizes.bro index 4862db318b..4b0805172c 100644 --- a/testing/btest/bifs/global_sizes.bro +++ b/testing/btest/bifs/global_sizes.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/hexdump.bro b/testing/btest/bifs/hexdump.bro index 4c248efb77..1c86ce0db8 100644 --- a/testing/btest/bifs/hexdump.bro +++ b/testing/btest/bifs/hexdump.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/identify_data.bro b/testing/btest/bifs/identify_data.bro index 39f289d40b..68cac55c61 100644 --- a/testing/btest/bifs/identify_data.bro +++ b/testing/btest/bifs/identify_data.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT | sed 's/PNG image data/PNG image/g' >out +# @TEST-EXEC: bro -b %INPUT | sed 's/PNG image data/PNG image/g' >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/is_ascii.bro b/testing/btest/bifs/is_ascii.bro index 4d1daf96b4..fa2d39d2d8 100644 --- a/testing/btest/bifs/is_ascii.bro +++ b/testing/btest/bifs/is_ascii.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/is_local_interface.bro b/testing/btest/bifs/is_local_interface.bro index 8befdca385..ac21b04bd3 100644 --- a/testing/btest/bifs/is_local_interface.bro +++ b/testing/btest/bifs/is_local_interface.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/is_port.bro b/testing/btest/bifs/is_port.bro index fe2c3f7c35..2fe4964913 100644 --- a/testing/btest/bifs/is_port.bro +++ b/testing/btest/bifs/is_port.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/join_string.bro b/testing/btest/bifs/join_string.bro index 16222d6303..83917ef322 100644 --- a/testing/btest/bifs/join_string.bro +++ b/testing/btest/bifs/join_string.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/length.bro b/testing/btest/bifs/length.bro index 335223c124..ca82d7eab7 100644 --- a/testing/btest/bifs/length.bro +++ b/testing/btest/bifs/length.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT > out +# @TEST-EXEC: bro -b %INPUT > out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/lookup_ID.bro b/testing/btest/bifs/lookup_ID.bro index b8a29ef41f..e263c192da 100644 --- a/testing/btest/bifs/lookup_ID.bro +++ b/testing/btest/bifs/lookup_ID.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out global a = "bro test"; diff --git a/testing/btest/bifs/lowerupper.bro b/testing/btest/bifs/lowerupper.bro index fcfdcde319..77e6b1c9d1 100644 --- a/testing/btest/bifs/lowerupper.bro +++ b/testing/btest/bifs/lowerupper.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/mask_addr.bro b/testing/btest/bifs/mask_addr.bro index e1e3bccfb6..e69a55f590 100644 --- a/testing/btest/bifs/mask_addr.bro +++ b/testing/btest/bifs/mask_addr.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output const one_to_32: vector of count = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}; diff --git a/testing/btest/bifs/math.bro b/testing/btest/bifs/math.bro index 90aed5b4e6..84ace8620c 100644 --- a/testing/btest/bifs/math.bro +++ b/testing/btest/bifs/math.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/merge_pattern.bro b/testing/btest/bifs/merge_pattern.bro index b447f9a15b..de4a3afd6a 100644 --- a/testing/btest/bifs/merge_pattern.bro +++ b/testing/btest/bifs/merge_pattern.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/netbios-functions.bro b/testing/btest/bifs/netbios-functions.bro index 1fd033dd59..9b075e8729 100644 --- a/testing/btest/bifs/netbios-functions.bro +++ b/testing/btest/bifs/netbios-functions.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/order.bro b/testing/btest/bifs/order.bro index 333a8acac1..9e59caa827 100644 --- a/testing/btest/bifs/order.bro +++ b/testing/btest/bifs/order.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out function myfunc1(a: addr, b: addr): int diff --git a/testing/btest/bifs/parse_ftp.bro b/testing/btest/bifs/parse_ftp.bro index ffdc941b4b..a8993fa6e0 100644 --- a/testing/btest/bifs/parse_ftp.bro +++ b/testing/btest/bifs/parse_ftp.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/piped_exec.bro b/testing/btest/bifs/piped_exec.bro index 3a76eba8f5..70f8d70523 100644 --- a/testing/btest/bifs/piped_exec.bro +++ b/testing/btest/bifs/piped_exec.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output # @TEST-EXEC: btest-diff test.txt diff --git a/testing/btest/bifs/ptr_name_to_addr.bro b/testing/btest/bifs/ptr_name_to_addr.bro index 89679ba57a..d1a7878e3d 100644 --- a/testing/btest/bifs/ptr_name_to_addr.bro +++ b/testing/btest/bifs/ptr_name_to_addr.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output global v6 = ptr_name_to_addr("2.1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.2.0.8.0.9.0.0.4.0.b.8.f.7.0.6.2.ip6.arpa"); diff --git a/testing/btest/bifs/raw_bytes_to_v4_addr.bro b/testing/btest/bifs/raw_bytes_to_v4_addr.bro index 754580a5b0..bd685216ef 100644 --- a/testing/btest/bifs/raw_bytes_to_v4_addr.bro +++ b/testing/btest/bifs/raw_bytes_to_v4_addr.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/reading_traces.bro b/testing/btest/bifs/reading_traces.bro index fc83c50ccb..46ad04c25f 100644 --- a/testing/btest/bifs/reading_traces.bro +++ b/testing/btest/bifs/reading_traces.bro @@ -1,5 +1,5 @@ -# @TEST-EXEC: bro %INPUT >out1 +# @TEST-EXEC: bro -b %INPUT >out1 # @TEST-EXEC: btest-diff out1 # @TEST-EXEC: bro -r $TRACES/web.trace %INPUT >out2 # @TEST-EXEC: btest-diff out2 diff --git a/testing/btest/bifs/record_type_to_vector.bro b/testing/btest/bifs/record_type_to_vector.bro index 18ddf35022..9795ce886b 100644 --- a/testing/btest/bifs/record_type_to_vector.bro +++ b/testing/btest/bifs/record_type_to_vector.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out type myrecord: record { diff --git a/testing/btest/bifs/records_fields.bro b/testing/btest/bifs/records_fields.bro index 4f8cc0538a..ccaf5a719d 100644 --- a/testing/btest/bifs/records_fields.bro +++ b/testing/btest/bifs/records_fields.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out type r: record { diff --git a/testing/btest/bifs/remask_addr.bro b/testing/btest/bifs/remask_addr.bro index d387667b6a..7b7e89c018 100644 --- a/testing/btest/bifs/remask_addr.bro +++ b/testing/btest/bifs/remask_addr.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output const one_to_32: vector of count = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}; diff --git a/testing/btest/bifs/resize.bro b/testing/btest/bifs/resize.bro index 37e4ac38d9..f4067f31c7 100644 --- a/testing/btest/bifs/resize.bro +++ b/testing/btest/bifs/resize.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/resource_usage.bro b/testing/btest/bifs/resource_usage.bro index 35f5b020d6..5cf3f0f962 100644 --- a/testing/btest/bifs/resource_usage.bro +++ b/testing/btest/bifs/resource_usage.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT event bro_init() { diff --git a/testing/btest/bifs/rotate_file.bro b/testing/btest/bifs/rotate_file.bro index 7132b0aaa8..a6109ff677 100644 --- a/testing/btest/bifs/rotate_file.bro +++ b/testing/btest/bifs/rotate_file.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/rotate_file_by_name.bro b/testing/btest/bifs/rotate_file_by_name.bro index 952b09aff3..f647edefe2 100644 --- a/testing/btest/bifs/rotate_file_by_name.bro +++ b/testing/btest/bifs/rotate_file_by_name.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/same_object.bro b/testing/btest/bifs/same_object.bro index eee8b1621d..dddfd80d3d 100644 --- a/testing/btest/bifs/same_object.bro +++ b/testing/btest/bifs/same_object.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/sort.bro b/testing/btest/bifs/sort.bro index 14aa286021..7b4ac9ba63 100644 --- a/testing/btest/bifs/sort.bro +++ b/testing/btest/bifs/sort.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out function myfunc1(a: addr, b: addr): int diff --git a/testing/btest/bifs/sort_string_array.bro b/testing/btest/bifs/sort_string_array.bro index 23c4f55848..1916f93d0c 100644 --- a/testing/btest/bifs/sort_string_array.bro +++ b/testing/btest/bifs/sort_string_array.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/split.bro b/testing/btest/bifs/split.bro index fc1b5e96a0..4fd994ce41 100644 --- a/testing/btest/bifs/split.bro +++ b/testing/btest/bifs/split.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/str_shell_escape.bro b/testing/btest/bifs/str_shell_escape.bro index a71cb4dcf6..e631458bc1 100644 --- a/testing/btest/bifs/str_shell_escape.bro +++ b/testing/btest/bifs/str_shell_escape.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/strcmp.bro b/testing/btest/bifs/strcmp.bro index af46c7fa96..92d0430f1d 100644 --- a/testing/btest/bifs/strcmp.bro +++ b/testing/btest/bifs/strcmp.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/strftime.bro b/testing/btest/bifs/strftime.bro index 31f9538632..3d9e388c90 100644 --- a/testing/btest/bifs/strftime.bro +++ b/testing/btest/bifs/strftime.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/string_fill.bro b/testing/btest/bifs/string_fill.bro index c47f1916cc..0968215cc0 100644 --- a/testing/btest/bifs/string_fill.bro +++ b/testing/btest/bifs/string_fill.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/string_to_pattern.bro b/testing/btest/bifs/string_to_pattern.bro index 5164c4576f..4bd04bbcea 100644 --- a/testing/btest/bifs/string_to_pattern.bro +++ b/testing/btest/bifs/string_to_pattern.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/strip.bro b/testing/btest/bifs/strip.bro index de6601b83c..e508f20e3d 100644 --- a/testing/btest/bifs/strip.bro +++ b/testing/btest/bifs/strip.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/strptime.bro b/testing/btest/bifs/strptime.bro index 7a58989679..215299b300 100644 --- a/testing/btest/bifs/strptime.bro +++ b/testing/btest/bifs/strptime.bro @@ -1,10 +1,9 @@ # -# @TEST-EXEC: bro %INPUT -# @TEST-EXEC: btest-diff .stdout -# @TEST-EXEC: btest-diff reporter.log +# @TEST-EXEC: bro -b %INPUT >out 2>&1 +# @TEST-EXEC: btest-diff out event bro_init() { print strptime("%Y-%m-%d", "2012-10-19"); print strptime("%m", "1980-10-24"); - } \ No newline at end of file + } diff --git a/testing/btest/bifs/strstr.bro b/testing/btest/bifs/strstr.bro index 58f79d593b..40cd8aa5fd 100644 --- a/testing/btest/bifs/strstr.bro +++ b/testing/btest/bifs/strstr.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/sub.bro b/testing/btest/bifs/sub.bro index f6a956f26a..773530ac74 100644 --- a/testing/btest/bifs/sub.bro +++ b/testing/btest/bifs/sub.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/subst_string.bro b/testing/btest/bifs/subst_string.bro index 81a3f89424..6ebed72321 100644 --- a/testing/btest/bifs/subst_string.bro +++ b/testing/btest/bifs/subst_string.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/system.bro b/testing/btest/bifs/system.bro index ab2642319c..bd27fc3db5 100644 --- a/testing/btest/bifs/system.bro +++ b/testing/btest/bifs/system.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/system_env.bro b/testing/btest/bifs/system_env.bro index 23928e9b10..cfe4e7dd2a 100644 --- a/testing/btest/bifs/system_env.bro +++ b/testing/btest/bifs/system_env.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT # @TEST-EXEC: btest-diff testfile event bro_init() diff --git a/testing/btest/bifs/to_count.bro b/testing/btest/bifs/to_count.bro index c1fe72ce52..33754117d4 100644 --- a/testing/btest/bifs/to_count.bro +++ b/testing/btest/bifs/to_count.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/to_double.bro b/testing/btest/bifs/to_double.bro index f13d34f69a..b6fb9917a7 100644 --- a/testing/btest/bifs/to_double.bro +++ b/testing/btest/bifs/to_double.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/to_int.bro b/testing/btest/bifs/to_int.bro index 9d108a9da7..0562209cd0 100644 --- a/testing/btest/bifs/to_int.bro +++ b/testing/btest/bifs/to_int.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/to_interval.bro b/testing/btest/bifs/to_interval.bro index 8fded315d2..71d73fed62 100644 --- a/testing/btest/bifs/to_interval.bro +++ b/testing/btest/bifs/to_interval.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/to_port.bro b/testing/btest/bifs/to_port.bro index 382bf5d333..0dfecac43e 100644 --- a/testing/btest/bifs/to_port.bro +++ b/testing/btest/bifs/to_port.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/to_time.bro b/testing/btest/bifs/to_time.bro index 97b109e647..d5a81b0934 100644 --- a/testing/btest/bifs/to_time.bro +++ b/testing/btest/bifs/to_time.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/type_name.bro b/testing/btest/bifs/type_name.bro index 3ec13fb27d..f331fe6aa9 100644 --- a/testing/btest/bifs/type_name.bro +++ b/testing/btest/bifs/type_name.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out type color: enum { Red, Blue }; diff --git a/testing/btest/bifs/unique_id-rnd.bro b/testing/btest/bifs/unique_id-rnd.bro index 4188725373..02be9fcb92 100644 --- a/testing/btest/bifs/unique_id-rnd.bro +++ b/testing/btest/bifs/unique_id-rnd.bro @@ -1,6 +1,6 @@ # -# @TEST-EXEC: BRO_SEED_FILE= bro %INPUT >out -# @TEST-EXEC: BRO_SEED_FILE= bro %INPUT >>out +# @TEST-EXEC: BRO_SEED_FILE= bro -b %INPUT >out +# @TEST-EXEC: BRO_SEED_FILE= bro -b %INPUT >>out # @TEST-EXEC: cat out | sort | uniq | wc -l | sed 's/ //g' >count # @TEST-EXEC: btest-diff count diff --git a/testing/btest/bifs/unique_id.bro b/testing/btest/bifs/unique_id.bro index 097f5d490d..d87c757f3f 100644 --- a/testing/btest/bifs/unique_id.bro +++ b/testing/btest/bifs/unique_id.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out print unique_id("A-"); diff --git a/testing/btest/bifs/uuid_to_string.bro b/testing/btest/bifs/uuid_to_string.bro index a64e81d783..dc84f349fa 100644 --- a/testing/btest/bifs/uuid_to_string.bro +++ b/testing/btest/bifs/uuid_to_string.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out event bro_init() diff --git a/testing/btest/bifs/val_size.bro b/testing/btest/bifs/val_size.bro index 5b2e535c5c..57b512b776 100644 --- a/testing/btest/bifs/val_size.bro +++ b/testing/btest/bifs/val_size.bro @@ -1,5 +1,5 @@ # -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT event bro_init() { diff --git a/testing/btest/core/discarder.bro b/testing/btest/core/discarder.bro index 0c87eece18..9e8f5e7a2f 100644 --- a/testing/btest/core/discarder.bro +++ b/testing/btest/core/discarder.bro @@ -1,7 +1,7 @@ -# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-ip.bro >output -# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-tcp.bro >>output -# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-udp.bro >>output -# @TEST-EXEC: bro -C -r $TRACES/icmp/icmp-destunreach-udp.pcap discarder-icmp.bro >>output +# @TEST-EXEC: bro -b -C -r $TRACES/wikipedia.trace discarder-ip.bro >output +# @TEST-EXEC: bro -b -C -r $TRACES/wikipedia.trace discarder-tcp.bro >>output +# @TEST-EXEC: bro -b -C -r $TRACES/wikipedia.trace discarder-udp.bro >>output +# @TEST-EXEC: bro -b -C -r $TRACES/icmp/icmp-destunreach-udp.pcap discarder-icmp.bro >>output # @TEST-EXEC: btest-diff output @TEST-START-FILE discarder-ip.bro diff --git a/testing/btest/core/ipv6_esp.test b/testing/btest/core/ipv6_esp.test index 8744df0036..508a4597f2 100644 --- a/testing/btest/core/ipv6_esp.test +++ b/testing/btest/core/ipv6_esp.test @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro -r $TRACES/ip6_esp.trace %INPUT >output +# @TEST-EXEC: bro -b -r $TRACES/ip6_esp.trace %INPUT >output # @TEST-EXEC: btest-diff output # Just check that the event is raised correctly for a packet containing diff --git a/testing/btest/core/ipv6_zero_len_ah.test b/testing/btest/core/ipv6_zero_len_ah.test index dc3acf8443..014ba7b3cc 100644 --- a/testing/btest/core/ipv6_zero_len_ah.test +++ b/testing/btest/core/ipv6_zero_len_ah.test @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro -r $TRACES/ipv6_zero_len_ah.trace %INPUT >output +# @TEST-EXEC: bro -b -r $TRACES/ipv6_zero_len_ah.trace %INPUT >output # @TEST-EXEC: btest-diff output # Shouldn't crash, but we also won't have seq and data fields set of the ip6_ah diff --git a/testing/btest/core/leaks/hook.bro b/testing/btest/core/leaks/hook.bro new file mode 100644 index 0000000000..9234184317 --- /dev/null +++ b/testing/btest/core/leaks/hook.bro @@ -0,0 +1,100 @@ +# Needs perftools support. +# +# @TEST-GROUP: leaks +# +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m -b -r $TRACES/wikipedia.trace %INPUT + +type rec: record { + a: count; + b: string; +}; + +global myhook: hook(r: rec); +global myhook2: hook(s: string); +# a hook doesn't have to take any arguments +global myhook4: hook(); + +hook myhook(r: rec) &priority=5 + { + print "myhook, &priority=5", r; + # break statement short-circuits the hook handling chain. + break; + print "ERROR: break statement should return from hook handler body"; + } + +hook myhook(r: rec) + { + # This handler shouldn't execute ever because of the handler at priority=5 + # exiting the body from a "break" statement. + print "myhook, &priority=0", rec; + } + +hook myhook(r: rec) &priority=10 + { + print "myhook, &priority=10", r; + # modifications to the record argument will be seen by remaining handlers. + r$a = 37; + r$b = "goobye world"; + # returning from the handler early, is fine, remaining handlers still run. + return; + print "ERROR: return statement should return from hook handler body"; + } + +hook myhook(r: rec) &priority=9 + { + print "myhook return F"; + # return value is ignored, remaining handlers still run, final return + # value is whether any hook body returned via break statement + return F; + print "ERROR: return statement should return from hook handler body"; + } + +hook myhook(r: rec) &priority=8 + { + print "myhook return T"; + # return value is ignored, remaining handlers still run, final return + # value is whether any hook body returned via break statement + return T; + print "ERROR: return statement should return from hook handler body"; + } + +# hook function doesn't need a declaration, we can go straight to defining +# a handler body. +hook myhook3(i: count) + { + print "myhook3", i; + } + +hook myhook4() &priority=1 + { + print "myhook4", 1; + } + +hook myhook4() &priority=2 + { + print "myhook4", 2; + } + +event new_connection(c: connection) + { + print "new_connection", c$id; + + print hook myhook([$a=1156, $b="hello world"]); + + # A hook with no handlers is fine, it's just a no-op. + print hook myhook2("nope"); + + print hook myhook3(8); + print hook myhook4(); + if ( hook myhook4() ) + { + print "myhook4 all handlers ran"; + } + + # A hook can be treated like other data types and doesn't have to be + # invoked directly by name. + local h = myhook; + print hook h([$a=2, $b="it works"]); + } diff --git a/testing/btest/core/load-duplicates.bro b/testing/btest/core/load-duplicates.bro index e5dd365838..8c86fbc272 100644 --- a/testing/btest/core/load-duplicates.bro +++ b/testing/btest/core/load-duplicates.bro @@ -3,11 +3,11 @@ # @TEST-EXEC: mkdir -p foo/bar # @TEST-EXEC: echo "@load bar/test" >loader.bro # @TEST-EXEC: cp %INPUT foo/bar/test.bro -# @TEST-EXEC: BROPATH=$BROPATH:.:./foo bro misc/loaded-scripts loader bar/test -# @TEST-EXEC: BROPATH=$BROPATH:.:./foo bro misc/loaded-scripts loader bar/test.bro -# @TEST-EXEC: BROPATH=$BROPATH:.:./foo bro misc/loaded-scripts loader foo/bar/test -# @TEST-EXEC: BROPATH=$BROPATH:.:./foo bro misc/loaded-scripts loader foo/bar/test.bro -# @TEST-EXEC: BROPATH=$BROPATH:.:./foo bro misc/loaded-scripts loader `pwd`/foo/bar/test.bro +# @TEST-EXEC: BROPATH=$BROPATH:.:./foo bro -b misc/loaded-scripts loader bar/test +# @TEST-EXEC: BROPATH=$BROPATH:.:./foo bro -b misc/loaded-scripts loader bar/test.bro +# @TEST-EXEC: BROPATH=$BROPATH:.:./foo bro -b misc/loaded-scripts loader foo/bar/test +# @TEST-EXEC: BROPATH=$BROPATH:.:./foo bro -b misc/loaded-scripts loader foo/bar/test.bro +# @TEST-EXEC: BROPATH=$BROPATH:.:./foo bro -b misc/loaded-scripts loader `pwd`/foo/bar/test.bro type Test: enum { TEST, diff --git a/testing/btest/core/load-pkg.bro b/testing/btest/core/load-pkg.bro index 26e190a14c..e6671e038d 100644 --- a/testing/btest/core/load-pkg.bro +++ b/testing/btest/core/load-pkg.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro foo >output +# @TEST-EXEC: bro -b foo >output # @TEST-EXEC: btest-diff output @TEST-START-FILE foo/__load__.bro diff --git a/testing/btest/core/load-relative.bro b/testing/btest/core/load-relative.bro index 4050150d93..3bd082cf8a 100644 --- a/testing/btest/core/load-relative.bro +++ b/testing/btest/core/load-relative.bro @@ -1,6 +1,6 @@ # A test of relative-path-based @load'ing -# @TEST-EXEC: bro foo/foo >output +# @TEST-EXEC: bro -b foo/foo >output # @TEST-EXEC: btest-diff output @TEST-START-FILE foo/foo.bro diff --git a/testing/btest/core/load-unload.bro b/testing/btest/core/load-unload.bro index f76e9e337d..6525a8e8ea 100644 --- a/testing/btest/core/load-unload.bro +++ b/testing/btest/core/load-unload.bro @@ -1,6 +1,6 @@ # This tests the @unload directive # -# @TEST-EXEC: bro %INPUT misc/loaded-scripts dontloadmebro > output +# @TEST-EXEC: bro -b %INPUT misc/loaded-scripts dontloadmebro > output # @TEST-EXEC: btest-diff output # @TEST-EXEC: grep -q dontloadmebro loaded_scripts.log && exit 1 || exit 0 diff --git a/testing/btest/doc/autogen-reST-enums.bro b/testing/btest/doc/autogen-reST-enums.bro index fc01bed243..e3cceba22e 100644 --- a/testing/btest/doc/autogen-reST-enums.bro +++ b/testing/btest/doc/autogen-reST-enums.bro @@ -34,3 +34,6 @@ redef enum TestEnum1 += { ## adding another FIVE, ##< value }; + +## this should reference the TestEnum1 type and not a generic "enum" type +const test_enum_option = ONE &redef; diff --git a/testing/btest/istate/events-ssl.bro b/testing/btest/istate/events-ssl.bro index 1d285869b4..e4440834a7 100644 --- a/testing/btest/istate/events-ssl.bro +++ b/testing/btest/istate/events-ssl.bro @@ -11,8 +11,8 @@ # @TEST-EXEC: cat receiver/http.log | $SCRIPTS/diff-remove-timestamps >receiver.http.log # @TEST-EXEC: cmp sender.http.log receiver.http.log # -# @TEST-EXEC: bro -x sender/events.bst | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' | $SCRIPTS/diff-remove-timestamps >events.snd.log -# @TEST-EXEC: bro -x receiver/events.bst | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' | $SCRIPTS/diff-remove-timestamps >events.rec.log +# @TEST-EXEC: bro -x sender/events.bst | sed 's/^event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' | $SCRIPTS/diff-remove-timestamps >events.snd.log +# @TEST-EXEC: bro -x receiver/events.bst | sed 's/^event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' | $SCRIPTS/diff-remove-timestamps >events.rec.log # @TEST-EXEC: btest-diff events.rec.log # @TEST-EXEC: btest-diff events.snd.log # @TEST-EXEC: cmp events.rec.log events.snd.log diff --git a/testing/btest/istate/events.bro b/testing/btest/istate/events.bro index 590aabcd23..c292f77113 100644 --- a/testing/btest/istate/events.bro +++ b/testing/btest/istate/events.bro @@ -11,8 +11,8 @@ # @TEST-EXEC: cat receiver/http.log | $SCRIPTS/diff-remove-timestamps >receiver.http.log # @TEST-EXEC: cmp sender.http.log receiver.http.log # -# @TEST-EXEC: bro -x sender/events.bst | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' | $SCRIPTS/diff-remove-timestamps >events.snd.log -# @TEST-EXEC: bro -x receiver/events.bst | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' | $SCRIPTS/diff-remove-timestamps >events.rec.log +# @TEST-EXEC: bro -x sender/events.bst | sed 's/^event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' | $SCRIPTS/diff-remove-timestamps >events.snd.log +# @TEST-EXEC: bro -x receiver/events.bst | sed 's/^event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' | $SCRIPTS/diff-remove-timestamps >events.rec.log # @TEST-EXEC: btest-diff events.rec.log # @TEST-EXEC: btest-diff events.snd.log # @TEST-EXEC: cmp events.rec.log events.snd.log diff --git a/testing/btest/language/any.bro b/testing/btest/language/any.bro index 7437ee9851..fca23f6db8 100644 --- a/testing/btest/language/any.bro +++ b/testing/btest/language/any.bro @@ -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) diff --git a/testing/btest/language/at-if.bro b/testing/btest/language/at-if.bro index 979ed0bb9a..0a3e87adfa 100644 --- a/testing/btest/language/at-if.bro +++ b/testing/btest/language/at-if.bro @@ -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) diff --git a/testing/btest/language/at-ifdef.bro b/testing/btest/language/at-ifdef.bro index c30236f204..e7bb961833 100644 --- a/testing/btest/language/at-ifdef.bro +++ b/testing/btest/language/at-ifdef.bro @@ -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) diff --git a/testing/btest/language/at-ifndef.bro b/testing/btest/language/at-ifndef.bro index c98287590f..8bff0c456b 100644 --- a/testing/btest/language/at-ifndef.bro +++ b/testing/btest/language/at-ifndef.bro @@ -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) diff --git a/testing/btest/language/at-load.bro b/testing/btest/language/at-load.bro index b51594be16..7427cd639a 100644 --- a/testing/btest/language/at-load.bro +++ b/testing/btest/language/at-load.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out # In this script, we try to access each object defined in a "@load"ed script diff --git a/testing/btest/language/bool.bro b/testing/btest/language/bool.bro index b75343025f..8a1404459c 100644 --- a/testing/btest/language/bool.bro +++ b/testing/btest/language/bool.bro @@ -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) diff --git a/testing/btest/language/conditional-expression.bro b/testing/btest/language/conditional-expression.bro index 74648b6ce8..ea0acf009f 100644 --- a/testing/btest/language/conditional-expression.bro +++ b/testing/btest/language/conditional-expression.bro @@ -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) diff --git a/testing/btest/language/copy.bro b/testing/btest/language/copy.bro index 6740a080c7..3ddbc15e23 100644 --- a/testing/btest/language/copy.bro +++ b/testing/btest/language/copy.bro @@ -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) diff --git a/testing/btest/language/count.bro b/testing/btest/language/count.bro index d6dcf5a97e..b0972e29fa 100644 --- a/testing/btest/language/count.bro +++ b/testing/btest/language/count.bro @@ -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) diff --git a/testing/btest/language/cross-product-init.bro b/testing/btest/language/cross-product-init.bro index c12f9eb0bd..8cb9c48367 100644 --- a/testing/btest/language/cross-product-init.bro +++ b/testing/btest/language/cross-product-init.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output global my_subs = { 1.2.3.4/19, 5.6.7.8/21 }; diff --git a/testing/btest/language/delete-field-set.bro b/testing/btest/language/delete-field-set.bro index ad7cf6e9fb..1f1c5b0c27 100644 --- a/testing/btest/language/delete-field-set.bro +++ b/testing/btest/language/delete-field-set.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output type FooBar: record { diff --git a/testing/btest/language/delete-field.bro b/testing/btest/language/delete-field.bro index 477466b76a..99136ff2b9 100644 --- a/testing/btest/language/delete-field.bro +++ b/testing/btest/language/delete-field.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output type X: record { diff --git a/testing/btest/language/double.bro b/testing/btest/language/double.bro index 62ca768e22..f85b216828 100644 --- a/testing/btest/language/double.bro +++ b/testing/btest/language/double.bro @@ -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) diff --git a/testing/btest/language/enum-scope.bro b/testing/btest/language/enum-scope.bro index c8667bfada..82e7c7fd7c 100644 --- a/testing/btest/language/enum-scope.bro +++ b/testing/btest/language/enum-scope.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output type foo: enum { a, b } &redef; diff --git a/testing/btest/language/enum.bro b/testing/btest/language/enum.bro index 5cafb323a6..6de7d345da 100644 --- a/testing/btest/language/enum.bro +++ b/testing/btest/language/enum.bro @@ -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) diff --git a/testing/btest/language/event.bro b/testing/btest/language/event.bro index 1ea5c7b6d8..e251a3e579 100644 --- a/testing/btest/language/event.bro +++ b/testing/btest/language/event.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out diff --git a/testing/btest/language/file.bro b/testing/btest/language/file.bro index 1f631eb4fe..47430b6813 100644 --- a/testing/btest/language/file.bro +++ b/testing/btest/language/file.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT # @TEST-EXEC: btest-diff out1 # @TEST-EXEC: btest-diff out2 diff --git a/testing/btest/language/for.bro b/testing/btest/language/for.bro index f10ef0eb1b..eb99a2705d 100644 --- a/testing/btest/language/for.bro +++ b/testing/btest/language/for.bro @@ -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) diff --git a/testing/btest/language/function.bro b/testing/btest/language/function.bro index 13efbb91f8..ab60c4fa62 100644 --- a/testing/btest/language/function.bro +++ b/testing/btest/language/function.bro @@ -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) diff --git a/testing/btest/language/hook.bro b/testing/btest/language/hook.bro new file mode 100644 index 0000000000..9c9ab30c18 --- /dev/null +++ b/testing/btest/language/hook.bro @@ -0,0 +1,93 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + +type rec: record { + a: count; + b: string; +}; + +global myhook: hook(r: rec); +global myhook2: hook(s: string); +# a hook doesn't have to take any arguments +global myhook4: hook(); + +hook myhook(r: rec) &priority=5 + { + print "myhook, &priority=5", r; + # break statement short-circuits the hook handling chain. + break; + print "ERROR: break statement should return from hook handler body"; + } + +hook myhook(r: rec) + { + # This handler shouldn't execute ever because of the handler at priority=5 + # exiting the body from a "break" statement. + print "myhook, &priority=0", rec; + } + +hook myhook(r: rec) &priority=10 + { + print "myhook, &priority=10", r; + # modifications to the record argument will be seen by remaining handlers. + r$a = 37; + r$b = "goobye world"; + # returning from the handler early, is fine, remaining handlers still run. + return; + print "ERROR: return statement should return from hook handler body"; + } + +hook myhook(r: rec) &priority=9 + { + print "myhook return F"; + # return value is ignored, remaining handlers still run, final return + # value is whether any hook body returned via break statement + return F; + print "ERROR: return statement should return from hook handler body"; + } + +hook myhook(r: rec) &priority=8 + { + print "myhook return T"; + # return value is ignored, remaining handlers still run, final return + # value is whether any hook body returned via break statement + return T; + print "ERROR: return statement should return from hook handler body"; + } + +# hook function doesn't need a declaration, we can go straight to defining +# a handler body. +hook myhook3(i: count) + { + print "myhook3", i; + } + +hook myhook4() &priority=1 + { + print "myhook4", 1; + } + +hook myhook4() &priority=2 + { + print "myhook4", 2; + } + +event bro_init() + { + print hook myhook([$a=1156, $b="hello world"]); + + # A hook with no handlers is fine, it's just a no-op. + print hook myhook2("nope"); + + print hook myhook3(8); + print hook myhook4(); + if ( hook myhook4() ) + { + print "myhook4 all handlers ran"; + } + + # A hook can be treated like other data types and doesn't have to be + # invoked directly by name. + local h = myhook; + print hook h([$a=2, $b="it works"]); + } diff --git a/testing/btest/language/hook_calls.bro b/testing/btest/language/hook_calls.bro new file mode 100644 index 0000000000..41ef6f52ae --- /dev/null +++ b/testing/btest/language/hook_calls.bro @@ -0,0 +1,82 @@ +# @TEST-EXEC: bro -b valid.bro >valid.out +# @TEST-EXEC: btest-diff valid.out +# @TEST-EXEC-FAIL: bro -b invalid.bro > invalid.out 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff invalid.out + +# hook functions must be called using the "hook" keyword as an operator... + +@TEST-START-FILE valid.bro +hook myhook(i: count) + { + print "myhook()", i; + if ( i == 0 ) break; + } + +hook myhook(i: count) &priority=-1 + { + print "other myhook()", i; + } + +function indirect(): hook(i: count) + { + print "indirect()"; + return myhook; + } + +function really_indirect(): function(): hook(i: count) + { + print "really_indirect()"; + return indirect; + } + +global t: table[count] of hook(i: count) = { + [0] = myhook, +}; + +event bro_init() + { + hook myhook(3); + print hook myhook(3); + print hook myhook(0); + print "-----------"; + hook indirect()(3); + print hook indirect()(3); + print "-----------"; + hook really_indirect()()(3); + print hook really_indirect()()(3); + print "-----------"; + local h = t[0]; + hook h(3); + print hook h(3); + if ( hook h(3) ) + print "yes"; + if ( ! hook h(0) ) + print "double yes"; + print "-----------"; + hook t[0](3); + print hook t[0](3); + } + +@TEST-END-FILE + +@TEST-START-FILE invalid.bro +hook myhook(i: count) + { + print "myhook()", i; + if ( i == 0 ) break; + } + +event bro_init() + { + myhook(3); + print myhook(3); + print myhook(0); + hook 2+2; + print hook 2+2; + local h = myhook; + h(3); + if ( h(3) ) + print "hmm"; + print "done"; + } +@TEST-END-FILE diff --git a/testing/btest/language/if.bro b/testing/btest/language/if.bro index e9acea865f..785030a012 100644 --- a/testing/btest/language/if.bro +++ b/testing/btest/language/if.bro @@ -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) diff --git a/testing/btest/language/int.bro b/testing/btest/language/int.bro index 5cfa1620bd..f511d82bbb 100644 --- a/testing/btest/language/int.bro +++ b/testing/btest/language/int.bro @@ -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) diff --git a/testing/btest/language/interval.bro b/testing/btest/language/interval.bro index 66d44206d3..660683f5ca 100644 --- a/testing/btest/language/interval.bro +++ b/testing/btest/language/interval.bro @@ -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) diff --git a/testing/btest/language/module.bro b/testing/btest/language/module.bro index 4c70546406..3278697a8d 100644 --- a/testing/btest/language/module.bro +++ b/testing/btest/language/module.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT secondtestfile >out +# @TEST-EXEC: bro -b %INPUT secondtestfile >out # @TEST-EXEC: btest-diff out # In this source file, we define a module and export some objects diff --git a/testing/btest/language/next-test.bro b/testing/btest/language/next-test.bro index 7e9626a62c..d46ad187c4 100644 --- a/testing/btest/language/next-test.bro +++ b/testing/btest/language/next-test.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output # This script tests "next" being called during the last iteration of a diff --git a/testing/btest/language/no-module.bro b/testing/btest/language/no-module.bro index eadce66c18..24795df0fb 100644 --- a/testing/btest/language/no-module.bro +++ b/testing/btest/language/no-module.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT secondtestfile >out +# @TEST-EXEC: bro -b %INPUT secondtestfile >out # @TEST-EXEC: btest-diff out # This is the same test as "module.bro", but here we omit the module definition diff --git a/testing/btest/language/null-statement.bro b/testing/btest/language/null-statement.bro index 420ebd8a6c..20c70f4876 100644 --- a/testing/btest/language/null-statement.bro +++ b/testing/btest/language/null-statement.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out diff --git a/testing/btest/language/pattern.bro b/testing/btest/language/pattern.bro index ec50dc66fe..b904fe8737 100644 --- a/testing/btest/language/pattern.bro +++ b/testing/btest/language/pattern.bro @@ -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) diff --git a/testing/btest/language/port.bro b/testing/btest/language/port.bro index 1874e1dca3..a9c7fd33e7 100644 --- a/testing/btest/language/port.bro +++ b/testing/btest/language/port.bro @@ -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) diff --git a/testing/btest/language/precedence.bro b/testing/btest/language/precedence.bro index da8fef311c..27fc1e024a 100644 --- a/testing/btest/language/precedence.bro +++ b/testing/btest/language/precedence.bro @@ -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) diff --git a/testing/btest/language/raw_output_attr.test b/testing/btest/language/raw_output_attr.test index 22e565e4b4..8bcd479fbf 100644 --- a/testing/btest/language/raw_output_attr.test +++ b/testing/btest/language/raw_output_attr.test @@ -1,7 +1,7 @@ # Files with the &raw_output attribute shouldn't interpret NUL characters # in strings that are `print`ed to it. -# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: bro -b %INPUT # @TEST-EXEC: tr '\000' 'X' output # @TEST-EXEC: btest-diff output # @TEST-EXEC: cmp myfile hookfile diff --git a/testing/btest/language/rec-comp-init.bro b/testing/btest/language/rec-comp-init.bro index 598c0cf3bd..c65ef69097 100644 --- a/testing/btest/language/rec-comp-init.bro +++ b/testing/btest/language/rec-comp-init.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output # Make sure composit types in records are initialized. diff --git a/testing/btest/language/rec-nested-opt.bro b/testing/btest/language/rec-nested-opt.bro index ab1a64dffd..3b4a478f6b 100644 --- a/testing/btest/language/rec-nested-opt.bro +++ b/testing/btest/language/rec-nested-opt.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output type Version: record { diff --git a/testing/btest/language/rec-of-tbl.bro b/testing/btest/language/rec-of-tbl.bro index 59d770bb30..8d2c9ab0e0 100644 --- a/testing/btest/language/rec-of-tbl.bro +++ b/testing/btest/language/rec-of-tbl.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output type x: record { diff --git a/testing/btest/language/rec-table-default.bro b/testing/btest/language/rec-table-default.bro index ee4a0e25ee..27e0043dc3 100644 --- a/testing/btest/language/rec-table-default.bro +++ b/testing/btest/language/rec-table-default.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output type X: record { diff --git a/testing/btest/language/record-extension.bro b/testing/btest/language/record-extension.bro index 21b704ca7a..78ef929a86 100644 --- a/testing/btest/language/record-extension.bro +++ b/testing/btest/language/record-extension.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output type Foo: record { diff --git a/testing/btest/language/record-recursive-coercion.bro b/testing/btest/language/record-recursive-coercion.bro index ad9e41bd3a..0eb24a70d9 100644 --- a/testing/btest/language/record-recursive-coercion.bro +++ b/testing/btest/language/record-recursive-coercion.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output type Version: record { diff --git a/testing/btest/language/record-ref-assign.bro b/testing/btest/language/record-ref-assign.bro index f71bc3890c..a9539ab716 100644 --- a/testing/btest/language/record-ref-assign.bro +++ b/testing/btest/language/record-ref-assign.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output type State: record { diff --git a/testing/btest/language/set-opt-record-index.bro b/testing/btest/language/set-opt-record-index.bro index 18ec963809..d42de8b041 100644 --- a/testing/btest/language/set-opt-record-index.bro +++ b/testing/btest/language/set-opt-record-index.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output # Make sure a set can be indexed with a record that has optional fields diff --git a/testing/btest/language/set.bro b/testing/btest/language/set.bro index 5e56e3b9b8..d1eef7e6f0 100644 --- a/testing/btest/language/set.bro +++ b/testing/btest/language/set.bro @@ -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) diff --git a/testing/btest/language/short-circuit.bro b/testing/btest/language/short-circuit.bro index f0ba585cea..598ac8da35 100644 --- a/testing/btest/language/short-circuit.bro +++ b/testing/btest/language/short-circuit.bro @@ -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) diff --git a/testing/btest/language/sizeof.bro b/testing/btest/language/sizeof.bro index 99d7b51ce8..8b29e119bd 100644 --- a/testing/btest/language/sizeof.bro +++ b/testing/btest/language/sizeof.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output # Demo policy for the sizeof operator "|x|". diff --git a/testing/btest/language/smith-waterman-test.bro b/testing/btest/language/smith-waterman-test.bro index 50f5c1dae1..2113d88e24 100644 --- a/testing/btest/language/smith-waterman-test.bro +++ b/testing/btest/language/smith-waterman-test.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output global params: sw_params = [ $min_strlen = 2, $sw_variant = 0 ]; diff --git a/testing/btest/language/string.bro b/testing/btest/language/string.bro index 3b9137cda5..abaa556b26 100644 --- a/testing/btest/language/string.bro +++ b/testing/btest/language/string.bro @@ -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) diff --git a/testing/btest/language/strings.bro b/testing/btest/language/strings.bro index 8e9eef43bf..f601797978 100644 --- a/testing/btest/language/strings.bro +++ b/testing/btest/language/strings.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output # Demo policy for string functions diff --git a/testing/btest/language/table-init-attrs.bro b/testing/btest/language/table-init-attrs.bro new file mode 100644 index 0000000000..76d98b9fed --- /dev/null +++ b/testing/btest/language/table-init-attrs.bro @@ -0,0 +1,115 @@ +# @TEST-EXEC: bro -b %INPUT >output +# @TEST-EXEC: btest-diff output + +# set()/table() constructors are allowed to have attributes. When initializing +# an identifier, those attributes should also apply to it. + +const my_set_ctor_init: set[string] = set("test1") &redef; + +redef my_set_ctor_init += { + "test2", + "test3", +}; + +redef my_set_ctor_init += set("test4"); + +const my_table_ctor_init: table[count] of string = table([1] = "test1") &redef &default="nope"; + +redef my_table_ctor_init += { + [2] = "test2", + [3] = "test3", +}; + +# initializer list versions work the same way. + +const my_set_init: set[string] = { "test1" } &redef; + +redef my_set_init += { + "test2", + "test3", +}; + +redef my_set_init += set("test4"); + +const my_table_init: table[count] of string = { [1] = "test1" } &redef &default="nope"; + +redef my_table_init += { + [2] = "test2", + [3] = "test3", +}; + +redef my_table_init += table([4] = "test4"); + +# For tables that yield tables, we can apply attributes to the both other and +# inner tables... + +global inception_table: table[count] of table[count] of string = table( + [0] = table([13] = "bar") &default="forty-two" +) &default=table() &default="we need to go deeper"; + +global inception_table2: table[count] of table[count] of string = { + [0] = table([13] = "bar") &default="forty-two", +} &default=table() &default="we need to go deeper"; + +event bro_init() + { + print "my_set_ctor_init"; + print my_set_ctor_init; + print ""; + print "my_table_ctor_init"; + print my_table_ctor_init; + print my_table_ctor_init[5]; + print ""; + print "my_set_init"; + print my_set_init; + print ""; + print "my_table_init"; + print my_table_init; + print my_table_init[5]; + print ""; + print "inception"; + print inception_table; + print inception_table[0]; + print inception_table[0][13]; + print inception_table[0][42]; + print inception_table[1]; + print inception_table[1][2]; + print inception_table2; + print inception_table2[0]; + print inception_table2[0][13]; + print inception_table2[0][42]; + print inception_table2[1]; + print inception_table2[1][2]; + print ""; + + # just checking attributes on locals works, too + print "local table t1"; + local t1: table[count] of string = table([1] = "foo") &default="nope"; + print t1; + print t1[1]; + print t1[2]; + print ""; + + print "local table t2"; + local t2: table[count] of string = {[1] = "foo"} &default="nope"; + print t2; + print t2[1]; + print t2[2]; + print ""; + + # and for empty initializers... + print "local table t3"; + local t3: table[count] of string = table() &default="nope"; + print t3; + print t3[1]; + print t3[2]; + print ""; + + print "local table t4"; + local t4: table[count] of string = {} &default="nope"; + print t4; + print t4[1]; + print t4[2]; + print ""; + + } diff --git a/testing/btest/language/table-init-container-ctors.bro b/testing/btest/language/table-init-container-ctors.bro new file mode 100644 index 0000000000..4829f41688 --- /dev/null +++ b/testing/btest/language/table-init-container-ctors.bro @@ -0,0 +1,95 @@ +# @TEST-EXEC: bro -b %INPUT >output +# @TEST-EXEC: btest-diff output + +# The various container constructor expressions should work in table +# initialization lists. + +type set_yield: set[string, count]; +type vector_yield: vector of count; +type table_yield: table[string, count] of count; +type record_yield: record { + a: count; + b: string; +}; + +global lone_set_ctor: set_yield = set(["foo", 1], ["bar", 2]); +global lone_vector_ctor: vector_yield = vector(1, 2); +global lone_table_ctor: table_yield = table(["foo", 1] = 1, ["bar", 2] = 2); +global lone_record_ctor: record_yield = record($a=1, $b="foo"); + +global table_of_set: table[count] of set_yield = { + [13] = lone_set_ctor, + [5] = set(["bah", 3], ["baz", 4]), +}; + +global table_of_vector: table[count] of vector_yield = { + [13] = lone_vector_ctor, + [5] = vector(3, 4), +}; + +global table_of_table: table[count] of table_yield = { + [13] = lone_table_ctor, + [5] = table(["bah", 3] = 3, ["baz", 4] = 4), +}; + +global table_of_record: table[count] of record_yield = { + [13] = lone_record_ctor, + [5] = record($a=2, $b="bar"), +}; + +# Just copying the inline ctors used in the table initializer lists here +# for later comparisons. +global inline_set_ctor: set_yield = set(["bah", 3], ["baz", 4]); +global inline_vector_ctor: vector_yield = vector(3, 4); +global inline_table_ctor: table_yield = table(["bah", 3] = 3, ["baz", 4] = 4); +global inline_record_ctor: record_yield = record($a=2, $b="bar"); + +function compare_set_yield(a: set_yield, b: set_yield) + { + local s: string; + local c: count; + for ( [s, c] in a ) + print [s, c] in b; + } + +function compare_vector_yield(a: vector_yield, b: vector_yield) + { + local c: count; + for ( c in a ) + print a[c] == b[c]; + } + +function compare_table_yield(a: table_yield, b: table_yield) + { + local s: string; + local c: count; + for ( [s, c] in a ) + print [s, c] in b && a[s, c] == b[s, c]; + } + +function compare_record_yield(a: record_yield, b: record_yield) + { + print a$a == b$a && a$b == b$b; + } + +print "table of set"; +print table_of_set; +print ""; +print "table of vector"; +print table_of_vector; +print ""; +print "table of table"; +print table_of_table; +print ""; +print "table of record"; +print table_of_record; +print ""; + +compare_set_yield(table_of_set[13], lone_set_ctor); +compare_set_yield(table_of_set[5], inline_set_ctor); +compare_vector_yield(table_of_vector[13], lone_vector_ctor); +compare_vector_yield(table_of_vector[5], inline_vector_ctor); +compare_table_yield(table_of_table[13], lone_table_ctor); +compare_table_yield(table_of_table[5], inline_table_ctor); +compare_record_yield(table_of_record[13], lone_record_ctor); +compare_record_yield(table_of_record[5], inline_record_ctor); diff --git a/testing/btest/language/table-init.bro b/testing/btest/language/table-init.bro index 5df682c5d2..7419a50879 100644 --- a/testing/btest/language/table-init.bro +++ b/testing/btest/language/table-init.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output global global_table: table[count] of string = { diff --git a/testing/btest/language/table.bro b/testing/btest/language/table.bro index d1b0751970..3c8e8db280 100644 --- a/testing/btest/language/table.bro +++ b/testing/btest/language/table.bro @@ -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 ); } diff --git a/testing/btest/language/time.bro b/testing/btest/language/time.bro index 43b6694101..dd4b6336fe 100644 --- a/testing/btest/language/time.bro +++ b/testing/btest/language/time.bro @@ -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) diff --git a/testing/btest/language/timeout.bro b/testing/btest/language/timeout.bro index 6bc0419b2f..b16ddd6e7c 100644 --- a/testing/btest/language/timeout.bro +++ b/testing/btest/language/timeout.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >out +# @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out diff --git a/testing/btest/language/vector-coerce-expr.bro b/testing/btest/language/vector-coerce-expr.bro index d58417f226..97f9617665 100644 --- a/testing/btest/language/vector-coerce-expr.bro +++ b/testing/btest/language/vector-coerce-expr.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro %INPUT >output 2>&1 +# @TEST-EXEC: bro -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output type X: record { diff --git a/testing/btest/language/vector-list-init-records.bro b/testing/btest/language/vector-list-init-records.bro index ee2b78c4a5..b1eee0ac92 100644 --- a/testing/btest/language/vector-list-init-records.bro +++ b/testing/btest/language/vector-list-init-records.bro @@ -1,7 +1,7 @@ # Initializing a vector with a list of records should promote elements as # necessary to match the vector's yield type. -# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: bro -b %INPUT >output # @TEST-EXEC: btest-diff output type Foo: record { diff --git a/testing/btest/language/vector.bro b/testing/btest/language/vector.bro index 928ddcb645..76fc8b69e3 100644 --- a/testing/btest/language/vector.bro +++ b/testing/btest/language/vector.bro @@ -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) diff --git a/testing/btest/language/wrong-delete-field.bro b/testing/btest/language/wrong-delete-field.bro index e0d0093258..63573faf8a 100644 --- a/testing/btest/language/wrong-delete-field.bro +++ b/testing/btest/language/wrong-delete-field.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC-FAIL: bro %INPUT >output 2>&1 +# @TEST-EXEC-FAIL: bro -b %INPUT >output 2>&1 # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff output type X: record { diff --git a/testing/btest/language/wrong-record-extension.bro b/testing/btest/language/wrong-record-extension.bro index 4e0210546a..a8ef6a64e9 100644 --- a/testing/btest/language/wrong-record-extension.bro +++ b/testing/btest/language/wrong-record-extension.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC-FAIL: bro %INPUT >output.tmp 2>&1 +# @TEST-EXEC-FAIL: bro -b %INPUT >output.tmp 2>&1 # @TEST-EXEC: sed 's#^.*:##g' output # @TEST-EXEC: btest-diff output diff --git a/testing/btest/scripts/base/frameworks/logging/ascii-tsv.bro b/testing/btest/scripts/base/frameworks/logging/ascii-tsv.bro new file mode 100644 index 0000000000..09276a08fd --- /dev/null +++ b/testing/btest/scripts/base/frameworks/logging/ascii-tsv.bro @@ -0,0 +1,37 @@ +# +# @TEST-EXEC: bro -b %INPUT +# @TEST-EXEC: cat ssh.log | grep -v PREFIX.*20..- >ssh-filtered.log +# @TEST-EXEC: btest-diff ssh-filtered.log + +module SSH; + +export { + redef enum Log::ID += { LOG }; + + type Log: record { + t: time; + id: conn_id; # Will be rolled out into individual columns. + status: string &optional; + country: string &default="unknown"; + b: bool &optional; + } &log; +} + +event bro_init() +{ + Log::create_stream(SSH::LOG, [$columns=Log]); + + local filter = Log::get_filter(SSH::LOG, "default"); + filter$config = table(["tsv"] = "T"); + Log::add_filter(SSH::LOG, filter); + + local cid = [$orig_h=1.2.3.4, $orig_p=1234/tcp, $resp_h=2.3.4.5, $resp_p=80/tcp]; + + Log::write(SSH::LOG, [$t=network_time(), $id=cid, $status="success"]); + Log::write(SSH::LOG, [$t=network_time(), $id=cid, $country="US"]); + Log::write(SSH::LOG, [$t=network_time(), $id=cid, $status="failure", $country="UK"]); + Log::write(SSH::LOG, [$t=network_time(), $id=cid, $country="BR"]); + Log::write(SSH::LOG, [$t=network_time(), $id=cid, $b=T, $status="failure", $country=""]); + +} +