From 14feb36cd6c27124f617efe750a790a751f00ae4 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 8 Dec 2025 15:38:48 -0500 Subject: [PATCH 1/3] `Hash::parseSRI` add explicit XP settings parameter This will be used for unit testing. --- src/libutil/hash.cc | 6 +++--- src/libutil/include/nix/util/hash.hh | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index d051225a7..b5d503940 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -164,7 +164,7 @@ static Hash parseLowLevel( return res; } -Hash Hash::parseSRI(std::string_view original) +Hash Hash::parseSRI(std::string_view original, const ExperimentalFeatureSettings & xpSettings) { auto rest = original; @@ -172,9 +172,9 @@ Hash Hash::parseSRI(std::string_view original) auto hashRaw = splitPrefixTo(rest, '-'); if (!hashRaw) throw BadHash("hash '%s' is not SRI", original); - HashAlgorithm parsedType = parseHashAlgo(*hashRaw); + HashAlgorithm parsedType = parseHashAlgo(*hashRaw, xpSettings); - return parseLowLevel(rest, parsedType, {base64::decode, "SRI"}); + return parseLowLevel(rest, parsedType, {base64::decode, "SRI"}, xpSettings); } /** diff --git a/src/libutil/include/nix/util/hash.hh b/src/libutil/include/nix/util/hash.hh index 199a9dd49..54b705105 100644 --- a/src/libutil/include/nix/util/hash.hh +++ b/src/libutil/include/nix/util/hash.hh @@ -110,7 +110,8 @@ struct Hash HashFormat explicitFormat, const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings); - static Hash parseSRI(std::string_view original); + static Hash + parseSRI(std::string_view original, const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings); public: /** From 401e08f839f9b109cf3aca6468735391ed45599e Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 8 Dec 2025 16:06:38 -0500 Subject: [PATCH 2/3] Fix mistake in the release note for derivations Floating CA outputs just have a hash algorith, not a whole hash. It is fixed ones which are a pair of a method and a hash, just like the `ca` field of store object info. --- doc/manual/rl-next/json-format-changes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/manual/rl-next/json-format-changes.md b/doc/manual/rl-next/json-format-changes.md index b5254d236..e264daf04 100644 --- a/doc/manual/rl-next/json-format-changes.md +++ b/doc/manual/rl-next/json-format-changes.md @@ -87,7 +87,7 @@ The derivation JSON format has been updated from version 3 to version 4: - **Consistent content addresses**: - Floating content-addressed outputs now use structured JSON format. + Fixed content-addressed outputs now use structured JSON format. This is the same format as `ca` in store path info (after the new version). Version 3 and earlier formats are *not* accepted when reading. From 61de9222b029ab4e9b8ad8697945371ddd6cd855 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 8 Dec 2025 15:34:15 -0500 Subject: [PATCH 3/3] Use SRI hash (strings) as the official JSON format for Hash after all The fact that we were introducing a conversion from the output of `nix path-info` into the input of `builtins.fetchTree` was the deciding factor. We want scripting outputs into inputs like that to be easy. Since JSON strings and objects are trivially distinguishable, we still have the option of introducing the JSON format as an alternative input scheme in the future, should we want to. (The output format would still be SRI in that case, presumably.) --- doc/manual/rl-next/json-format-changes.md | 11 ++---- doc/manual/source/protocols/json/hash.md | 4 +-- .../source/protocols/json/schema/hash-v1.yaml | 35 ++++--------------- src/json-schema-checks/meson.build | 4 +-- .../data/common-protocol/content-address.json | 18 ++-------- .../optional-content-address.json | 6 +--- .../data/content-address/nar.json | 6 +--- .../data/content-address/text.json | 6 +--- .../data/derivation/output-caFixedFlat.json | 6 +--- .../data/derivation/output-caFixedNAR.json | 6 +--- .../data/derivation/output-caFixedText.json | 6 +--- .../data/dummy-store/one-flat-file.json | 12 ++----- .../data/nar-info/json-2/impure.json | 18 ++-------- .../data/nar-info/json-2/pure.json | 12 ++----- .../data/path-info/json-2/empty_impure.json | 6 +--- .../data/path-info/json-2/empty_pure.json | 6 +--- .../data/path-info/json-2/impure.json | 12 ++----- .../data/path-info/json-2/pure.json | 12 ++----- .../data/serve-protocol/content-address.json | 18 ++-------- .../optional-content-address.json | 6 +--- .../unkeyed-valid-path-info-2.3.json | 12 ++----- .../unkeyed-valid-path-info-2.4.json | 18 ++-------- .../data/worker-protocol/content-address.json | 18 ++-------- .../optional-content-address.json | 6 +--- .../unkeyed-valid-path-info-1.15.json | 12 ++----- .../worker-protocol/valid-path-info-1.15.json | 12 ++----- .../worker-protocol/valid-path-info-1.16.json | 24 +++---------- .../data/hash/blake3-base16.json | 5 --- src/libutil-tests/data/hash/blake3.json | 1 + .../data/hash/sha256-base16.json | 5 --- .../data/hash/sha256-base64.json | 5 --- src/libutil-tests/data/hash/sha256-nix32.json | 5 --- src/libutil-tests/data/hash/sha256.json | 1 + src/libutil-tests/data/hash/sha512.json | 1 + src/libutil-tests/data/hash/simple.json | 5 --- src/libutil-tests/hash.cc | 24 ++----------- src/libutil/hash.cc | 20 ++--------- tests/functional/fixed.sh | 6 +--- tests/functional/git-hashing/simple-common.sh | 13 ++++--- tests/functional/impure-derivations.sh | 2 +- tests/functional/nix-profile.sh | 2 +- tests/functional/path-info.sh | 12 ++----- tests/functional/signing.sh | 2 +- tests/nixos/fetchers-substitute.nix | 5 ++- 44 files changed, 78 insertions(+), 348 deletions(-) delete mode 100644 src/libutil-tests/data/hash/blake3-base16.json create mode 100644 src/libutil-tests/data/hash/blake3.json delete mode 100644 src/libutil-tests/data/hash/sha256-base16.json delete mode 100644 src/libutil-tests/data/hash/sha256-base64.json delete mode 100644 src/libutil-tests/data/hash/sha256-nix32.json create mode 100644 src/libutil-tests/data/hash/sha256.json create mode 100644 src/libutil-tests/data/hash/sha512.json delete mode 100644 src/libutil-tests/data/hash/simple.json diff --git a/doc/manual/rl-next/json-format-changes.md b/doc/manual/rl-next/json-format-changes.md index e264daf04..78e543512 100644 --- a/doc/manual/rl-next/json-format-changes.md +++ b/doc/manual/rl-next/json-format-changes.md @@ -49,17 +49,10 @@ The new structured format follows the [JSON guidelines](@docroot@/development/js Content address is now a structured JSON object instead of a string: - Old: `"ca": "fixed:r:sha256:1abc..."` - - New: `"ca": {"method": "nar", "hash": {"algorithm": "sha256", "format": "base16", "hash": "10c209fa..."}}` + - New: `"ca": {"method": "nar", "hash": "sha256-ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0="}` - Still `null` values for input-addressed store objects -- **Structured hash fields**: - - Hash values (`narHash` and `downloadHash`) are now structured JSON objects instead of strings: - - - Old: `"narHash": "sha256:FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="` - - New: `"narHash": {"algorithm": "sha256", "format": "base16", "hash": "15e3c5608946..."}` - - Same structure applies to `downloadHash` in NAR info contexts - - The `format` field is always `"base16"` (hexadecimal) + The `hash` field uses the [SRI](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) format like other hashes. Nix currently only produces, and doesn't consume this format. diff --git a/doc/manual/source/protocols/json/hash.md b/doc/manual/source/protocols/json/hash.md index f2af5303f..3ecff4da0 100644 --- a/doc/manual/source/protocols/json/hash.md +++ b/doc/manual/source/protocols/json/hash.md @@ -5,13 +5,13 @@ ### SHA-256 ```json -{{#include schema/hash-v1/sha256-base16.json}} +{{#include schema/hash-v1/sha256.json}} ``` ### BLAKE3 ```json -{{#include schema/hash-v1/blake3-base16.json}} +{{#include schema/hash-v1/blake3.json}} ```