1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-08 18:11:02 +01:00

JSON for Hash now has to be Base16

Fix #14532.

As discussed on the call today:

1. We'll stick with `format = "base16"` and `hash = "<hash>"`, not do
   `base16 = "<hash>"`, in order to be forward compatible with
   supporting more versioning formats.

   The motivation we discussed for someday *possibly* doing this is
   making it easier to write very slap-dash lang2nix tools that create
   (not consume) derivations with dynamic derivations.

2. We will remove support for non-base16 (and make that the default, not
   base64) in `Hash`, so this is strictly forward contingency, *not*
   yet something we support. (And also not something we have concrete
   plans to start supporting.)
This commit is contained in:
John Ericson 2025-11-10 16:07:28 -05:00
parent 5b95745bc9
commit bec3c5cfcd
36 changed files with 141 additions and 162 deletions

View file

@ -19,7 +19,7 @@ The store path info JSON format has been updated from version 1 to version 2:
Content address is now a structured JSON object instead of a string: Content address is now a structured JSON object instead of a string:
- Old: `"ca": "fixed:r:sha256:1abc..."` - Old: `"ca": "fixed:r:sha256:1abc..."`
- New: `"ca": {"method": "nar", "hash": {"algorithm": "sha256", "format": "base64", "hash": "EMIJ+giQ..."}}` - New: `"ca": {"method": "nar", "hash": {"algorithm": "sha256", "format": "base16", "hash": "10c209fa..."}}`
- Still `null` values for input-addressed store objects - Still `null` values for input-addressed store objects
- **Structured hash fields**: - **Structured hash fields**:
@ -27,8 +27,9 @@ The store path info JSON format has been updated from version 1 to version 2:
Hash values (`narHash` and `downloadHash`) are now structured JSON objects instead of strings: Hash values (`narHash` and `downloadHash`) are now structured JSON objects instead of strings:
- Old: `"narHash": "sha256:FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="` - Old: `"narHash": "sha256:FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="`
- New: `"narHash": {"algorithm": "sha256", "format": "base64", "hash": "FePFYIlM..."}` - New: `"narHash": {"algorithm": "sha256", "format": "base16", "hash": "15e3c5608946..."}`
- Same structure applies to `downloadHash` in NAR info contexts - Same structure applies to `downloadHash` in NAR info contexts
- The `format` field is always `"base16"` (hexadecimal)
Nix currently only produces, and doesn't consume this format. Nix currently only produces, and doesn't consume this format.
@ -48,8 +49,8 @@ The derivation JSON format has been updated from version 3 to version 4:
- **Consistent content addresses**: - **Consistent content addresses**:
Floating content-addressed outputs now use structured JSON format. Floating content-addressed outputs now use structured JSON format.
This is the same format as `ca` in in store path info (after the new version). 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. Version 3 and earlier formats are *not* accepted when reading.
**Affected command**: `nix derivation`, namely it's `show` and `add` sub-commands. **Affected command**: `nix derivation`, namely its `show` and `add` sub-commands.

View file

