From 5b889360705120c9061390214881ea376819c669 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 24 Oct 2017 10:29:34 -0700 Subject: [PATCH] Fix assignments to event arguments becoming visible to subsequent handlers. It's well known that changes to mutable event arguments, like tables, become visible to all places where those values are used, including subsequent handlers of the same event. However, there's a related case that's more suprising: simply assigning *a new value* to an event argument passes through, too. This commit fixes that behaviour. (We even had a btest with a baseline reflecting the problen). --- aux/btest | 2 +- src/Func.cc | 22 +++++++++++++++---- .../Baseline/core.event-arg-reuse/output | 2 ++ .../Baseline/signatures.load-sigs/output | 2 +- testing/btest/core/event-arg-reuse.bro | 20 +++++++++++++++++ 5 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 testing/btest/Baseline/core.event-arg-reuse/output create mode 100644 testing/btest/core/event-arg-reuse.bro diff --git a/aux/btest b/aux/btest index 154dd9f9b2..56a368491d 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit 154dd9f9b2011341d2f76a3d3fee1c9a5ac4e393 +Subproject commit 56a368491d8ef3ef527061b353875099070148ad diff --git a/src/Func.cc b/src/Func.cc index 88da9a7a04..32cc9faf5a 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -383,11 +383,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const FType()->FlavorString().c_str(), d.Description()); } - loop_over_list(*args, i) - f->SetElement(i, (*args)[i]); - stmt_flow_type flow = FLOW_NEXT; - Val* result = 0; for ( size_t i = 0; i < bodies.size(); ++i ) @@ -397,6 +393,19 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const bodies[i].stmts->GetLocationInfo()); Unref(result); + + loop_over_list(*args, j) + { + Val* arg = (*args)[j]; + if ( f->NthElement(j) != arg ) + { + // Either not yet set, or somebody reassigned + // the frame slot. + Ref(arg); + f->SetElement(j, arg); + } + } + f->Reset(args->length()); try @@ -434,6 +443,11 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const } } + // We have an extra Ref for each argument (so that they don't get + // deleted between bodies), release that. + loop_over_list(*args, k) + Unref((*args)[k]); + if ( Flavor() == FUNC_FLAVOR_HOOK ) { if ( ! result ) diff --git a/testing/btest/Baseline/core.event-arg-reuse/output b/testing/btest/Baseline/core.event-arg-reuse/output new file mode 100644 index 0000000000..52024ab5f2 --- /dev/null +++ b/testing/btest/Baseline/core.event-arg-reuse/output @@ -0,0 +1,2 @@ +f1, 2 +f2, 1 diff --git a/testing/btest/Baseline/signatures.load-sigs/output b/testing/btest/Baseline/signatures.load-sigs/output index 52e0eeb92c..d58d0c0a39 100644 --- a/testing/btest/Baseline/signatures.load-sigs/output +++ b/testing/btest/Baseline/signatures.load-sigs/output @@ -1,3 +1,3 @@ [orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp] works -GET /images/wikimedia-button.png HTTP/1.1\x0d\x0aHost: meta.wikimedia.org\x0d\x0aUser-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Geck... +GET /images/wikimedia-button.png HTTP/1.1\x0d\x0aHost: meta.wikimedia.org\x0d\x0aUser-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15\x0d\x0aAccept: image/png,image/*;q=0.8,*/*;q=0.5\x0d\x0aAccept-Language: en-us,en;q=0.5\x0d\x0aAccept-Encoding: gzip,deflate\x0d\x0aAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\x0d\x0aKeep-Alive: 115\x0d\x0aConnection: keep-alive\x0d\x0aReferer: http://www.wikipedia.org/\x0d\x0aIf-Modified-Since: Fri, 05 Nov 2010 16:00:03 GMT\x0d\x0aIf-None-Match: "97a-494505e0c46c0"\x0d\x0aCache-Control: max-age=0\x0d\x0a\x0d\x0a diff --git a/testing/btest/core/event-arg-reuse.bro b/testing/btest/core/event-arg-reuse.bro new file mode 100644 index 0000000000..6634d059b9 --- /dev/null +++ b/testing/btest/core/event-arg-reuse.bro @@ -0,0 +1,20 @@ +# TEST-DOC: Check that assignment to event parameters isn't visible to other handlers. +# +# @TEST-EXEC: bro -b %INPUT >output +# @TEST-EXEC: btest-diff output + +event f(a: int) &priority=5 + { + a = 2; + print "f1", a; + } + +event f(a: int) &priority=-5 + { + print "f2", a; + } + +event bro_init() + { + event f(1); + }