authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-06 14:03:09-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-06 14:03:09-08:00
log5f453b45d395239d1b26d6cec3d3ac7f407e0fb0
treeb0ebba1999075e873959c8c8538b870a58a24e65
parent699063c5a0e1bba14710c76ef5b2ed1cb1343b62

Package: fix Hash.projectId decoding


1 files changed, 17 insertions(+), 5 deletions(-)

src/Package.zig+17-5
...@@ -139,11 +139,12 @@ pub const Hash = struct {...@@ -139,11 +139,12 @@ pub const Hash = struct {
139 }139 }
140140
141 pub fn projectId(hash: *const Hash) ProjectId {141 pub fn projectId(hash: *const Hash) ProjectId {
142 const name = std.mem.sliceTo(&hash.bytes, '-');142 const bytes = hash.toSlice();
143 const hashplus = hash.bytes[std.mem.findScalarLast(u8, &hash.bytes, '-').? + 1 ..];143 const name = std.mem.sliceTo(bytes, '-');
144 var decoded: [6]u8 = undefined;144 const encoded_hashplus = bytes[bytes.len - 44 ..];
145 std.base64.url_safe_no_pad.Decoder.decode(&decoded, hashplus[0..8]) catch unreachable;145 var hashplus: [33]u8 = undefined;
146 const fingerprint_id = std.mem.readInt(u32, decoded[0..4], .little);146 std.base64.url_safe_no_pad.Decoder.decode(&hashplus, encoded_hashplus) catch unreachable;
147 const fingerprint_id = std.mem.readInt(u32, hashplus[0..4], .little);
147 return .init(name, fingerprint_id);148 return .init(name, fingerprint_id);
148 }149 }
149150
...@@ -157,6 +158,17 @@ pub const Hash = struct {...@@ -157,6 +158,17 @@ pub const Hash = struct {
157158
158 try std.testing.expectEqual(0xd8fa4f9a, project_id.fingerprint_id);159 try std.testing.expectEqual(0xd8fa4f9a, project_id.fingerprint_id);
159 }160 }
161
162 test "projectId with dashes in the base64" {
163 const hash: Hash = .fromSlice("dvui-0.4.0-dev-AQFJmayi2gAKE7FeJoF61v5U1IV9-SupoEcFutIZYpkC");
164 const project_id = hash.projectId();
165
166 var expected_name: [32]u8 = @splat(0);
167 expected_name[0.."dvui".len].* = "dvui".*;
168 try std.testing.expectEqualSlices(u8, &expected_name, &project_id.padded_name);
169
170 try std.testing.expectEqual(0x99490101, project_id.fingerprint_id);
171 }
160};172};
161173
162/// Minimum information required to identify whether a package is an artifact174/// Minimum information required to identify whether a package is an artifact