1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-28 13:41:15 +02:00

libexpr: fix UB in builtins.ceil and builtins.floor

tighten and fix specification of both builtins
This commit is contained in:
Philipp Otterbein 2025-04-13 04:36:09 +02:00
parent 71567373b6
commit 56d37656ac
2 changed files with 76 additions and 12 deletions

View file

@ -56,11 +56,31 @@ namespace nix {
TEST_F(PrimOpTest, ceil) {
auto v = eval("builtins.ceil 1.9");
ASSERT_THAT(v, IsIntEq(2));
auto intMin = eval("builtins.ceil (-4611686018427387904 - 4611686018427387904)");
ASSERT_THAT(intMin, IsIntEq(std::numeric_limits<NixInt::Inner>::min()));
ASSERT_THROW(eval("builtins.ceil 1.0e200"), EvalError);
ASSERT_THROW(eval("builtins.ceil -1.0e200"), EvalError);
ASSERT_THROW(eval("builtins.ceil (1.0e200 * 1.0e200)"), EvalError); // inf
ASSERT_THROW(eval("builtins.ceil (-1.0e200 * 1.0e200)"), EvalError); // -inf
ASSERT_THROW(eval("builtins.ceil (1.0e200 * 1.0e200 - 1.0e200 * 1.0e200)"), EvalError); // nan
// bugs in previous Nix versions
ASSERT_THROW(eval("builtins.ceil (4611686018427387904 + 4611686018427387903)"), EvalError);
ASSERT_THROW(eval("builtins.ceil (-4611686018427387904 - 4611686018427387903)"), EvalError);
}
TEST_F(PrimOpTest, floor) {
auto v = eval("builtins.floor 1.9");
ASSERT_THAT(v, IsIntEq(1));
auto intMin = eval("builtins.ceil (-4611686018427387904 - 4611686018427387904)");
ASSERT_THAT(intMin, IsIntEq(std::numeric_limits<NixInt::Inner>::min()));
ASSERT_THROW(eval("builtins.ceil 1.0e200"), EvalError);
ASSERT_THROW(eval("builtins.ceil -1.0e200"), EvalError);
ASSERT_THROW(eval("builtins.ceil (1.0e200 * 1.0e200)"), EvalError); // inf
ASSERT_THROW(eval("builtins.ceil (-1.0e200 * 1.0e200)"), EvalError); // -inf
ASSERT_THROW(eval("builtins.ceil (1.0e200 * 1.0e200 - 1.0e200 * 1.0e200)"), EvalError); // nan
// bugs in previous Nix versions
ASSERT_THROW(eval("builtins.ceil (4611686018427387904 + 4611686018427387903)"), EvalError);
ASSERT_THROW(eval("builtins.ceil (-4611686018427387904 - 4611686018427387903)"), EvalError);
}
TEST_F(PrimOpTest, tryEvalFailure) {