diff --git a/src/language/node_processor/FunctionArgumentConverter.hpp b/src/language/node_processor/FunctionArgumentConverter.hpp index 3e22a9ae188574db47278f69cc264d0faf0c2f2c..3f7b941af98887136af60b4415640d8694bd3ed6 100644 --- a/src/language/node_processor/FunctionArgumentConverter.hpp +++ b/src/language/node_processor/FunctionArgumentConverter.hpp @@ -65,8 +65,13 @@ class FunctionArgumentConverter final : public IFunctionArgumentConverter if constexpr (std::is_same_v<ExpectedValueType, ProvidedValueType>) { exec_policy.currentContext()[m_argument_id] = std::move(value); } else { - exec_policy.currentContext()[m_argument_id] = - std::move(static_cast<ExpectedValueType>(std::get<ProvidedValueType>(value))); + const ProvidedValueType& v = std::get<ProvidedValueType>(value); + if constexpr (std::is_same_v<uint64_t, ExpectedValueType> and std::is_same_v<int64_t, ProvidedValueType>) { + if (v < 0) { + throw std::domain_error("trying to convert negative value (" + std::to_string(v) + ")"); + } + } + exec_policy.currentContext()[m_argument_id] = std::move(static_cast<ExpectedValueType>(v)); } return {}; } @@ -201,6 +206,11 @@ class FunctionTupleArgumentConverter final : public IFunctionArgumentConverter TupleType list_value; list_value.reserve(v.size()); for (size_t i = 0; i < v.size(); ++i) { + if constexpr (std::is_same_v<ContentType, uint64_t> and std::is_same_v<ContentT, int64_t>) { + if (v[i] < 0) { + throw std::domain_error("trying to convert negative value (" + std::to_string(v[i]) + ")"); + } + } list_value.push_back(static_cast<ContentType>(v[i])); } exec_policy.currentContext()[m_argument_id] = std::move(list_value); @@ -305,6 +315,11 @@ class FunctionListArgumentConverter final : public IFunctionArgumentConverter demangle<ContentType>() + "'"); // LCOV_EXCL_STOP } else if constexpr (std::is_convertible_v<Vi_T, ContentType>) { + if constexpr (std::is_same_v<ContentType, uint64_t> and std::is_same_v<Vi_T, int64_t>) { + if (vi < 0) { + throw std::domain_error("trying to convert negative value (" + std::to_string(vi) + ")"); + } + } list_value.emplace_back(vi); } else { // LCOV_EXCL_START diff --git a/tests/test_FunctionArgumentConverter.cpp b/tests/test_FunctionArgumentConverter.cpp index 643fbba0b092d337743ea5aeaedb25eb86a5b445..17d481ad2d73f497946e19f2408b6ce005b17191 100644 --- a/tests/test_FunctionArgumentConverter.cpp +++ b/tests/test_FunctionArgumentConverter.cpp @@ -208,4 +208,31 @@ TEST_CASE("FunctionArgumentConverter", "[language]") REQUIRE(tuple.size() == 1); REQUIRE(tuple[0].id() == f_id); } + + SECTION("error") + { + SECTION("FunctionArgumentConverter negative value to N") + { + const int64_t negative_value = -2; + FunctionArgumentConverter<uint64_t, int64_t> converter{0}; + REQUIRE_THROWS_WITH(converter.convert(execution_policy, negative_value), "trying to convert negative value (-2)"); + } + + SECTION("FunctionTupleOfNArgumentConverter negative value to N") + { + const int64_t i = 1; + const int64_t j = 3; + const int64_t k = -6; + FunctionTupleArgumentConverter<uint64_t, int64_t> converter{0}; + REQUIRE_THROWS_WITH(converter.convert(execution_policy, std::vector<int64_t>{i, j, k}), + "trying to convert negative value (-6)"); + } + + SECTION("FunctionListArgumentConverter") + { + AggregateDataVariant v{std::vector<DataVariant>{1ul, -3l}}; + FunctionListArgumentConverter<uint64_t, uint64_t> converter{2}; + REQUIRE_THROWS_WITH(converter.convert(execution_policy, v), "trying to convert negative value (-3)"); + } + } }