mirror of
https://github.com/pantor/inja.git
synced 2026-09-16 02:48:02 +00:00
Throw instead of trapping on modulo by zero (#347)
Op::Modulo was the only arithmetic operator in the switch without a
zero-divisor guard, so {{ a % b }} raised SIGFPE and aborted the host
process. Op::Division already throws at renderer.hpp:307 and
Op::DivisibleBy already checks at :359. Guard the converted divisor,
which is what DivisibleBy does, so a fractional divisor that truncates
to zero is caught too.
This commit is contained in:
@@ -321,7 +321,11 @@ class Renderer : public NodeVisitor {
|
||||
} break;
|
||||
case Op::Modulo: {
|
||||
const auto args = get_arguments<2>(node);
|
||||
make_result(args[0]->get<const json::number_integer_t>() % args[1]->get<const json::number_integer_t>());
|
||||
const auto divisor = args[1]->get<const json::number_integer_t>();
|
||||
if (divisor == 0) {
|
||||
throw_renderer_error("modulo by zero", node);
|
||||
}
|
||||
make_result(args[0]->get<const json::number_integer_t>() % divisor);
|
||||
} break;
|
||||
case Op::AtId: {
|
||||
const auto container = get_arguments<1, 0, false>(node)[0];
|
||||
|
||||
@@ -2479,7 +2479,11 @@ class Renderer : public NodeVisitor {
|
||||
} break;
|
||||
case Op::Modulo: {
|
||||
const auto args = get_arguments<2>(node);
|
||||
make_result(args[0]->get<const json::number_integer_t>() % args[1]->get<const json::number_integer_t>());
|
||||
const auto divisor = args[1]->get<const json::number_integer_t>();
|
||||
if (divisor == 0) {
|
||||
throw_renderer_error("modulo by zero", node);
|
||||
}
|
||||
make_result(args[0]->get<const json::number_integer_t>() % divisor);
|
||||
} break;
|
||||
case Op::AtId: {
|
||||
const auto container = get_arguments<1, 0, false>(node)[0];
|
||||
|
||||
@@ -36,11 +36,15 @@ TEST_CASE("functions") {
|
||||
CHECK(env.render("{{ 1 + 1 * 3 }}", data) == "4");
|
||||
CHECK(env.render("{{ (1 + 1) * 3 }}", data) == "6");
|
||||
CHECK(env.render("{{ 5 / 2 }}", data) == "2.5");
|
||||
CHECK(env.render("{{ 5 % 2 }}", data) == "1");
|
||||
CHECK(env.render("{{ 7 % -2 }}", data) == "1");
|
||||
CHECK(env.render("{{ 5^3 }}", data) == "125");
|
||||
CHECK(env.render("{{ 5 + 12 + 4 * (4 - (1 + 1))^2 - 75 * 1 }}", data) == "-42");
|
||||
|
||||
CHECK_THROWS_WITH(env.render("{{ +1 }}", data), "[inja.exception.parser_error] (at 1:7) too few arguments");
|
||||
CHECK_THROWS_WITH(env.render("{{ 1 + }}", data), "[inja.exception.parser_error] (at 1:8) too few arguments");
|
||||
CHECK_THROWS_WITH(env.render("{{ 5 % 0 }}", data), "[inja.exception.render_error] (at 1:6) modulo by zero");
|
||||
CHECK_THROWS_WITH(env.render("{{ 5 % 0.5 }}", data), "[inja.exception.render_error] (at 1:6) modulo by zero");
|
||||
}
|
||||
|
||||
SUBCASE("upper") {
|
||||
|
||||
Reference in New Issue
Block a user