@ -2,28 +2,16 @@
## Examples ## Examples
### SHA-256 with Base64 encoding ### SHA-256
```json
{{#include schema/hash-v1/sha256-base64.json}}
```
### SHA-256 with Base16 (hexadecimal) encoding
```json ```json
{{#include schema/hash-v1/sha256-base16.json}} {{#include schema/hash-v1/sha256-base16.json}}
``` ```
### SHA-256 with Nix32 encoding ### BLAKE3
```json ```json
{{#include schema/hash-v1/sha256-nix32.json}} {{#include schema/hash-v1/blake3-base16.json}}
```
### BLAKE3 with Base64 encoding
```json
{{#include schema/hash-v1/blake3-base64.json}}
``` ```
<!-- need to convert YAML to JSON first <!-- need to convert YAML to JSON first

View file

@ -12,18 +12,14 @@ properties:
format: format:
type: string type: string
enum: enum:
- base64
- nix32
- base16 - base16
- sri
title: Hash format title: Hash format
description: | description: |
The encoding format of the hash value. The encoding format of the hash value.
- `base64` uses standard Base64 encoding [RFC 4648, section 4](https://datatracker.ietf.org/doc/html/rfc4648#section-4) `base16` (lowercase hexadecimal) is the only format that is currently supported for JSON serialization.
- `nix32` is Nix-specific base-32 encoding This field exists primarily to reduce ambiguity about what the hash means.
- `base16` is lowercase hexadecimal It would also help us support other formats in the future, but there are no concrete plans to do so at this.
- `sri` is the [Subresource Integrity format](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity).
hash: hash:
type: string type: string
title: Hash title: Hash

View file

@ -32,10 +32,8 @@ schemas = [
'stem' : 'hash', 'stem' : 'hash',
'schema' : schema_dir / 'hash-v1.yaml', 'schema' : schema_dir / 'hash-v1.yaml',
'files' : [ 'files' : [
'sha256-base64.json',
'sha256-base16.json', 'sha256-base16.json',
'sha256-nix32.json', 'blake3-base16.json',
'blake3-base64.json',
], ],
}, },
{ {

View file

@ -2,24 +2,24 @@
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "+Xc9Ll6mcPltwaewrk/BAQ56Y3G5T//wzhKUc0zrYu0=" "hash": "f9773d2e5ea670f96dc1a7b0ae4fc1010e7a6371b94ffff0ce1294734ceb62ed"
}, },
"method": "text" "method": "text"
}, },
{ {
"hash": { "hash": {
"algorithm": "sha1", "algorithm": "sha1",
"format": "base64", "format": "base16",
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo=" "hash": "8067a60687a7562359337862c2a9ecfc5833ab0a"
}, },
"method": "flat" "method": "flat"
}, },
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM=" "hash": "10c209fa0890fe02c85a8c663ca8e7a37cc766bc5b1b29a0cc61b266f64121d3"
}, },
"method": "nar" "method": "nar"
} }

View file

@ -3,8 +3,8 @@
{ {
"hash": { "hash": {
"algorithm": "sha1", "algorithm": "sha1",
"format": "base64", "format": "base16",
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo=" "hash": "8067a60687a7562359337862c2a9ecfc5833ab0a"
}, },
"method": "flat" "method": "flat"
} }

View file

@ -1,8 +1,8 @@
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "9vLqj0XYoFfJVmoz+ZR02i5camYE1zYSFlDicwxvsKM=" "hash": "f6f2ea8f45d8a057c9566a33f99474da2e5c6a6604d736121650e2730c6fb0a3"
}, },
"method": "nar" "method": "nar"
} }

View file

@ -1,8 +1,8 @@
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "8OTC92xYkW7CWPJGhRvqCR0U1CR6L8PhhpRGGxgW4Ts=" "hash": "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b"
}, },
"method": "text" "method": "text"
} }

View file

@ -1,8 +1,8 @@
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8=" "hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f"
}, },
"method": "flat" "method": "flat"
} }

View file

@ -1,8 +1,8 @@
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8=" "hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f"
}, },
"method": "nar" "method": "nar"
} }

View file

@ -1,8 +1,8 @@
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8=" "hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f"
}, },
"method": "text" "method": "text"
} }

View file

@ -14,16 +14,16 @@
"ca": { "ca": {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "f1eduuSIYC1BofXA1tycF79Ai2NSMJQtUErx5DxLYSU=" "hash": "7f579dbae488602d41a1f5c0d6dc9c17bf408b635230942d504af1e43c4b6125"
}, },
"method": "nar" "method": "nar"
}, },
"deriver": null, "deriver": null,
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "f1eduuSIYC1BofXA1tycF79Ai2NSMJQtUErx5DxLYSU=" "hash": "7f579dbae488602d41a1f5c0d6dc9c17bf408b635230942d504af1e43c4b6125"
}, },
"narSize": 120, "narSize": 120,
"references": [], "references": [],

View file

