mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
Deprecate Plugin::HookCallFunction(), replace with HookFunctionCall()
This also changes the argument type of Func::operator() to zeek::Args* to allow plugins to be able to alter function arguments in place as was previously documented.
This commit is contained in:
parent
46c5dea733
commit
272db640aa
27 changed files with 417 additions and 77 deletions
5
NEWS
5
NEWS
|
@ -106,6 +106,11 @@ Removed Functionality
|
|||
Deprecated Functionality
|
||||
------------------------
|
||||
|
||||
- The ``plugin::Plugin::HookCallFunction()`` method is deprecated. Note
|
||||
that compilers will not emit a deprecation warning, but the replacement
|
||||
method to now use is called ``HookFunctionCall`` and uses ``IntrusivePtr``
|
||||
arguments and return value.
|
||||
|
||||
- The ``Func::Call(val_list*, ...)`` method is now deprecated. Use operator()
|
||||
instead which takes a ``zeek::Args`` (``std::vector<IntrusivePtr<Val>>``).
|
||||
There's also a variadic template for operator() that forwards all arguments
|
||||
|
|
|
@ -43,7 +43,7 @@ bool Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
|
|||
|
||||
try
|
||||
{
|
||||
discard_packet = check_ip->operator()(args)->AsBool();
|
||||
discard_packet = check_ip->operator()(&args)->AsBool();
|
||||
}
|
||||
|
||||
catch ( InterpreterException& e )
|
||||
|
@ -98,7 +98,7 @@ bool Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
|
|||
|
||||
try
|
||||
{
|
||||
discard_packet = check_tcp->operator()(args)->AsBool();
|
||||
discard_packet = check_tcp->operator()(&args)->AsBool();
|
||||
}
|
||||
|
||||
catch ( InterpreterException& e )
|
||||
|
@ -122,7 +122,7 @@ bool Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
|
|||
|
||||
try
|
||||
{
|
||||
discard_packet = check_udp->operator()(args)->AsBool();
|
||||
discard_packet = check_udp->operator()(&args)->AsBool();
|
||||
}
|
||||
|
||||
catch ( InterpreterException& e )
|
||||
|
@ -142,7 +142,7 @@ bool Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
|
|||
|
||||
try
|
||||
{
|
||||
discard_packet = check_icmp->operator()(args)->AsBool();
|
||||
discard_packet = check_icmp->operator()(&args)->AsBool();
|
||||
}
|
||||
|
||||
catch ( InterpreterException& e )
|
||||
|
|
|
@ -56,7 +56,7 @@ void Event::Dispatch(bool no_remote)
|
|||
|
||||
try
|
||||
{
|
||||
handler->Call(args, no_remote);
|
||||
handler->Call(&args, no_remote);
|
||||
}
|
||||
|
||||
catch ( InterpreterException& e )
|
||||
|
|
|
@ -44,7 +44,7 @@ const IntrusivePtr<FuncType>& EventHandler::GetType(bool check_export)
|
|||
return type;
|
||||
}
|
||||
|
||||
void EventHandler::Call(const zeek::Args& vl, bool no_remote)
|
||||
void EventHandler::Call(zeek::Args* vl, bool no_remote)
|
||||
{
|
||||
#ifdef PROFILE_BRO_FUNCTIONS
|
||||
DEBUG_MSG("Event: %s\n", Name());
|
||||
|
@ -59,12 +59,12 @@ void EventHandler::Call(const zeek::Args& vl, bool no_remote)
|
|||
{
|
||||
// Send event in form [name, xs...] where xs represent the arguments.
|
||||
broker::vector xs;
|
||||
xs.reserve(vl.size());
|
||||
xs.reserve(vl->size());
|
||||
bool valid_args = true;
|
||||
|
||||
for ( auto i = 0u; i < vl.size(); ++i )
|
||||
for ( auto i = 0u; i < vl->size(); ++i )
|
||||
{
|
||||
auto opt_data = bro_broker::val_to_data(vl[i].get());
|
||||
auto opt_data = bro_broker::val_to_data((*vl)[i].get());
|
||||
|
||||
if ( opt_data )
|
||||
xs.emplace_back(std::move(*opt_data));
|
||||
|
@ -101,7 +101,7 @@ void EventHandler::Call(const zeek::Args& vl, bool no_remote)
|
|||
local->operator()(vl);
|
||||
}
|
||||
|
||||
void EventHandler::NewEvent(const zeek::Args& vl)
|
||||
void EventHandler::NewEvent(zeek::Args* vl)
|
||||
{
|
||||
if ( ! new_event )
|
||||
return;
|
||||
|
@ -132,8 +132,8 @@ void EventHandler::NewEvent(const zeek::Args& vl)
|
|||
if ( fdefault )
|
||||
rec->Assign(2, std::move(fdefault));
|
||||
|
||||
if ( i < static_cast<int>(vl.size()) && vl[i] )
|
||||
rec->Assign(3, vl[i]);
|
||||
if ( i < static_cast<int>(vl->size()) && (*vl)[i] )
|
||||
rec->Assign(3, (*vl)[i]);
|
||||
|
||||
vargs->Assign(i, std::move(rec));
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
auto_publish.erase(topic);
|
||||
}
|
||||
|
||||
void Call(const zeek::Args& vl, bool no_remote = false);
|
||||
void Call(zeek::Args* vl, bool no_remote = false);
|
||||
|
||||
// Returns true if there is at least one local or remote handler.
|
||||
explicit operator bool() const;
|
||||
|
@ -66,7 +66,7 @@ public:
|
|||
bool GenerateAlways() { return generate_always; }
|
||||
|
||||
private:
|
||||
void NewEvent(const zeek::Args& vl); // Raise new_event() meta event.
|
||||
void NewEvent(zeek::Args* vl); // Raise new_event() meta event.
|
||||
|
||||
std::string name;
|
||||
IntrusivePtr<Func> local;
|
||||
|
|
|
@ -4133,7 +4133,8 @@ IntrusivePtr<Val> CallExpr::Eval(Frame* f) const
|
|||
if ( f )
|
||||
f->SetCall(this);
|
||||
|
||||
ret = funcv->operator()(*v, f);
|
||||
auto& args = *v;
|
||||
ret = funcv->operator()(&args, f);
|
||||
|
||||
if ( f )
|
||||
f->SetCall(current_call);
|
||||
|
|
51
src/Func.cc
51
src/Func.cc
|
@ -214,13 +214,13 @@ void Func::CopyStateInto(Func* other) const
|
|||
other->unique_id = unique_id;
|
||||
}
|
||||
|
||||
void Func::CheckPluginResult(bool hooked, const IntrusivePtr<Val>& hook_result,
|
||||
void Func::CheckPluginResult(bool handled, const IntrusivePtr<Val>& hook_result,
|
||||
function_flavor flavor) const
|
||||
{
|
||||
// Helper function factoring out this code from BroFunc:Call() for
|
||||
// better readability.
|
||||
|
||||
if ( ! hooked )
|
||||
if ( ! handled )
|
||||
{
|
||||
if ( hook_result )
|
||||
reporter->InternalError("plugin set processed flag to false but actually returned a value");
|
||||
|
@ -297,9 +297,12 @@ bool BroFunc::IsPure() const
|
|||
}
|
||||
|
||||
Val* Func::Call(val_list* args, Frame* parent) const
|
||||
{ return operator()(zeek::val_list_to_args(*args), parent).release(); };
|
||||
{
|
||||
auto zargs = zeek::val_list_to_args(*args);
|
||||
return operator()(&zargs, parent).release();
|
||||
};
|
||||
|
||||
IntrusivePtr<Val> BroFunc::operator()(const zeek::Args& args, Frame* parent) const
|
||||
IntrusivePtr<Val> BroFunc::operator()(zeek::Args* args, Frame* parent) const
|
||||
{
|
||||
#ifdef PROFILE_BRO_FUNCTIONS
|
||||
DEBUG_MSG("Function: %s\n", Name());
|
||||
|
@ -309,13 +312,13 @@ IntrusivePtr<Val> BroFunc::operator()(const zeek::Args& args, Frame* parent) con
|
|||
if ( sample_logger )
|
||||
sample_logger->FunctionSeen(this);
|
||||
|
||||
auto [hooked, hook_result] = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION,
|
||||
HookCallFunction(this, parent, args),
|
||||
empty_hook_result);
|
||||
auto [handled, hook_result] = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION,
|
||||
HookCallFunction(this, parent, args),
|
||||
empty_hook_result);
|
||||
|
||||
CheckPluginResult(hooked, hook_result, Flavor());
|
||||
CheckPluginResult(handled, hook_result, Flavor());
|
||||
|
||||
if ( hooked )
|
||||
if ( handled )
|
||||
return hook_result;
|
||||
|
||||
if ( bodies.empty() )
|
||||
|
@ -325,7 +328,7 @@ IntrusivePtr<Val> BroFunc::operator()(const zeek::Args& args, Frame* parent) con
|
|||
return Flavor() == FUNC_FLAVOR_HOOK ? val_mgr->True() : nullptr;
|
||||
}
|
||||
|
||||
auto f = make_intrusive<Frame>(frame_size, this, &args);
|
||||
auto f = make_intrusive<Frame>(frame_size, this, args);
|
||||
|
||||
if ( closure )
|
||||
f->CaptureClosure(closure, outer_ids);
|
||||
|
@ -339,12 +342,12 @@ IntrusivePtr<Val> BroFunc::operator()(const zeek::Args& args, Frame* parent) con
|
|||
|
||||
g_frame_stack.push_back(f.get()); // used for backtracing
|
||||
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
|
||||
call_stack.emplace_back(CallInfo{call_expr, this, args});
|
||||
call_stack.emplace_back(CallInfo{call_expr, this, *args});
|
||||
|
||||
if ( g_trace_state.DoTrace() )
|
||||
{
|
||||
ODesc d;
|
||||
DescribeDebug(&d, &args);
|
||||
DescribeDebug(&d, args);
|
||||
|
||||
g_trace_state.LogTrace("%s called: %s\n",
|
||||
GetType()->FlavorString().c_str(), d.Description());
|
||||
|
@ -360,16 +363,16 @@ IntrusivePtr<Val> BroFunc::operator()(const zeek::Args& args, Frame* parent) con
|
|||
body.stmts->GetLocationInfo());
|
||||
|
||||
// Fill in the rest of the frame with the function's arguments.
|
||||
for ( auto j = 0u; j < args.size(); ++j )
|
||||
for ( auto j = 0u; j < args->size(); ++j )
|
||||
{
|
||||
Val* arg = args[j].get();
|
||||
Val* arg = (*args)[j].get();
|
||||
|
||||
if ( f->NthElement(j) != arg )
|
||||
// Either not yet set, or somebody reassigned the frame slot.
|
||||
f->SetElement(j, arg->Ref());
|
||||
}
|
||||
|
||||
f->Reset(args.size());
|
||||
f->Reset(args->size());
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -607,7 +610,7 @@ bool BuiltinFunc::IsPure() const
|
|||
return is_pure;
|
||||
}
|
||||
|
||||
IntrusivePtr<Val> BuiltinFunc::operator()(const zeek::Args& args, Frame* parent) const
|
||||
IntrusivePtr<Val> BuiltinFunc::operator()(zeek::Args* args, Frame* parent) const
|
||||
{
|
||||
#ifdef PROFILE_BRO_FUNCTIONS
|
||||
DEBUG_MSG("Function: %s\n", Name());
|
||||
|
@ -617,26 +620,26 @@ IntrusivePtr<Val> BuiltinFunc::operator()(const zeek::Args& args, Frame* parent)
|
|||
if ( sample_logger )
|
||||
sample_logger->FunctionSeen(this);
|
||||
|
||||
auto [hooked, hook_result] = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION,
|
||||
HookCallFunction(this, parent, args),
|
||||
empty_hook_result);
|
||||
auto [handled, hook_result] = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION,
|
||||
HookCallFunction(this, parent, args),
|
||||
empty_hook_result);
|
||||
|
||||
CheckPluginResult(hooked, hook_result, FUNC_FLAVOR_FUNCTION);
|
||||
CheckPluginResult(handled, hook_result, FUNC_FLAVOR_FUNCTION);
|
||||
|
||||
if ( hooked )
|
||||
if ( handled )
|
||||
return hook_result;
|
||||
|
||||
if ( g_trace_state.DoTrace() )
|
||||
{
|
||||
ODesc d;
|
||||
DescribeDebug(&d, &args);
|
||||
DescribeDebug(&d, args);
|
||||
|
||||
g_trace_state.LogTrace("\tBuiltin Function called: %s\n", d.Description());
|
||||
}
|
||||
|
||||
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
|
||||
call_stack.emplace_back(CallInfo{call_expr, this, args});
|
||||
auto result = std::move(func(parent, &args).rval);
|
||||
call_stack.emplace_back(CallInfo{call_expr, this, *args});
|
||||
auto result = std::move(func(parent, args).rval);
|
||||
call_stack.pop_back();
|
||||
|
||||
if ( result && g_trace_state.DoTrace() )
|
||||
|
|
13
src/Func.h
13
src/Func.h
|
@ -60,7 +60,7 @@ public:
|
|||
* @param parent the frame from which the function is being called.
|
||||
* @return the return value of the function call.
|
||||
*/
|
||||
virtual IntrusivePtr<Val> operator()(const zeek::Args& args,
|
||||
virtual IntrusivePtr<Val> operator()(zeek::Args* args,
|
||||
Frame* parent = nullptr) const = 0;
|
||||
|
||||
/**
|
||||
|
@ -72,7 +72,10 @@ public:
|
|||
IntrusivePtr<Val>>,
|
||||
IntrusivePtr<Val>>
|
||||
operator()(Args&&... args) const
|
||||
{ return operator()(zeek::Args{std::forward<Args>(args)...}); }
|
||||
{
|
||||
auto zargs = zeek::Args{std::forward<Args>(args)...};
|
||||
return operator()(&zargs);
|
||||
}
|
||||
|
||||
// Add a new event handler to an existing function (event).
|
||||
virtual void AddBody(IntrusivePtr<Stmt> new_body, id_list* new_inits,
|
||||
|
@ -110,7 +113,7 @@ protected:
|
|||
void CopyStateInto(Func* other) const;
|
||||
|
||||
// Helper function for checking result of plugin hook.
|
||||
void CheckPluginResult(bool hooked, const IntrusivePtr<Val>& hook_result,
|
||||
void CheckPluginResult(bool handled, const IntrusivePtr<Val>& hook_result,
|
||||
function_flavor flavor) const;
|
||||
|
||||
std::vector<Body> bodies;
|
||||
|
@ -129,7 +132,7 @@ public:
|
|||
~BroFunc() override;
|
||||
|
||||
bool IsPure() const override;
|
||||
IntrusivePtr<Val> operator()(const zeek::Args& args, Frame* parent) const override;
|
||||
IntrusivePtr<Val> operator()(zeek::Args* args, Frame* parent) const override;
|
||||
|
||||
/**
|
||||
* Adds adds a closure to the function. Closures are cloned and
|
||||
|
@ -225,7 +228,7 @@ public:
|
|||
~BuiltinFunc() override;
|
||||
|
||||
bool IsPure() const override;
|
||||
IntrusivePtr<Val> operator()(const zeek::Args& args, Frame* parent) const override;
|
||||
IntrusivePtr<Val> operator()(zeek::Args* args, Frame* parent) const override;
|
||||
built_in_func TheFunc() const { return func; }
|
||||
|
||||
void Describe(ODesc* d) const override;
|
||||
|
|
|
@ -181,7 +181,7 @@ bool RuleConditionEval::DoMatch(Rule* rule, RuleEndpointState* state,
|
|||
|
||||
try
|
||||
{
|
||||
auto val = id->GetVal()->AsFunc()->operator()(args);
|
||||
auto val = id->GetVal()->AsFunc()->operator()(&args);
|
||||
result = val && val->AsBool();
|
||||
}
|
||||
|
||||
|
|
|
@ -1879,7 +1879,7 @@ IntrusivePtr<Val> TableVal::Default(const IntrusivePtr<Val>& index)
|
|||
|
||||
try
|
||||
{
|
||||
result = f->operator()(vl);
|
||||
result = f->operator()(&vl);
|
||||
}
|
||||
|
||||
catch ( InterpreterException& e )
|
||||
|
@ -2088,7 +2088,7 @@ void TableVal::CallChangeFunc(const Val* index,
|
|||
vl.emplace_back(old_value);
|
||||
|
||||
in_change_func = true;
|
||||
f->operator()(vl);
|
||||
f->operator()(&vl);
|
||||
}
|
||||
catch ( InterpreterException& e )
|
||||
{
|
||||
|
@ -2545,7 +2545,7 @@ double TableVal::CallExpireFunc(IntrusivePtr<ListVal> idx)
|
|||
vl.emplace_back(std::move(idx));
|
||||
}
|
||||
|
||||
auto result = f->operator()(vl);
|
||||
auto result = f->operator()(&vl);
|
||||
|
||||
if ( result )
|
||||
secs = result->AsInterval();
|
||||
|
|
|
@ -188,7 +188,7 @@ function Cluster::publish_rr%(pool: Pool, key: string, ...%): bool
|
|||
topic_func = global_scope()->Find("Cluster::rr_topic")->GetVal()->AsFunc();
|
||||
|
||||
zeek::Args vl{{NewRef{}, pool}, {NewRef{}, key}};
|
||||
auto topic = topic_func->operator()(vl);
|
||||
auto topic = topic_func->operator()(&vl);
|
||||
|
||||
if ( ! topic->AsString()->Len() )
|
||||
return val_mgr->False();
|
||||
|
@ -225,7 +225,7 @@ function Cluster::publish_hrw%(pool: Pool, key: any, ...%): bool
|
|||
topic_func = global_scope()->Find("Cluster::hrw_topic")->GetVal()->AsFunc();
|
||||
|
||||
zeek::Args vl{{NewRef{}, pool}, {NewRef{}, key}};
|
||||
auto topic = topic_func->operator()(vl);
|
||||
auto topic = topic_func->operator()(&vl);
|
||||
|
||||
if ( ! topic->AsString()->Len() )
|
||||
return val_mgr->False();
|
||||
|
|
|
@ -1768,7 +1768,7 @@ bool Manager::CallPred(Func* pred_func, const int numvals, ...) const
|
|||
|
||||
va_end(lP);
|
||||
|
||||
auto v = pred_func->operator()(vl);
|
||||
auto v = pred_func->operator()(&vl);
|
||||
|
||||
if ( v )
|
||||
result = v->AsBool();
|
||||
|
|
|
@ -24,7 +24,7 @@ static bool call_option_handlers_and_set_value(StringVal* name, const IntrusiveP
|
|||
if ( add_loc )
|
||||
vl.emplace_back(NewRef{}, location);
|
||||
|
||||
val = handler_function->operator()(vl); // consumed by next call.
|
||||
val = handler_function->operator()(&vl); // consumed by next call.
|
||||
|
||||
if ( ! val )
|
||||
{
|
||||
|
|
|
@ -624,43 +624,35 @@ int Manager::HookLoadFile(const Plugin::LoadType type, const string& file, const
|
|||
|
||||
std::pair<bool, IntrusivePtr<Val>>
|
||||
Manager::HookCallFunction(const Func* func, Frame* parent,
|
||||
const zeek::Args& vecargs) const
|
||||
zeek::Args* vecargs) const
|
||||
{
|
||||
HookArgumentList args;
|
||||
std::optional<val_list> vargs;
|
||||
val_list vargs;
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||
{
|
||||
vargs = val_list(vecargs.size());
|
||||
vargs.resize(vecargs->size());
|
||||
|
||||
for ( const auto& v : vecargs )
|
||||
vargs->push_back(v.get());
|
||||
for ( const auto& v : *vecargs )
|
||||
vargs.push_back(v.get());
|
||||
|
||||
args.push_back(HookArgument(func));
|
||||
args.push_back(HookArgument(parent));
|
||||
args.push_back(HookArgument(&vargs.value()));
|
||||
args.push_back(HookArgument(&vargs));
|
||||
MetaHookPre(HOOK_CALL_FUNCTION, args);
|
||||
}
|
||||
|
||||
hook_list* l = hooks[HOOK_CALL_FUNCTION];
|
||||
|
||||
std::pair<bool, Val*> rval{false, nullptr};
|
||||
std::pair<bool, IntrusivePtr<Val>> rval{false, nullptr};
|
||||
|
||||
if ( l )
|
||||
{
|
||||
if ( ! vargs )
|
||||
{
|
||||
vargs = val_list(vecargs.size());
|
||||
|
||||
for ( const auto& v : vecargs )
|
||||
vargs->push_back(v.get());
|
||||
}
|
||||
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
|
||||
rval = p->HookCallFunction(func, parent, &vargs.value());
|
||||
rval = p->HookFunctionCall(func, parent, vecargs);
|
||||
|
||||
if ( rval.first )
|
||||
break;
|
||||
|
@ -668,9 +660,10 @@ Manager::HookCallFunction(const Func* func, Frame* parent,
|
|||
}
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_POST) )
|
||||
MetaHookPost(HOOK_CALL_FUNCTION, args, HookArgument(rval));
|
||||
MetaHookPost(HOOK_CALL_FUNCTION, args,
|
||||
HookArgument(std::make_pair(rval.first, rval.second.get())));
|
||||
|
||||
return {rval.first, {AdoptRef{}, rval.second}};
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool Manager::HookQueueEvent(Event* event) const
|
||||
|
|
|
@ -256,7 +256,7 @@ public:
|
|||
* the method returns null.
|
||||
*/
|
||||
std::pair<bool, IntrusivePtr<Val>>
|
||||
HookCallFunction(const Func* func, Frame* parent, const zeek::Args& args) const;
|
||||
HookCallFunction(const Func* func, Frame* parent, zeek::Args* args) const;
|
||||
|
||||
/**
|
||||
* Hook that filters the queuing of an event.
|
||||
|
|
|
@ -151,6 +151,17 @@ void HookArgument::Describe(ODesc* d) const
|
|||
d->Add("<null>");
|
||||
break;
|
||||
|
||||
case ARG_LIST:
|
||||
if ( arg.args)
|
||||
{
|
||||
d->Add("(");
|
||||
describe_vals(*arg.args, d);
|
||||
d->Add(")");
|
||||
}
|
||||
else
|
||||
d->Add("<null>");
|
||||
break;
|
||||
|
||||
case VOID:
|
||||
d->Add("<void>");
|
||||
break;
|
||||
|
@ -364,6 +375,26 @@ int Plugin::HookLoadFile(const LoadType type, const std::string& file, const std
|
|||
return -1;
|
||||
}
|
||||
|
||||
std::pair<bool, IntrusivePtr<Val>>
|
||||
Plugin::HookFunctionCall(const Func* func, Frame* parent,
|
||||
zeek::Args* args)
|
||||
{
|
||||
val_list vlargs(args->size());
|
||||
|
||||
for ( auto& v : *args )
|
||||
vlargs.push_back(v.release());
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
auto [handled, result] = HookCallFunction(func, parent, &vlargs);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
for ( auto i = 0u; i < args->size(); ++i )
|
||||
(*args)[i] = {AdoptRef{}, vlargs[i]};
|
||||
|
||||
return {handled, {AdoptRef{}, result}};
|
||||
}
|
||||
|
||||
std::pair<bool, Val*> Plugin::HookCallFunction(const Func* func, Frame *parent, val_list* args)
|
||||
{
|
||||
std::pair<bool, Val*> result(false, NULL);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "zeek-config.h"
|
||||
#include "logging/WriterBackend.h"
|
||||
#include "ZeekArgs.h"
|
||||
|
||||
// Increase this when making incompatible changes to the plugin API. Note
|
||||
// that the constant is never used in C code. It's picked up on by CMake.
|
||||
|
@ -177,7 +178,8 @@ public:
|
|||
*/
|
||||
enum Type {
|
||||
BOOL, DOUBLE, EVENT, FRAME, FUNC, FUNC_RESULT, INT, STRING, VAL,
|
||||
VAL_LIST, VOID, VOIDP, WRITER_INFO, CONN, THREAD_FIELDS, LOCATION
|
||||
VAL_LIST, VOID, VOIDP, WRITER_INFO, CONN, THREAD_FIELDS, LOCATION,
|
||||
ARG_LIST
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -260,6 +262,11 @@ public:
|
|||
*/
|
||||
explicit HookArgument(const Location* location) { type = LOCATION; arg.loc = location; }
|
||||
|
||||
/**
|
||||
* Constructor with a zeek::Args argument.
|
||||
*/
|
||||
explicit HookArgument(const zeek::Args* args) { type = ARG_LIST; arg.args = args; }
|
||||
|
||||
/**
|
||||
* Returns the value for a boolen argument. The argument's type must
|
||||
* match accordingly.
|
||||
|
@ -338,6 +345,11 @@ public:
|
|||
*/
|
||||
const val_list* AsValList() const { assert(type == VAL_LIST); return arg.vals; }
|
||||
|
||||
/**
|
||||
* Returns the value as a zeek::Args.
|
||||
*/
|
||||
const zeek::Args* AsArgList() const { assert(type == ARG_LIST); return arg.args; }
|
||||
|
||||
/**
|
||||
* Returns the value for a vod pointer argument. The argument's type
|
||||
* must match accordingly.
|
||||
|
@ -368,6 +380,7 @@ private:
|
|||
int int_;
|
||||
const Val* val;
|
||||
const val_list* vals;
|
||||
const zeek::Args* args;
|
||||
const void* voidp;
|
||||
const logging::WriterBackend::WriterInfo* winfo;
|
||||
const Location* loc;
|
||||
|
@ -664,12 +677,15 @@ protected:
|
|||
* in place as long as it ensures matching types and correct reference
|
||||
* counting.
|
||||
*
|
||||
* @return If the plugin handled the call, a std::pair<bool, Val*> with the
|
||||
* processed flag set to true, and a value set on the object with
|
||||
* a+1 reference count containing the result value to pass back to the
|
||||
* interpreter. If the plugin did not handle the call, it must
|
||||
* return a pair with the processed flag set to 'false'.
|
||||
* @return If the plugin handled the call, a pair with the first member
|
||||
* set to true, and a Val representing the result value to pass back to the
|
||||
* interpreter. If the plugin did not handle the call, it must return a
|
||||
* pair with the first member set to 'false' and null result value.
|
||||
*/
|
||||
virtual std::pair<bool, IntrusivePtr<Val>>
|
||||
HookFunctionCall(const Func* func, Frame* parent, zeek::Args* args);
|
||||
|
||||
[[deprecated("Remove in v4.1. Use HookFunctionCall()")]]
|
||||
virtual std::pair<bool, Val*> HookCallFunction(const Func* func, Frame *parent, val_list* args);
|
||||
|
||||
/**
|
||||
|
|
4
testing/btest/Baseline/plugins.func-hook/output
Normal file
4
testing/btest/Baseline/plugins.func-hook/output
Normal file
|
@ -0,0 +1,4 @@
|
|||
1590206064.237264 MetaHookPre CallFunction(foo, <frame>, (1, 2, 3, yo))
|
||||
1590206064.237264 | HookFunctionCall foo(1, 2, 3, yo)
|
||||
1590206064.237264 MetaHookPost CallFunction(foo, <frame>, (1, 2, 3, yo)) -> <no result>
|
||||
foo, 42, 2, 3, yo
|
4
testing/btest/Baseline/plugins.legacy-func-hook/output
Normal file
4
testing/btest/Baseline/plugins.legacy-func-hook/output
Normal file
|
@ -0,0 +1,4 @@
|
|||
1590205948.002795 MetaHookPre CallFunction(foo, <frame>, (1, 2, 3, yo))
|
||||
1590205948.002795 | HookCallFunction foo(1, 2, 3, yo)
|
||||
1590205948.002795 MetaHookPost CallFunction(foo, <frame>, (1, 2, 3, yo)) -> <no result>
|
||||
foo, 13, 2, 3, yo
|
0
testing/btest/plugins/func-hook-plugin/.btest-ignore
Normal file
0
testing/btest/plugins/func-hook-plugin/.btest-ignore
Normal file
86
testing/btest/plugins/func-hook-plugin/src/Plugin.cc
Normal file
86
testing/btest/plugins/func-hook-plugin/src/Plugin.cc
Normal file
|
@ -0,0 +1,86 @@
|
|||
|
||||
#include "Plugin.h"
|
||||
|
||||
#include <Val.h>
|
||||
#include <Func.h>
|
||||
#include <Event.h>
|
||||
#include <Conn.h>
|
||||
#include <Desc.h>
|
||||
#include <threading/Formatter.h>
|
||||
|
||||
namespace plugin { namespace Demo_Hooks { Plugin plugin; } }
|
||||
|
||||
using namespace plugin::Demo_Hooks;
|
||||
|
||||
plugin::Configuration Plugin::Configure()
|
||||
{
|
||||
EnableHook(HOOK_CALL_FUNCTION);
|
||||
EnableHook(META_HOOK_PRE);
|
||||
EnableHook(META_HOOK_POST);
|
||||
|
||||
plugin::Configuration config;
|
||||
config.name = "Demo::Hooks";
|
||||
config.description = "Exercises all plugin hooks";
|
||||
config.version.major = 1;
|
||||
config.version.minor = 0;
|
||||
config.version.patch = 0;
|
||||
return config;
|
||||
}
|
||||
|
||||
static void describe_hook_args(const plugin::HookArgumentList& args, ODesc* d)
|
||||
{
|
||||
bool first = true;
|
||||
|
||||
for ( plugin::HookArgumentList::const_iterator i = args.begin(); i != args.end(); i++ )
|
||||
{
|
||||
if ( ! first )
|
||||
d->Add(", ");
|
||||
|
||||
i->Describe(d);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<bool, IntrusivePtr<Val>> Plugin::HookFunctionCall(const Func* func,
|
||||
Frame* frame,
|
||||
zeek::Args* args)
|
||||
{
|
||||
ODesc d;
|
||||
d.SetShort();
|
||||
HookArgument(func).Describe(&d);
|
||||
HookArgument(args).Describe(&d);
|
||||
fprintf(stderr, "%.6f %-15s %s\n", network_time, "| HookFunctionCall",
|
||||
d.Description());
|
||||
|
||||
if ( streq(func->Name(), "foo") )
|
||||
{
|
||||
auto& vl = *args;
|
||||
vl[0] = val_mgr->Count(42);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void Plugin::MetaHookPre(HookType hook, const HookArgumentList& args)
|
||||
{
|
||||
ODesc d;
|
||||
d.SetShort();
|
||||
describe_hook_args(args, &d);
|
||||
fprintf(stderr, "%.6f %-15s %s(%s)\n", network_time, " MetaHookPre",
|
||||
hook_name(hook), d.Description());
|
||||
}
|
||||
|
||||
void Plugin::MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result)
|
||||
{
|
||||
ODesc d1;
|
||||
d1.SetShort();
|
||||
describe_hook_args(args, &d1);
|
||||
|
||||
ODesc d2;
|
||||
d2.SetShort();
|
||||
result.Describe(&d2);
|
||||
|
||||
fprintf(stderr, "%.6f %-15s %s(%s) -> %s\n", network_time, " MetaHookPost",
|
||||
hook_name(hook), d1.Description(),
|
||||
d2.Description());
|
||||
}
|
27
testing/btest/plugins/func-hook-plugin/src/Plugin.h
Normal file
27
testing/btest/plugins/func-hook-plugin/src/Plugin.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <plugin/Plugin.h>
|
||||
|
||||
namespace plugin {
|
||||
namespace Demo_Hooks {
|
||||
|
||||
class Plugin : public ::plugin::Plugin
|
||||
{
|
||||
protected:
|
||||
|
||||
std::pair<bool, IntrusivePtr<Val>> HookFunctionCall(const Func* func,
|
||||
Frame* frame,
|
||||
zeek::Args* args) override;
|
||||
|
||||
void MetaHookPre(HookType hook, const HookArgumentList& args) override;
|
||||
void MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result) override;
|
||||
|
||||
// Overridden from plugin::Plugin.
|
||||
plugin::Configuration Configure() override;
|
||||
};
|
||||
|
||||
extern Plugin plugin;
|
||||
|
||||
}
|
||||
}
|
17
testing/btest/plugins/func-hook.zeek
Normal file
17
testing/btest/plugins/func-hook.zeek
Normal file
|
@ -0,0 +1,17 @@
|
|||
# @TEST-EXEC: ${DIST}/aux/zeek-aux/plugin-support/init-plugin -u . Demo Hooks
|
||||
# @TEST-EXEC: cp -r %DIR/func-hook-plugin/* .
|
||||
# @TEST-EXEC: ./configure --zeek-dist=${DIST} && make
|
||||
# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Demo::Hooks" ZEEK_PLUGIN_PATH=`pwd` zeek -b %INPUT 2>&1 | grep foo >output
|
||||
# @TEST-EXEC: btest-diff output
|
||||
|
||||
@unload base/misc/version
|
||||
|
||||
function foo(a: count, b: count, c: count, s: string)
|
||||
{
|
||||
print "foo", a, b, c, s;
|
||||
}
|
||||
|
||||
event zeek_init()
|
||||
{
|
||||
foo(1, 2, 3, "yo");
|
||||
}
|
105
testing/btest/plugins/legacy-func-hook-plugin/src/Plugin.cc
Normal file
105
testing/btest/plugins/legacy-func-hook-plugin/src/Plugin.cc
Normal file
|
@ -0,0 +1,105 @@
|
|||
|
||||
#include "Plugin.h"
|
||||
|
||||
#include <Val.h>
|
||||
#include <Func.h>
|
||||
#include <Event.h>
|
||||
#include <Conn.h>
|
||||
#include <Desc.h>
|
||||
#include <threading/Formatter.h>
|
||||
|
||||
namespace plugin { namespace Demo_Hooks { Plugin plugin; } }
|
||||
|
||||
using namespace plugin::Demo_Hooks;
|
||||
|
||||
plugin::Configuration Plugin::Configure()
|
||||
{
|
||||
EnableHook(HOOK_CALL_FUNCTION);
|
||||
EnableHook(META_HOOK_PRE);
|
||||
EnableHook(META_HOOK_POST);
|
||||
|
||||
plugin::Configuration config;
|
||||
config.name = "Demo::Hooks";
|
||||
config.description = "Exercises all plugin hooks";
|
||||
config.version.major = 1;
|
||||
config.version.minor = 0;
|
||||
config.version.patch = 0;
|
||||
return config;
|
||||
}
|
||||
|
||||
static void describe_hook_args(const plugin::HookArgumentList& args, ODesc* d)
|
||||
{
|
||||
bool first = true;
|
||||
|
||||
for ( plugin::HookArgumentList::const_iterator i = args.begin(); i != args.end(); i++ )
|
||||
{
|
||||
if ( ! first )
|
||||
d->Add(", ");
|
||||
|
||||
i->Describe(d);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<bool, Val*> Plugin::HookCallFunction(const Func* func, Frame* frame, val_list* args)
|
||||
{
|
||||
ODesc d;
|
||||
d.SetShort();
|
||||
HookArgument(func).Describe(&d);
|
||||
HookArgument(args).Describe(&d);
|
||||
fprintf(stderr, "%.6f %-15s %s\n", network_time, "| HookCallFunction",
|
||||
d.Description());
|
||||
|
||||
if ( streq(func->Name(), "foo") )
|
||||
{
|
||||
auto& vl = *args;
|
||||
Unref(vl[0]);
|
||||
vl[0] = val_mgr->Count(13).release();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/* std::pair<bool, IntrusivePtr<Val>> Plugin::HookFunctionCall(const Func* func, */
|
||||
/* Frame* frame, */
|
||||
/* zeek::Args* args) */
|
||||
/* { */
|
||||
/* ODesc d; */
|
||||
/* d.SetShort(); */
|
||||
/* HookArgument(func).Describe(&d); */
|
||||
/* HookArgument(args).Describe(&d); */
|
||||
/* fprintf(stderr, "%.6f %-15s %s\n", network_time, "| HookFunctionCall", */
|
||||
/* d.Description()); */
|
||||
|
||||
/* if ( streq(func->Name(), "foo") ) */
|
||||
/* { */
|
||||
/* auto& vl = *args; */
|
||||
/* vl[0] = val_mgr->Count(42); */
|
||||
/* } */
|
||||
|
||||
/* return {}; */
|
||||
/* } */
|
||||
|
||||
void Plugin::MetaHookPre(HookType hook, const HookArgumentList& args)
|
||||
{
|
||||
ODesc d;
|
||||
d.SetShort();
|
||||
describe_hook_args(args, &d);
|
||||
fprintf(stderr, "%.6f %-15s %s(%s)\n", network_time, " MetaHookPre",
|
||||
hook_name(hook), d.Description());
|
||||
}
|
||||
|
||||
void Plugin::MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result)
|
||||
{
|
||||
ODesc d1;
|
||||
d1.SetShort();
|
||||
describe_hook_args(args, &d1);
|
||||
|
||||
ODesc d2;
|
||||
d2.SetShort();
|
||||
result.Describe(&d2);
|
||||
|
||||
fprintf(stderr, "%.6f %-15s %s(%s) -> %s\n", network_time, " MetaHookPost",
|
||||
hook_name(hook), d1.Description(),
|
||||
d2.Description());
|
||||
}
|
28
testing/btest/plugins/legacy-func-hook-plugin/src/Plugin.h
Normal file
28
testing/btest/plugins/legacy-func-hook-plugin/src/Plugin.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <plugin/Plugin.h>
|
||||
|
||||
namespace plugin {
|
||||
namespace Demo_Hooks {
|
||||
|
||||
class Plugin : public ::plugin::Plugin
|
||||
{
|
||||
protected:
|
||||
std::pair<bool, Val*> HookCallFunction(const Func* func, Frame* frame, val_list* args) override;
|
||||
|
||||
/* std::pair<bool, IntrusivePtr<Val>> HookFunctionCall(const Func* func, */
|
||||
/* Frame* frame, */
|
||||
/* zeek::Args* args) override; */
|
||||
|
||||
void MetaHookPre(HookType hook, const HookArgumentList& args) override;
|
||||
void MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result) override;
|
||||
|
||||
// Overridden from plugin::Plugin.
|
||||
plugin::Configuration Configure() override;
|
||||
};
|
||||
|
||||
extern Plugin plugin;
|
||||
|
||||
}
|
||||
}
|
17
testing/btest/plugins/legacy-func-hook.zeek
Normal file
17
testing/btest/plugins/legacy-func-hook.zeek
Normal file
|
@ -0,0 +1,17 @@
|
|||
# @TEST-EXEC: ${DIST}/aux/zeek-aux/plugin-support/init-plugin -u . Demo Hooks
|
||||
# @TEST-EXEC: cp -r %DIR/legacy-func-hook-plugin/* .
|
||||
# @TEST-EXEC: ./configure --zeek-dist=${DIST} && make
|
||||
# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Demo::Hooks" ZEEK_PLUGIN_PATH=`pwd` zeek -b %INPUT 2>&1 | grep foo >output
|
||||
# @TEST-EXEC: btest-diff output
|
||||
|
||||
@unload base/misc/version
|
||||
|
||||
function foo(a: count, b: count, c: count, s: string)
|
||||
{
|
||||
print "foo", a, b, c, s;
|
||||
}
|
||||
|
||||
event zeek_init()
|
||||
{
|
||||
foo(1, 2, 3, "yo");
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue