From 07da9567e67643ed3a252ba1d10379ef23a6f682 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 29 Aug 2025 21:16:29 -0700 Subject: [PATCH] compiler: fix macos build --- lib/std/crypto/Certificate/Bundle/macos.zig | 124 ++++++++++---------- 1 file changed, 65 insertions(+), 59 deletions(-) diff --git a/lib/std/crypto/Certificate/Bundle/macos.zig b/lib/std/crypto/Certificate/Bundle/macos.zig index adf9775c92..5aa842f245 100644 --- a/lib/std/crypto/Certificate/Bundle/macos.zig +++ b/lib/std/crypto/Certificate/Bundle/macos.zig @@ -11,77 +11,83 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator) RescanMacError!void { cb.bytes.clearRetainingCapacity(); cb.map.clearRetainingCapacity(); - const keychainPaths = [2][]const u8{ + const keychain_paths = [2][]const u8{ "/System/Library/Keychains/SystemRootCertificates.keychain", "/Library/Keychains/System.keychain", }; - for (keychainPaths) |keychainPath| { - const file = try fs.openFileAbsolute(keychainPath, .{}); - defer file.close(); - - const bytes = try file.readToEndAlloc(gpa, std.math.maxInt(u32)); + for (keychain_paths) |keychain_path| { + const bytes = std.fs.cwd().readFileAlloc(keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) { + error.StreamTooLong => return error.FileTooBig, + else => |e| return e, + }; defer gpa.free(bytes); var reader: std.Io.Reader = .fixed(bytes); - - const db_header = try reader.takeStruct(ApplDbHeader, .big); - assert(mem.eql(u8, &db_header.signature, "kych")); - - reader.seek = db_header.schema_offset; - - const db_schema = try reader.takeStruct(ApplDbSchema, .big); - - var table_list = try gpa.alloc(u32, db_schema.table_count); - defer gpa.free(table_list); - - var table_idx: u32 = 0; - while (table_idx < table_list.len) : (table_idx += 1) { - table_list[table_idx] = try reader.takeInt(u32, .big); - } - - const now_sec = std.time.timestamp(); - - for (table_list) |table_offset| { - reader.seek = db_header.schema_offset + table_offset; - - const table_header = try reader.takeStruct(TableHeader, .big); - - if (@as(std.c.DB_RECORDTYPE, @enumFromInt(table_header.table_id)) != .X509_CERTIFICATE) { - continue; - } - - var record_list = try gpa.alloc(u32, table_header.record_count); - defer gpa.free(record_list); - - var record_idx: u32 = 0; - while (record_idx < record_list.len) : (record_idx += 1) { - record_list[record_idx] = try reader.takeInt(u32, .big); - } - - for (record_list) |record_offset| { - // An offset of zero means that the record is not present. - // An offset that is not 4-byte-aligned is invalid. - if (record_offset == 0 or record_offset % 4 != 0) continue; - - reader.seek = db_header.schema_offset + table_offset + record_offset; - - const cert_header = try reader.takeStruct(X509CertHeader, .big); - - if (cert_header.cert_size == 0) continue; - - const cert_start = @as(u32, @intCast(cb.bytes.items.len)); - const dest_buf = try cb.bytes.addManyAsSlice(gpa, cert_header.cert_size); - try reader.readSliceAll(dest_buf); - - try cb.parseCert(gpa, cert_start, now_sec); - } - } + scanReader(cb, gpa, &reader) catch |err| switch (err) { + error.ReadFailed => unreachable, // prebuffered + else => |e| return e, + }; } cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len); } +fn scanReader(cb: *Bundle, gpa: Allocator, reader: *std.Io.Reader) !void { + const db_header = try reader.takeStruct(ApplDbHeader, .big); + assert(mem.eql(u8, &db_header.signature, "kych")); + + reader.seek = db_header.schema_offset; + + const db_schema = try reader.takeStruct(ApplDbSchema, .big); + + var table_list = try gpa.alloc(u32, db_schema.table_count); + defer gpa.free(table_list); + + var table_idx: u32 = 0; + while (table_idx < table_list.len) : (table_idx += 1) { + table_list[table_idx] = try reader.takeInt(u32, .big); + } + + const now_sec = std.time.timestamp(); + + for (table_list) |table_offset| { + reader.seek = db_header.schema_offset + table_offset; + + const table_header = try reader.takeStruct(TableHeader, .big); + + if (@as(std.c.DB_RECORDTYPE, @enumFromInt(table_header.table_id)) != .X509_CERTIFICATE) { + continue; + } + + var record_list = try gpa.alloc(u32, table_header.record_count); + defer gpa.free(record_list); + + var record_idx: u32 = 0; + while (record_idx < record_list.len) : (record_idx += 1) { + record_list[record_idx] = try reader.takeInt(u32, .big); + } + + for (record_list) |record_offset| { + // An offset of zero means that the record is not present. + // An offset that is not 4-byte-aligned is invalid. + if (record_offset == 0 or record_offset % 4 != 0) continue; + + reader.seek = db_header.schema_offset + table_offset + record_offset; + + const cert_header = try reader.takeStruct(X509CertHeader, .big); + + if (cert_header.cert_size == 0) continue; + + const cert_start: u32 = @intCast(cb.bytes.items.len); + const dest_buf = try cb.bytes.addManyAsSlice(gpa, cert_header.cert_size); + try reader.readSliceAll(dest_buf); + + try cb.parseCert(gpa, cert_start, now_sec); + } + } +} + const ApplDbHeader = extern struct { signature: [4]u8, version: u32,