Questions about bro module declarations

Hi Bro people,

I have a few questions about Bro Module declarations (more specifically the GLOBAL module), see below.

I tried this script :

export {
    const var : string = "GLOBAL::var_1";
}

module GLOBAL;

export {
    const var : string = "GLOBAL::var_2";
}

Bro returns an error, which is what I was expecting. Great.
error in ././trybro.bro, line 3 and ././trybro.bro, line 9: already defined (var)
internal warning in ././trybro.bro, line 9: Duplicate identifier documentation: var

So I guess I have defined a variable with scope GLOBAL::var in both cases ?

Then I tried this second script :

export {
    const var : string = "GLOBAL::var_1";
}

module Module1;

export {
    function test_func() { print var; }
}

event bro_init() {
    Module1::test_func();
}

It prints "GLOBAL::var_1". Good. So Module1::test_func() has "default" visibility on GLOBAL module.

Third try :

export {
    const var : string = "GLOBAL::var_1";
}

module Module1;
    const var : string = "Module1::var";
    function test_func() { print var; }
}

It prints "Module1::var". Why not.
However, I was expecting Bro to report a conflict between using GLOBAL::var or Module1::var, as both are visible...

Fourth test : try to force the use of GLOBAL::var in test_func().

export {
    const var : string = "GLOBAL::var_1";
}

module Module1;
    const var : string = "Module1::var";
    function test_func() { print GLOBAL::var; }
}

Bro reports an error :
line 15: unknown identifier GLOBAL::var, at or near "GLOBAL::var"

Did I miss something ?
What exactly is GLOBAL and what are its visibility rules and how does Bro search for identifiers in modules ?
How to explicitly make a reference to an identifier in GLOBAL module, as GLOBAL:: does not work ?

Thank you for all helpful tips !

François

Then I tried this second script :

export {
   const var : string = "GLOBAL::var_1";
}

module Module1;

export {
   function test_func() { print var; }
}

event bro_init() {
   Module1::test_func();
}

It prints "GLOBAL::var_1". Good. So Module1::test_func() has "default" visibility on GLOBAL module.

It's just looking to the global scope since there is no var_1 in the local scope.

Third try :

export {
   const var : string = "GLOBAL::var_1";
}

module Module1;
export {
   const var : string = "Module1::var";
   function test_func() { print var; }
}

It prints "Module1::var". Why not.
However, I was expecting Bro to report a conflict between using GLOBAL::var or Module1::var, as both are visible...

This is the same as your second script. It looks for the id in the local scope and then tries the global module if the local module doesn't have one with that name.

Fourth test : try to force the use of GLOBAL::var in test_func().

export {
   const var : string = "GLOBAL::var_1";
}

module Module1;
export {
   const var : string = "Module1::var";
   function test_func() { print GLOBAL::var; }
}

Bro reports an error :
line 15: unknown identifier GLOBAL::var, at or near "GLOBAL::var"

Did I miss something ?
What exactly is GLOBAL and what are its visibility rules and how does Bro search for identifiers in modules ?
How to explicitly make a reference to an identifier in GLOBAL module, as GLOBAL:: does not work ?

I'm pretty sure you just encountered a bug. I see the same behavior and it definitely shouldn't be working that way. I filed a bug ticket:
  [BIT-1758] - Bro Tracker

Thanks!
  .Seth

Hi,

Thank you for your answer.
I took a glimpse at "Scope" C++ code but nothing obvious :frowning:

Btw, what do you think of the following test case :

module Module1;
export {
    const var : string = "Module1::var";
     
    function test_func1(var : string) { print var, Module1::var; }
    
    function test_func2( ) { print var, Module1::var; }
}

event bro_init()
  {
  test_func1("Argument");
  test_func2();
  }

Output for this test is :

Argument Argument
Module1::var Module1::var

I think it's a bit disturbing ? I was expecting a warning on variable name clashes, at least.
(I get this one while renaming a local variable in one of my big bro script, suddently everything was broken... ).

Thank you.

----- Mail original -----

Hi again,

Maybe this example is better to illustrate my problem :

global var : string = "global::var";

function fun1(var : string) {
    print var; # OK, no error, no warning, function parameter overrides global variable. It prints "parameter var"
}

function fun2(param: string) {
    local var : string = "local var"; # KO, error in ././trybro.bro, line 2: already a global identifier (var)
                                        # error in ././trybro.bro, line 2 and ././trybro.bro, line 9: already defined (var)
    print var;
}

event bro_init()
{
    fun1("parameter var");
    fun2("parameter var");
}

To summarize :
- a function parameter can overrides a global variable with the same name
- a local variable in a function can not override a global variable with the same name

I think this is inconsistent and function parameter and local variables should have the very same behaviour.

What do you think ?

Thanks,
François

----- Mail original -----