@ -2,8 +2,8 @@
"ca": { "ca": {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM=" "hash": "10c209fa0890fe02c85a8c663ca8e7a37cc766bc5b1b29a0cc61b266f64121d3"
}, },
"method": "nar" "method": "nar"
}, },
@ -11,14 +11,14 @@
"deriver": "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", "deriver": "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
"downloadHash": { "downloadHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"downloadSize": 4029176, "downloadSize": 4029176,
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"references": [ "references": [

View file

@ -2,15 +2,15 @@
"ca": { "ca": {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM=" "hash": "10c209fa0890fe02c85a8c663ca8e7a37cc766bc5b1b29a0cc61b266f64121d3"
}, },
"method": "nar" "method": "nar"
}, },
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"references": [ "references": [

View file

@ -3,8 +3,8 @@
"deriver": null, "deriver": null,
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 0, "narSize": 0,
"references": [], "references": [],

View file

@ -2,8 +2,8 @@
"ca": null, "ca": null,
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 0, "narSize": 0,
"references": [], "references": [],

View file

@ -2,16 +2,16 @@
"ca": { "ca": {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM=" "hash": "10c209fa0890fe02c85a8c663ca8e7a37cc766bc5b1b29a0cc61b266f64121d3"
}, },
"method": "nar" "method": "nar"
}, },
"deriver": "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", "deriver": "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"references": [ "references": [

View file

@ -2,15 +2,15 @@
"ca": { "ca": {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM=" "hash": "10c209fa0890fe02c85a8c663ca8e7a37cc766bc5b1b29a0cc61b266f64121d3"
}, },
"method": "nar" "method": "nar"
}, },
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"references": [ "references": [

View file

@ -2,24 +2,24 @@
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "+Xc9Ll6mcPltwaewrk/BAQ56Y3G5T//wzhKUc0zrYu0=" "hash": "f9773d2e5ea670f96dc1a7b0ae4fc1010e7a6371b94ffff0ce1294734ceb62ed"
}, },
"method": "text" "method": "text"
}, },
{ {
"hash": { "hash": {
"algorithm": "sha1", "algorithm": "sha1",
"format": "base64", "format": "base16",
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo=" "hash": "8067a60687a7562359337862c2a9ecfc5833ab0a"
}, },
"method": "flat" "method": "flat"
}, },
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM=" "hash": "10c209fa0890fe02c85a8c663ca8e7a37cc766bc5b1b29a0cc61b266f64121d3"
}, },
"method": "nar" "method": "nar"
} }

View file

@ -3,8 +3,8 @@
{ {
"hash": { "hash": {
"algorithm": "sha1", "algorithm": "sha1",
"format": "base64", "format": "base16",
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo=" "hash": "8067a60687a7562359337862c2a9ecfc5833ab0a"
}, },
"method": "flat" "method": "flat"
} }

View file

@ -4,8 +4,8 @@
"deriver": null, "deriver": null,
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" "hash": "0000000000000000000000000000000000000000000000000000000000000000"
}, },
"narSize": 34878, "narSize": 34878,
"references": [], "references": [],
@ -19,8 +19,8 @@
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", "deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" "hash": "0000000000000000000000000000000000000000000000000000000000000000"
}, },
"narSize": 34878, "narSize": 34878,
"references": [ "references": [

View file

@ -4,8 +4,8 @@
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", "deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"references": [ "references": [
@ -20,16 +20,16 @@
"ca": { "ca": {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM=" "hash": "10c209fa0890fe02c85a8c663ca8e7a37cc766bc5b1b29a0cc61b266f64121d3"
}, },
"method": "nar" "method": "nar"
}, },
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", "deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"references": [ "references": [

View file

@ -2,24 +2,24 @@
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "+Xc9Ll6mcPltwaewrk/BAQ56Y3G5T//wzhKUc0zrYu0=" "hash": "f9773d2e5ea670f96dc1a7b0ae4fc1010e7a6371b94ffff0ce1294734ceb62ed"
}, },
"method": "text" "method": "text"
}, },
{ {
"hash": { "hash": {
"algorithm": "sha1", "algorithm": "sha1",
"format": "base64", "format": "base16",
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo=" "hash": "8067a60687a7562359337862c2a9ecfc5833ab0a"
}, },
"method": "flat" "method": "flat"
}, },
{ {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM=" "hash": "10c209fa0890fe02c85a8c663ca8e7a37cc766bc5b1b29a0cc61b266f64121d3"
}, },
"method": "nar" "method": "nar"
} }

View file

@ -3,8 +3,8 @@
{ {
"hash": { "hash": {
"algorithm": "sha1", "algorithm": "sha1",
"format": "base64", "format": "base16",
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo=" "hash": "8067a60687a7562359337862c2a9ecfc5833ab0a"
}, },
"method": "flat" "method": "flat"
} }

View file

@ -4,8 +4,8 @@
"deriver": null, "deriver": null,
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"references": [], "references": [],
@ -19,8 +19,8 @@
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", "deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"references": [ "references": [

View file

@ -4,8 +4,8 @@
"deriver": null, "deriver": null,
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar", "path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
@ -20,8 +20,8 @@
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", "deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar", "path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",

View file

@ -4,8 +4,8 @@
"deriver": null, "deriver": null,
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar", "path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
@ -20,8 +20,8 @@
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", "deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar", "path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
@ -41,16 +41,16 @@
"ca": { "ca": {
"hash": { "hash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM=" "hash": "10c209fa0890fe02c85a8c663ca8e7a37cc766bc5b1b29a0cc61b266f64121d3"
}, },
"method": "nar" "method": "nar"
}, },
"deriver": null, "deriver": null,
"narHash": { "narHash": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=" "hash": "15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527"
}, },
"narSize": 34878, "narSize": 34878,
"path": "n5wkd9frr45pa74if5gpz9j7mifg27fh-foo", "path": "n5wkd9frr45pa74if5gpz9j7mifg27fh-foo",

