authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-06-06 22:48:09-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-06-06 22:48:09-04:00
loge96d86064eb81977f254fa8f36481b7d150cb3b6
treedb68c1089fcd0d78b790924b3f58136fcbf77645
parent38266c50351fc64fd4f513d684d6f2c1aaad7f9a
parentbc3ce4b9715fc487eddfa1819a252a8fc82a369e
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #24090 from fardragon/handle-empty-hash

zig build: Handle empty hashes in build.zig.zon

2 files changed, 10 insertions(+), 3 deletions(-)

src/Package.zig+7-1
...@@ -66,10 +66,11 @@ pub const Hash = struct {...@@ -66,10 +66,11 @@ pub const Hash = struct {
6666
67 pub fn toSlice(ph: *const Hash) []const u8 {67 pub fn toSlice(ph: *const Hash) []const u8 {
68 var end: usize = ph.bytes.len;68 var end: usize = ph.bytes.len;
69 while (true) {69 while (end > 0) {
70 end -= 1;70 end -= 1;
71 if (ph.bytes[end] != 0) return ph.bytes[0 .. end + 1];71 if (ph.bytes[end] != 0) return ph.bytes[0 .. end + 1];
72 }72 }
73 return ph.bytes[0..0];
73 }74 }
7475
75 pub fn eql(a: *const Hash, b: *const Hash) bool {76 pub fn eql(a: *const Hash, b: *const Hash) bool {
...@@ -195,6 +196,11 @@ test Hash {...@@ -195,6 +196,11 @@ test Hash {
195 try std.testing.expectEqualStrings("nasm-2.16.1-3-vrr-ygAAoADH9XG3tOdvPNuHen_d-XeHndOG-nNXmved", result.toSlice());196 try std.testing.expectEqualStrings("nasm-2.16.1-3-vrr-ygAAoADH9XG3tOdvPNuHen_d-XeHndOG-nNXmved", result.toSlice());
196}197}
197198
199test "empty hash" {
200 const hash = Hash.fromSlice("");
201 try std.testing.expectEqualStrings("", hash.toSlice());
202}
203
198test {204test {
199 _ = Fetch;205 _ = Fetch;
200}206}
src/Package/Fetch.zig+3-2
...@@ -568,14 +568,14 @@ fn runResource(...@@ -568,14 +568,14 @@ fn runResource(
568 const actual_hex = Package.multiHashHexDigest(f.computed_hash.digest);568 const actual_hex = Package.multiHashHexDigest(f.computed_hash.digest);
569 if (!std.mem.eql(u8, declared_hash.toSlice(), &actual_hex)) {569 if (!std.mem.eql(u8, declared_hash.toSlice(), &actual_hex)) {
570 return f.fail(hash_tok, try eb.printString(570 return f.fail(hash_tok, try eb.printString(
571 "hash mismatch: manifest declares {s} but the fetched package has {s}",571 "hash mismatch: manifest declares '{s}' but the fetched package has '{s}'",
572 .{ declared_hash.toSlice(), actual_hex },572 .{ declared_hash.toSlice(), actual_hex },
573 ));573 ));
574 }574 }
575 } else {575 } else {
576 if (!computed_package_hash.eql(&declared_hash)) {576 if (!computed_package_hash.eql(&declared_hash)) {
577 return f.fail(hash_tok, try eb.printString(577 return f.fail(hash_tok, try eb.printString(
578 "hash mismatch: manifest declares {s} but the fetched package has {s}",578 "hash mismatch: manifest declares '{s}' but the fetched package has '{s}'",
579 .{ declared_hash.toSlice(), computed_package_hash.toSlice() },579 .{ declared_hash.toSlice(), computed_package_hash.toSlice() },
580 ));580 ));
581 }581 }
...@@ -726,6 +726,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {...@@ -726,6 +726,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
726 .hash = h: {726 .hash = h: {
727 const h = dep.hash orelse break :h null;727 const h = dep.hash orelse break :h null;
728 const pkg_hash: Package.Hash = .fromSlice(h);728 const pkg_hash: Package.Hash = .fromSlice(h);
729 if (h.len == 0) break :h pkg_hash;
729 const gop = f.job_queue.table.getOrPutAssumeCapacity(pkg_hash);730 const gop = f.job_queue.table.getOrPutAssumeCapacity(pkg_hash);
730 if (gop.found_existing) {731 if (gop.found_existing) {
731 if (!dep.lazy) {732 if (!dep.lazy) {