Commit ea516f0e81
Changed files (4)
doc/build.zig.zon.md
@@ -22,9 +22,11 @@ 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.
+
### `nonce`
-Together with name, this represents a globally unique package identifier. This
+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.
@@ -34,14 +36,14 @@ project is still maintained. Otherwise, the fork is *hostile*, attempting to
take control over the original project's identity. The nonce can be regenerated
by deleting the field and running `zig build`.
-This 64-bit integer is the combination of a 16-bit id component, a 32-bit
-checksum, and 16 bits of reserved zeroes.
+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:
-`0x0000` is reserved for legacy packages.
+`0x00000000` is reserved for legacy packages.
-`0xffff` is reserved to represent "naked" packages.
+`0xffffffff` is reserved to represent "naked" packages.
The checksum is computed from `name` and serves to protect Zig users from
accidental id collisions.
src/Package/Manifest.zig
@@ -36,7 +36,7 @@ pub const ErrorMessage = struct {
};
name: []const u8,
-id: u16,
+id: u32,
version: std.SemanticVersion,
version_node: Ast.Node.Index,
dependencies: std.StringArrayHashMapUnmanaged(Dependency),
@@ -149,7 +149,7 @@ const Parse = struct {
errors: std.ArrayListUnmanaged(ErrorMessage),
name: []const u8,
- id: u16,
+ id: u32,
version: std.SemanticVersion,
version_node: Ast.Node.Index,
dependencies: std.StringArrayHashMapUnmanaged(Dependency),
src/Package.zig
@@ -11,20 +11,19 @@ pub const multihash_hex_digest_len = 2 * multihash_len;
pub const MultiHashHexDigest = [multihash_hex_digest_len]u8;
pub const Nonce = packed struct(u64) {
- id: u16,
- reserved: u16 = 0,
+ id: u32,
checksum: u32,
pub fn generate(name: []const u8) Nonce {
return .{
- .id = std.crypto.random.intRangeLessThan(u16, 0x0001, 0xffff),
+ .id = std.crypto.random.intRangeLessThan(u32, 1, 0xffffffff),
.checksum = std.hash.Crc32.hash(name),
};
}
pub fn validate(n: Nonce, name: []const u8) bool {
switch (n.id) {
- 0x0000, 0xffff => return false,
+ 0x00000000, 0xffffffff => return false,
else => return std.hash.Crc32.hash(name) == n.checksum,
}
}
@@ -54,8 +53,8 @@ pub const Hash = struct {
pub const Algo = std.crypto.hash.sha2.Sha256;
pub const Digest = [Algo.digest_length]u8;
- /// Example: "nnnn-vvvv-hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
- pub const max_len = 32 + 1 + 32 + 1 + (16 + 32 + 192) / 6;
+ /// Example: "nnnn-vvvv-hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
+ pub const max_len = 32 + 1 + 32 + 1 + (32 + 32 + 200) / 6;
pub fn fromSlice(s: []const u8) Hash {
assert(s.len <= max_len);
@@ -96,14 +95,12 @@ pub const Hash = struct {
/// bytes and assumed be a valid zig identifier
/// * semver is the version field from build.zig.zon, asserted to be at
/// most 32 bytes
- /// * hashplus is the following 39-byte array, base64 encoded using -_ to make
+ /// * hashplus is the following 33-byte array, base64 encoded using -_ to make
/// it filesystem safe:
- /// - (2 bytes) LE u16 Package ID
+ /// - (4 bytes) LE u32 Package ID
/// - (4 bytes) LE u32 total decompressed size in bytes, overflow saturated
- /// - (24 bytes) truncated SHA-256 digest of hashed files of the package
- ///
- /// example: "nasm-2.16.1-3-AAD_ZlwACpGU-c3QXp_yNyn07Q5U9Rq-Cb1ur2G1"
- pub fn init(digest: Digest, name: []const u8, ver: []const u8, id: u16, size: u32) Hash {
+ /// - (25 bytes) truncated SHA-256 digest of hashed files of the package
+ pub fn init(digest: Digest, name: []const u8, ver: []const u8, id: u32, size: u32) Hash {
assert(name.len <= 32);
assert(ver.len <= 32);
var result: Hash = undefined;
@@ -112,11 +109,11 @@ pub const Hash = struct {
buf.appendAssumeCapacity('-');
buf.appendSliceAssumeCapacity(ver);
buf.appendAssumeCapacity('-');
- var hashplus: [30]u8 = undefined;
- std.mem.writeInt(u16, hashplus[0..2], id, .little);
- std.mem.writeInt(u32, hashplus[2..6], size, .little);
- hashplus[6..].* = digest[0..24].*;
- _ = std.base64.url_safe_no_pad.Encoder.encode(buf.addManyAsArrayAssumeCapacity(40), &hashplus);
+ var hashplus: [33]u8 = undefined;
+ std.mem.writeInt(u32, hashplus[0..4], id, .little);
+ std.mem.writeInt(u32, hashplus[4..8], size, .little);
+ hashplus[8..].* = digest[0..25].*;
+ _ = std.base64.url_safe_no_pad.Encoder.encode(buf.addManyAsArrayAssumeCapacity(44), &hashplus);
@memset(buf.unusedCapacitySlice(), 0);
return result;
}
@@ -194,8 +191,8 @@ test Hash {
0xc7, 0xf5, 0x71, 0xb7, 0xb4, 0xe7, 0x6f, 0x3c, 0xdb, 0x87, 0x7a, 0x7f, 0xdd, 0xf9, 0x77, 0x87,
0x9d, 0xd3, 0x86, 0xfa, 0x73, 0x57, 0x9a, 0xf7, 0x9d, 0x1e, 0xdb, 0x8f, 0x3a, 0xd9, 0xbd, 0x9f,
};
- const result: Hash = .init(example_digest, "nasm", "2.16.1-2", 0xcafe, 10 * 1024 * 1024);
- try std.testing.expectEqualStrings("nasm-2.16.1-2-_soAAKAAx_Vxt7Tnbzzbh3p_3fl3h53ThvpzV5r3", result.toSlice());
+ const result: Hash = .init(example_digest, "nasm", "2.16.1-3", 0xcafebabe, 10 * 1024 * 1024);
+ try std.testing.expectEqualStrings("nasm-2.16.1-3-vrr-ygAAoADH9XG3tOdvPNuHen_d-XeHndOG-nNXmved", result.toSlice());
}
test {
build.zig.zon
@@ -12,5 +12,5 @@
},
},
.paths = .{""},
- .nonce = 0xc1ce10810000f013,
+ .nonce = 0xc1ce108124179e16,
}