lib: fix overflowing fromHexString tests and example#433710
lib: fix overflowing fromHexString tests and example#433710emilazy merged 2 commits intoNixOS:masterfrom
fromHexString tests and example#433710Conversation
fromHexString tests and examplefromHexString tests and example
This would have allowed us to catch to fromTOML regression in [1] without waiting for the dogfooding on master, since previously these tests [2] were not run for the Nix/Lix under test - only the host nix. [1]: NixOS/nix#13741 [2]: NixOS#433710
lf-
left a comment
There was a problem hiding this comment.
oh yeah that is ..... a nasty thing to throw into a test in nixpkgs tbh. thanks for fixing it. lossful encoding is not ideal.
|
CI disagrees: |
|
Yeah it turns out that this doesn’t handle negative literals at all. Will fix soon. |
7d50b2c to
6474066
Compare
This was cherry‐picked from <NixOS#266705> and merged as part of <NixOS#318712>, despite there being a blocking review on the former pointing out these kinds of issues. This documents some of the dodgy behaviour. It also can’t handle negative literals. It might be worth considering deprecating and dropping this, by inlining it into `lib.network.ipv6.fromString`, its only in‐tree user.
`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]: <https://toml.io/en/v1.0.0#integer> 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: * <https://nix.dev/manual/nix/stable/release-notes/rl-2.25> * <https://docs.lix.systems/manual/lix/stable/release-notes/rl-2.91.html#fixes> 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.
6474066 to
449ad44
Compare
|
I’ve fixed that and added some more tests for some really bad behaviour of this function. @woojiq @Janik-Haag I think it is unfortunate that this was merged as part of #318712, despite the PR it was cherry‐picked from having a blocking review from @infinisil from half a year prior pointing out serious problems with this function. If those had been addressed this wouldn’t be blocking correctness fixes in Nix implementations and an update of our toml11 package, and we wouldn’t have shipped behaviour like |
|
Maybe I'm off the mark, but why does fromHexString use builtins.fromTOML? |
Network library that was planned to be implemented as part of the "google summer of code" project. But after implementation I didn't see much activity in pull-requests (no reviews, suggestions, etc), and probably no one really needed it, so it wasn't fully merged and finished. This happened because of some "political" nixpkgs stuff (that I haven't tried to understand), after which my mentor left the nixpkgs community. P.S. My bad for not fixing blocking threads in cherry-picked commit. I'll take this as a lesson. |
It seems like it’s used in the Akkoma module and in a few out‐of‐tree repos, and I don’t see any immediate issues with its interface or implementation. So I think there’s no reason to drop it – it’s providing value to people and not causing any harm.
Sorry if you didn’t have a great GSoC experience, and sorry if I came off as a little cranky here! It’s a failure of review processes on our side more than anything; just a matter of figuring out how we can ensure |
|
BTW, it seems like Snix and Tvix already reject this test due to using a more compliant TOML parser: and funnily enough, so did 2.3: |
|
Forgot to reply to this:
Because Nix has no native integer parsing functions so we just use TOML and JSON 🫠 |
There was a problem hiding this comment.
Seems lgtm to me.
Negative numbers such as 0x-8 would need support in nix ideally.
A possible workaround until then could be to detect and strip the negative sign, then apply it afterwards to the result.
We could handle this, now and remove it once it is fixed in nix. I'll leave this up to you, since this is not really related to the fix done in this PR.
Otherwise i'd merge as is.
|
We could easily support them in this function, but considering its input format is so unintentionally permissive to begin with, I’d rather focus on locking it down for now than expanding it. Not sure what Nix‐side fix you’re referring to? |
|
Successfully created backport PR for |
|
Opened #434218 to follow up on restricting the format here. |
This version changes the handling of TOML timestamps, and throws an error on out‐of‐range integer literals rather than the previous saturating behaviour, as required by [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]: <https://toml.io/en/v1.0.0#integer> The only known use of this is a questionable Nixpkgs test that I have proposed [a fix] for. [a fix]: <NixOS/nixpkgs#433710> Bumping this ahead of Nixpkgs ensures we can test these cases on HEAD in advance. I presume that the next Lix major version will be released after 25.05 goes out of support, so it should be fine to drop support for the old version of toml11. The co‐authors of this commit are the contributors to the vendored package definition from Nixpkgs. Co-authored-by: Anderson Torres <torres.anderson.85@protonmail.com> Co-authored-by: Artturin <Artturin@artturin.com> Co-authored-by: Silvan Mosberger <silvan.mosberger@moduscreate.com> Change-Id: I6a6a69644a188b6e09eee5c9cf91ddd3c81d24ee
This would have allowed us to catch to fromTOML regression in [1] without waiting for the dogfooding on master, since previously these tests [2] were not run for the Nix/Lix under test - only the host nix. [1]: NixOS/nix#13741 [2]: #433710 (cherry picked from commit 67ef265)
This would have allowed us to catch to fromTOML regression in [1] without waiting for the dogfooding on master, since previously these tests [2] were not run for the Nix/Lix under test - only the host nix. [1]: NixOS/nix#13741 [2]: NixOS/nixpkgs#433710 (cherry picked from commit 67ef2657ff6e3e8ece62a7a08b4231573a052a15)
This would have allowed us to catch to fromTOML regression in [1] without waiting for the dogfooding on master, since previously these tests [2] were not run for the Nix/Lix under test - only the host nix. [1]: NixOS/nix#13741 [2]: NixOS/nixpkgs#433710
This version changes the handling of TOML timestamps, and throws an error on out‐of‐range integer literals rather than the previous saturating behaviour, as required by [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]: <https://toml.io/en/v1.0.0#integer> The only known use of this is a questionable Nixpkgs test that I have proposed [a fix] for. [a fix]: <NixOS/nixpkgs#433710> Bumping this ahead of Nixpkgs ensures we can test these cases on HEAD in advance. I presume that the next Lix major version will be released after 25.05 goes out of support, so it should be fine to drop support for the old version of toml11. The co‐authors of this commit are the contributors to the vendored package definition from Nixpkgs. Co-authored-by: Anderson Torres <torres.anderson.85@protonmail.com> Co-authored-by: Artturin <Artturin@artturin.com> Co-authored-by: Silvan Mosberger <silvan.mosberger@moduscreate.com> Change-Id: I6a6a69644a188b6e09eee5c9cf91ddd3c81d24ee
fromHexStringis backed bybuiltins.fromTOML. Per 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.fromJSONto explicitly reject overflowing integer literals. I believe that the case forbuiltins.fromTOMLis 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.
Things done
passthru.tests.nixpkgs-reviewon this PR. See nixpkgs-review usage../result/bin/.Add a 👍 reaction to pull requests you find important.