mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Improve alternate event/hook prototype matching
This fixes it to again allow the old behavior of matching a handler against the canonical prototype as long as all argument types, but not necessarily names, match.
This commit is contained in:
parent
8c0e8ecd28
commit
9b6934eab8
5 changed files with 85 additions and 8 deletions
15
src/Type.cc
15
src/Type.cc
|
@ -584,8 +584,10 @@ void FuncType::AddPrototype(Prototype p)
|
||||||
|
|
||||||
std::optional<FuncType::Prototype> FuncType::FindPrototype(const RecordType& args) const
|
std::optional<FuncType::Prototype> FuncType::FindPrototype(const RecordType& args) const
|
||||||
{
|
{
|
||||||
for ( const auto& p : prototypes )
|
for ( auto i = 0u; i < prototypes.size(); ++i )
|
||||||
{
|
{
|
||||||
|
const auto& p = prototypes[i];
|
||||||
|
|
||||||
if ( args.NumFields() != p.args->NumFields() )
|
if ( args.NumFields() != p.args->NumFields() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -604,11 +606,12 @@ std::optional<FuncType::Prototype> FuncType::FindPrototype(const RecordType& arg
|
||||||
auto ptype = p.args->FieldType(i);
|
auto ptype = p.args->FieldType(i);
|
||||||
auto desired_type = args.FieldType(i);
|
auto desired_type = args.FieldType(i);
|
||||||
|
|
||||||
if ( same_type(ptype, desired_type) )
|
if ( ! same_type(ptype, desired_type) ||
|
||||||
continue;
|
! streq(args.FieldName(i), p.args->FieldName(i)) )
|
||||||
|
{
|
||||||
matched = false;
|
matched = false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( matched )
|
if ( matched )
|
||||||
|
|
26
src/Var.cc
26
src/Var.cc
|
@ -432,6 +432,21 @@ static std::optional<FuncType::Prototype> func_type_check(const FuncType* decl,
|
||||||
return decl->FindPrototype(*impl->Args());
|
return decl->FindPrototype(*impl->Args());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool canonical_arg_types_match(const FuncType* decl, const FuncType* impl)
|
||||||
|
{
|
||||||
|
auto canon_args = decl->Args();
|
||||||
|
auto impl_args = impl->Args();
|
||||||
|
|
||||||
|
if ( canon_args->NumFields() != impl_args->NumFields() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for ( auto i = 0; i < canon_args->NumFields(); ++i )
|
||||||
|
if ( ! same_type(canon_args->FieldType(i), impl_args->FieldType(i)) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
||||||
bool is_redef, IntrusivePtr<FuncType> t, attr_list* attrs)
|
bool is_redef, IntrusivePtr<FuncType> t, attr_list* attrs)
|
||||||
{
|
{
|
||||||
|
@ -462,7 +477,16 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
||||||
t->Warn("use of deprecated prototype", id);
|
t->Warn("use of deprecated prototype", id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
t->Error("use of undeclared alternate prototype", id);
|
{
|
||||||
|
auto decl = id->Type()->AsFuncType();
|
||||||
|
|
||||||
|
// Allow renaming arguments, but only for the canonical
|
||||||
|
// prototypes of hooks/events.
|
||||||
|
if ( canonical_arg_types_match(decl, t.get()) )
|
||||||
|
prototype = decl->Prototypes()[0];
|
||||||
|
else
|
||||||
|
t->Error("use of undeclared alternate prototype", id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( is_redef )
|
else if ( is_redef )
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.alternate-event-hook-prototypes-invalid-arg/alternate-event-hook-prototypes-invalid-arg.zeek, line 5 and /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.alternate-event-hook-prototypes-invalid-arg/alternate-event-hook-prototypes-invalid-arg.zeek, line 4: alternate function prototype already exists (event(nope:string; cantdothis:count;) and record { s:string; c:count; })
|
error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.alternate-event-hook-prototypes-invalid-arg/alternate-event-hook-prototypes-invalid-arg.zeek, line 5 and /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.alternate-event-hook-prototypes-invalid-arg/alternate-event-hook-prototypes-invalid-arg.zeek, line 4: alternate function prototype arg 'nope' not found in canonical prototype (event(nope:string; cantdothis:count;) and event(s:string; c:count;))
|
||||||
error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.alternate-event-hook-prototypes-invalid-arg/alternate-event-hook-prototypes-invalid-arg.zeek, line 8 and /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.alternate-event-hook-prototypes-invalid-arg/alternate-event-hook-prototypes-invalid-arg.zeek, line 7: alternate function prototype arg 'andnotthiseither' not found in canonical prototype (hook(andnotthiseither:addr;) : bool and hook(s:string; c:count;) : bool)
|
error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.alternate-event-hook-prototypes-invalid-arg/alternate-event-hook-prototypes-invalid-arg.zeek, line 8 and /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.alternate-event-hook-prototypes-invalid-arg/alternate-event-hook-prototypes-invalid-arg.zeek, line 7: alternate function prototype arg 'andnotthiseither' not found in canonical prototype (hook(andnotthiseither:addr;) : bool and hook(s:string; c:count;) : bool)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
foo, A, B, C
|
||||||
|
foo, A, B, C
|
||||||
|
reverse foo, A, B, C
|
||||||
|
foo a, A
|
||||||
|
foo b, B
|
||||||
|
foo c, C
|
|
@ -0,0 +1,44 @@
|
||||||
|
# @TEST-EXEC: zeek -b %INPUT > out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
|
global foo: event(a: string, b: string, c: string);
|
||||||
|
global foo: event(c: string, b: string, a: string);
|
||||||
|
global foo: event(a: string);
|
||||||
|
global foo: event(b: string);
|
||||||
|
global foo: event(c: string);
|
||||||
|
|
||||||
|
event foo(a: string, b: string, c: string)
|
||||||
|
{
|
||||||
|
print "foo", a, b, c;
|
||||||
|
}
|
||||||
|
|
||||||
|
event foo(mya: string, b: string, c: string)
|
||||||
|
{
|
||||||
|
print "foo", mya, b, c;
|
||||||
|
}
|
||||||
|
|
||||||
|
event foo(c: string, b: string, a: string)
|
||||||
|
{
|
||||||
|
print "reverse foo", a, b, c;
|
||||||
|
}
|
||||||
|
|
||||||
|
event foo(a: string)
|
||||||
|
{
|
||||||
|
print "foo a", a;
|
||||||
|
}
|
||||||
|
|
||||||
|
event foo(b: string)
|
||||||
|
{
|
||||||
|
print "foo b", b;
|
||||||
|
}
|
||||||
|
|
||||||
|
event foo(c: string)
|
||||||
|
{
|
||||||
|
print "foo c", c;
|
||||||
|
}
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
event foo("A", "B", "C");
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue