authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-26 04:01:28-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-26 11:42:04-08:00
logde43f5eb6ae4a569efe15e3469b3de76a86d9cd1
treedca7d9277507de70c93ec5f7fc95425995231e59
parent67904e925d2b33c48dda3d4ddaf158328964dc2e

rename "nonce" to "fingerprint"


7 files changed, 38 insertions(+), 38 deletions(-)

build.zig.zon+1-1
......@@ -12,5 +12,5 @@
1212 },
1313 },
1414 .paths = .{""},
15 .nonce = 0xc1ce108124179e16,
15 .fingerprint = 0xc1ce108124179e16,
1616}
doc/build.zig.zon.md+5-5
......@@ -22,24 +22,24 @@ Zig package namespace.
2222
2323Must be a valid bare Zig identifier (don't `@` me), limited to 32 bytes.
2424
25Together with `nonce`, this represents a globally unique package identifier.
25Together with `fingerprint`, this represents a globally unique package identifier.
2626
27### `nonce`
27### `fingerprint`
2828
2929Together with `name`, this represents a globally unique package identifier. This
3030field is auto-initialized by the toolchain when the package is first created,
3131and then *never changes*. This allows Zig to unambiguously detect when one
3232package is an updated version of another.
3333
34When forking a Zig project, this nonce should be regenerated if the upstream
34When forking a Zig project, this fingerprint should be regenerated if the upstream
3535project is still maintained. Otherwise, the fork is *hostile*, attempting to
36take control over the original project's identity. The nonce can be regenerated
36take control over the original project's identity. The fingerprint can be regenerated
3737by deleting the field and running `zig build`.
3838
3939This 64-bit integer is the combination of a 32-bit id component and a 32-bit
4040checksum.
4141
42The id component within the nonce has these restrictions:
42The id component within the fingerprint has these restrictions:
4343
4444`0x00000000` is reserved for legacy packages.
4545
lib/init/build.zig.zon+1-1
......@@ -24,7 +24,7 @@
2424 // original project's identity. Thus it is recommended to leave the comment
2525 // on the following line intact, so that it shows up in code reviews that
2626 // modify the field.
27 .nonce = .NONCE, // Changing this has security and trust implications.
27 .fingerprint = .FINGERPRINT, // Changing this has security and trust implications.
2828
2929 // Tracks the earliest Zig version that the package considers to be a
3030 // supported use case.
src/Package.zig+4-4
......@@ -10,25 +10,25 @@ pub const multihash_len = 1 + 1 + Hash.Algo.digest_length;
1010pub const multihash_hex_digest_len = 2 * multihash_len;
1111pub const MultiHashHexDigest = [multihash_hex_digest_len]u8;
1212
13pub const Nonce = packed struct(u64) {
13pub const Fingerprint = packed struct(u64) {
1414 id: u32,
1515 checksum: u32,
1616
17 pub fn generate(name: []const u8) Nonce {
17 pub fn generate(name: []const u8) Fingerprint {
1818 return .{
1919 .id = std.crypto.random.intRangeLessThan(u32, 1, 0xffffffff),
2020 .checksum = std.hash.Crc32.hash(name),
2121 };
2222 }
2323
24 pub fn validate(n: Nonce, name: []const u8) bool {
24 pub fn validate(n: Fingerprint, name: []const u8) bool {
2525 switch (n.id) {
2626 0x00000000, 0xffffffff => return false,
2727 else => return std.hash.Crc32.hash(name) == n.checksum,
2828 }
2929 }
3030
31 pub fn int(n: Nonce) u64 {
31 pub fn int(n: Fingerprint) u64 {
3232 return @bitCast(n);
3333 }
3434};
src/Package/Fetch.zig+4-4
......@@ -44,7 +44,7 @@ omit_missing_hash_error: bool,
4444/// which specifies inclusion rules. This is intended to be true for the first
4545/// fetch task and false for the recursive dependencies.
4646allow_missing_paths_field: bool,
47allow_missing_nonce: bool,
47allow_missing_fingerprint: bool,
4848allow_name_string: bool,
4949/// If true and URL points to a Git repository, will use the latest commit.
5050use_latest_commit: bool,
......@@ -649,7 +649,7 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void {
649649
650650 f.manifest = try Manifest.parse(arena, ast.*, .{
651651 .allow_missing_paths_field = f.allow_missing_paths_field,
652 .allow_missing_nonce = f.allow_missing_nonce,
652 .allow_missing_fingerprint = f.allow_missing_fingerprint,
653653 .allow_name_string = f.allow_name_string,
654654 });
655655 const manifest = &f.manifest.?;
......@@ -752,7 +752,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
752752 .job_queue = f.job_queue,
753753 .omit_missing_hash_error = false,
754754 .allow_missing_paths_field = true,
755 .allow_missing_nonce = true,
755 .allow_missing_fingerprint = true,
756756 .allow_name_string = true,
757757 .use_latest_commit = false,
758758
......@@ -2323,7 +2323,7 @@ const TestFetchBuilder = struct {
23232323 .job_queue = &self.job_queue,
23242324 .omit_missing_hash_error = true,
23252325 .allow_missing_paths_field = false,
2326 .allow_missing_nonce = true, // so we can keep using the old testdata .tar.gz
2326 .allow_missing_fingerprint = true, // so we can keep using the old testdata .tar.gz
23272327 .allow_name_string = true, // so we can keep using the old testdata .tar.gz
23282328 .use_latest_commit = true,
23292329
src/Package/Manifest.zig+13-13
......@@ -52,7 +52,7 @@ pub const ParseOptions = struct {
5252 /// Deprecated, to be removed after 0.14.0 is tagged.
5353 allow_name_string: bool = true,
5454 /// Deprecated, to be removed after 0.14.0 is tagged.
55 allow_missing_nonce: bool = true,
55 allow_missing_fingerprint: bool = true,
5656};
5757
5858pub const Error = Allocator.Error;
......@@ -81,7 +81,7 @@ pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest {
8181 .paths = .{},
8282 .allow_missing_paths_field = options.allow_missing_paths_field,
8383 .allow_name_string = options.allow_name_string,
84 .allow_missing_nonce = options.allow_missing_nonce,
84 .allow_missing_fingerprint = options.allow_missing_fingerprint,
8585 .minimum_zig_version = null,
8686 .buf = .{},
8787 };
......@@ -157,7 +157,7 @@ const Parse = struct {
157157 paths: std.StringArrayHashMapUnmanaged(void),
158158 allow_missing_paths_field: bool,
159159 allow_name_string: bool,
160 allow_missing_nonce: bool,
160 allow_missing_fingerprint: bool,
161161 minimum_zig_version: ?std.SemanticVersion,
162162
163163 const InnerError = error{ ParseFailure, OutOfMemory };
......@@ -175,7 +175,7 @@ const Parse = struct {
175175 var have_name = false;
176176 var have_version = false;
177177 var have_included_paths = false;
178 var nonce: ?Package.Nonce = null;
178 var fingerprint: ?Package.Fingerprint = null;
179179
180180 for (struct_init.ast.fields) |field_init| {
181181 const name_token = ast.firstToken(field_init) - 2;
......@@ -192,8 +192,8 @@ const Parse = struct {
192192 } else if (mem.eql(u8, field_name, "name")) {
193193 p.name = try parseName(p, field_init);
194194 have_name = true;
195 } else if (mem.eql(u8, field_name, "nonce")) {
196 nonce = try parseNonce(p, field_init);
195 } else if (mem.eql(u8, field_name, "fingerprint")) {
196 fingerprint = try parseFingerprint(p, field_init);
197197 } else if (mem.eql(u8, field_name, "version")) {
198198 p.version_node = field_init;
199199 const version_text = try parseString(p, field_init);
......@@ -220,16 +220,16 @@ const Parse = struct {
220220 if (!have_name) {
221221 try appendError(p, main_token, "missing top-level 'name' field", .{});
222222 } else {
223 if (nonce) |n| {
223 if (fingerprint) |n| {
224224 if (!n.validate(p.name)) {
225 return fail(p, main_token, "invalid nonce: 0x{x}; if this is a new or forked package, use this value: 0x{x}", .{
226 n.int(), Package.Nonce.generate(p.name).int(),
225 return fail(p, main_token, "invalid fingerprint: 0x{x}; if this is a new or forked package, use this value: 0x{x}", .{
226 n.int(), Package.Fingerprint.generate(p.name).int(),
227227 });
228228 }
229229 p.id = n.id;
230 } else if (!p.allow_missing_nonce) {
231 try appendError(p, main_token, "missing top-level 'nonce' field; suggested value: 0x{x}", .{
232 Package.Nonce.generate(p.name).int(),
230 } else if (!p.allow_missing_fingerprint) {
231 try appendError(p, main_token, "missing top-level 'fingerprint' field; suggested value: 0x{x}", .{
232 Package.Fingerprint.generate(p.name).int(),
233233 });
234234 } else {
235235 p.id = 0;
......@@ -385,7 +385,7 @@ const Parse = struct {
385385 }
386386 }
387387
388 fn parseNonce(p: *Parse, node: Ast.Node.Index) !Package.Nonce {
388 fn parseFingerprint(p: *Parse, node: Ast.Node.Index) !Package.Fingerprint {
389389 const ast = p.ast;
390390 const node_tags = ast.nodes.items(.tag);
391391 const main_tokens = ast.nodes.items(.main_token);
src/main.zig+10-10
......@@ -4752,10 +4752,10 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
47524752 };
47534753 var ok_count: usize = 0;
47544754
4755 const nonce: Package.Nonce = .generate(sanitized_root_name);
4755 const fingerprint: Package.Fingerprint = .generate(sanitized_root_name);
47564756
47574757 for (template_paths) |template_path| {
4758 if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, nonce)) |_| {
4758 if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, fingerprint)) |_| {
47594759 std.log.info("created {s}", .{template_path});
47604760 ok_count += 1;
47614761 } else |err| switch (err) {
......@@ -5225,7 +5225,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
52255225 .job_queue = &job_queue,
52265226 .omit_missing_hash_error = true,
52275227 .allow_missing_paths_field = false,
5228 .allow_missing_nonce = false,
5228 .allow_missing_fingerprint = false,
52295229 .allow_name_string = false,
52305230 .use_latest_commit = false,
52315231
......@@ -7127,7 +7127,7 @@ fn cmdFetch(
71277127 .job_queue = &job_queue,
71287128 .omit_missing_hash_error = true,
71297129 .allow_missing_paths_field = false,
7130 .allow_missing_nonce = true,
7130 .allow_missing_fingerprint = true,
71317131 .allow_name_string = true,
71327132 .use_latest_commit = true,
71337133
......@@ -7468,10 +7468,10 @@ fn loadManifest(
74687468 0,
74697469 ) catch |err| switch (err) {
74707470 error.FileNotFound => {
7471 const nonce: Package.Nonce = .generate(options.root_name);
7471 const fingerprint: Package.Fingerprint = .generate(options.root_name);
74727472 var templates = findTemplates(gpa, arena);
74737473 defer templates.deinit();
7474 templates.write(arena, options.dir, options.root_name, Package.Manifest.basename, nonce) catch |e| {
7474 templates.write(arena, options.dir, options.root_name, Package.Manifest.basename, fingerprint) catch |e| {
74757475 fatal("unable to write {s}: {s}", .{
74767476 Package.Manifest.basename, @errorName(e),
74777477 });
......@@ -7529,7 +7529,7 @@ const Templates = struct {
75297529 out_dir: fs.Dir,
75307530 root_name: []const u8,
75317531 template_path: []const u8,
7532 nonce: Package.Nonce,
7532 fingerprint: Package.Fingerprint,
75337533 ) !void {
75347534 if (fs.path.dirname(template_path)) |dirname| {
75357535 out_dir.makePath(dirname) catch |err| {
......@@ -7555,9 +7555,9 @@ const Templates = struct {
75557555 try templates.buffer.appendSlice(root_name);
75567556 i += ".NAME".len;
75577557 continue;
7558 } else if (std.mem.startsWith(u8, contents[i..], ".NONCE")) {
7559 try templates.buffer.writer().print("0x{x}", .{nonce.int()});
7560 i += ".NONCE".len;
7558 } else if (std.mem.startsWith(u8, contents[i..], ".FINGERPRINT")) {
7559 try templates.buffer.writer().print("0x{x}", .{fingerprint.int()});
7560 i += ".FINGERPRINT".len;
75617561 continue;
75627562 } else if (std.mem.startsWith(u8, contents[i..], ".ZIGVER")) {
75637563 try templates.buffer.appendSlice(build_options.version);