From de43f5eb6ae4a569efe15e3469b3de76a86d9cd1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 26 Feb 2025 04:01:28 -0800 Subject: [PATCH] rename "nonce" to "fingerprint" --- build.zig.zon | 2 +- doc/build.zig.zon.md | 10 +++++----- lib/init/build.zig.zon | 2 +- src/Package.zig | 8 ++++---- src/Package/Fetch.zig | 8 ++++---- src/Package/Manifest.zig | 26 +++++++++++++------------- src/main.zig | 20 ++++++++++---------- 7 files changed, 38 insertions(+), 38 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 412c9c099b..4f4b948217 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -12,5 +12,5 @@ }, }, .paths = .{""}, - .nonce = 0xc1ce108124179e16, + .fingerprint = 0xc1ce108124179e16, } diff --git a/doc/build.zig.zon.md b/doc/build.zig.zon.md index 541408d30e..690905a400 100644 --- a/doc/build.zig.zon.md +++ b/doc/build.zig.zon.md @@ -22,24 +22,24 @@ Zig package namespace. Must be a valid bare Zig identifier (don't `@` me), limited to 32 bytes. -Together with `nonce`, this represents a globally unique package identifier. +Together with `fingerprint`, this represents a globally unique package identifier. -### `nonce` +### `fingerprint` Together with `name`, this represents a globally unique package identifier. This field is auto-initialized by the toolchain when the package is first created, and then *never changes*. This allows Zig to unambiguously detect when one package is an updated version of another. -When forking a Zig project, this nonce should be regenerated if the upstream +When forking a Zig project, this fingerprint should be regenerated if the upstream project is still maintained. Otherwise, the fork is *hostile*, attempting to -take control over the original project's identity. The nonce can be regenerated +take control over the original project's identity. The fingerprint can be regenerated by deleting the field and running `zig build`. This 64-bit integer is the combination of a 32-bit id component and a 32-bit checksum. -The id component within the nonce has these restrictions: +The id component within the fingerprint has these restrictions: `0x00000000` is reserved for legacy packages. diff --git a/lib/init/build.zig.zon b/lib/init/build.zig.zon index b154ddc16b..1dbe7519e7 100644 --- a/lib/init/build.zig.zon +++ b/lib/init/build.zig.zon @@ -24,7 +24,7 @@ // original project's identity. Thus it is recommended to leave the comment // on the following line intact, so that it shows up in code reviews that // modify the field. - .nonce = .NONCE, // Changing this has security and trust implications. + .fingerprint = .FINGERPRINT, // Changing this has security and trust implications. // Tracks the earliest Zig version that the package considers to be a // supported use case. diff --git a/src/Package.zig b/src/Package.zig index 145678291a..7f231f5ad7 100644 --- a/src/Package.zig +++ b/src/Package.zig @@ -10,25 +10,25 @@ pub const multihash_len = 1 + 1 + Hash.Algo.digest_length; pub const multihash_hex_digest_len = 2 * multihash_len; pub const MultiHashHexDigest = [multihash_hex_digest_len]u8; -pub const Nonce = packed struct(u64) { +pub const Fingerprint = packed struct(u64) { id: u32, checksum: u32, - pub fn generate(name: []const u8) Nonce { + pub fn generate(name: []const u8) Fingerprint { return .{ .id = std.crypto.random.intRangeLessThan(u32, 1, 0xffffffff), .checksum = std.hash.Crc32.hash(name), }; } - pub fn validate(n: Nonce, name: []const u8) bool { + pub fn validate(n: Fingerprint, name: []const u8) bool { switch (n.id) { 0x00000000, 0xffffffff => return false, else => return std.hash.Crc32.hash(name) == n.checksum, } } - pub fn int(n: Nonce) u64 { + pub fn int(n: Fingerprint) u64 { return @bitCast(n); } }; diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index bbf13e57b8..efee6605ed 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -44,7 +44,7 @@ omit_missing_hash_error: bool, /// which specifies inclusion rules. This is intended to be true for the first /// fetch task and false for the recursive dependencies. allow_missing_paths_field: bool, -allow_missing_nonce: bool, +allow_missing_fingerprint: bool, allow_name_string: bool, /// If true and URL points to a Git repository, will use the latest commit. use_latest_commit: bool, @@ -649,7 +649,7 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void { f.manifest = try Manifest.parse(arena, ast.*, .{ .allow_missing_paths_field = f.allow_missing_paths_field, - .allow_missing_nonce = f.allow_missing_nonce, + .allow_missing_fingerprint = f.allow_missing_fingerprint, .allow_name_string = f.allow_name_string, }); const manifest = &f.manifest.?; @@ -752,7 +752,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void { .job_queue = f.job_queue, .omit_missing_hash_error = false, .allow_missing_paths_field = true, - .allow_missing_nonce = true, + .allow_missing_fingerprint = true, .allow_name_string = true, .use_latest_commit = false, @@ -2323,7 +2323,7 @@ const TestFetchBuilder = struct { .job_queue = &self.job_queue, .omit_missing_hash_error = true, .allow_missing_paths_field = false, - .allow_missing_nonce = true, // so we can keep using the old testdata .tar.gz + .allow_missing_fingerprint = true, // so we can keep using the old testdata .tar.gz .allow_name_string = true, // so we can keep using the old testdata .tar.gz .use_latest_commit = true, diff --git a/src/Package/Manifest.zig b/src/Package/Manifest.zig index 7e15dde225..c526854df2 100644 --- a/src/Package/Manifest.zig +++ b/src/Package/Manifest.zig @@ -52,7 +52,7 @@ pub const ParseOptions = struct { /// Deprecated, to be removed after 0.14.0 is tagged. allow_name_string: bool = true, /// Deprecated, to be removed after 0.14.0 is tagged. - allow_missing_nonce: bool = true, + allow_missing_fingerprint: bool = true, }; pub const Error = Allocator.Error; @@ -81,7 +81,7 @@ pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest { .paths = .{}, .allow_missing_paths_field = options.allow_missing_paths_field, .allow_name_string = options.allow_name_string, - .allow_missing_nonce = options.allow_missing_nonce, + .allow_missing_fingerprint = options.allow_missing_fingerprint, .minimum_zig_version = null, .buf = .{}, }; @@ -157,7 +157,7 @@ const Parse = struct { paths: std.StringArrayHashMapUnmanaged(void), allow_missing_paths_field: bool, allow_name_string: bool, - allow_missing_nonce: bool, + allow_missing_fingerprint: bool, minimum_zig_version: ?std.SemanticVersion, const InnerError = error{ ParseFailure, OutOfMemory }; @@ -175,7 +175,7 @@ const Parse = struct { var have_name = false; var have_version = false; var have_included_paths = false; - var nonce: ?Package.Nonce = null; + var fingerprint: ?Package.Fingerprint = null; for (struct_init.ast.fields) |field_init| { const name_token = ast.firstToken(field_init) - 2; @@ -192,8 +192,8 @@ const Parse = struct { } else if (mem.eql(u8, field_name, "name")) { p.name = try parseName(p, field_init); have_name = true; - } else if (mem.eql(u8, field_name, "nonce")) { - nonce = try parseNonce(p, field_init); + } else if (mem.eql(u8, field_name, "fingerprint")) { + fingerprint = try parseFingerprint(p, field_init); } else if (mem.eql(u8, field_name, "version")) { p.version_node = field_init; const version_text = try parseString(p, field_init); @@ -220,16 +220,16 @@ const Parse = struct { if (!have_name) { try appendError(p, main_token, "missing top-level 'name' field", .{}); } else { - if (nonce) |n| { + if (fingerprint) |n| { if (!n.validate(p.name)) { - return fail(p, main_token, "invalid nonce: 0x{x}; if this is a new or forked package, use this value: 0x{x}", .{ - n.int(), Package.Nonce.generate(p.name).int(), + return fail(p, main_token, "invalid fingerprint: 0x{x}; if this is a new or forked package, use this value: 0x{x}", .{ + n.int(), Package.Fingerprint.generate(p.name).int(), }); } p.id = n.id; - } else if (!p.allow_missing_nonce) { - try appendError(p, main_token, "missing top-level 'nonce' field; suggested value: 0x{x}", .{ - Package.Nonce.generate(p.name).int(), + } else if (!p.allow_missing_fingerprint) { + try appendError(p, main_token, "missing top-level 'fingerprint' field; suggested value: 0x{x}", .{ + Package.Fingerprint.generate(p.name).int(), }); } else { p.id = 0; @@ -385,7 +385,7 @@ const Parse = struct { } } - fn parseNonce(p: *Parse, node: Ast.Node.Index) !Package.Nonce { + fn parseFingerprint(p: *Parse, node: Ast.Node.Index) !Package.Fingerprint { const ast = p.ast; const node_tags = ast.nodes.items(.tag); const main_tokens = ast.nodes.items(.main_token); diff --git a/src/main.zig b/src/main.zig index 3dc6155db6..7b1bc50bd6 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4752,10 +4752,10 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { }; var ok_count: usize = 0; - const nonce: Package.Nonce = .generate(sanitized_root_name); + const fingerprint: Package.Fingerprint = .generate(sanitized_root_name); for (template_paths) |template_path| { - if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, nonce)) |_| { + if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, fingerprint)) |_| { std.log.info("created {s}", .{template_path}); ok_count += 1; } else |err| switch (err) { @@ -5225,7 +5225,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { .job_queue = &job_queue, .omit_missing_hash_error = true, .allow_missing_paths_field = false, - .allow_missing_nonce = false, + .allow_missing_fingerprint = false, .allow_name_string = false, .use_latest_commit = false, @@ -7127,7 +7127,7 @@ fn cmdFetch( .job_queue = &job_queue, .omit_missing_hash_error = true, .allow_missing_paths_field = false, - .allow_missing_nonce = true, + .allow_missing_fingerprint = true, .allow_name_string = true, .use_latest_commit = true, @@ -7468,10 +7468,10 @@ fn loadManifest( 0, ) catch |err| switch (err) { error.FileNotFound => { - const nonce: Package.Nonce = .generate(options.root_name); + const fingerprint: Package.Fingerprint = .generate(options.root_name); var templates = findTemplates(gpa, arena); defer templates.deinit(); - templates.write(arena, options.dir, options.root_name, Package.Manifest.basename, nonce) catch |e| { + templates.write(arena, options.dir, options.root_name, Package.Manifest.basename, fingerprint) catch |e| { fatal("unable to write {s}: {s}", .{ Package.Manifest.basename, @errorName(e), }); @@ -7529,7 +7529,7 @@ const Templates = struct { out_dir: fs.Dir, root_name: []const u8, template_path: []const u8, - nonce: Package.Nonce, + fingerprint: Package.Fingerprint, ) !void { if (fs.path.dirname(template_path)) |dirname| { out_dir.makePath(dirname) catch |err| { @@ -7555,9 +7555,9 @@ const Templates = struct { try templates.buffer.appendSlice(root_name); i += ".NAME".len; continue; - } else if (std.mem.startsWith(u8, contents[i..], ".NONCE")) { - try templates.buffer.writer().print("0x{x}", .{nonce.int()}); - i += ".NONCE".len; + } else if (std.mem.startsWith(u8, contents[i..], ".FINGERPRINT")) { + try templates.buffer.writer().print("0x{x}", .{fingerprint.int()}); + i += ".FINGERPRINT".len; continue; } else if (std.mem.startsWith(u8, contents[i..], ".ZIGVER")) { try templates.buffer.appendSlice(build_options.version);