From 5e8960ee9609a81d288b9f9f747318a856dcaff4 Mon Sep 17 00:00:00 2001
From: Luca Guerra <luca@guerra.sh>
Date: Wed, 12 Jun 2024 11:02:00 +0000
Subject: [PATCH 1/2] fix(libsinsp): fix regression in signed comparison

Signed-off-by: Luca Guerra <luca@guerra.sh>
---
 userspace/libsinsp/filter_compare.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/userspace/libsinsp/filter_compare.cpp b/userspace/libsinsp/filter_compare.cpp
index 29cc670d02..d409db0617 100644
--- a/userspace/libsinsp/filter_compare.cpp
+++ b/userspace/libsinsp/filter_compare.cpp
@@ -415,7 +415,7 @@ static inline void _throw_if_not_comparable(cmpop op, Check c)
 }
 
 template<typename T>
-static inline bool flt_compare_numeric(cmpop op, uint64_t operand1, uint64_t operand2)
+static inline bool flt_compare_numeric(cmpop op, T operand1, T operand2)
 {
 	switch(op)
 	{

From 90df56587b9d6b1ef401ee55bea99367f6001865 Mon Sep 17 00:00:00 2001
From: Luca Guerra <luca@guerra.sh>
Date: Wed, 12 Jun 2024 17:29:46 +0000
Subject: [PATCH 2/2] update(tests): add tests for numeric compare

Signed-off-by: Luca Guerra <luca@guerra.sh>
---
 userspace/libsinsp/test/CMakeLists.txt        |  1 +
 .../test/filter_op_numeric_compare.ut.cpp     | 59 +++++++++++++++++++
 .../libsinsp/test/sinsp_with_test_input.cpp   | 14 +++++
 .../libsinsp/test/sinsp_with_test_input.h     |  3 +
 4 files changed, 77 insertions(+)
 create mode 100644 userspace/libsinsp/test/filter_op_numeric_compare.ut.cpp

diff --git a/userspace/libsinsp/test/CMakeLists.txt b/userspace/libsinsp/test/CMakeLists.txt
index 06ccdf475e..8dd0138fdc 100644
--- a/userspace/libsinsp/test/CMakeLists.txt
+++ b/userspace/libsinsp/test/CMakeLists.txt
@@ -107,6 +107,7 @@ set(LIBSINSP_UNIT_TESTS_SOURCES
 	filter_parser.ut.cpp
 	filter_op_bcontains.ut.cpp
 	filter_op_pmatch.ut.cpp
+	filter_op_numeric_compare.ut.cpp
 	filter_compiler.ut.cpp
 	filter_transformer.ut.cpp
 	user.ut.cpp
diff --git a/userspace/libsinsp/test/filter_op_numeric_compare.ut.cpp b/userspace/libsinsp/test/filter_op_numeric_compare.ut.cpp
new file mode 100644
index 0000000000..d73fd9a213
--- /dev/null
+++ b/userspace/libsinsp/test/filter_op_numeric_compare.ut.cpp
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+Copyright (C) 2024 The Falco Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License"));
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#include <libsinsp/sinsp.h>
+#include <gtest/gtest.h>
+
+#include <sinsp_with_test_input.h>
+
+TEST_F(sinsp_with_test_input, signed_int_compare)
+{
+	add_default_init_thread();
+
+	open_inspector();
+
+	sinsp_evt * evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_EPOLL_CREATE_X, 1, (uint64_t)-22);
+
+	EXPECT_EQ(get_field_as_string(evt, "evt.cpu"), "1");
+
+	EXPECT_TRUE(eval_filter(evt, "evt.cpu < 300"));
+	EXPECT_FALSE(eval_filter(evt, "evt.cpu > 300"));
+	EXPECT_TRUE(eval_filter(evt, "evt.cpu < 2"));
+	EXPECT_TRUE(eval_filter(evt, "evt.cpu > -500"));
+	EXPECT_TRUE(eval_filter(evt, "evt.cpu < 500"));
+	EXPECT_TRUE(eval_filter(evt, "evt.cpu <= 500"));
+
+	EXPECT_TRUE(eval_filter(evt, "evt.cpu <= 1025"));
+	EXPECT_FALSE(eval_filter(evt, "evt.cpu >= 1025"));
+
+	EXPECT_FALSE(eval_filter(evt, "evt.rawarg.res > 0"));
+	EXPECT_TRUE(eval_filter(evt, "evt.rawarg.res < 0"));
+	EXPECT_FALSE(eval_filter(evt, "evt.rawarg.res > 4294967295"));
+	EXPECT_TRUE(eval_filter(evt, "evt.rawarg.res < -1"));
+	EXPECT_TRUE(eval_filter(evt, "evt.rawarg.res > -65535"));
+
+	evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_OPEN_E, 3, "/tmp/the_file", PPM_O_NONE, 0666);
+	evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_OPEN_X, 6, (int64_t)(-1), "/tmp/the_file", PPM_O_NONE, 0666, 123, (uint64_t)456);
+
+	EXPECT_FALSE(eval_filter(evt, "fd.num >= 0"));
+	EXPECT_FALSE(eval_filter(evt, "fd.num > 0"));
+	EXPECT_TRUE(eval_filter(evt, "fd.num < 0"));
+	EXPECT_FALSE(eval_filter(evt, "fd.num > 4294967295"));
+	EXPECT_FALSE(eval_filter(evt, "fd.num < -1"));
+	EXPECT_TRUE(eval_filter(evt, "fd.num > -65535"));
+}
diff --git a/userspace/libsinsp/test/sinsp_with_test_input.cpp b/userspace/libsinsp/test/sinsp_with_test_input.cpp
index 17afbd3d43..a0b53f70af 100644
--- a/userspace/libsinsp/test/sinsp_with_test_input.cpp
+++ b/userspace/libsinsp/test/sinsp_with_test_input.cpp
@@ -497,6 +497,20 @@ std::string sinsp_with_test_input::get_field_as_string(sinsp_evt* evt, std::stri
 	return result;
 }
 
