zeek.bif: Add find_in_zeekpath() helper

Relates to #3594. This helper can be used to determine the path that
will be used by @load, if at all.
This commit is contained in:
Arne Welzel 2024-02-21 15:22:42 +01:00
parent 4a9b580dab
commit 704f75a214
6 changed files with 108 additions and 0 deletions

View file

@ -5328,3 +5328,35 @@ function table_pattern_matcher_stats%(tbl: any%) : MatcherStats
return std::move(result); return std::move(result);
%} %}
## Determine the path used by a non-relative @load directive.
##
## This function is package aware: Passing *package* will yield the
## path to *package.zeek*, *package/__load__.zeek* or an empty string
## if neither can be found. Note that passing a relative path or absolute
## path is an error.
##
## path: The filename, package or path to search for in ZEEKPATH.
##
## Returns: Path of script file that would be loaded by an @load directive.
function find_in_zeekpath%(p: string%): string
%{
auto path = p->ToStdString();
if ( ! path.empty() && (path[0] == '.' || path[0] == '/') )
{
zeek::reporter->Error("find_in_zeek_path: path must be relative or absolute");
return zeek::val_mgr->EmptyString();
}
auto resolved = zeek::util::find_script_file(path, zeek::util::zeek_path());
if ( ! resolved.empty() && zeek::util::is_dir(resolved.c_str()) )
{
// If it's a directory, try opening the package using
// the absolute path. This is zeek::util::open_package()
// without the noisy error log.
resolved.append("/__load__.zeek");
resolved = zeek::util::find_file(resolved, "");
}
return zeek::make_intrusive<zeek::StringVal>(resolved.c_str());
%}

View file

@ -0,0 +1 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.

View file

@ -0,0 +1,3 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
error: find_in_zeek_path: path must be relative or absolute
error: find_in_zeek_path: path must be relative or absolute

View file

@ -0,0 +1,3 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
relative,
absolute,

View file

@ -0,0 +1,10 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
find_in_zeekpath base/protocols/conn, base/protocols/conn/__load__.zeek
find_in_zeekpath protocols/conn (empty expected, no __load__.zeek),
find_in_zeekpath protocols/conn/vlan-logging, policy/protocols/conn/vlan-logging.zeek
find_in_zeekpath pkg1, ./pkg1.zeek
find_in_zeekpath pkg1.zeek, ./pkg1.zeek
find_in_zeekpath pkg2, ./pkg2/__load__.zeek
find_in_zeekpath pkg3,
pkg1!
pkg2!

View file

@ -0,0 +1,59 @@
# @TEST-DOC: Test find_in_zeekpath() and demo conditional @load'ing.
#
# @TEST-EXEC: zeek -b %INPUT >out
# @TEST-EXEC: btest-diff out
# @TEST-EXEC: btest-diff .stderr
#
# @TEST-EXEC: zeek -b errors.zeek >errors.stdout 2>errors.stderr
# @TEST-EXEC: btest-diff errors.stdout
# @TEST-EXEC: btest-diff errors.stderr
@if ( find_in_zeekpath("pkg1") != "" )
@load pkg1
@endif
@if ( find_in_zeekpath("pkg2") != "" )
@load pkg2
@endif
@if ( find_in_zeekpath("pkg3") != "" )
@load pkg3
@endif
function path_tail(r: string): string
{
if ( |r| == 0 )
return r;
local parts = split_string(r, /\//);
return join_string_vec(parts[-4:], "/");
}
print "find_in_zeekpath base/protocols/conn", path_tail(find_in_zeekpath("base/protocols/conn"));
print "find_in_zeekpath protocols/conn (empty expected, no __load__.zeek)", find_in_zeekpath("protocols/conn");
print "find_in_zeekpath protocols/conn/vlan-logging", path_tail(find_in_zeekpath("protocols/conn/vlan-logging"));
print "find_in_zeekpath pkg1", find_in_zeekpath("pkg1");
print "find_in_zeekpath pkg1.zeek", find_in_zeekpath("pkg1.zeek");
print "find_in_zeekpath pkg2", find_in_zeekpath("pkg2");
print "find_in_zeekpath pkg3", find_in_zeekpath("pkg3");
@TEST-START-FILE pkg1.zeek
event zeek_init()
{
print "pkg1!";
}
@TEST-END-FILE
@TEST-START-FILE pkg2/__load__.zeek
event zeek_init()
{
print "pkg2!";
}
@TEST-END-FILE
@TEST-START-FILE errors.zeek
# Using relative and absolute paths is an error (empty string)
print "relative", find_in_zeekpath("./pkg1.zeek");
print "absolute", find_in_zeekpath("/pkg1");
@TEST-END-FILE