From fce01f7d71457982563557b4dac3d24e91ba40eb Mon Sep 17 00:00:00 2001 From: Emily Date: Thu, 14 Aug 2025 15:41:55 +0100 Subject: [PATCH] lib: fix overflowing `fromHexString` tests and example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `fromHexString` is backed by `builtins.fromTOML`. Per [the TOML v1.0.0 specification]: > Arbitrary 64-bit signed integers (from −2^63 to 2^63−1) should be > accepted and handled losslessly. If an integer cannot be represented > losslessly, an error must be thrown. [the TOML v1.0.0 specification]: The saturating behaviour of the toml11 version currently used by Nix is not lossless, and is therefore a violation of the TOML specification. We should not be relying on it. This blocks the update of toml11, as it became stricter about reporting this condition. This, yes, is arguably an evaluation compatibility break. However, integer overflow was recently explicitly defined as an error by both Nix and Lix, as opposed to the C++ undefined behaviour it was previously implemented as: * * This included changing `builtins.fromJSON` to explicitly reject overflowing integer literals. I believe that the case for `builtins.fromTOML` is comparable, and that we are effectively testing undefined behaviour in TOML and the Nix language here, in the same way that we would have been if we had tests relying on overflowing integer arithmetic. I am not aware of any use of this behaviour outside of these tests; the reverted toml11 bump in Nix did not break the 23.11 evaluation regression test, for example. C++ undefined behaviour is not involved here, as toml11 used the C++ formatted input functions that are specified to saturate on invalid values. But it’s still a violation of the TOML specification caused by insufficient error checking in the old version of the library, and inconsistent with the handling of overflowing literals in the rest of Nix. Let’s fix this so that Nix implementations can correctly flag up this error and we can unblock the toml11 update. (cherry picked from commit 449ad44f163198718caaf8bc89080e6187418dc9) --- lib/tests/misc.nix | 5 +++-- lib/trivial.nix | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 8fd02e49cded..a44561fb1e69 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -380,8 +380,9 @@ runTests { expected = 255; }; - testFromHexStringSecondExample = { - expr = fromHexString (builtins.hashString "sha256" "test"); + # Highest supported integer value in Nix. + testFromHexStringMaximum = { + expr = fromHexString "7fffffffffffffff"; expected = 9223372036854775807; }; diff --git a/lib/trivial.nix b/lib/trivial.nix index eba6dd69b12e..ada83b8fb4be 100644 --- a/lib/trivial.nix +++ b/lib/trivial.nix @@ -1114,7 +1114,7 @@ in fromHexString "FF" => 255 - fromHexString (builtins.hashString "sha256" "test") + fromHexString "0x7fffffffffffffff" => 9223372036854775807 ``` */