From 2e8d9af241ea37fe12d4520c126b71beb228e5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com> Date: Tue, 7 Jun 2022 17:55:41 +0200 Subject: [PATCH] Forbid implicit conversion of negative integer to N or (N) arguments - add missing non-negativity check for tuples of N that are initialized by a single value - add related tests --- .../BuiltinFunctionProcessor.hpp | 15 ++++++++-- .../FunctionArgumentConverter.hpp | 5 ++++ tests/test_BuiltinFunctionProcessor.cpp | 29 +++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/language/node_processor/BuiltinFunctionProcessor.hpp b/src/language/node_processor/BuiltinFunctionProcessor.hpp index 4e5583adb..7e5a112b4 100644 --- a/src/language/node_processor/BuiltinFunctionProcessor.hpp +++ b/src/language/node_processor/BuiltinFunctionProcessor.hpp @@ -52,14 +52,25 @@ class BuiltinFunctionProcessor : public INodeProcessor ExecutionPolicy context_exec_policy{exec_policy, ExecutionPolicy::Context{-1, std::make_shared<ExecutionPolicy::Context::Values>( m_argument_converters.size())}}; + if (m_argument_converters.size() == 1) { - m_argument_converters[0]->convert(context_exec_policy, m_argument_node.execute(context_exec_policy)); + try { + m_argument_converters[0]->convert(context_exec_policy, m_argument_node.execute(context_exec_policy)); + } + catch (std::domain_error& e) { + throw ParseError(e.what(), m_argument_node.begin()); + } } else { AggregateDataVariant argument_values{ std::get<AggregateDataVariant>(m_argument_node.execute(context_exec_policy))}; for (size_t i = 0; i < m_argument_converters.size(); ++i) { - m_argument_converters[i]->convert(context_exec_policy, std::move(argument_values[i])); + try { + m_argument_converters[i]->convert(context_exec_policy, std::move(argument_values[i])); + } + catch (std::domain_error& e) { + throw ParseError(e.what(), m_argument_node.children[i]->begin()); + } } } diff --git a/src/language/node_processor/FunctionArgumentConverter.hpp b/src/language/node_processor/FunctionArgumentConverter.hpp index 3f7b941af..769bcd9ef 100644 --- a/src/language/node_processor/FunctionArgumentConverter.hpp +++ b/src/language/node_processor/FunctionArgumentConverter.hpp @@ -222,6 +222,11 @@ class FunctionTupleArgumentConverter final : public IFunctionArgumentConverter } } else if constexpr (std::is_convertible_v<ValueT, ContentType> and not is_tiny_vector_v<ContentType> and not is_tiny_matrix_v<ContentType>) { + if constexpr (std::is_same_v<ContentType, uint64_t> and std::is_same_v<ValueT, int64_t>) { + if (v < 0) { + throw std::domain_error("trying to convert negative value (" + std::to_string(v) + ")"); + } + } exec_policy.currentContext()[m_argument_id] = std::move(TupleType{static_cast<ContentType>(v)}); } else { throw UnexpectedError(std::string{"cannot convert '"} + demangle<ValueT>() + "' to '" + diff --git a/tests/test_BuiltinFunctionProcessor.cpp b/tests/test_BuiltinFunctionProcessor.cpp index bbc5ac52e..1cdfec95e 100644 --- a/tests/test_BuiltinFunctionProcessor.cpp +++ b/tests/test_BuiltinFunctionProcessor.cpp @@ -368,5 +368,34 @@ runtimeError(); CHECK_AST_THROWS_WITH(data, error); } + + SECTION("negative Z to N conversion") + { + std::string_view data = R"( +NtoR(3); +NtoR(-4); +)"; + + CHECK_AST_THROWS_WITH(data, std::string{"trying to convert negative value (-4)"}); + } + + SECTION("negative Z in list to (N) conversion") + { + std::string_view data = R"( +tuple_NtoR(2); +tuple_NtoR(-1); +)"; + + CHECK_AST_THROWS_WITH(data, std::string{"trying to convert negative value (-1)"}); + } + + SECTION("negative Z in list to (N) conversion") + { + std::string_view data = R"( +tuple_NtoR((3, 2, -3, 2)); +)"; + + CHECK_AST_THROWS_WITH(data, std::string{"trying to convert negative value (-3)"}); + } } } -- GitLab