+bool sinsp_with_test_input::eval_filter(sinsp_evt* evt, std::string filter_str)
+{
+	auto factory = std::make_shared<sinsp_filter_factory>(&m_inspector, m_default_filterlist);
+	sinsp_filter_compiler compiler(factory, filter_str);
+
+	auto filter = compiler.compile();
+	if (!filter)
+	{
+		throw sinsp_exception(std::string("could not compile filter ") + filter_str);
+	}
+
+	return filter->run(evt);
+}
+
 sinsp_evt* sinsp_with_test_input::next_event()
 {
 	sinsp_evt* evt;
diff --git a/userspace/libsinsp/test/sinsp_with_test_input.h b/userspace/libsinsp/test/sinsp_with_test_input.h
index 8389bdd9bf..cac743c436 100644
--- a/userspace/libsinsp/test/sinsp_with_test_input.h
+++ b/userspace/libsinsp/test/sinsp_with_test_input.h
@@ -192,12 +192,15 @@ class sinsp_with_test_input : public ::testing::Test
 	void add_default_init_thread();
 	void add_simple_thread(int64_t tid, int64_t pid, int64_t ptid, const std::string& comm = "random");
 	uint64_t increasing_ts();
+
 	bool field_exists(sinsp_evt*, std::string_view field_name);
 	bool field_exists(sinsp_evt*, std::string_view field_name, filter_check_list&);
 	bool field_has_value(sinsp_evt*, std::string_view field_name);
 	bool field_has_value(sinsp_evt*, std::string_view field_name, filter_check_list&);
 	std::string get_field_as_string(sinsp_evt*, std::string_view field_name);
 	std::string get_field_as_string(sinsp_evt*, std::string_view field_name, filter_check_list&);
+	bool eval_filter(sinsp_evt* evt, std::string filter);
+
 	sinsp_evt* next_event();
 
 	scap_test_input_data m_test_data;