Commit Graph
13 Commits
Author SHA1 Message Date
Emily 86303ffb05 libexpr: treat too‐large unsigned JSON integers as floats
JSON has only one numeric type, with vague semantics. [RFC 8259] says:

> This specification allows implementations to set limits on the range
> and precision of numbers accepted.  Since software that implements
> IEEE 754 binary64 (double precision) numbers [IEEE754] is generally
> available and widely used, good interoperability can be achieved by
> implementations that expect no more precision or range than these
> provide, in the sense that implementations will approximate JSON
> numbers within the expected precision.  A JSON number such as 1E400
> or 3.141592653589793238462643383279 may indicate potential
> interoperability problems, since it suggests that the software that
> created it expects receiving software to have greater capabilities
> for numeric magnitude and precision than is widely available.
>
> Note that when such software is used, numbers that are integers and
> are in the range [-(2**53)+1, (2**53)-1] are interoperable in the
> sense that implementations will agree exactly on their numeric
> values.

[RFC 8259]: <https://www.rfc-editor.org/rfc/rfc8259.html#section-6>

Floating‐point numbers are annoying to deal with in Nix, so it
optimistically parses integer‐looking literals as Nix‐language
integers where possible. Nixpkgs relies on this behaviour, as it backs
its `lib.toInt` family of functions with `builtins.fromJSON` in lieu
of a real integer‐parsing built‐in, and treats floating‐point
outputs as an error. Therefore, dealing with integer‐looking
JSON number literals that are outside the interoperable range is
unavoidable.

However, this raises the question of how literals that look
like integers, but exceed the range of a Nix‐language integer,
should be handled. The JSON library we use attempts to represent
integer‐looking literals as a unsigned or signed C++ integer type
before falling back to floating‐point numbers.

This means that we were parsing literals below −2⁶³ as
floating‐point numbers, while rejecting ones above (2⁶³ + 1)
with an error. This was done to avoid the C++ undefined behaviour in
the previous code path, but is hard to justify. This change causes
them to both be parsed as floating‐point numbers.

The alternative would be to reject the signed case too. However,
I believe that is less consistent with how JSON handles its single
numeric type, less interoperable with JSON documents found in the wild,
and that it is preferable to avoid the function being needlessly
partial in this case. It does mean that round‐tripping is less
lossless than before, but extreme floating‐point values already
caused these kinds of issues, and from JSON’s point of view that’s
exactly what these literals represent. Only numeric values outside the
RFC’s suggested interoperable range will have any round‐tripping
issues, and we continue to guarantee the behaviour on all values that
can be represented as Nix‐language integers.

Change-Id: I6a6a696412383e8a2cc160397716cb7f7bc7a2d4
2025-08-15 23:46:14 +01:00
Emily c586596a9f libexpr: format fromTOML source
Otherwise the next diff becomes very messy.

Change-Id: I6a6a6964d96543ade130d491f413ebd9fe2b7ff1
2025-08-15 01:11:52 +01:00
Emily d84bc45e17 tests/functional2/lang: add test for underflowing JSON number literal
Change-Id: I6a6a6964c49a82244f7c0062c27ec9a5feadd910
2025-08-15 00:19:25 +01:00
EmilyandPhilipp Otterbein 860984be27 tests/functional2/lang: add tests for NUL bytes in JSON and TOML
Based on the tests in the upstream PR.

Co-authored-by: Philipp Otterbein <potterbein@blockstream.com>
Upstream-PR: https://github.com/NixOS/nix/pull/12024
Change-Id: I6a6a69643ae9bd2445e551013d09e64ac1fe9916
2025-08-14 22:19:29 +01:00
Emily 5359ab9a76 doc: update emilazy in change-authors
Change-Id: I6a6a6964bf752f27fde54d3bb3f94afdae4fe139
2025-08-14 19:56:18 +01:00
Emily 52872026fb packaging: actually run install checks
`mesonCheckPhase` of course runs `preCheck` and `postCheck` hooks,
not `preInstallCheck`, so this was not doing the right thing. Really
sorry for breaking CI :(

Fixes: e6da29ad6b
Change-Id: I6a6a69642a242e2c8bfe10ac61d3f6756d666548
2025-08-01 18:17:47 +01:00
Emily 93acdd40f6 packaging: remove redundant apple-sdk_11
This is now the default in all supported Nixpkgs versions.

Change-Id: I6a6a69642951c2e1ae117d8360b450cc9fdc741b
2025-07-29 20:45:58 +01:00
Emily 99cf661187 packaging: remove redundant --print-errorlogs
These were added to Nixpkgs in
4dec85d68b81ed971e7f2953cfea895f0f0c0c2c, back in 2024.

Change-Id: I6a6a69646f6a09fb3d8bae3efbf9d6e56d662ca3
2025-07-29 20:45:58 +01:00
Emily e6da29ad6b packaging: use the upstream mesonCheckPhase for installCheckPhase
This gets us `--print-errorlogs` and `--timeout-multiplier=0` for free,
and also fixes the concatenation logic with `__structuredAttrs`.

Change-Id: I6a6a69643ea7224cb24508505c554143f83ae243
2025-07-29 20:45:58 +01:00
Emily d1db3e5fa3 libstore: fix Unix sockets in the build directory on sandboxed macOS
We’re already allowing `/tmp` anyway, so this should be harmless,
and it fixes a regression in the default configuration caused by
moving the build directories out of `temp-dir`. (For instance, that
broke the Lix `guessOrInventPath.sockets` test.)

Note that removing `/tmp` breaks quite a few builds, so although it may
be a good idea in general it would require work on the Nixpkgs side.

Fixes: 749afbbe99
Change-Id: I6a6a69645f429bc50d4cb24283feda3d3091f534
2025-06-29 13:18:00 +01:00
Emily e1ccbe9abd daemon: prefer daemon stores for nix-daemon --stdio
Using `AllowDaemon::Disallow` here broke `ssh-ng://` remote builds in
multi‐user setups where the remote builder user does not have write
access to the store, now that the automatic store selection logic
has changed. Switch to the default behaviour for this path to fix that.

This causes `ssh-ng://` builds to use the daemon by default on the
remote end, even as `root`. I think this is desirable, as the previous
change already made `ssh://` behave this way, and the pitfalls of
local stores apply to remote builds too. For instance, there were
persistent `ulimit` issues on the NixOS Hydra macOS builders that were
resolved by forcing use of the daemon, and I believe the Linux builders
also go through the daemon these days due to using non‐`root` SSH
users. I believe that the `root` vs. non‐`root` difference is just
as confusing for remote builds as it is for local ones.

`ssh-ng://root@builder?remote-store=local` can be used to revert back
to the previous default if necessary.

Closes: #884
Fixes: 9a59106c17
Change-Id: I6a6a696410f46cd3f2f5a94073ea924ad45dc99c
2025-06-29 01:14:07 +01:00
Emily b395831510 libstore: expose the allowDaemon parameter of openStore()
This allows other functions to parameterize over it themselves. An
enum class is used to avoid API misuse.

Change-Id: I6a6a6964d2b5ad47ae5ea9eb11af9b6373ce2141
2025-06-29 01:13:48 +01:00
Emily 3cfce7b37e tests: add test for bug with remote builds as non‐root user
Change-Id: I6a6a696420847c1f47f79269be6b63108ab63afa
2025-06-28 22:15:26 +01:00