Make using local IDs in @if directives an error.

Addresses BIT-1296.
This commit is contained in:
Jon Siwek 2014-12-02 12:30:46 -06:00
parent 379593c7fd
commit cdbe459f20
4 changed files with 94 additions and 3 deletions

View file

@ -26,6 +26,7 @@
#include "Reporter.h"
#include "RE.h"
#include "Net.h"
#include "Traverse.h"
#include "analyzer/Analyzer.h"
#include "broxygen/Manager.h"
@ -615,11 +616,48 @@ void end_RE()
BEGIN(INITIAL);
}
struct LocalNameFinder : public TraversalCallback {
LocalNameFinder()
{}
virtual TraversalCode PreExpr(const Expr* expr)
{
if ( expr->Tag() != EXPR_NAME )
return TC_CONTINUE;
const NameExpr* name_expr = static_cast<const NameExpr*>(expr);
if ( name_expr->Id()->IsGlobal() )
return TC_CONTINUE;
local_names.push_back(name_expr);
return TC_CONTINUE;
}
std::vector<const NameExpr*> local_names;
};
void do_atif(Expr* expr)
{
++current_depth;
Val* val = expr->Eval(0);
LocalNameFinder cb;
expr->Traverse(&cb);
Val* val = 0;
if ( cb.local_names.empty() )
val = expr->Eval(0);
else
for ( size_t i = 0; i < cb.local_names.size(); ++i )
cb.local_names[i]->Error("referencing a local name in @if");
if ( ! val )
{
expr->Error("invalid expression in @if");
return;
}
if ( ! val->AsBool() )
{
if_stack.append(current_depth);

View file

@ -0,0 +1,4 @@
error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.at-if-invalid/at-if-invalid.bro, line 28: referencing a local name in @if (xyz)
error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.at-if-invalid/at-if-invalid.bro, line 28: invalid expression in @if (F && foo(xyz))
error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.at-if-invalid/at-if-invalid.bro, line 36: referencing a local name in @if (local_true_condition)
error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.at-if-invalid/at-if-invalid.bro, line 36: invalid expression in @if (T && TRUE_CONDITION && local_true_condition)

View file

@ -0,0 +1,41 @@
# @TEST-EXEC-FAIL: bro -b %INPUT >out 2>&1
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out
function foo(c: count): bool
{ return c == 42 ? T : F; }
global TRUE_CONDITION = T;
event bro_init()
{
local xyz = 0;
local local_true_condition = T;
@if ( F )
xyz += 1;
@endif
@if ( foo(0) )
xyz += 1;
@endif
@if ( T && foo(42) )
xyz += 2;
@endif
xyz = 0;
@if ( F && foo(xyz) )
xyz += 1;
@else
xyz += 2;
@endif
xyz = 0;
@if ( T && TRUE_CONDITION && local_true_condition )
xyz += 1;
@else
xyz += 2;
@endif
}

View file

@ -6,6 +6,10 @@ function test_case(msg: string, expect: bool)
print fmt("%s (%s)", msg, expect ? "PASS" : "FAIL");
}
function foo(c: count): bool
{ return c == 42 ? T : F; }
global TRUE_CONDITION = T;
event bro_init()
{
@ -17,7 +21,11 @@ event bro_init()
xyz += 1;
@endif
@if ( T )
@if ( foo(0) )
xyz += 1;
@endif
@if ( T && foo(42) )
xyz += 2;
@endif
@ -37,7 +45,7 @@ event bro_init()
xyz = 0;
@if ( T )
@if ( T && TRUE_CONDITION )
xyz += 1;
@else
xyz += 2;