From fa30d4a31365c448cd044d1dc4a5dc08a26ce7f2 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 22 Apr 2013 12:55:07 -0500 Subject: [PATCH 1/4] Fix schedule statements used outside event handlers (addresses #974). --- src/Expr.cc | 4 ++++ testing/btest/Baseline/language.event/out | 4 +++- testing/btest/language/event.bro | 9 ++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index dd514df74b..7cceccc117 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -4297,6 +4297,10 @@ Val* ScheduleExpr::Eval(Frame* f) const if ( args ) { TimerMgr* tmgr = mgr.CurrentTimerMgr(); + + if ( ! tmgr ) + tmgr = timer_mgr; + tmgr->Add(new ScheduleTimer(event->Handler(), args, dt, tmgr)); } diff --git a/testing/btest/Baseline/language.event/out b/testing/btest/Baseline/language.event/out index d5a22b3745..41c3e0d717 100644 --- a/testing/btest/Baseline/language.event/out +++ b/testing/btest/Baseline/language.event/out @@ -1,4 +1,6 @@ event statement event part1 event part2 -schedule statement +schedule statement in bro_init +schedule statement in global +schedule statement another in bro_init diff --git a/testing/btest/language/event.bro b/testing/btest/language/event.bro index e251a3e579..39a3e0da48 100644 --- a/testing/btest/language/event.bro +++ b/testing/btest/language/event.bro @@ -9,9 +9,9 @@ event e1() print "Error: this should not happen"; } -event e2() +event e2(s: string) { - print "schedule statement"; + print fmt("schedule statement %s", s); } event e3(test: string) @@ -36,7 +36,8 @@ event bro_init() event e1(); # Test calling an event with "schedule" statement - schedule 1 sec { e2() }; + schedule 1 sec { e2("in bro_init") }; + schedule 3 sec { e2("another in bro_init") }; # Test calling an event that has two separate definitions event e3("foo"); @@ -47,3 +48,5 @@ event bro_init() event e5(6); # TODO: this does not do anything } +# scheduling in outside of an event handler shouldn't crash. +schedule 2sec { e2("in global") }; From 7069f679c3205d9667daa28cc3e86c078f054e67 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 23 Apr 2013 09:57:55 -0500 Subject: [PATCH 2/4] Fix record coercion for default inner record fields (addresses #973). --- src/Expr.cc | 21 ++++++++- src/Val.cc | 14 +++++- .../language.record-default-coercion/out | 18 ++++++++ .../language/record-default-coercion.bro | 44 ++++++++++++++++--- 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index dd514df74b..04bee8aba7 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -4026,7 +4026,26 @@ Val* RecordCoerceExpr::Fold(Val* v) const Type()->AsRecordType()->FieldDecl(i)->FindAttr(ATTR_DEFAULT); if ( def ) - val->Assign(i, def->AttrExpr()->Eval(0)); + { + Val* def_val = def->AttrExpr()->Eval(0); + BroType* def_type = def_val->Type(); + BroType* field_type = Type()->AsRecordType()->FieldType(i); + + if ( def_type->Tag() == TYPE_RECORD && + field_type->Tag() == TYPE_RECORD && + ! same_type(def_type, field_type) ) + { + Val* tmp = def_val->AsRecordVal()->CoerceTo( + field_type->AsRecordType()); + if ( tmp ) + { + Unref(def_val); + def_val = tmp; + } + } + + val->Assign(i, def_val); + } else val->Assign(i, 0); } diff --git a/src/Val.cc b/src/Val.cc index 5133550236..dd86e71a9e 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -2560,10 +2560,22 @@ RecordVal::RecordVal(RecordType* t) : MutableVal(t) Attributes* a = record_type->FieldDecl(i)->attrs; Attr* def_attr = a ? a->FindAttr(ATTR_DEFAULT) : 0; Val* def = def_attr ? def_attr->AttrExpr()->Eval(0) : 0; + BroType* type = record_type->FieldDecl(i)->type; + + if ( def && type->Tag() == TYPE_RECORD && + def->Type()->Tag() == TYPE_RECORD && + ! same_type(def->Type(), type) ) + { + Val* tmp = def->AsRecordVal()->CoerceTo(type->AsRecordType()); + if ( tmp ) + { + Unref(def); + def = tmp; + } + } if ( ! def && ! (a && a->FindAttr(ATTR_OPTIONAL)) ) { - BroType* type = record_type->FieldDecl(i)->type; TypeTag tag = type->Tag(); if ( tag == TYPE_RECORD ) diff --git a/testing/btest/Baseline/language.record-default-coercion/out b/testing/btest/Baseline/language.record-default-coercion/out index 2f0e6cd17d..bf76ba5033 100644 --- a/testing/btest/Baseline/language.record-default-coercion/out +++ b/testing/btest/Baseline/language.record-default-coercion/out @@ -1,3 +1,21 @@ +[bar=4321, foo=[foo=1234, quux=9876]] +[foo=1234, quux=9876] +9876 +[bar=4231, foo=[foo=1000, quux=9876]] +[foo=1000, quux=9876] +9876 +[bar=4321, foo=[foo=10, quux=42]] +[foo=10, quux=42] +42 +[bar=100, foo=[foo=1234, quux=9876]] +[foo=1234, quux=9876] +9876 +[bar=100, foo=[foo=1001, quux=9876]] +[foo=1001, quux=9876] +9876 +[bar=100, foo=[foo=11, quux=7]] +[foo=11, quux=7] +7 [a=13, c=13, v=[]] 0 [a=13, c=13, v=[test]] diff --git a/testing/btest/language/record-default-coercion.bro b/testing/btest/language/record-default-coercion.bro index 7e717c39e2..822b845f65 100644 --- a/testing/btest/language/record-default-coercion.bro +++ b/testing/btest/language/record-default-coercion.bro @@ -7,12 +7,42 @@ type MyRecord: record { v: vector of string &default=vector(); }; -event bro_init() +type Foo: record { + foo: count; + quux: count &default=9876; +}; + +type Bar: record { + bar: count; + foo: Foo &default=[$foo=1234]; +}; + +function print_bar(b: Bar) { - local r: MyRecord = [$c=13]; - print r; - print |r$v|; - r$v[|r$v|] = "test"; - print r; - print |r$v|; + print b; + print b$foo; + print b$foo$quux; } + +global bar: Bar = [$bar=4321]; +global bar2: Bar = [$bar=4231, $foo=[$foo=1000]]; +global bar3: Bar = [$bar=4321, $foo=[$foo=10, $quux=42]]; + +print_bar(bar); +print_bar(bar2); +print_bar(bar3); + +local bar4: Bar = [$bar=100]; +local bar5: Bar = [$bar=100, $foo=[$foo=1001]]; +local bar6: Bar = [$bar=100, $foo=[$foo=11, $quux=7]]; + +print_bar(bar4); +print_bar(bar5); +print_bar(bar6); + +local r: MyRecord = [$c=13]; +print r; +print |r$v|; +r$v[|r$v|] = "test"; +print r; +print |r$v|; From 3fff71b37aad0953ec4a592c52590e0cc481c693 Mon Sep 17 00:00:00 2001 From: Yun Zheng Hu Date: Fri, 22 Mar 2013 11:23:48 +0100 Subject: [PATCH 3/4] Add bytestring_to_count function to bro.bif --- src/bro.bif | 94 +++++++++++++++++++ .../Baseline/bifs.bytestring_to_count/out | 36 +++++++ testing/btest/bifs/bytestring_to_count.bro | 55 +++++++++++ 3 files changed, 185 insertions(+) create mode 100644 testing/btest/Baseline/bifs.bytestring_to_count/out create mode 100644 testing/btest/bifs/bytestring_to_count.bro diff --git a/src/bro.bif b/src/bro.bif index ac54da0e75..8fbef565e5 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2464,6 +2464,100 @@ function bytestring_to_double%(s: string%): double return new Val(ntohd(d), TYPE_DOUBLE); %} +## Converts a string of bytes (in network byte order) to a :bro:type:`count`. +## +## s: A string of bytes containing the binary representation of the value. +## is_le: if true, *s* is in little endian format, else it's big endian. +## +## Returns: The value contained in *s*, or 0 if the conversion +## failed. +## +function bytestring_to_count%(s: string, is_le: bool%): count + %{ +#ifdef HOST_BIGENDIAN + static bool host_bigendian = true; +#else + static bool host_bigendian = false; +#endif + const u_char *p = s->Bytes(); + int i; + + switch ( s->Len() ) { + case sizeof(uint8): + { + uint8 value = 0; + memcpy(&value, p, sizeof(uint8)); + return new Val(value, TYPE_COUNT); + } + break; + + case sizeof(uint16): + { + uint16 value = 0; + if (host_bigendian && is_le || !host_bigendian && !is_le) + { + char buf[sizeof(uint16)]; + char *d = &buf[sizeof(uint16)-1]; + + for (i = 0; i < sizeof(uint16); i++) + *d-- = *p++; + memcpy(&value, buf, sizeof(uint16)); + } + else + { + memcpy(&value, p, sizeof(uint16)); + } + return new Val(value, TYPE_COUNT); + } + break; + + case sizeof(uint32): + { + uint32 value = 0; + if (host_bigendian && is_le || !host_bigendian && !is_le) + { + char buf[sizeof(uint32)]; + char *d = &buf[sizeof(uint32)-1]; + + for (i = 0; i < sizeof(uint32); i++) + *d-- = *p++; + memcpy(&value, buf, sizeof(uint32)); + } + else + { + memcpy(&value, p, sizeof(uint32)); + } + return new Val(value, TYPE_COUNT); + } + break; + + case sizeof(uint64): + { + uint64 value = 0; + if (host_bigendian && is_le || !host_bigendian && !is_le) + { + char buf[sizeof(uint64)]; + char *d = &buf[sizeof(uint64)-1]; + + for (i = 0; i < sizeof(uint64); i++) + *d-- = *p++; + memcpy(&value, buf, sizeof(uint64)); + } + else + { + memcpy(&value, p, sizeof(uint64)); + } + return new Val(value, TYPE_COUNT); + } + break; + + default: + break; + } + builtin_error("unsupported byte length for bytestring_to_count"); + return new Val(0, TYPE_COUNT); + %} + ## 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/testing/btest/Baseline/bifs.bytestring_to_count/out b/testing/btest/Baseline/bifs.bytestring_to_count/out new file mode 100644 index 0000000000..4d378f874e --- /dev/null +++ b/testing/btest/Baseline/bifs.bytestring_to_count/out @@ -0,0 +1,36 @@ +0 +0 +0 +0 +0 +0 +255 +255 +0 +0 +1000 +1000 +12345 +12345 +0 +0 +65535 +65535 +4294967295 +4294967295 +287454020 +1144201745 +255 +255 +2864429994 +2864429994 +0 +0 +18446744073709551615 +18446744073709551615 +18446742974214701055 +18446742974214701055 +65535 +65535 +0 +0 \ No newline at end of file diff --git a/testing/btest/bifs/bytestring_to_count.bro b/testing/btest/bifs/bytestring_to_count.bro new file mode 100644 index 0000000000..e26b201f26 --- /dev/null +++ b/testing/btest/bifs/bytestring_to_count.bro @@ -0,0 +1,55 @@ + # +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + + +event bro_init() + { + + # unsupported byte lengths + print bytestring_to_count("", T); # 0 + print bytestring_to_count("", F); # 0 + print bytestring_to_count("\xAA\xBB\xCC", T); # 0 + print bytestring_to_count("\xAA\xBB\xCC", F); # 0 + print bytestring_to_count("\xAA\xBB\xCC\xDD\xEE", T); # 0 + print bytestring_to_count("\xAA\xBB\xCC\xDD\xEE", F); # 0 + + # 8 bit + print bytestring_to_count("\xff", T); # 255 + print bytestring_to_count("\xff", F); # 255 + print bytestring_to_count("\x00", T); # 0 + print bytestring_to_count("\x00", F); # 0 + + # 16 bit + print bytestring_to_count("\x03\xe8", F); # 1000 + print bytestring_to_count("\xe8\x03", T); # 1000 + print bytestring_to_count("\x30\x39", F); # 12345 + print bytestring_to_count("\x39\x30", T); # 12345 + print bytestring_to_count("\x00\x00", F); # 0 + print bytestring_to_count("\x00\x00", T); # 0 + + # 32 bit + print bytestring_to_count("\x00\x00\xff\xff", F); # 65535 + print bytestring_to_count("\xff\xff\x00\x00", T); # 65535 + print bytestring_to_count("\xff\xff\xff\xff", F); # 4294967295 + print bytestring_to_count("\xff\xff\xff\xff", T); # 4294967295 + print bytestring_to_count("\x11\x22\x33\x44", F); # 287454020 + print bytestring_to_count("\x11\x22\x33\x44", T); # 1144201745 + print bytestring_to_count("\x00\x00\x00\xff", F); # 255 + print bytestring_to_count("\xff\x00\x00\x00", T); # 255 + print bytestring_to_count("\xAA\xBB\xBB\xAA", F); # 2864429994 + print bytestring_to_count("\xAA\xBB\xBB\xAA", T); # 2864429994 + print bytestring_to_count("\x00\x00\x00\x00", F); # 0 + print bytestring_to_count("\x00\x00\x00\x00", T); # 0 + + # 64 bit + print bytestring_to_count("\xff\xff\xff\xff\xff\xff\xff\xff", F); # 18446744073709551615 + print bytestring_to_count("\xff\xff\xff\xff\xff\xff\xff\xff", T); # 18446744073709551615 + print bytestring_to_count("\xff\xff\xff\x00\x00\xff\xff\xff", F); # 18446742974214701055 + print bytestring_to_count("\xff\xff\xff\x00\x00\xff\xff\xff", T); # 18446742974214701055 + print bytestring_to_count("\x00\x00\x00\x00\x00\x00\xff\xff", F); # 65535 + print bytestring_to_count("\xff\xff\x00\x00\x00\x00\x00\x00", T); # 65535 + print bytestring_to_count("\x00\x00\x00\x00\x00\x00\x00\x00", T); # 0 + print bytestring_to_count("\x00\x00\x00\x00\x00\x00\x00\x00", F); # 0 + + } From 71591d706ea447dab000868a3d388284d26415b0 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 23 Apr 2013 20:29:33 -0700 Subject: [PATCH 4/4] Small tweaks for bytestring_to_count(). Closes #968. --- src/bro.bif | 51 +++++++++---------- .../Baseline/bifs.bytestring_to_count/out | 2 +- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/bro.bif b/src/bro.bif index 8fbef565e5..bea8e343c0 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -622,7 +622,7 @@ function md5_hmac%(...%): string ## ``md5_hash_update(c$http$md5_handle, some_more_data)`` in the ## :bro:id:`http_entity_data` event handler. When all data has arrived, a call ## to :bro:id:`md5_hash_finish` returns the final hash value. -## +## ## Returns: The opaque handle associated with this hash computation. ## ## .. bro:see:: md5_hmac md5_hash md5_hash_update md5_hash_finish @@ -2464,23 +2464,23 @@ function bytestring_to_double%(s: string%): double return new Val(ntohd(d), TYPE_DOUBLE); %} -## Converts a string of bytes (in network byte order) to a :bro:type:`count`. +## Converts a string of bytes to a :bro:type:`count`. ## ## s: A string of bytes containing the binary representation of the value. -## is_le: if true, *s* is in little endian format, else it's big endian. ## -## Returns: The value contained in *s*, or 0 if the conversion -## failed. +## is_le: If true, *s* is assumed to be in little endian format, else it's big endian. +## +## Returns: The value contained in *s*, or 0 if the conversion failed. ## function bytestring_to_count%(s: string, is_le: bool%): count %{ #ifdef HOST_BIGENDIAN - static bool host_bigendian = true; + static const bool host_bigendian = true; #else - static bool host_bigendian = false; + static const bool host_bigendian = false; #endif const u_char *p = s->Bytes(); - int i; + unsigned int i; switch ( s->Len() ) { case sizeof(uint8): @@ -2489,71 +2489,68 @@ function bytestring_to_count%(s: string, is_le: bool%): count memcpy(&value, p, sizeof(uint8)); return new Val(value, TYPE_COUNT); } - break; case sizeof(uint16): { uint16 value = 0; - if (host_bigendian && is_le || !host_bigendian && !is_le) + + if ( (host_bigendian && is_le) || (! host_bigendian && ! is_le) ) { char buf[sizeof(uint16)]; char *d = &buf[sizeof(uint16)-1]; - for (i = 0; i < sizeof(uint16); i++) + for ( i = 0; i < sizeof(uint16); i++ ) *d-- = *p++; + memcpy(&value, buf, sizeof(uint16)); } else - { memcpy(&value, p, sizeof(uint16)); - } + return new Val(value, TYPE_COUNT); } - break; case sizeof(uint32): { uint32 value = 0; - if (host_bigendian && is_le || !host_bigendian && !is_le) + + if ( (host_bigendian && is_le) || (! host_bigendian && ! is_le) ) { char buf[sizeof(uint32)]; char *d = &buf[sizeof(uint32)-1]; - for (i = 0; i < sizeof(uint32); i++) + for ( i = 0; i < sizeof(uint32); i++ ) *d-- = *p++; + memcpy(&value, buf, sizeof(uint32)); } else - { memcpy(&value, p, sizeof(uint32)); - } + return new Val(value, TYPE_COUNT); } - break; case sizeof(uint64): { uint64 value = 0; - if (host_bigendian && is_le || !host_bigendian && !is_le) + + if ( (host_bigendian && is_le) || (! host_bigendian && ! is_le) ) { char buf[sizeof(uint64)]; char *d = &buf[sizeof(uint64)-1]; - for (i = 0; i < sizeof(uint64); i++) + for ( i = 0; i < sizeof(uint64); i++ ) *d-- = *p++; + memcpy(&value, buf, sizeof(uint64)); } else - { memcpy(&value, p, sizeof(uint64)); - } + return new Val(value, TYPE_COUNT); } - break; - - default: - break; } + builtin_error("unsupported byte length for bytestring_to_count"); return new Val(0, TYPE_COUNT); %} diff --git a/testing/btest/Baseline/bifs.bytestring_to_count/out b/testing/btest/Baseline/bifs.bytestring_to_count/out index 4d378f874e..e5f8c84f26 100644 --- a/testing/btest/Baseline/bifs.bytestring_to_count/out +++ b/testing/btest/Baseline/bifs.bytestring_to_count/out @@ -33,4 +33,4 @@ 65535 65535 0 -0 \ No newline at end of file +0