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 @@...@@ -12,5 +12,5 @@
12 },12 },
13 },13 },
14 .paths = .{""},14 .paths = .{""},
15 .nonce = 0xc1ce108124179e16,15 .fingerprint = 0xc1ce108124179e16,
16}16}
doc/build.zig.zon.md+5-5
...@@ -22,24 +22,24 @@ Zig package namespace....@@ -22,24 +22,24 @@ Zig package namespace.
2222
23Must be a valid bare Zig identifier (don't `@` me), limited to 32 bytes.23Must 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
29Together with `name`, this represents a globally unique package identifier. This29Together with `name`, this represents a globally unique package identifier. This
30field is auto-initialized by the toolchain when the package is first created,30field is auto-initialized by the toolchain when the package is first created,
31and then *never changes*. This allows Zig to unambiguously detect when one31and then *never changes*. This allows Zig to unambiguously detect when one
32package is an updated version of another.32package is an updated version of another.
3333
34When forking a Zig project, this nonce should be regenerated if the upstream34When forking a Zig project, this fingerprint should be regenerated if the upstream
35project is still maintained. Otherwise, the fork is *hostile*, attempting to35project is still maintained. Otherwise, the fork is *hostile*, attempting to
36take control over the original project's identity. The nonce can be regenerated36take control over the original project's identity. The fingerprint can be regenerated
37by deleting the field and running `zig build`.37by deleting the field and running `zig build`.
3838
39This 64-bit integer is the combination of a 32-bit id component and a 32-bit39This 64-bit integer is the combination of a 32-bit id component and a 32-bit
40checksum.40checksum.
4141
42The id component within the nonce has these restrictions:42The id component within the fingerprint has these restrictions:
4343
44`0x00000000` is reserved for legacy packages.44`0x00000000` is reserved for legacy packages.
4545
lib/init/build.zig.zon+1-1
...@@ -24,7 +24,7 @@...@@ -24,7 +24,7 @@
24 // original project's identity. Thus it is recommended to leave the comment24 // original project's identity. Thus it is recommended to leave the comment
25 // on the following line intact, so that it shows up in code reviews that25 // on the following line intact, so that it shows up in code reviews that
26 // modify the field.26 // modify the field.
27 .nonce = .NONCE, // Changing this has security and trust implications.27 .fingerprint = .FINGERPRINT, // Changing this has security and trust implications.
2828
29 // Tracks the earliest Zig version that the package considers to be a29 // Tracks the earliest Zig version that the package considers to be a
30 // supported use case.30 // supported use case.
src/Package.zig+4-4
...@@ -10,25 +10,25 @@ pub const multihash_len = 1 + 1 + Hash.Algo.digest_length;...@@ -10,25 +10,25 @@ pub const multihash_len = 1 + 1 + Hash.Algo.digest_length;
10pub const multihash_hex_digest_len = 2 * multihash_len;10pub const multihash_hex_digest_len = 2 * multihash_len;
11pub const MultiHashHexDigest = [multihash_hex_digest_len]u8;11pub const MultiHashHexDigest = [multihash_hex_digest_len]u8;
1212
13pub const Nonce = packed struct(u64) {13pub const Fingerprint = packed struct(u64) {
14 id: u32,14 id: u32,
15 checksum: u32,15 checksum: u32,
1616
17 pub fn generate(name: []const u8) Nonce {17 pub fn generate(name: []const u8) Fingerprint {
18 return .{18 return .{
19 .id = std.crypto.random.intRangeLessThan(u32, 1, 0xffffffff),19 .id = std.crypto.random.intRangeLessThan(u32, 1, 0xffffffff),
20 .checksum = std.hash.Crc32.hash(name),20 .checksum = std.hash.Crc32.hash(name),
21 };21 };
22 }22 }
2323
24 pub fn validate(n: Nonce, name: []const u8) bool {24 pub fn validate(n: Fingerprint, name: []const u8) bool {
25 switch (n.id) {25 switch (n.id) {
26 0x00000000, 0xffffffff => return false,26 0x00000000, 0xffffffff => return false,
27 else => return std.hash.Crc32.hash(name) == n.checksum,27 else => return std.hash.Crc32.hash(name) == n.checksum,
28 }28 }
29 }29 }
3030
31 pub fn int(n: Nonce) u64 {31 pub fn int(n: Fingerprint) u64 {
32 return @bitCast(n);32 return @bitCast(n);
33 }33 }
34};34};
src/Package/Fetch.zig+4-4
...@@ -44,7 +44,7 @@ omit_missing_hash_error: bool,...@@ -44,7 +44,7 @@ omit_missing_hash_error: bool,
44/// which specifies inclusion rules. This is intended to be true for the first44/// which specifies inclusion rules. This is intended to be true for the first
45/// fetch task and false for the recursive dependencies.45/// fetch task and false for the recursive dependencies.
46allow_missing_paths_field: bool,46allow_missing_paths_field: bool,
47allow_missing_nonce: bool,47allow_missing_fingerprint: bool,
48allow_name_string: bool,48allow_name_string: bool,
49/// If true and URL points to a Git repository, will use the latest commit.49/// If true and URL points to a Git repository, will use the latest commit.
50use_latest_commit: bool,50use_latest_commit: bool,
...@@ -649,7 +649,7 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void {...@@ -649,7 +649,7 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void {
649649
650 f.manifest = try Manifest.parse(arena, ast.*, .{650 f.manifest = try Manifest.parse(arena, ast.*, .{
651 .allow_missing_paths_field = f.allow_missing_paths_field,651 .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,
653 .allow_name_string = f.allow_name_string,653 .allow_name_string = f.allow_name_string,
654 });654 });
655 const manifest = &f.manifest.?;655 const manifest = &f.manifest.?;
...@@ -752,7 +752,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {...@@ -752,7 +752,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
752 .job_queue = f.job_queue,752 .job_queue = f.job_queue,
753 .omit_missing_hash_error = false,753 .omit_missing_hash_error = false,
754 .allow_missing_paths_field = true,754 .allow_missing_paths_field = true,
755 .allow_missing_nonce = true,755 .allow_missing_fingerprint = true,
756 .allow_name_string = true,756 .allow_name_string = true,
757 .use_latest_commit = false,757 .use_latest_commit = false,
758758
...@@ -2323,7 +2323,7 @@ const TestFetchBuilder = struct {...@@ -2323,7 +2323,7 @@ const TestFetchBuilder = struct {
2323 .job_queue = &self.job_queue,2323 .job_queue = &self.job_queue,
2324 .omit_missing_hash_error = true,2324 .omit_missing_hash_error = true,
2325 .allow_missing_paths_field = false,2325 .allow_missing_paths_field = false,
2326 .allow_missing_nonce = true, // so we can keep using the old testdata .tar.gz2326 .allow_missing_fingerprint = true, // so we can keep using the old testdata .tar.gz
2327 .allow_name_string = true, // so we can keep using the old testdata .tar.gz2327 .allow_name_string = true, // so we can keep using the old testdata .tar.gz
2328 .use_latest_commit = true,2328 .use_latest_commit = true,
23292329
src/Package/Manifest.zig+13-13
...@@ -52,7 +52,7 @@ pub const ParseOptions = struct {...@@ -52,7 +52,7 @@ pub const ParseOptions = struct {
52 /// Deprecated, to be removed after 0.14.0 is tagged.52 /// Deprecated, to be removed after 0.14.0 is tagged.
53 allow_name_string: bool = true,53 allow_name_string: bool = true,
54 /// Deprecated, to be removed after 0.14.0 is tagged.54 /// Deprecated, to be removed after 0.14.0 is tagged.
55 allow_missing_nonce: bool = true,55 allow_missing_fingerprint: bool = true,
56};56};
5757
58pub const Error = Allocator.Error;58pub const Error = Allocator.Error;
...@@ -81,7 +81,7 @@ pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest {...@@ -81,7 +81,7 @@ pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest {
81 .paths = .{},81 .paths = .{},
82 .allow_missing_paths_field = options.allow_missing_paths_field,82 .allow_missing_paths_field = options.allow_missing_paths_field,
83 .allow_name_string = options.allow_name_string,83 .allow_name_string = options.allow_name_string,
84 .allow_missing_nonce = options.allow_missing_nonce,84 .allow_missing_fingerprint = options.allow_missing_fingerprint,
85 .minimum_zig_version = null,85 .minimum_zig_version = null,
86 .buf = .{},86 .buf = .{},
87 };87 };
...@@ -157,7 +157,7 @@ const Parse = struct {...@@ -157,7 +157,7 @@ const Parse = struct {
157 paths: std.StringArrayHashMapUnmanaged(void),157 paths: std.StringArrayHashMapUnmanaged(void),
158 allow_missing_paths_field: bool,158 allow_missing_paths_field: bool,
159 allow_name_string: bool,159 allow_name_string: bool,
160 allow_missing_nonce: bool,160 allow_missing_fingerprint: bool,
161 minimum_zig_version: ?std.SemanticVersion,161 minimum_zig_version: ?std.SemanticVersion,
162162
163 const InnerError = error{ ParseFailure, OutOfMemory };163 const InnerError = error{ ParseFailure, OutOfMemory };
...@@ -175,7 +175,7 @@ const Parse = struct {...@@ -175,7 +175,7 @@ const Parse = struct {
175 var have_name = false;175 var have_name = false;
176 var have_version = false;176 var have_version = false;
177 var have_included_paths = false;177 var have_included_paths = false;
178 var nonce: ?Package.Nonce = null;178 var fingerprint: ?Package.Fingerprint = null;
179179
180 for (struct_init.ast.fields) |field_init| {180 for (struct_init.ast.fields) |field_init| {
181 const name_token = ast.firstToken(field_init) - 2;181 const name_token = ast.firstToken(field_init) - 2;
...@@ -192,8 +192,8 @@ const Parse = struct {...@@ -192,8 +192,8 @@ const Parse = struct {
192 } else if (mem.eql(u8, field_name, "name")) {192 } else if (mem.eql(u8, field_name, "name")) {
193 p.name = try parseName(p, field_init);193 p.name = try parseName(p, field_init);
194 have_name = true;194 have_name = true;
195 } else if (mem.eql(u8, field_name, "nonce")) {195 } else if (mem.eql(u8, field_name, "fingerprint")) {
196 nonce = try parseNonce(p, field_init);196 fingerprint = try parseFingerprint(p, field_init);
197 } else if (mem.eql(u8, field_name, "version")) {197 } else if (mem.eql(u8, field_name, "version")) {
198 p.version_node = field_init;198 p.version_node = field_init;
199 const version_text = try parseString(p, field_init);199 const version_text = try parseString(p, field_init);
...@@ -220,16 +220,16 @@ const Parse = struct {...@@ -220,16 +220,16 @@ const Parse = struct {
220 if (!have_name) {220 if (!have_name) {
221 try appendError(p, main_token, "missing top-level 'name' field", .{});221 try appendError(p, main_token, "missing top-level 'name' field", .{});
222 } else {222 } else {
223 if (nonce) |n| {223 if (fingerprint) |n| {
224 if (!n.validate(p.name)) {224 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}", .{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.Nonce.generate(p.name).int(),226 n.int(), Package.Fingerprint.generate(p.name).int(),
227 });227 });
228 }228 }
229 p.id = n.id;229 p.id = n.id;
230 } else if (!p.allow_missing_nonce) {230 } else if (!p.allow_missing_fingerprint) {
231 try appendError(p, main_token, "missing top-level 'nonce' field; suggested value: 0x{x}", .{231 try appendError(p, main_token, "missing top-level 'fingerprint' field; suggested value: 0x{x}", .{
232 Package.Nonce.generate(p.name).int(),232 Package.Fingerprint.generate(p.name).int(),
233 });233 });
234 } else {234 } else {
235 p.id = 0;235 p.id = 0;
...@@ -385,7 +385,7 @@ const Parse = struct {...@@ -385,7 +385,7 @@ const Parse = struct {
385 }385 }
386 }386 }
387387
388 fn parseNonce(p: *Parse, node: Ast.Node.Index) !Package.Nonce {388 fn parseFingerprint(p: *Parse, node: Ast.Node.Index) !Package.Fingerprint {
389 const ast = p.ast;389 const ast = p.ast;
390 const node_tags = ast.nodes.items(.tag);390 const node_tags = ast.nodes.items(.tag);
391 const main_tokens = ast.nodes.items(.main_token);391 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 {...@@ -4752,10 +4752,10 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4752 };4752 };
4753 var ok_count: usize = 0;4753 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
4757 for (template_paths) |template_path| {4757 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)) |_| {
4759 std.log.info("created {s}", .{template_path});4759 std.log.info("created {s}", .{template_path});
4760 ok_count += 1;4760 ok_count += 1;
4761 } else |err| switch (err) {4761 } else |err| switch (err) {
...@@ -5225,7 +5225,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5225,7 +5225,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5225 .job_queue = &job_queue,5225 .job_queue = &job_queue,
5226 .omit_missing_hash_error = true,5226 .omit_missing_hash_error = true,
5227 .allow_missing_paths_field = false,5227 .allow_missing_paths_field = false,
5228 .allow_missing_nonce = false,5228 .allow_missing_fingerprint = false,
5229 .allow_name_string = false,5229 .allow_name_string = false,
5230 .use_latest_commit = false,5230 .use_latest_commit = false,
52315231
...@@ -7127,7 +7127,7 @@ fn cmdFetch(...@@ -7127,7 +7127,7 @@ fn cmdFetch(
7127 .job_queue = &job_queue,7127 .job_queue = &job_queue,
7128 .omit_missing_hash_error = true,7128 .omit_missing_hash_error = true,
7129 .allow_missing_paths_field = false,7129 .allow_missing_paths_field = false,
7130 .allow_missing_nonce = true,7130 .allow_missing_fingerprint = true,
7131 .allow_name_string = true,7131 .allow_name_string = true,
7132 .use_latest_commit = true,7132 .use_latest_commit = true,
71337133
...@@ -7468,10 +7468,10 @@ fn loadManifest(...@@ -7468,10 +7468,10 @@ fn loadManifest(
7468 0,7468 0,
7469 ) catch |err| switch (err) {7469 ) catch |err| switch (err) {
7470 error.FileNotFound => {7470 error.FileNotFound => {
7471 const nonce: Package.Nonce = .generate(options.root_name);7471 const fingerprint: Package.Fingerprint = .generate(options.root_name);
7472 var templates = findTemplates(gpa, arena);7472 var templates = findTemplates(gpa, arena);
7473 defer templates.deinit();7473 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| {
7475 fatal("unable to write {s}: {s}", .{7475 fatal("unable to write {s}: {s}", .{
7476 Package.Manifest.basename, @errorName(e),7476 Package.Manifest.basename, @errorName(e),
7477 });7477 });
...@@ -7529,7 +7529,7 @@ const Templates = struct {...@@ -7529,7 +7529,7 @@ const Templates = struct {
7529 out_dir: fs.Dir,7529 out_dir: fs.Dir,
7530 root_name: []const u8,7530 root_name: []const u8,
7531 template_path: []const u8,7531 template_path: []const u8,
7532 nonce: Package.Nonce,7532 fingerprint: Package.Fingerprint,
7533 ) !void {7533 ) !void {
7534 if (fs.path.dirname(template_path)) |dirname| {7534 if (fs.path.dirname(template_path)) |dirname| {
7535 out_dir.makePath(dirname) catch |err| {7535 out_dir.makePath(dirname) catch |err| {
...@@ -7555,9 +7555,9 @@ const Templates = struct {...@@ -7555,9 +7555,9 @@ const Templates = struct {
7555 try templates.buffer.appendSlice(root_name);7555 try templates.buffer.appendSlice(root_name);
7556 i += ".NAME".len;7556 i += ".NAME".len;
7557 continue;7557 continue;
7558 } else if (std.mem.startsWith(u8, contents[i..], ".NONCE")) {7558 } else if (std.mem.startsWith(u8, contents[i..], ".FINGERPRINT")) {
7559 try templates.buffer.writer().print("0x{x}", .{nonce.int()});7559 try templates.buffer.writer().print("0x{x}", .{fingerprint.int()});
7560 i += ".NONCE".len;7560 i += ".FINGERPRINT".len;
7561 continue;7561 continue;
7562 } else if (std.mem.startsWith(u8, contents[i..], ".ZIGVER")) {7562 } else if (std.mem.startsWith(u8, contents[i..], ".ZIGVER")) {
7563 try templates.buffer.appendSlice(build_options.version);7563 try templates.buffer.appendSlice(build_options.version);