View file

@ -0,0 +1,5 @@
{
"algorithm": "blake3",
"format": "base16",
"hash": "9e70ee1449965fb62d049040a1ed06ec377430da6ec13173e7c4fffcd28be980"
}

View file

@ -1,5 +0,0 @@
{
"algorithm": "blake3",
"format": "base64",
"hash": "nnDuFEmWX7YtBJBAoe0G7Dd0MNpuwTFz58T//NKL6YA="
}

View file

@ -1,5 +1,5 @@
{ {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base16", "format": "base16",
"hash": "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b" "hash": "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b"
} }

View file

@ -1,5 +1,5 @@
{ {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "8OTC92xYkW7CWPJGhRvqCR0U1CR6L8PhhpRGGxgW4Ts=" "hash": "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b"
} }

View file

@ -215,9 +215,7 @@ struct HashJsonTest : virtual HashTest,
::testing::WithParamInterface<std::pair<std::string_view, Hash>> ::testing::WithParamInterface<std::pair<std::string_view, Hash>>
{}; {};
struct HashJsonParseOnlyTest : virtual HashTest, struct HashJsonParseFailureTest : virtual HashTest, ::testing::WithParamInterface<std::string_view>
JsonCharacterizationTest<Hash>,
::testing::WithParamInterface<std::pair<std::string_view, Hash>>
{}; {};
struct BLAKE3HashJsonTest : virtual HashTest, struct BLAKE3HashJsonTest : virtual HashTest,
@ -238,10 +236,12 @@ TEST_P(HashJsonTest, to_json)
writeJsonTest(name, value); writeJsonTest(name, value);
} }
TEST_P(HashJsonParseOnlyTest, from_json) TEST_P(HashJsonParseFailureTest, from_json)
{ {
auto & [name, expected] = GetParam(); auto & name = GetParam();
readJsonTest(name, expected); auto path = goldenMaster(Path{name} + ".json");
auto encoded = json::parse(readFile(path));
ASSERT_THROW(nlohmann::adl_serializer<Hash>::from_json(encoded), Error);
} }
TEST_P(BLAKE3HashJsonTest, from_json) TEST_P(BLAKE3HashJsonTest, from_json)
@ -256,8 +256,8 @@ TEST_P(BLAKE3HashJsonTest, to_json)
writeJsonTest(name, expected); writeJsonTest(name, expected);
} }
// Round-trip tests (from_json + to_json) for base64 format only // Round-trip tests (from_json + to_json) for base16 format only
// (to_json always outputs base64) // (to_json always outputs base16)
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
HashJSON, HashJSON,
HashJsonTest, HashJsonTest,
@ -266,32 +266,22 @@ INSTANTIATE_TEST_SUITE_P(
"simple", "simple",
hashString(HashAlgorithm::SHA256, "asdf"), hashString(HashAlgorithm::SHA256, "asdf"),
}, },
std::pair{
"sha256-base64",
hashString(HashAlgorithm::SHA256, "asdf"),
}));
// Parse-only tests for non-base64 formats
// These verify C++ can deserialize other formats correctly
INSTANTIATE_TEST_SUITE_P(
HashJSONParseOnly,
HashJsonParseOnlyTest,
::testing::Values(
std::pair{ std::pair{
"sha256-base16", "sha256-base16",
hashString(HashAlgorithm::SHA256, "asdf"), hashString(HashAlgorithm::SHA256, "asdf"),
},
std::pair{
"sha256-nix32",
hashString(HashAlgorithm::SHA256, "asdf"),
})); }));
INSTANTIATE_TEST_SUITE_P(BLAKE3HashJSONParseOnly, BLAKE3HashJsonTest, ([] { // Failure tests for unsupported formats (base64, nix32, sri)
// These verify that non-base16 formats are rejected
INSTANTIATE_TEST_SUITE_P(
HashJSONParseFailure, HashJsonParseFailureTest, ::testing::Values("sha256-base64", "sha256-nix32"));
INSTANTIATE_TEST_SUITE_P(BLAKE3HashJSON, BLAKE3HashJsonTest, ([] {
ExperimentalFeatureSettings mockXpSettings; ExperimentalFeatureSettings mockXpSettings;
mockXpSettings.set("experimental-features", "blake3-hashes"); mockXpSettings.set("experimental-features", "blake3-hashes");
return ::testing::Values( return ::testing::Values(
std::pair{ std::pair{
"blake3-base64", "blake3-base16",
hashString(HashAlgorithm::BLAKE3, "asdf", mockXpSettings), hashString(HashAlgorithm::BLAKE3, "asdf", mockXpSettings),
}); });
}())); }()));

