Skip to content

Commit

Permalink
new(libsinsp): add basename() string transformer
Browse files Browse the repository at this point in the history
Signed-off-by: Luca Guerra <[email protected]>
  • Loading branch information
LucaGuerra authored and poiana committed Jul 2, 2024
1 parent a1f8b3b commit 0ec2ad8
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 3 deletions.
2 changes: 1 addition & 1 deletion userspace/libsinsp/filter/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ static constexpr const char* s_field_transformer_val = "val(";

static const std::vector<std::string> s_field_transformers =
{
"tolower(", "toupper(", "b64(",
"tolower(", "toupper(", "b64(", "basename(",
};

static inline void update_pos(const char c, ast::pos_info& pos)
Expand Down
2 changes: 1 addition & 1 deletion userspace/libsinsp/filter/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ namespace re2 { class RE2; };
// | 'startswith ' | 'bstartswith ' | 'endswith '
// ListOperator ::= 'intersects' | 'in' | 'pmatch'
// FieldTransformerVal ::= 'val('
// FieldTransformerType ::= 'tolower(' | 'toupper(' | 'b64('
// FieldTransformerType ::= 'tolower(' | 'toupper(' | 'b64(' | 'basename('
//
// Tokens (Regular Expressions):
// Identifier ::= [a-zA-Z]+[a-zA-Z0-9_]*
Expand Down
27 changes: 27 additions & 0 deletions userspace/libsinsp/sinsp_filter_transformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,19 @@ bool sinsp_filter_transformer::transform_type(ppm_param_type& t) const
// for STORAGE, the transformed type is the same as the input type
return true;
}
case FTR_BASENAME:
{
switch(t)
{
case PT_CHARBUF:
case PT_FSPATH:
case PT_FSRELPATH:
// for BASENAME, the transformed type is the same as the input type
return true;
default:
return false;
}
}
default:
throw_unsupported_err(m_type);
return false;
Expand Down Expand Up @@ -180,6 +193,20 @@ bool sinsp_filter_transformer::transform_values(std::vector<extract_value_t>& ve
}
return true;
}
case FTR_BASENAME:
{
return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool {
auto last_slash_pos = in.find_last_of("/");
ssize_t start_idx = last_slash_pos == std::string_view::npos ? 0 : last_slash_pos + 1;

for (ssize_t i = start_idx; i < in.length(); i++)
{
out.push_back(in[i]);
}

return true;
});
}
default:
throw_unsupported_err(m_type);
return false;
Expand Down
7 changes: 7 additions & 0 deletions userspace/libsinsp/sinsp_filter_transformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ enum filter_transformer_type: uint8_t
FTR_TOLOWER = 1,
FTR_BASE64 = 2,
FTR_STORAGE = 3, // This transformer is only used internally
FTR_BASENAME = 4,
};

static inline std::string filter_transformer_type_str(filter_transformer_type m)
Expand All @@ -42,6 +43,8 @@ static inline std::string filter_transformer_type_str(filter_transformer_type m)
return "b64";
case FTR_STORAGE:
return "storage";
case FTR_BASENAME:
return "basename";
default:
throw sinsp_exception("unknown field transfomer id " + std::to_string(m));
}
Expand All @@ -65,6 +68,10 @@ static inline filter_transformer_type filter_transformer_from_str(const std::str
{
return filter_transformer_type::FTR_STORAGE;
}
if (str == "basename")
{
return filter_transformer_type::FTR_BASENAME;
}
throw sinsp_exception("unknown field transfomer '" + str + "'");
}

Expand Down
2 changes: 1 addition & 1 deletion userspace/libsinsp/test/filter_parser.ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ TEST(parser, supported_field_transformers)
{
std::string expected_val = "val";
std::vector<std::string> expected = {
"tolower", "toupper", "b64" };
"tolower", "toupper", "b64", "basename" };

auto actual = parser::supported_field_transformers();
ASSERT_EQ(actual.size(), expected.size());
Expand Down
73 changes: 73 additions & 0 deletions userspace/libsinsp/test/filter_transformer.ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ limitations under the License.
#include <unordered_set>
#include <libsinsp/utils.h>
#include <libsinsp/sinsp_filter_transformer.h>
#include <sinsp_with_test_input.h>

static std::unordered_set<ppm_param_type> all_param_types()
{
Expand Down Expand Up @@ -231,3 +232,75 @@ TEST(sinsp_filter_transformer, b64)
EXPECT_EQ(t, PT_CHARBUF);
}
}

TEST(sinsp_filter_transformer, basename)
{
sinsp_filter_transformer tr(filter_transformer_type::FTR_BASENAME);

auto all_types = all_param_types();

auto supported_types = std::unordered_set<ppm_param_type>({PT_CHARBUF, PT_FSPATH, PT_FSRELPATH });

auto test_cases = std::vector<std::pair<std::string, std::string>>{
{"/home/ubuntu/hello.txt", "hello.txt"},
{"/usr/local/bin/cat", "cat"},
{"/", ""},
{"", ""},
{"/hello/", ""},
{"hello", "hello"},
};


std::vector<extract_value_t> sample_vals;

for (auto& tc : test_cases)
{
sample_vals.push_back(const_str_to_extract_value(tc.first.c_str()));
}

// check for unsupported types
for (auto t : all_types)
{
if (supported_types.find(t) == supported_types.end())
{
auto vals = sample_vals;
EXPECT_FALSE(tr.transform_type(t)) << supported_type_msg(t, false);
EXPECT_ANY_THROW(tr.transform_values(vals, t)) << supported_type_msg(t, false);
}
}

// check for supported types
for (auto t : supported_types)
{
auto original = t;
EXPECT_TRUE(tr.transform_type(t)) << supported_type_msg(original, true);
EXPECT_EQ(original, t); // note: basename is expected not to alter the type

auto vals = sample_vals;
EXPECT_TRUE(tr.transform_values(vals, t)) << supported_type_msg(original, true);
EXPECT_EQ(original, t);
EXPECT_EQ(vals.size(), test_cases.size());

for (uint32_t i = 0; i < test_cases.size(); i++)
{
EXPECT_EQ(std::string((const char *)vals[i].ptr), test_cases[i].second) << eq_test_msg(test_cases[i]);
EXPECT_EQ(vals[i].len, test_cases[i].second.length() + 1) << eq_test_msg(test_cases[i]);
}
}
}

TEST_F(sinsp_with_test_input, basename_transformer)
{
add_default_init_thread();
open_inspector();

sinsp_evt *evt;

int64_t dirfd = 3;
const char *file_to_run = "/tmp/file_to_run";
add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_OPEN_E, 3, file_to_run, 0, 0);
evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_OPEN_X, 6, dirfd, file_to_run, 0, 0, 0, (uint64_t) 0);

EXPECT_TRUE(eval_filter(evt, "basename(fd.name) = file_to_run"));
EXPECT_FALSE(eval_filter(evt, "basename(fd.name) = /tmp/file_to_run"));
}

0 comments on commit 0ec2ad8

Please sign in to comment.