diff --git a/userspace/libsinsp/sinsp_filter_transformer.cpp b/userspace/libsinsp/sinsp_filter_transformer.cpp index 158d39ce86..9b8bc1a90e 100644 --- a/userspace/libsinsp/sinsp_filter_transformer.cpp +++ b/userspace/libsinsp/sinsp_filter_transformer.cpp @@ -25,6 +25,14 @@ static void throw_type_incompatibility_err(ppm_param_type t, const std::string& "' transformer"); } +// base class +sinsp_filter_transformer::~sinsp_filter_transformer() {} + +bool sinsp_filter_transformer::transform_type(ppm_param_type& t, uint32_t& flags) const { + throw_unsupported_err(m_type); + return false; +} + bool sinsp_filter_transformer::string_transformer(std::vector& vec, ppm_param_type t, str_transformer_func_t f) { @@ -63,200 +71,279 @@ bool sinsp_filter_transformer::string_transformer(std::vector& return true; } -bool sinsp_filter_transformer::transform_type(ppm_param_type& t, uint32_t& flags) const { - bool is_list = flags & EPF_IS_LIST; - switch(m_type) { - case FTR_TOUPPER: { - switch(t) { - case PT_CHARBUF: - case PT_FSPATH: - case PT_FSRELPATH: - // for TOUPPER, the transformed type is the same as the input type - return true; - default: - return false; +// toupper +sinsp_filter_toupper_transformer::sinsp_filter_toupper_transformer() { + m_type = FTR_TOUPPER; +}; + +bool sinsp_filter_toupper_transformer::transform_type(ppm_param_type& t, uint32_t& flags) const { + switch(t) { + case PT_CHARBUF: + case PT_FSPATH: + case PT_FSRELPATH: + // for TOUPPER, the transformed type is the same as the input type + return true; + default: + return false; + } +} + +bool sinsp_filter_toupper_transformer::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + if(!transform_type(t, flags)) { + throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); + } + + return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { + for(auto c : in) { + out.push_back(toupper(c)); } + return true; + }); +} + +// tolower +sinsp_filter_tolower_transformer::sinsp_filter_tolower_transformer() { + m_type = FTR_TOLOWER; +}; + +bool sinsp_filter_tolower_transformer::transform_type(ppm_param_type& t, uint32_t& flags) const { + switch(t) { + case PT_CHARBUF: + case PT_FSPATH: + case PT_FSRELPATH: + // for TOLOWER, the transformed type is the same as the input type + return true; + default: + return false; } - case FTR_TOLOWER: { - switch(t) { - case PT_CHARBUF: - case PT_FSPATH: - case PT_FSRELPATH: - // for TOLOWER, the transformed type is the same as the input type - return true; - default: - return false; +} + +bool sinsp_filter_tolower_transformer::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + if(!transform_type(t, flags)) { + throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); + } + + return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { + for(auto c : in) { + out.push_back(tolower(c)); } + return true; + }); +} + +// base64 +sinsp_filter_base64_transformer::sinsp_filter_base64_transformer() { + m_type = FTR_BASE64; +} + +bool sinsp_filter_base64_transformer::transform_type(ppm_param_type& t, uint32_t& flags) const { + switch(t) { + case PT_CHARBUF: + case PT_BYTEBUF: + // for BASE64, the transformed type is the same as the input type + return true; + default: + return false; } - case FTR_BASE64: { - switch(t) { - case PT_CHARBUF: - case PT_BYTEBUF: - // for BASE64, the transformed type is the same as the input type - return true; - default: - return false; +} + +bool sinsp_filter_base64_transformer::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + if(!transform_type(t, flags)) { + throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); + } + + return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { + return Base64::decodeWithoutPadding(in, out); + }); +} + +// storage +sinsp_filter_storage_transformer::sinsp_filter_storage_transformer() { + m_type = FTR_STORAGE; +}; + +bool sinsp_filter_storage_transformer::transform_type(ppm_param_type& t, uint32_t& flags) const { + return true; +} + +bool sinsp_filter_storage_transformer::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + // note: for STORAGE, the transformed type is the same as the input type + m_storage_values.resize(vec.size()); + for(std::size_t i = 0; i < vec.size(); i++) { + storage_t& buf = m_storage_values[i]; + + buf.clear(); + if(vec[i].ptr == nullptr) { + continue; } + + // We reserve one extra chat for the null terminator + buf.resize(vec[i].len + 1); + memcpy(&(buf[0]), vec[i].ptr, vec[i].len); + // We put the string terminator in any case + buf[vec[i].len] = '\0'; + vec[i].ptr = &(buf[0]); + // `vec[i].len` is the same as before } - case FTR_STORAGE: { - // for STORAGE, the transformed type is the same as the input type + return true; +} + +// basename +sinsp_filter_basename_transformer::sinsp_filter_basename_transformer() { + m_type = FTR_BASENAME; +}; + +bool sinsp_filter_basename_transformer::transform_type(ppm_param_type& t, uint32_t& flags) const { + 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; } - 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; - } +} + +bool sinsp_filter_basename_transformer::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + if(!transform_type(t, flags)) { + throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); } - case FTR_LEN: { - if(is_list) { - t = PT_UINT64; - flags = flags & ~EPF_IS_LIST; - return true; - } - switch(t) { - case PT_CHARBUF: - case PT_BYTEBUF: - case PT_FSPATH: - case PT_FSRELPATH: - t = PT_UINT64; - return true; - default: - return false; + + return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { + auto last_slash_pos = in.find_last_of("/"); + std::string_view::size_type start_idx = + last_slash_pos == std::string_view::npos ? 0 : last_slash_pos + 1; + + for(std::string_view::size_type i = start_idx; i < in.length(); i++) { + out.push_back(in[i]); } + + return true; + }); +} + +// len +sinsp_filter_len_transformer::sinsp_filter_len_transformer() { + m_type = FTR_LEN; +}; + +bool sinsp_filter_len_transformer::transform_type(ppm_param_type& t, uint32_t& flags) const { + bool is_list = flags & EPF_IS_LIST; + if(is_list) { + t = PT_UINT64; + flags = flags & ~EPF_IS_LIST; + return true; } + switch(t) { + case PT_CHARBUF: + case PT_BYTEBUF: + case PT_FSPATH: + case PT_FSRELPATH: + t = PT_UINT64; + return true; default: - throw_unsupported_err(m_type); return false; } } -bool sinsp_filter_transformer::transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) { +bool sinsp_filter_len_transformer::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { bool is_list = flags & EPF_IS_LIST; ppm_param_type original_type = t; if(!transform_type(t, flags)) { throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); } - switch(m_type) { + assert((void("len() type must be PT_UINT64"), t == PT_UINT64)); + m_storage_values.clear(); + if(is_list) { + uint64_t len = static_cast(vec.size()); + auto stored_val = store_scalar(len); + vec.clear(); + vec.push_back(stored_val); + return true; + } + + // not a list: could be string or buffer + bool is_string = false; + switch(original_type) { + case PT_CHARBUF: + case PT_FSPATH: + case PT_FSRELPATH: + is_string = true; + break; + case PT_BYTEBUF: + is_string = false; + break; + default: + return false; + } + + if(vec.size() == 0) { + // should never happen since there is no way to + // call len() with no arguments + return false; + } + + // we are assuming that if this is not a list then it's a single element + assert((void("non-list elements to transform with len() must be a vector with a single " + "element"), + vec.size() == 1)); + uint64_t len; + if(vec[0].ptr == nullptr) { + vec[0] = store_scalar(0); + return true; + } + + if(is_string) { + len = static_cast(strnlen(reinterpret_cast(vec[0].ptr), vec[0].len)); + vec[0] = store_scalar(len); + return true; + } + + // buffer + len = static_cast(vec[0].len); + vec[0] = store_scalar(len); + return true; +} + +std::unique_ptr sinsp_filter_transformer::create_transformer( + filter_transformer_type trtype) { + switch(trtype) { case FTR_TOUPPER: { - return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { - for(auto c : in) { - out.push_back(toupper(c)); - } - return true; - }); + return std::make_unique(); } case FTR_TOLOWER: { - return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { - for(auto c : in) { - out.push_back(tolower(c)); - } - return true; - }); + return std::make_unique(); } case FTR_BASE64: { - return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { - return Base64::decodeWithoutPadding(in, out); - }); + return std::make_unique(); } case FTR_STORAGE: { - // note: for STORAGE, the transformed type is the same as the input type - m_storage_values.resize(vec.size()); - for(std::size_t i = 0; i < vec.size(); i++) { - storage_t& buf = m_storage_values[i]; - - buf.clear(); - if(vec[i].ptr == nullptr) { - continue; - } - - // We reserve one extra chat for the null terminator - buf.resize(vec[i].len + 1); - memcpy(&(buf[0]), vec[i].ptr, vec[i].len); - // We put the string terminator in any case - buf[vec[i].len] = '\0'; - vec[i].ptr = &(buf[0]); - // `vec[i].len` is the same as before - } - return true; + // for STORAGE, the transformed type is the same as the input type + // return true; + return std::make_unique(); } case FTR_BASENAME: { - return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { - auto last_slash_pos = in.find_last_of("/"); - std::string_view::size_type start_idx = - last_slash_pos == std::string_view::npos ? 0 : last_slash_pos + 1; - - for(std::string_view::size_type i = start_idx; i < in.length(); i++) { - out.push_back(in[i]); - } - - return true; - }); + return std::make_unique(); } case FTR_LEN: { - assert((void("len() type must be PT_UINT64"), t == PT_UINT64)); - m_storage_values.clear(); - if(is_list) { - uint64_t len = static_cast(vec.size()); - auto stored_val = store_scalar(len); - vec.clear(); - vec.push_back(stored_val); - return true; - } - - // not a list: could be string or buffer - bool is_string = false; - switch(original_type) { - case PT_CHARBUF: - case PT_FSPATH: - case PT_FSRELPATH: - is_string = true; - break; - case PT_BYTEBUF: - is_string = false; - break; - default: - return false; - } - - if(vec.size() == 0) { - // should never happen since there is no way to - // call len() with no arguments - return false; - } - - // we are assuming that if this is not a list then it's a single element - assert((void("non-list elements to transform with len() must be a vector with a single " - "element"), - vec.size() == 1)); - uint64_t len; - if(vec[0].ptr == nullptr) { - vec[0] = store_scalar(0); - return true; - } - - if(is_string) { - len = static_cast( - strnlen(reinterpret_cast(vec[0].ptr), vec[0].len)); - vec[0] = store_scalar(len); - return true; - } - - // buffer - len = static_cast(vec[0].len); - vec[0] = store_scalar(len); - return true; + return std::make_unique(); } default: - throw_unsupported_err(m_type); - return false; + throw_unsupported_err(trtype); + return nullptr; } } diff --git a/userspace/libsinsp/sinsp_filter_transformer.h b/userspace/libsinsp/sinsp_filter_transformer.h index 1ccaed76c0..8f5d39a509 100644 --- a/userspace/libsinsp/sinsp_filter_transformer.h +++ b/userspace/libsinsp/sinsp_filter_transformer.h @@ -70,13 +70,18 @@ class sinsp_filter_transformer { public: using storage_t = std::vector; - sinsp_filter_transformer(filter_transformer_type t): m_type(t) {}; + virtual ~sinsp_filter_transformer(); - bool transform_type(ppm_param_type& t, uint32_t& flags) const; + virtual bool transform_type(ppm_param_type& t, uint32_t& flags) const; - bool transform_values(std::vector& vals, ppm_param_type& t, uint32_t& flags); + virtual bool transform_values(std::vector& vals, + ppm_param_type& t, + uint32_t& flags) = 0; -private: + static std::unique_ptr create_transformer( + filter_transformer_type trtype); + +protected: using str_transformer_func_t = std::function; bool string_transformer(std::vector& vec, @@ -93,3 +98,57 @@ class sinsp_filter_transformer { filter_transformer_type m_type; std::vector m_storage_values; }; + +class sinsp_filter_toupper_transformer : public sinsp_filter_transformer { +public: + sinsp_filter_toupper_transformer(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; + +class sinsp_filter_tolower_transformer : public sinsp_filter_transformer { +public: + sinsp_filter_tolower_transformer(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; + +class sinsp_filter_base64_transformer : public sinsp_filter_transformer { +public: + sinsp_filter_base64_transformer(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; + +class sinsp_filter_storage_transformer : public sinsp_filter_transformer { +public: + sinsp_filter_storage_transformer(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; + +class sinsp_filter_basename_transformer : public sinsp_filter_transformer { +public: + sinsp_filter_basename_transformer(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; + +class sinsp_filter_len_transformer : public sinsp_filter_transformer { +public: + sinsp_filter_len_transformer(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; diff --git a/userspace/libsinsp/sinsp_filtercheck.cpp b/userspace/libsinsp/sinsp_filtercheck.cpp index f1954209c2..0f585dc55c 100644 --- a/userspace/libsinsp/sinsp_filtercheck.cpp +++ b/userspace/libsinsp/sinsp_filtercheck.cpp @@ -1060,8 +1060,8 @@ void sinsp_filter_check::add_transformer(filter_transformer_type trtype) { // apply type transformation, both as a feasibility check and // as an information to be returned later on - sinsp_filter_transformer tr(trtype); - if(!tr.transform_type(m_transformed_field->m_type, m_transformed_field->m_flags)) { + auto tr = sinsp_filter_transformer::create_transformer(trtype); + if(!tr->transform_type(m_transformed_field->m_type, m_transformed_field->m_flags)) { throw sinsp_exception("can't add field transformer: type '" + std::string(param_type_to_string(m_transformed_field->m_type)) + "' is not supported by '" + filter_transformer_type_str(trtype) + @@ -1083,7 +1083,7 @@ bool sinsp_filter_check::apply_transformers(std::vector& values auto field_type = field_info->m_type; auto field_flags = field_info->m_flags; for(auto& tr : m_transformers) { - if(!tr.transform_values(values, field_type, field_flags)) { + if(!tr->transform_values(values, field_type, field_flags)) { return false; } } diff --git a/userspace/libsinsp/sinsp_filtercheck.h b/userspace/libsinsp/sinsp_filtercheck.h index 81c77f7de0..43dcffd25b 100644 --- a/userspace/libsinsp/sinsp_filtercheck.h +++ b/userspace/libsinsp/sinsp_filtercheck.h @@ -238,7 +238,7 @@ class sinsp_filter_check { const std::vector& values); inline void check_rhs_field_type_consistency() const; - std::list m_transformers; + std::list> m_transformers; std::unique_ptr m_rhs_filter_check = nullptr; std::unique_ptr m_transformed_field = nullptr; diff --git a/userspace/libsinsp/test/filter_transformer.ut.cpp b/userspace/libsinsp/test/filter_transformer.ut.cpp index 81aef376b4..4473de313f 100644 --- a/userspace/libsinsp/test/filter_transformer.ut.cpp +++ b/userspace/libsinsp/test/filter_transformer.ut.cpp @@ -86,7 +86,7 @@ struct test_case_entry { std::vector expected; }; -static void check_unsupported_types(sinsp_filter_transformer& tr, +static void check_unsupported_types(const std::unique_ptr& tr, std::set& supported_types, std::set& supported_list_types) { auto all_types = all_param_types(); @@ -94,25 +94,25 @@ static void check_unsupported_types(sinsp_filter_transformer& tr, for(auto t : all_types) { uint32_t flags = EPF_IS_LIST; if(supported_list_types.find(t) == supported_list_types.end()) { - EXPECT_FALSE(tr.transform_type(t, flags)) << supported_type_msg(t, flags, false); + EXPECT_FALSE(tr->transform_type(t, flags)) << supported_type_msg(t, flags, false); // vals is empty for simplicity, should not affect the test std::vector vals{}; - EXPECT_ANY_THROW(tr.transform_values(vals, t, flags)) + EXPECT_ANY_THROW(tr->transform_values(vals, t, flags)) << supported_type_msg(t, flags, false); } flags = 0; if(supported_types.find(t) == supported_types.end()) { - EXPECT_FALSE(tr.transform_type(t, flags)) << supported_type_msg(t, flags, false); + EXPECT_FALSE(tr->transform_type(t, flags)) << supported_type_msg(t, flags, false); std::vector vals{}; - EXPECT_ANY_THROW(tr.transform_values(vals, t, flags)) + EXPECT_ANY_THROW(tr->transform_values(vals, t, flags)) << supported_type_msg(t, flags, false); } } } TEST(sinsp_filter_transformer, toupper) { - sinsp_filter_transformer tr(filter_transformer_type::FTR_TOUPPER); + auto tr = sinsp_filter_transformer::create_transformer(filter_transformer_type::FTR_TOUPPER); std::set supported_types{PT_CHARBUF, PT_FSPATH, PT_FSRELPATH}; std::set supported_list_types = supported_types; @@ -135,7 +135,7 @@ TEST(sinsp_filter_transformer, toupper) { auto transformed_type = tc.input_type; uint32_t flags = tc.flags; bool is_list = flags & EPF_IS_LIST; - EXPECT_TRUE(tr.transform_type(transformed_type, flags)) + EXPECT_TRUE(tr->transform_type(transformed_type, flags)) << supported_type_msg(tc.input_type, is_list, true); EXPECT_EQ(transformed_type, tc.expected_type); @@ -145,7 +145,7 @@ TEST(sinsp_filter_transformer, toupper) { } transformed_type = tc.input_type; - EXPECT_TRUE(tr.transform_values(vals, transformed_type, flags)) + EXPECT_TRUE(tr->transform_values(vals, transformed_type, flags)) << supported_type_msg(tc.input_type, is_list, true); EXPECT_EQ(vals.size(), tc.expected.size()); @@ -159,7 +159,7 @@ TEST(sinsp_filter_transformer, toupper) { } TEST(sinsp_filter_transformer, tolower) { - sinsp_filter_transformer tr(filter_transformer_type::FTR_TOLOWER); + auto tr = sinsp_filter_transformer::create_transformer(filter_transformer_type::FTR_TOLOWER); std::set supported_types{PT_CHARBUF, PT_FSPATH, PT_FSRELPATH}; std::set supported_list_types = supported_types; @@ -183,7 +183,7 @@ TEST(sinsp_filter_transformer, tolower) { uint32_t flags = tc.flags; auto transformed_type = tc.input_type; - EXPECT_TRUE(tr.transform_type(transformed_type, flags)) + EXPECT_TRUE(tr->transform_type(transformed_type, flags)) << supported_type_msg(tc.input_type, is_list, true); EXPECT_EQ(transformed_type, tc.expected_type); @@ -193,7 +193,7 @@ TEST(sinsp_filter_transformer, tolower) { } transformed_type = tc.input_type; - EXPECT_TRUE(tr.transform_values(vals, transformed_type, flags)) + EXPECT_TRUE(tr->transform_values(vals, transformed_type, flags)) << supported_type_msg(tc.input_type, is_list, true); EXPECT_EQ(vals.size(), tc.expected.size()); @@ -207,7 +207,7 @@ TEST(sinsp_filter_transformer, tolower) { } TEST(sinsp_filter_transformer, b64) { - sinsp_filter_transformer tr(filter_transformer_type::FTR_BASE64); + auto tr = sinsp_filter_transformer::create_transformer(filter_transformer_type::FTR_BASE64); std::set supported_types{PT_CHARBUF, PT_FSPATH, PT_FSRELPATH, PT_BYTEBUF}; std::set supported_list_types = supported_types; @@ -225,7 +225,7 @@ TEST(sinsp_filter_transformer, b64) { uint32_t flags = tc.flags; auto transformed_type = tc.input_type; - EXPECT_TRUE(tr.transform_type(transformed_type, flags)) + EXPECT_TRUE(tr->transform_type(transformed_type, flags)) << supported_type_msg(tc.input_type, is_list, true); EXPECT_EQ(transformed_type, tc.expected_type); @@ -235,7 +235,7 @@ TEST(sinsp_filter_transformer, b64) { } transformed_type = tc.input_type; - EXPECT_TRUE(tr.transform_values(vals, transformed_type, flags)) + EXPECT_TRUE(tr->transform_values(vals, transformed_type, flags)) << supported_type_msg(tc.input_type, is_list, true); EXPECT_EQ(vals.size(), tc.expected.size()); @@ -249,7 +249,7 @@ TEST(sinsp_filter_transformer, b64) { } TEST(sinsp_filter_transformer, basename) { - sinsp_filter_transformer tr(filter_transformer_type::FTR_BASENAME); + auto tr = sinsp_filter_transformer::create_transformer(filter_transformer_type::FTR_BASENAME); std::set supported_types{PT_CHARBUF, PT_FSPATH, PT_FSRELPATH}; std::set supported_list_types = supported_types; @@ -270,7 +270,7 @@ TEST(sinsp_filter_transformer, basename) { uint32_t flags = tc.flags; auto transformed_type = tc.input_type; - EXPECT_TRUE(tr.transform_type(transformed_type, flags)) + EXPECT_TRUE(tr->transform_type(transformed_type, flags)) << supported_type_msg(tc.input_type, is_list, true); EXPECT_EQ(transformed_type, tc.expected_type); @@ -280,7 +280,7 @@ TEST(sinsp_filter_transformer, basename) { } transformed_type = tc.input_type; - EXPECT_TRUE(tr.transform_values(vals, transformed_type, flags)) + EXPECT_TRUE(tr->transform_values(vals, transformed_type, flags)) << supported_type_msg(tc.input_type, is_list, true); EXPECT_EQ(vals.size(), tc.expected.size()); @@ -294,7 +294,7 @@ TEST(sinsp_filter_transformer, basename) { } TEST(sinsp_filter_transformer, len) { - sinsp_filter_transformer tr(filter_transformer_type::FTR_LEN); + auto tr = sinsp_filter_transformer::create_transformer(filter_transformer_type::FTR_LEN); std::set supported_types{PT_CHARBUF, PT_FSPATH, PT_FSRELPATH, PT_BYTEBUF}; std::set supported_list_types = all_param_types(); @@ -314,7 +314,7 @@ TEST(sinsp_filter_transformer, len) { uint32_t flags = tc.flags; auto transformed_type = tc.input_type; - EXPECT_TRUE(tr.transform_type(transformed_type, flags)) + EXPECT_TRUE(tr->transform_type(transformed_type, flags)) << supported_type_msg(tc.input_type, is_list, true); EXPECT_EQ(transformed_type, tc.expected_type); @@ -325,7 +325,7 @@ TEST(sinsp_filter_transformer, len) { transformed_type = tc.input_type; flags = tc.flags; - EXPECT_TRUE(tr.transform_values(vals, transformed_type, flags)) + EXPECT_TRUE(tr->transform_values(vals, transformed_type, flags)) << supported_type_msg(tc.input_type, is_list, true); EXPECT_EQ(vals.size(), tc.expected.size());