View file

@ -508,7 +508,14 @@ Hash adl_serializer<Hash>::from_json(const json & json, const ExperimentalFeatur
{ {
auto & obj = getObject(json); auto & obj = getObject(json);
auto algo = parseHashAlgo(getString(valueAt(obj, "algorithm")), xpSettings); auto algo = parseHashAlgo(getString(valueAt(obj, "algorithm")), xpSettings);
auto format = parseHashFormat(getString(valueAt(obj, "format"))); auto formatStr = getString(valueAt(obj, "format"));
auto format = parseHashFormat(formatStr);
// Only base16 format is supported for JSON serialization
if (format != HashFormat::Base16) {
throw Error("hash format '%s' is not supported in JSON; only 'base16' is currently supported", formatStr);
}
auto & hashS = getString(valueAt(obj, "hash")); auto & hashS = getString(valueAt(obj, "hash"));
return Hash::parseExplicitFormatUnprefixed(hashS, algo, format, xpSettings); return Hash::parseExplicitFormatUnprefixed(hashS, algo, format, xpSettings);
} }
@ -516,9 +523,9 @@ Hash adl_serializer<Hash>::from_json(const json & json, const ExperimentalFeatur
void adl_serializer<Hash>::to_json(json & json, const Hash & hash) void adl_serializer<Hash>::to_json(json & json, const Hash & hash)
{ {
json = { json = {
{"format", printHashFormat(HashFormat::Base64)}, {"format", printHashFormat(HashFormat::Base16)},
{"algorithm", printHashAlgo(hash.algo)}, {"algorithm", printHashAlgo(hash.algo)},
{"hash", hash.to_string(HashFormat::Base64, false)}, {"hash", hash.to_string(HashFormat::Base16, false)},
}; };
} }

View file

@ -15,13 +15,12 @@ nix-build fixed.nix -A bad --no-out-link && fail "should fail"
# a side-effect. # a side-effect.
[[ -e $path ]] [[ -e $path ]]
nix path-info --json "$path" | jq -e \ nix path-info --json "$path" | jq -e \
--arg hash "$(nix hash convert --to base64 "md5:8ddd8be4b179a529afa5f2ffae4b9858")" \
'.[].ca == { '.[].ca == {
method: "flat", method: "flat",
hash: { hash: {
algorithm: "md5", algorithm: "md5",
format: "base64", format: "base16",
hash: $hash hash: "8ddd8be4b179a529afa5f2ffae4b9858"
}, },
}' }'

View file

@ -49,12 +49,12 @@ try2 () {
nix path-info --json "$path" | jq -e \ nix path-info --json "$path" | jq -e \
--arg algo "$hashAlgo" \ --arg algo "$hashAlgo" \
--arg hash "$(nix hash convert --to base64 "$hashAlgo:$hashFromGit")" \ --arg hash "$hashFromGit" \
'.[].ca == { '.[].ca == {
method: "git", method: "git",
hash: { hash: {
algorithm: $algo, algorithm: $algo,
format: "base64", format: "base16",
hash: $hash hash: $hash
}, },
}' }'

View file

@ -19,13 +19,13 @@ diff --unified --color=always \
{ {
"$foo": { "$foo": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "QvtAMbUl/uvi+LCObmqOhvNOapHdA2raiI4xG5zI5pA=" "hash": "42fb4031b525feebe2f8b08e6e6a8e86f34e6a91dd036ada888e311b9cc8e690"
}, },
"$bar": { "$bar": {
"algorithm": "sha256", "algorithm": "sha256",
"format": "base64", "format": "base16",
"hash": "9fhYGu9fqxcQC2Kc81qh2RMo1QcLBUBo8U+pPn+jthQ=" "hash": "f5f8581aef5fab17100b629cf35aa1d91328d5070b054068f14fa93e7fa3b614"
}, },
"$baz": null "$baz": null
} }