ReviewOS

also looking at this

mail-os/mail

Harden encrypted mail storage, recovery, and forwarding

#8
Merged chris wants to merge codex/mail-storage-hardening into main
50 files +1701 -9001

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

packages/zig/build.zigmodified+5-3
Changes to packages/zig/build.zig
@@ -74,9 +74,11 @@ pub fn build(b: *std.Build) void {
7474 // and embed an existing pre-rendered webmail_dist instead of failing the
7575 // whole build on an unspawnable command. webmail_dist is gitignored, so
7676 // whoever invokes such a build must pre-render it (the Docker CI job does).
77 const have_bun = (b.findProgram(&.{"bun"}, &.{}) catch null) != null;
77 const have_bun = blk: {
78 break :blk b.findProgram(.{ .names = &.{"bun"} }) != null;
79 };
7880 const have_webmail_pkg = blk: {
79 std.Io.Dir.cwd().access(b.graph.io, "../webmail", .{}) catch break :blk false;
81 b.root.access(b.graph.io, "../webmail", .{}) catch break :blk false;
8082 break :blk true;
8183 };
8284 if (have_bun and have_webmail_pkg) {
@@ -91,7 +93,7 @@ pub fn build(b: *std.Build) void {
9193 // Run step: mail serve
9294 const run_cmd = b.addRunArtifact(mail_exe);
9395 run_cmd.step.dependOn(b.getInstallStep());
94 if (b.args) |args| run_cmd.addArgs(args);
96 run_cmd.addPassthruArgs();
9597
9698 const run_step = b.step("run", "Run the mail CLI");
9799 run_step.dependOn(&run_cmd.step);
packages/zig/build.zig.zonmodified+2-5
Changes to packages/zig/build.zig.zon
@@ -39,11 +39,8 @@
3939 .path = "vendor/zig-search-engine",
4040 },
4141 .zig_cli = .{
42 // Pin the last revision tested against Zig 0.16's unmanaged
43 // ArrayList API. Later zig-cli commits target Zig 0.17-only
44 // builtins/build APIs.
45 .url = "git+https://github.com/zig-utils/zig-cli.git#b44ab9c372c18e73ada883afe9d0f9f9b2a6e80e",
46 .hash = "zig_cli-0.1.1-18T51O3rAwBy6Q2GH6mEZGDrAGmx9-0RQfiIMpqYRGiN",
42 .url = "git+https://github.com/zig-utils/zig-cli.git#d5b6d7cce234514e53073d566696cd2e69ef4836",
43 .hash = "zig_cli-0.1.3-18T51LbtAwC1D5ymlw-xAeLSMooNBx2X2gDM4PawGb6c",
4744 },
4845 },
4946 .paths = .{
packages/zig/src/antispam/dane.zigmodified+4-4
Changes to packages/zig/src/antispam/dane.zig
@@ -263,9 +263,9 @@ pub const TLSARecord = struct { renamed throughout
263263 /// Format the TLSA record as a DNS presentation string.
264264 pub fn format(self: *const TLSARecord, allocator: std.mem.Allocator) ![]u8 {
265265 return std.fmt.allocPrint(allocator, "{d} {d} {d} {s}", .{
266 @intFromEnum(self.usage),
267 @intFromEnum(self.selector),
268 @intFromEnum(self.matching_type),
266 @backingInt(self.usage),
267 @backingInt(self.selector),
268 @backingInt(self.matching_type),
269269 self.certificate_data,
270270 });
271271 }
@@ -1512,7 +1512,7 @@ test "All TLSA usage values are covered" {
15121512 const parsed = TLSAUsage.fromInt(val);
15131513 try testing.expect(parsed != null);
15141514 try testing.expectEqual(exp, parsed.?);
1515 try testing.expectEqual(val, @intFromEnum(parsed.?));
1515 try testing.expectEqual(val, @backingInt(parsed.?));
15161516 }
15171517}
15181518
packages/zig/src/antispam/dnsbl.zigmodified+1-1
Changes to packages/zig/src/antispam/dnsbl.zig
@@ -178,7 +178,7 @@ pub const DnsblChecker = struct {
178178 defer if (result) |r| std.c.freeaddrinfo(r);
179179
180180 // rc != 0 means the name did not resolve (NXDOMAIN etc.) => not listed.
181 if (@intFromEnum(rc) != 0) return false;
181 if (@backingInt(rc) != 0) return false;
182182
183183 // Walk the result list and look for an A record in 127.0.0.0/8.
184184 var node = result;
packages/zig/src/core/error_handler.zigmodified+5-5
Changes to packages/zig/src/core/error_handler.zig
@@ -293,7 +293,7 @@ pub const ErrorHandler = struct {
293293 }
294294
295295 // Check severity
296 if (@intFromEnum(ctx.severity) < @intFromEnum(self.config.min_log_severity)) return;
296 if (@backingInt(ctx.severity) < @backingInt(self.config.min_log_severity)) return;
297297
298298 // Log the error
299299 if (self.config.log_all_errors) {
@@ -494,8 +494,8 @@ pub const ErrorMetrics = struct { renamed throughout
494494
495495 pub fn record(self: *Self, ctx: ErrorContext) void {
496496 _ = self.total_errors.fetchAdd(1, .monotonic);
497 _ = self.errors_by_category[@intFromEnum(ctx.category)].fetchAdd(1, .monotonic);
498 _ = self.errors_by_severity[@intFromEnum(ctx.severity)].fetchAdd(1, .monotonic);
497 _ = self.errors_by_category[@backingInt(ctx.category)].fetchAdd(1, .monotonic);
498 _ = self.errors_by_severity[@backingInt(ctx.severity)].fetchAdd(1, .monotonic);
499499 self.last_error_time.store(ctx.timestamp, .monotonic);
500500
501501 if (ctx.is_retryable) {
@@ -508,11 +508,11 @@ pub const ErrorMetrics = struct { renamed throughout
508508 }
509509
510510 pub fn getErrorsByCategory(self: *const Self, category: ErrorCategory) u64 {
511 return self.errors_by_category[@intFromEnum(category)].load(.monotonic);
511 return self.errors_by_category[@backingInt(category)].load(.monotonic);
512512 }
513513
514514 pub fn getErrorsBySeverity(self: *const Self, severity: ErrorSeverity) u64 {
515 return self.errors_by_severity[@intFromEnum(severity)].load(.monotonic);
515 return self.errors_by_severity[@backingInt(severity)].load(.monotonic);
516516 }
517517
518518 pub fn getCriticalErrors(self: *const Self) u64 {
packages/zig/src/core/fs_compat.zigmodified+1-1
Changes to packages/zig/src/core/fs_compat.zig
@@ -63,7 +63,7 @@ pub const Dir = struct {
6363 .CLOEXEC = true,
6464 }, @as(std.c.mode_t, 0o644));
6565 if (fd < 0) {
66 const e: std.c.E = @enumFromInt(std.c._errno().*);
66 const e: std.c.E = @fromBackingInt(@intCast(std.c._errno().*));
6767 if (e == .EXIST) return error.PathAlreadyExists;
6868 return error.SystemResources;
6969 }
packages/zig/src/core/logger.zigmodified+2-2
Changes to packages/zig/src/core/logger.zig
@@ -93,7 +93,7 @@ pub const Logger = struct {
9393 }
9494
9595 pub fn log(self: *Logger, level: LogLevel, comptime fmt: []const u8, args: anytype) void {
96 if (@intFromEnum(level) < @intFromEnum(self.min_level)) return;
96 if (@backingInt(level) < @backingInt(self.min_level)) return;
9797
9898 const timestamp = time_compat.timestamp();
9999 var buf: [8192]u8 = undefined;
@@ -278,7 +278,7 @@ pub const Logger = struct {
278278 };
279279
280280 pub fn logStructured(self: *Logger, slog: *StructuredLog) void {
281 if (@intFromEnum(slog.level) < @intFromEnum(self.min_level)) return;
281 if (@backingInt(slog.level) < @backingInt(self.min_level)) return;
282282
283283 const timestamp = time_compat.timestamp();
284284 var log_buf: [8192]u8 = undefined;
packages/zig/src/core/socket_compat.zigmodified+5-5
Changes to packages/zig/src/core/socket_compat.zig
@@ -127,8 +127,8 @@ pub const Server = struct {
127127 if (address.family == .ipv4) {
128128 const sockaddr = address.toSockaddrIn();
129129 if (std.c.bind(fd, @ptrCast(&sockaddr), @sizeOf(@TypeOf(sockaddr))) < 0) {
130 const e: posix.E = @enumFromInt(std.c._errno().*);
131 std.log.err("bind() failed on port {d}: errno={d}", .{ address.port, @intFromEnum(e) });
130 const e: posix.E = @fromBackingInt(@intCast(std.c._errno().*));
131 std.log.err("bind() failed on port {d}: errno={d}", .{ address.port, @backingInt(e) });
132132 return switch (e) {
133133 .ADDRINUSE => error.AddressInUse,
134134 .ADDRNOTAVAIL => error.AddressNotAvailable,
@@ -139,8 +139,8 @@ pub const Server = struct {
139139 } else {
140140 const sockaddr = address.toSockaddrIn6();
141141 if (std.c.bind(fd, @ptrCast(&sockaddr), @sizeOf(@TypeOf(sockaddr))) < 0) {
142 const e: posix.E = @enumFromInt(std.c._errno().*);
143 std.log.err("bind() failed on port {d}: errno={d}", .{ address.port, @intFromEnum(e) });
142 const e: posix.E = @fromBackingInt(@intCast(std.c._errno().*));
143 std.log.err("bind() failed on port {d}: errno={d}", .{ address.port, @backingInt(e) });
144144 return switch (e) {
145145 .ADDRINUSE => error.AddressInUse,
146146 .ADDRNOTAVAIL => error.AddressNotAvailable,
@@ -170,7 +170,7 @@ pub const Server = struct {
170170 // Use raw syscall to avoid Zig 0.16 error type mismatch
171171 const rc = std.c.accept(self.fd, &client_addr, &addr_len);
172172 if (rc < 0) {
173 const err: posix.E = @enumFromInt(std.c._errno().*);
173 const err: posix.E = @fromBackingInt(@intCast(std.c._errno().*));
174174 return switch (err) {
175175 .AGAIN => error.WouldBlock,
176176 .INTR => error.OperationCancelled,
packages/zig/src/core/tls.zigmodified+20-20
Changes to packages/zig/src/core/tls.zig
@@ -1026,7 +1026,7 @@ pub const CipherNegotiator = struct {
10261026 // Server preference: iterate server's list first
10271027 for (self.server_config.cipher_suites) |server_suite| {
10281028 for (client_suites) |client_suite| {
1029 if (@intFromEnum(server_suite) == client_suite) {
1029 if (@backingInt(server_suite) == client_suite) {
10301030 return server_suite;
10311031 }
10321032 }
@@ -1035,7 +1035,7 @@ pub const CipherNegotiator = struct {
10351035 // Client preference: iterate client's list first
10361036 for (client_suites) |client_suite| {
10371037 for (self.server_config.cipher_suites) |server_suite| {
1038 if (@intFromEnum(server_suite) == client_suite) {
1038 if (@backingInt(server_suite) == client_suite) {
10391039 return server_suite;
10401040 }
10411041 }
@@ -1051,7 +1051,7 @@ pub const CipherNegotiator = struct {
10511051 ) ?NamedGroup {
10521052 for (self.server_config.named_groups) |server_group| {
10531053 for (client_groups) |client_group| {
1054 if (@intFromEnum(server_group) == client_group) {
1054 if (@backingInt(server_group) == client_group) {
10551055 return server_group;
10561056 }
10571057 }
@@ -1072,7 +1072,7 @@ pub const CipherNegotiator = struct {
10721072 }
10731073
10741074 for (client_schemes) |client_scheme| {
1075 if (@intFromEnum(server_scheme) == client_scheme) {
1075 if (@backingInt(server_scheme) == client_scheme) {
10761076 return server_scheme;
10771077 }
10781078 }
@@ -1294,7 +1294,7 @@ pub const ServerHelloBuilder = struct {
12941294
12951295 // Named group (2 bytes)
12961296 var group_bytes: [2]u8 = undefined;
1297 std.mem.writeInt(u16, &group_bytes, @intFromEnum(group), .big);
1297 std.mem.writeInt(u16, &group_bytes, @backingInt(group), .big);
12981298 try data.appendSlice(self.allocator, &group_bytes);
12991299
13001300 // Key exchange length (2 bytes)
@@ -1329,7 +1329,7 @@ pub const ServerHelloBuilder = struct {
13291329
13301330 // Cipher suite (2 bytes)
13311331 var cipher_bytes: [2]u8 = undefined;
1332 std.mem.writeInt(u16, &cipher_bytes, @intFromEnum(self.cipher_suite), .big);
1332 std.mem.writeInt(u16, &cipher_bytes, @backingInt(self.cipher_suite), .big);
13331333 try output.appendSlice(self.allocator, &cipher_bytes);
13341334
13351335 // Compression method (0 = null)
@@ -1344,7 +1344,7 @@ pub const ServerHelloBuilder = struct {
13441344 for (self.extensions.items) |ext| {
13451345 // Extension type (2 bytes)
13461346 var ext_type_bytes: [2]u8 = undefined;
1347 std.mem.writeInt(u16, &ext_type_bytes, @intFromEnum(ext.ext_type), .big);
1347 std.mem.writeInt(u16, &ext_type_bytes, @backingInt(ext.ext_type), .big);
13481348 try output.appendSlice(self.allocator, &ext_type_bytes);
13491349
13501350 // Extension data length (2 bytes)
@@ -1452,8 +1452,8 @@ pub const TlsAlert = struct {
14521452 return .{
14531453 21, // Alert content type
14541454 0x03, 0x03, // Version (TLS 1.2 for compatibility)
1455 0x00, 0x02, // Length
1456 @intFromEnum(self.level), @intFromEnum(self.description),
1455 0x00, 0x02, // Length
1456 @backingInt(self.level), @backingInt(self.description),
14571457 };
14581458 }
14591459
@@ -1706,9 +1706,9 @@ test "cipher negotiation server preference" { renamed throughout
17061706
17071707 // Client offers TLS 1.2 ciphers first, then TLS 1.3
17081708 const client_suites = [_]u16{
1709 @intFromEnum(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256),
1710 @intFromEnum(CipherSuite.TLS_AES_128_GCM_SHA256),
1711 @intFromEnum(CipherSuite.TLS_AES_256_GCM_SHA384),
1709 @backingInt(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256),
1710 @backingInt(CipherSuite.TLS_AES_128_GCM_SHA256),
1711 @backingInt(CipherSuite.TLS_AES_256_GCM_SHA384),
17121712 };
17131713
17141714 // Server prefers TLS_AES_256_GCM_SHA384 (first in server list)
@@ -1744,8 +1744,8 @@ test "named group negotiation" { renamed throughout
17441744 var negotiator = CipherNegotiator.init(testing.allocator, .{});
17451745
17461746 const client_groups = [_]u16{
1747 @intFromEnum(NamedGroup.secp256r1),
1748 @intFromEnum(NamedGroup.x25519),
1747 @backingInt(NamedGroup.secp256r1),
1748 @backingInt(NamedGroup.x25519),
17491749 };
17501750
17511751 // Server prefers x25519
@@ -1761,17 +1761,17 @@ test "full negotiation" { renamed throughout
17611761
17621762 const client_hello = ClientHelloParams{
17631763 .cipher_suites = &[_]u16{
1764 @intFromEnum(CipherSuite.TLS_AES_128_GCM_SHA256),
1765 @intFromEnum(CipherSuite.TLS_AES_256_GCM_SHA384),
1764 @backingInt(CipherSuite.TLS_AES_128_GCM_SHA256),
1765 @backingInt(CipherSuite.TLS_AES_256_GCM_SHA384),
17661766 },
17671767 .supported_versions = &[_]u16{ 0x0304, 0x0303 },
17681768 .named_groups = &[_]u16{
1769 @intFromEnum(NamedGroup.x25519),
1770 @intFromEnum(NamedGroup.secp256r1),
1769 @backingInt(NamedGroup.x25519),
1770 @backingInt(NamedGroup.secp256r1),
17711771 },
17721772 .signature_algorithms = &[_]u16{
1773 @intFromEnum(SignatureScheme.ecdsa_secp256r1_sha256),
1774 @intFromEnum(SignatureScheme.rsa_pss_rsae_sha256),
1773 @backingInt(SignatureScheme.ecdsa_secp256r1_sha256),
1774 @backingInt(SignatureScheme.rsa_pss_rsae_sha256),
17751775 },
17761776 .server_name = "mail.example.com",
17771777 };
packages/zig/src/delivery/outbound.zigmodified+1-1
Changes to packages/zig/src/delivery/outbound.zig
@@ -309,7 +309,7 @@ fn deliverOnce(
309309
310310 var result: ?*std.c.addrinfo = null;
311311 const gai_ret = std.c.getaddrinfo(mx_host_z.ptr, "25", &hints, &result);
312 if (@intFromEnum(gai_ret) != 0 or result == null) {
312 if (@backingInt(gai_ret) != 0 or result == null) {
313313 std.log.err("Failed to resolve MX host {s}", .{mx_host});
314314 return error.MxResolutionFailed;
315315 }
packages/zig/src/features/sieve.zigmodified+2-2
Changes to packages/zig/src/features/sieve.zig
@@ -280,8 +280,8 @@ pub const SieveParser = struct {
280280 .pos = 0,
281281 .line = 1,
282282 .column = 1,
283 .errors = .empty,
284 .requires = .empty,
283 .errors = .{},
284 .requires = .{},
285285 };
286286 }
287287
packages/zig/src/infrastructure/cluster_network.zigmodified+1-1
Changes to packages/zig/src/infrastructure/cluster_network.zig
@@ -144,7 +144,7 @@ pub const ClusterNetwork = struct {
144144 try std.json.stringify(message, .{}, body.writer());
145145
146146 // Write message type (1 byte)
147 const type_byte = [1]u8{@intFromEnum(msg_type)};
147 const type_byte = [1]u8{@backingInt(msg_type)};
148148 _ = try stream.write(&type_byte);
149149
150150 // Write message length (4 bytes, big-endian)
packages/zig/src/infrastructure/multi_region.zigmodified+1-1
Changes to packages/zig/src/infrastructure/multi_region.zig
@@ -350,7 +350,7 @@ pub const MultiRegionManager = struct {
350350 // Serialize event
351351 try batch.writer().print("{d}:{d}:{s}\n", .{
352352 event.id,
353 @intFromEnum(event.event_type),
353 @backingInt(event.event_type),
354354 event.payload,
355355 });
356356 }
packages/zig/src/observability/alerting.zigmodified+3-3
Changes to packages/zig/src/observability/alerting.zig
@@ -502,7 +502,7 @@ pub const AlertManager = struct {
502502 };
503503
504504 // Check severity threshold
505 return @intFromEnum(alert.severity) >= @intFromEnum(min_severity);
505 return @backingInt(alert.severity) >= @backingInt(min_severity);
506506 }
507507
508508 fn sendToChannel(self: *AlertManager, channel: AlertChannel, alert: Alert) !void {
@@ -702,8 +702,8 @@ test "add slack channel" {
702702test "severity comparison" {
703703 const testing = std.testing;
704704
705 try testing.expect(@intFromEnum(Severity.critical) > @intFromEnum(Severity.warning));
706 try testing.expect(@intFromEnum(Severity.warning) > @intFromEnum(Severity.info));
705 try testing.expect(@backingInt(Severity.critical) > @backingInt(Severity.warning));
706 try testing.expect(@backingInt(Severity.warning) > @backingInt(Severity.info));
707707}
708708
709709test "default rules creation" {
packages/zig/src/protocol/activesync.zigmodifiedrenamed throughout+3-3
Changes to packages/zig/src/protocol/activesync.zig
@@ -735,7 +735,7 @@ test "Protocol version parsing" {
735735test "Folder types" {
736736 const testing = std.testing;
737737
738 try testing.expectEqual(@as(u8, 2), @intFromEnum(FolderType.default_inbox));
739 try testing.expectEqual(@as(u8, 8), @intFromEnum(FolderType.default_calendar));
740 try testing.expectEqual(@as(u8, 9), @intFromEnum(FolderType.default_contacts));
738 try testing.expectEqual(@as(u8, 2), @backingInt(FolderType.default_inbox));
739 try testing.expectEqual(@as(u8, 8), @backingInt(FolderType.default_calendar));
740 try testing.expectEqual(@as(u8, 9), @backingInt(FolderType.default_contacts));
741741}
packages/zig/src/protocol/eas.zigmodified+1-1
Changes to packages/zig/src/protocol/eas.zig
@@ -856,7 +856,7 @@ fn civilFromEpoch(epoch: i64) Civil {
856856 const ds = es.getDaySeconds();
857857 return .{
858858 .year = year_day.year,
859 .month = @intFromEnum(month_day.month),
859 .month = @backingInt(month_day.month),
860860 .day = @as(u8, month_day.day_index) + 1,
861861 .hour = ds.getHoursIntoDay(),
862862 .minute = ds.getMinutesIntoHour(),
packages/zig/src/protocol/ews/ews.zigmodified+2-2
Changes to packages/zig/src/protocol/ews/ews.zig
@@ -757,7 +757,7 @@ fn ewsDate(a: std.mem.Allocator, epoch: i64) []const u8 {
757757 const md = yd.calculateMonthDay();
758758 const ds = es.getDaySeconds();
759759 return std.fmt.allocPrint(a, "{d:0>4}-{d:0>2}-{d:0>2}T{d:0>2}:{d:0>2}:{d:0>2}Z", .{
760 yd.year, @intFromEnum(md.month), @as(u32, md.day_index) + 1,
760 yd.year, @backingInt(md.month), @as(u32, md.day_index) + 1,
761761 ds.getHoursIntoDay(), ds.getMinutesIntoHour(), ds.getSecondsIntoMinute(),
762762 }) catch "1970-01-01T00:00:00Z";
763763}
@@ -945,7 +945,7 @@ fn rfc2822Date(a: std.mem.Allocator, epoch: i64) []const u8 {
945945 const wdays = [_][]const u8{ "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed" };
946946 const months = [_][]const u8{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
947947 const wd = wdays[@intCast(ed.day % 7)];
948 const mon = months[@intFromEnum(md.month) - 1];
948 const mon = months[@backingInt(md.month) - 1];
949949 return std.fmt.allocPrint(a, "{s}, {d:0>2} {s} {d} {d:0>2}:{d:0>2}:{d:0>2} +0000", .{
950950 wd, @as(u32, md.day_index) + 1, mon, yd.year,
951951 ds.getHoursIntoDay(), ds.getMinutesIntoHour(), ds.getSecondsIntoMinute(),
packages/zig/src/protocol/managesieve.zigmodified+1-1
Changes to packages/zig/src/protocol/managesieve.zig
@@ -904,7 +904,7 @@ test "command parsing - unknown returns null" {
904904
905905test "command toString round-trips" {
906906 inline for (@typeInfo(ManageSieveCommand).@"enum".field_values) |value| {
907 const c: ManageSieveCommand = @enumFromInt(value);
907 const c: ManageSieveCommand = @fromBackingInt(@intCast(value));
908908 try std.testing.expectEqual(c, ManageSieveCommand.fromString(c.toString()).?);
909909 }
910910}
packages/zig/src/protocol/milter.zigmodified+55-55
Changes to packages/zig/src/protocol/milter.zig
@@ -69,7 +69,7 @@ pub const MilterCommand = enum(u8) {
6969 /// Convert a raw byte to a MilterCommand, returning null if unrecognized.
7070 pub fn fromByte(byte: u8) ?MilterCommand {
7171 inline for (@typeInfo(MilterCommand).@"enum".field_values) |value| {
72 if (byte == value) return @enumFromInt(value);
72 if (byte == value) return @fromBackingInt(@intCast(value));
7373 }
7474 return null;
7575 }
@@ -142,7 +142,7 @@ pub const MilterResponse = enum(u8) {
142142 /// Convert a raw byte to a MilterResponse, returning null if unrecognized.
143143 pub fn fromByte(byte: u8) ?MilterResponse {
144144 inline for (@typeInfo(MilterResponse).@"enum".field_values) |value| {
145 if (byte == value) return @enumFromInt(value);
145 if (byte == value) return @fromBackingInt(@intCast(value));
146146 }
147147 return null;
148148 }
@@ -371,7 +371,7 @@ pub const MilterFamily = enum(u8) {
371371
372372 pub fn fromByte(byte: u8) ?MilterFamily {
373373 inline for (@typeInfo(MilterFamily).@"enum".field_values) |value| {
374 if (byte == value) return @enumFromInt(value);
374 if (byte == value) return @fromBackingInt(@intCast(value));
375375 }
376376 return null;
377377 }
@@ -477,7 +477,7 @@ pub const MilterPacket = struct {
477477 /// Convenience: create a command-only packet with no data.
478478 pub fn commandOnly(cmd: MilterCommand) MilterPacket {
479479 return .{
480 .command = @intFromEnum(cmd),
480 .command = @backingInt(cmd),
481481 .data = &[_]u8{},
482482 };
483483 }
@@ -784,14 +784,14 @@ pub const MilterClient = struct { renamed throughout
784784 std.mem.writeInt(u32, payload[8..12], offered_protocol.toNetworkU32(), .big);
785785
786786 try self.sendPacket(.{
787 .command = @intFromEnum(MilterCommand.option_negotiation),
787 .command = @backingInt(MilterCommand.option_negotiation),
788788 .data = &payload,
789789 });
790790
791791 // Read the SMFIR_OPTNEG response.
792792 const pkt = try self.readPacket();
793793
794 if (pkt.command != @intFromEnum(MilterResponse.option_negotiation)) {
794 if (pkt.command != @backingInt(MilterResponse.option_negotiation)) {
795795 return error.UnexpectedResponse;
796796 }
797797 if (pkt.data.len < 12) {
@@ -837,7 +837,7 @@ pub const MilterClient = struct {
837837 offset += hostname.len;
838838 buf[offset] = 0;
839839 offset += 1;
840 buf[offset] = @intFromEnum(family);
840 buf[offset] = @backingInt(family);
841841 offset += 1;
842842 std.mem.writeInt(u16, buf[offset..][0..2], port, .big);
843843 offset += 2;
@@ -846,7 +846,7 @@ pub const MilterClient = struct {
846846 buf[offset] = 0;
847847
848848 try self.sendPacket(.{
849 .command = @intFromEnum(MilterCommand.connect),
849 .command = @backingInt(MilterCommand.connect),
850850 .data = buf,
851851 });
852852
@@ -862,7 +862,7 @@ pub const MilterClient = struct {
862862 buf[hostname.len] = 0;
863863
864864 try self.sendPacket(.{
865 .command = @intFromEnum(MilterCommand.helo),
865 .command = @backingInt(MilterCommand.helo),
866866 .data = buf,
867867 });
868868
@@ -891,7 +891,7 @@ pub const MilterClient = struct {
891891 }
892892
893893 try self.sendPacket(.{
894 .command = @intFromEnum(MilterCommand.mail_from),
894 .command = @backingInt(MilterCommand.mail_from),
895895 .data = payload.items,
896896 });
897897
@@ -919,7 +919,7 @@ pub const MilterClient = struct {
919919 }
920920
921921 try self.sendPacket(.{
922 .command = @intFromEnum(MilterCommand.rcpt_to),
922 .command = @backingInt(MilterCommand.rcpt_to),
923923 .data = payload.items,
924924 });
925925
@@ -942,7 +942,7 @@ pub const MilterClient = struct {
942942 buf[name.len + 1 + value.len] = 0;
943943
944944 try self.sendPacket(.{
945 .command = @intFromEnum(MilterCommand.header),
945 .command = @backingInt(MilterCommand.header),
946946 .data = buf,
947947 });
948948
@@ -963,7 +963,7 @@ pub const MilterClient = struct {
963963 if (chunk.len > MILTER_CHUNK_SIZE) return error.ChunkTooLarge;
964964
965965 try self.sendPacket(.{
966 .command = @intFromEnum(MilterCommand.body),
966 .command = @backingInt(MilterCommand.body),
967967 .data = chunk,
968968 });
969969
@@ -1029,7 +1029,7 @@ pub const MilterClient = struct {
10291029 var payload: std.ArrayList(u8) = .empty;
10301030 defer payload.deinit(self.allocator);
10311031
1032 try payload.append(self.allocator, @intFromEnum(cmd_code));
1032 try payload.append(self.allocator, @backingInt(cmd_code));
10331033
10341034 for (macros) |pair| {
10351035 try payload.appendSlice(self.allocator, pair[0]);
@@ -1039,7 +1039,7 @@ pub const MilterClient = struct {
10391039 }
10401040
10411041 try self.sendPacket(.{
1042 .command = @intFromEnum(MilterCommand.macro),
1042 .command = @backingInt(MilterCommand.macro),
10431043 .data = payload.items,
10441044 });
10451045 // Macros do not expect a response.
@@ -1788,21 +1788,21 @@ pub const MilterManagerStats = struct { renamed throughout
17881788test "MilterCommand byte values" {
17891789 const testing = std.testing;
17901790
1791 try testing.expectEqual(@as(u8, 'A'), @intFromEnum(MilterCommand.abort));
1792 try testing.expectEqual(@as(u8, 'B'), @intFromEnum(MilterCommand.body));
1793 try testing.expectEqual(@as(u8, 'C'), @intFromEnum(MilterCommand.connect));
1794 try testing.expectEqual(@as(u8, 'D'), @intFromEnum(MilterCommand.macro));
1795 try testing.expectEqual(@as(u8, 'E'), @intFromEnum(MilterCommand.end_of_body));
1796 try testing.expectEqual(@as(u8, 'H'), @intFromEnum(MilterCommand.helo));
1797 try testing.expectEqual(@as(u8, 'L'), @intFromEnum(MilterCommand.header));
1798 try testing.expectEqual(@as(u8, 'N'), @intFromEnum(MilterCommand.end_of_headers));
1799 try testing.expectEqual(@as(u8, 'M'), @intFromEnum(MilterCommand.mail_from));
1800 try testing.expectEqual(@as(u8, 'O'), @intFromEnum(MilterCommand.option_negotiation));
1801 try testing.expectEqual(@as(u8, 'Q'), @intFromEnum(MilterCommand.quit));
1802 try testing.expectEqual(@as(u8, 'R'), @intFromEnum(MilterCommand.rcpt_to));
1803 try testing.expectEqual(@as(u8, 'T'), @intFromEnum(MilterCommand.data));
1804 try testing.expectEqual(@as(u8, 'K'), @intFromEnum(MilterCommand.quit_new_connection));
1805 try testing.expectEqual(@as(u8, 'U'), @intFromEnum(MilterCommand.unknown));
1791 try testing.expectEqual(@as(u8, 'A'), @backingInt(MilterCommand.abort));
1792 try testing.expectEqual(@as(u8, 'B'), @backingInt(MilterCommand.body));
1793 try testing.expectEqual(@as(u8, 'C'), @backingInt(MilterCommand.connect));
1794 try testing.expectEqual(@as(u8, 'D'), @backingInt(MilterCommand.macro));
1795 try testing.expectEqual(@as(u8, 'E'), @backingInt(MilterCommand.end_of_body));
1796 try testing.expectEqual(@as(u8, 'H'), @backingInt(MilterCommand.helo));
1797 try testing.expectEqual(@as(u8, 'L'), @backingInt(MilterCommand.header));
1798 try testing.expectEqual(@as(u8, 'N'), @backingInt(MilterCommand.end_of_headers));
1799 try testing.expectEqual(@as(u8, 'M'), @backingInt(MilterCommand.mail_from));
1800 try testing.expectEqual(@as(u8, 'O'), @backingInt(MilterCommand.option_negotiation));
1801 try testing.expectEqual(@as(u8, 'Q'), @backingInt(MilterCommand.quit));
1802 try testing.expectEqual(@as(u8, 'R'), @backingInt(MilterCommand.rcpt_to));
1803 try testing.expectEqual(@as(u8, 'T'), @backingInt(MilterCommand.data));
1804 try testing.expectEqual(@as(u8, 'K'), @backingInt(MilterCommand.quit_new_connection));
1805 try testing.expectEqual(@as(u8, 'U'), @backingInt(MilterCommand.unknown));
18061806}
18071807
18081808test "MilterCommand fromByte round-trips" {
@@ -1829,21 +1829,21 @@ test "MilterCommand toString" { renamed throughout
18291829test "MilterResponse byte values" {
18301830 const testing = std.testing;
18311831
1832 try testing.expectEqual(@as(u8, '+'), @intFromEnum(MilterResponse.add_recipient));
1833 try testing.expectEqual(@as(u8, '-'), @intFromEnum(MilterResponse.delete_recipient));
1834 try testing.expectEqual(@as(u8, 'a'), @intFromEnum(MilterResponse.accept));
1835 try testing.expectEqual(@as(u8, 'b'), @intFromEnum(MilterResponse.replace_body));
1836 try testing.expectEqual(@as(u8, 'c'), @intFromEnum(MilterResponse.@"continue"));
1837 try testing.expectEqual(@as(u8, 'd'), @intFromEnum(MilterResponse.discard));
1838 try testing.expectEqual(@as(u8, 'h'), @intFromEnum(MilterResponse.add_header));
1839 try testing.expectEqual(@as(u8, 'i'), @intFromEnum(MilterResponse.insert_header));
1840 try testing.expectEqual(@as(u8, 'm'), @intFromEnum(MilterResponse.change_header));
1841 try testing.expectEqual(@as(u8, 'p'), @intFromEnum(MilterResponse.progress));
1842 try testing.expectEqual(@as(u8, 'q'), @intFromEnum(MilterResponse.quarantine));
1843 try testing.expectEqual(@as(u8, 'r'), @intFromEnum(MilterResponse.reject));
1844 try testing.expectEqual(@as(u8, 't'), @intFromEnum(MilterResponse.temp_fail));
1845 try testing.expectEqual(@as(u8, 'y'), @intFromEnum(MilterResponse.reply_code));
1846 try testing.expectEqual(@as(u8, 's'), @intFromEnum(MilterResponse.skip));
1832 try testing.expectEqual(@as(u8, '+'), @backingInt(MilterResponse.add_recipient));
1833 try testing.expectEqual(@as(u8, '-'), @backingInt(MilterResponse.delete_recipient));
1834 try testing.expectEqual(@as(u8, 'a'), @backingInt(MilterResponse.accept));
1835 try testing.expectEqual(@as(u8, 'b'), @backingInt(MilterResponse.replace_body));
1836 try testing.expectEqual(@as(u8, 'c'), @backingInt(MilterResponse.@"continue"));
1837 try testing.expectEqual(@as(u8, 'd'), @backingInt(MilterResponse.discard));
1838 try testing.expectEqual(@as(u8, 'h'), @backingInt(MilterResponse.add_header));
1839 try testing.expectEqual(@as(u8, 'i'), @backingInt(MilterResponse.insert_header));
1840 try testing.expectEqual(@as(u8, 'm'), @backingInt(MilterResponse.change_header));
1841 try testing.expectEqual(@as(u8, 'p'), @backingInt(MilterResponse.progress));
1842 try testing.expectEqual(@as(u8, 'q'), @backingInt(MilterResponse.quarantine));
1843 try testing.expectEqual(@as(u8, 'r'), @backingInt(MilterResponse.reject));
1844 try testing.expectEqual(@as(u8, 't'), @backingInt(MilterResponse.temp_fail));
1845 try testing.expectEqual(@as(u8, 'y'), @backingInt(MilterResponse.reply_code));
1846 try testing.expectEqual(@as(u8, 's'), @backingInt(MilterResponse.skip));
18471847}
18481848
18491849test "MilterResponse fromByte round-trips" {
@@ -2010,10 +2010,10 @@ test "MilterProtocol merge and intersect" { renamed throughout
20102010test "MilterFamily byte values" {
20112011 const testing = std.testing;
20122012
2013 try testing.expectEqual(@as(u8, 'U'), @intFromEnum(MilterFamily.unknown));
2014 try testing.expectEqual(@as(u8, 'L'), @intFromEnum(MilterFamily.unix));
2015 try testing.expectEqual(@as(u8, '4'), @intFromEnum(MilterFamily.inet));
2016 try testing.expectEqual(@as(u8, '6'), @intFromEnum(MilterFamily.inet6));
2013 try testing.expectEqual(@as(u8, 'U'), @backingInt(MilterFamily.unknown));
2014 try testing.expectEqual(@as(u8, 'L'), @backingInt(MilterFamily.unix));
2015 try testing.expectEqual(@as(u8, '4'), @backingInt(MilterFamily.inet));
2016 try testing.expectEqual(@as(u8, '6'), @backingInt(MilterFamily.inet6));
20172017}
20182018
20192019test "MilterPacket encode command-only packet" {
@@ -2039,7 +2039,7 @@ test "MilterPacket encode with data" {
20392039
20402040 const data = "test.example.com\x00";
20412041 const pkt = MilterPacket{
2042 .command = @intFromEnum(MilterCommand.helo),
2042 .command = @backingInt(MilterCommand.helo),
20432043 .data = data,
20442044 };
20452045
@@ -2089,7 +2089,7 @@ test "MilterPacket encode-decode round-trip" {
20892089 const testing = std.testing;
20902090
20912091 const original = MilterPacket{
2092 .command = @intFromEnum(MilterCommand.header),
2092 .command = @backingInt(MilterCommand.header),
20932093 .data = "Subject\x00Hello World\x00",
20942094 };
20952095
@@ -2132,7 +2132,7 @@ test "MilterPacket encode buffer too small" {
21322132 const testing = std.testing;
21332133
21342134 const pkt = MilterPacket{
2135 .command = @intFromEnum(MilterCommand.body),
2135 .command = @backingInt(MilterCommand.body),
21362136 .data = "some body data",
21372137 };
21382138
@@ -2147,7 +2147,7 @@ test "MilterPacket encodedLen" {
21472147 try testing.expectEqual(@as(usize, 5), pkt_no_data.encodedLen());
21482148
21492149 const pkt_with_data = MilterPacket{
2150 .command = @intFromEnum(MilterCommand.body),
2150 .command = @backingInt(MilterCommand.body),
21512151 .data = "Hello",
21522152 };
21532153 try testing.expectEqual(@as(usize, 10), pkt_with_data.encodedLen());
@@ -2163,7 +2163,7 @@ test "negotiation packet encoding" {
21632163 std.mem.writeInt(u32, payload[8..12], MilterProtocol.all_callbacks.toNetworkU32(), .big);
21642164
21652165 const pkt = MilterPacket{
2166 .command = @intFromEnum(MilterCommand.option_negotiation),
2166 .command = @backingInt(MilterCommand.option_negotiation),
21672167 .data = &payload,
21682168 };
21692169
@@ -2562,7 +2562,7 @@ test "MilterPacket network byte order verification" {
25622562 @memset(&data, 'X');
25632563
25642564 const pkt = MilterPacket{
2565 .command = @intFromEnum(MilterCommand.body),
2565 .command = @backingInt(MilterCommand.body),
25662566 .data = &data,
25672567 };
25682568
packages/zig/src/protocol/websocket.zigmodified+6-6
Changes to packages/zig/src/protocol/websocket.zig
@@ -378,7 +378,7 @@ pub const WebSocketSession = struct {
378378 defer frame_header.deinit(self.allocator);
379379
380380 // First byte: FIN + RSV + OpCode
381 const byte1: u8 = 0x80 | @intFromEnum(opcode); // FIN=1, RSV=0, OpCode
381 const byte1: u8 = 0x80 | @backingInt(opcode); // FIN=1, RSV=0, OpCode
382382 try frame_header.append(self.allocator, byte1);
383383
384384 // Second byte: MASK + Payload length
@@ -768,11 +768,11 @@ test "WebSocket accept key generation" { renamed throughout
768768test "OpCode enum values" {
769769 const testing = std.testing;
770770
771 try testing.expectEqual(@as(u8, 0x1), @intFromEnum(OpCode.text));
772 try testing.expectEqual(@as(u8, 0x2), @intFromEnum(OpCode.binary));
773 try testing.expectEqual(@as(u8, 0x8), @intFromEnum(OpCode.close));
774 try testing.expectEqual(@as(u8, 0x9), @intFromEnum(OpCode.ping));
775 try testing.expectEqual(@as(u8, 0xA), @intFromEnum(OpCode.pong));
771 try testing.expectEqual(@as(u8, 0x1), @backingInt(OpCode.text));
772 try testing.expectEqual(@as(u8, 0x2), @backingInt(OpCode.binary));
773 try testing.expectEqual(@as(u8, 0x8), @backingInt(OpCode.close));
774 try testing.expectEqual(@as(u8, 0x9), @backingInt(OpCode.ping));
775 try testing.expectEqual(@as(u8, 0xA), @backingInt(OpCode.pong));
776776}
777777
778778test "Notification manager" {
packages/zig/src/security/secrets.zigmodified+2-2
Changes to packages/zig/src/security/secrets.zig
@@ -993,7 +993,7 @@ pub const AwsSigV4Signer = struct {
993993
994994 return try std.fmt.allocPrint(self.allocator, "{d:0>4}{d:0>2}{d:0>2}", .{
995995 year_and_day.year,
996 @intFromEnum(month_day.month),
996 @backingInt(month_day.month),
997997 month_day.day_index + 1,
998998 });
999999 }
@@ -1013,7 +1013,7 @@ pub const AwsSigV4Signer = struct {
10131013
10141014 return try std.fmt.allocPrint(self.allocator, "{d:0>4}{d:0>2}{d:0>2}T{d:0>2}{d:0>2}{d:0>2}Z", .{
10151015 year_and_day.year,
1016 @intFromEnum(month_day.month),
1016 @backingInt(month_day.month),
10171017 month_day.day_index + 1,
10181018 hours,
10191019 minutes,
packages/zig/src/storage/caldav_store.zigmodified+3-3
Changes to packages/zig/src/storage/caldav_store.zig
@@ -397,7 +397,7 @@ pub const CalDavStore = struct {
397397 stmt.bindInt(9, if (ev.all_day) 1 else 0) catch return;
398398 bindOptText(&stmt, 10, ev.rrule) catch return;
399399 bindOptText(&stmt, 11, ev.organizer) catch return;
400 stmt.bindInt(12, @intFromEnum(ev.status)) catch return;
400 stmt.bindInt(12, @backingInt(ev.status)) catch return;
401401 stmt.bindInt(13, ev.created_at) catch return;
402402 stmt.bindInt(14, ev.modified_at) catch return;
403403 stmt.bindText(15, ev.etag) catch return;
@@ -454,7 +454,7 @@ pub const CalDavStore = struct {
454454 defer stmt.finalize();
455455 stmt.bindInt(1, @intCast(contact_id)) catch continue;
456456 stmt.bindText(2, e.email) catch continue;
457 stmt.bindInt(3, @intFromEnum(e.email_type)) catch continue;
457 stmt.bindInt(3, @backingInt(e.email_type)) catch continue;
458458 stmt.bindInt(4, if (e.is_primary) 1 else 0) catch continue;
459459 _ = stmt.step() catch continue;
460460 }
@@ -464,7 +464,7 @@ pub const CalDavStore = struct {
464464 defer stmt.finalize();
465465 stmt.bindInt(1, @intCast(contact_id)) catch continue;
466466 stmt.bindText(2, p.number) catch continue;
467 stmt.bindInt(3, @intFromEnum(p.phone_type)) catch continue;
467 stmt.bindInt(3, @backingInt(p.phone_type)) catch continue;
468468 stmt.bindInt(4, if (p.is_primary) 1 else 0) catch continue;
469469 _ = stmt.step() catch continue;
470470 }
packages/zig/src/storage/encryption.zigmodified+1-1
Changes to packages/zig/src/storage/encryption.zig
@@ -500,7 +500,7 @@ pub const EncryptedTimeSeriesStorage = struct {
500500
501501 return Date{
502502 .year = @intCast(year_and_day.year),
503 .month = @intFromEnum(month_day.month),
503 .month = @backingInt(month_day.month),
504504 .day = month_day.day_index + 1,
505505 };
506506 }
packages/zig/src/storage/s3storage.zigmodified+1-1
Changes to packages/zig/src/storage/s3storage.zig
@@ -148,7 +148,7 @@ pub const S3Storage = struct {
148148 return try std.fmt.allocPrint(
149149 self.allocator,
150150 "{s}/{d}/{d:0>2}/{s}.eml",
151 .{ email, year_and_day.year, @intFromEnum(month_day.month), message_id },
151 .{ email, year_and_day.year, @backingInt(month_day.month), message_id },
152152 );
153153 }
154154
packages/zig/src/storage/timeseries_storage.zigmodified+1-1
Changes to packages/zig/src/storage/timeseries_storage.zig
@@ -365,7 +365,7 @@ pub const TimeSeriesStorage = struct {
365365
366366 return Date{
367367 .year = @intCast(year_and_day.year),
368 .month = @intFromEnum(month_day.month),
368 .month = @backingInt(month_day.month),
369369 .day = month_day.day_index + 1,
370370 };
371371 }
packages/zig/vendor/zig-search-engine/src/http.zigmodified+1-1
Changes to packages/zig/vendor/zig-search-engine/src/http.zig
@@ -48,7 +48,7 @@ fn tcpConnect(host: [:0]const u8, port: u16, timeout_seconds: u32) types.Error!s
4848 });
4949 var result: ?*std.c.addrinfo = null;
5050 const gai = std.c.getaddrinfo(host.ptr, port_z.ptr, &hints, &result);
51 if (@intFromEnum(gai) != 0 or result == null) return error.ConnectFailed;
51 if (@backingInt(gai) != 0 or result == null) return error.ConnectFailed;
5252 defer std.c.freeaddrinfo(result.?);
5353
5454 const family: c_uint = @intCast(std.posix.AF.INET);
packages/zig/vendor/zig-tls/src/cipher.zigmodified+2-2
Changes to packages/zig/vendor/zig-tls/src/cipher.zig
@@ -497,7 +497,7 @@ fn Aead13Type(comptime AeadType: type, comptime Hash: type) type {
497497 if (&cleartext[0] != &buf[record.header_len]) {
498498 @memcpy(buf[record.header_len..][0..cleartext.len], cleartext);
499499 }
500 buf[record.header_len + cleartext.len] = @intFromEnum(content_type);
500 buf[record.header_len + cleartext.len] = @backingInt(content_type);
501501 const ciphertext = buf[record.header_len..][0 .. cleartext.len + 1];
502502 const auth_tag = buf[record.header_len + ciphertext.len ..][0..auth_tag_len];
503503
@@ -541,7 +541,7 @@ fn Aead13Type(comptime AeadType: type, comptime Hash: type) type {
541541 while (buf[content_type_idx] == 0 and content_type_idx > 0) : (content_type_idx -= 1) {}
542542
543543 const cleartext = buf[0..content_type_idx];
544 const content_type: proto.ContentType = @enumFromInt(buf[content_type_idx]);
544 const content_type: proto.ContentType = @fromBackingInt(@intCast(buf[content_type_idx]));
545545 self.decrypt_seq +%= 1;
546546 return .{ content_type, cleartext };
547547 }
packages/zig/vendor/zig-tls/src/connection.zigmodified+2-2
Changes to packages/zig/vendor/zig-tls/src/connection.zig
@@ -98,7 +98,7 @@ pub const Connection = struct {
9898 switch (content_type) {
9999 .application_data => {},
100100 .handshake => {
101 const handshake_type: proto.Handshake = @enumFromInt(cleartext[0]);
101 const handshake_type: proto.Handshake = @fromBackingInt(@intCast(cleartext[0]));
102102 switch (handshake_type) {
103103 .new_session_ticket => {
104104 if (c.session_resumption) |r| {
@@ -111,7 +111,7 @@ pub const Connection = struct {
111111 // rfc: Upon receiving a KeyUpdate, the receiver MUST
112112 // update its receiving keys.
113113 try c.cipher.keyUpdateDecrypt();
114 const key: proto.KeyUpdateRequest = @enumFromInt(cleartext[4]);
114 const key: proto.KeyUpdateRequest = @fromBackingInt(@intCast(cleartext[4]));
115115 switch (key) {
116116 .update_requested => {
117117 @atomicStore(bool, &c.key_update_requested, true, .monotonic);
packages/zig/vendor/zig-tls/src/handshake_client.zigmodified+11-11
Changes to packages/zig/vendor/zig-tls/src/handshake_client.zig
@@ -77,11 +77,11 @@ pub const Options = struct {
7777 session_resumption: ?*SessionResumption = null,
7878
7979 pub const Diagnostic = struct {
80 tls_version: proto.Version = @enumFromInt(0),
81 cipher_suite_tag: CipherSuite = @enumFromInt(0),
82 named_group: proto.NamedGroup = @enumFromInt(0),
83 signature_scheme: proto.SignatureScheme = @enumFromInt(0),
84 client_signature_scheme: proto.SignatureScheme = @enumFromInt(0),
80 tls_version: proto.Version = @fromBackingInt(@intCast(0)),
81 cipher_suite_tag: CipherSuite = @fromBackingInt(@intCast(0)),
82 named_group: proto.NamedGroup = @fromBackingInt(@intCast(0)),
83 signature_scheme: proto.SignatureScheme = @fromBackingInt(@intCast(0)),
84 client_signature_scheme: proto.SignatureScheme = @fromBackingInt(@intCast(0)),
8585 is_session_resumption: bool = false,
8686 max_server_record_len: usize = 0,
8787 max_server_cleartext_len: usize = 0,
@@ -109,7 +109,7 @@ pub const Options = struct {
109109
110110 pub fn init(payload: []const u8, secret: []const u8) !Ticket {
111111 var d = record.Decoder.init(.handshake, payload);
112 const handshake_type: proto.Handshake = @enumFromInt(try d.decode(u8));
112 const handshake_type: proto.Handshake = @fromBackingInt(@intCast(try d.decode(u8)));
113113 if (handshake_type != proto.Handshake.new_session_ticket) return error.InvalidType;
114114 const length = try d.decode(u24);
115115 if (d.rest().len != length) return error.InvalidLength;
@@ -219,7 +219,7 @@ pub const Handshake = struct {
219219 key_material: [48 * 4]u8 = undefined, // for sha256 32 * 4 is filled, for sha384 48 * 4
220220
221221 transcript: Transcript = .{},
222 cipher_suite: CipherSuite = @enumFromInt(0),
222 cipher_suite: CipherSuite = @fromBackingInt(@intCast(0)),
223223 named_group: ?proto.NamedGroup = null,
224224 dh_kp: DhKeyPair = undefined,
225225 rsa_secret: RsaSecret = undefined,
@@ -728,8 +728,8 @@ pub const Handshake = struct { renamed throughout
728728 var w = Io.Writer.fixed(&buffer);
729729 try w.writeAll(&h.client_random);
730730 try w.writeAll(&h.server_random);
731 try w.writeByte(@intFromEnum(proto.Curve.named_curve));
732 try w.writeInt(u16, @intFromEnum(h.named_group.?), .big);
731 try w.writeByte(@backingInt(proto.Curve.named_curve));
732 try w.writeInt(u16, @backingInt(h.named_group.?), .big);
733733 try w.writeByte(@intCast(h.server_pub_key.len));
734734 try w.writeAll(h.server_pub_key);
735735 break :brk w.buffered();
@@ -890,7 +890,7 @@ pub const Handshake = struct {
890890 if (opt.diagnostic) |d| {
891891 d.tls_version = h.tls_version;
892892 d.cipher_suite_tag = h.cipher_suite;
893 d.named_group = h.named_group orelse @as(proto.NamedGroup, @enumFromInt(0x0000));
893 d.named_group = h.named_group orelse @as(proto.NamedGroup, @fromBackingInt(@intCast(0x0000)));
894894 d.signature_scheme = h.cert.signature_scheme;
895895 d.is_session_resumption = is_session_resumption;
896896 d.max_server_record_len = h.max_server_record_len;
@@ -1203,7 +1203,7 @@ pub const NonBlock = struct {
12031203 server_flight_2,
12041204
12051205 fn next(self: *State) void {
1206 self.* = @enumFromInt(@intFromEnum(self.*) + 1);
1206 self.* = @fromBackingInt(@intCast(@backingInt(self.*) + 1));
12071207 }
12081208 };
12091209
packages/zig/vendor/zig-tls/src/handshake_common.zigmodified+1-1
Changes to packages/zig/vendor/zig-tls/src/handshake_common.zig
@@ -326,7 +326,7 @@ pub const CertificateParser = struct {
326326 pub_key_buf: [1038]u8 = undefined,
327327 pub_key: []const u8 = undefined,
328328
329 signature_scheme: proto.SignatureScheme = @enumFromInt(0),
329 signature_scheme: proto.SignatureScheme = @fromBackingInt(@intCast(0)),
330330 signature_buf: [1024]u8 = undefined,
331331 signature: []const u8 = undefined,
332332
packages/zig/vendor/zig-tls/src/handshake_server.zigmodified+32-32
Changes to packages/zig/vendor/zig-tls/src/handshake_server.zig
@@ -74,9 +74,9 @@ pub const Handshake = struct {
7474 client_random: [32]u8 = undefined,
7575 legacy_session_id_buf: [32]u8 = undefined,
7676 legacy_session_id: []u8 = &.{},
77 cipher_suite: CipherSuite = @enumFromInt(0),
78 signature_scheme: proto.SignatureScheme = @enumFromInt(0),
79 named_group: proto.NamedGroup = @enumFromInt(0),
77 cipher_suite: CipherSuite = @fromBackingInt(@intCast(0)),
78 signature_scheme: proto.SignatureScheme = @fromBackingInt(@intCast(0)),
79 named_group: proto.NamedGroup = @fromBackingInt(@intCast(0)),
8080 client_pub_key_buf: [max_pub_key_len]u8 = undefined,
8181 client_pub_key: []u8 = &.{},
8282 server_pub_key_buf: [max_pub_key_len]u8 = undefined,
@@ -169,7 +169,7 @@ pub const Handshake = struct {
169169 var w: record.Writer = .initFromIo(h.output);
170170
171171 // Debug: log the selected named_group (use info level to show in production)
172 log.info("TLS 1.2 serverFlightTls12: named_group={x}, cipher_suite={x}", .{ @intFromEnum(h.named_group), @intFromEnum(h.cipher_suite) });
172 log.info("TLS 1.2 serverFlightTls12: named_group={x}, cipher_suite={x}", .{ @backingInt(h.named_group), @backingInt(h.cipher_suite) });
173173
174174 // Generate server's DH public key
175175 log.info("TLS 1.2: generating DH public key", .{});
@@ -278,7 +278,7 @@ pub const Handshake = struct {
278278 _ = try hw.skip(4);
279279
280280 // ECParameters - named_curve type + curve ID
281 try hw.int(u8, @intFromEnum(proto.Curve.named_curve));
281 try hw.int(u8, @backingInt(proto.Curve.named_curve));
282282 try hw.enumValue(h.named_group);
283283
284284 // ECPoint - public key
@@ -299,7 +299,7 @@ pub const Handshake = struct {
299299
300300 // Sign the data using the appropriate signing method based on key type
301301 const signature_scheme = auth.key.signature_scheme;
302 log.info("TLS 1.2 ServerKeyExchange: signature_scheme={x}, ecdsa_key_pair_present={}", .{ @intFromEnum(signature_scheme), auth.ecdsa_key_pair != null });
302 log.info("TLS 1.2 ServerKeyExchange: signature_scheme={x}, ecdsa_key_pair_present={}", .{ @backingInt(signature_scheme), auth.ecdsa_key_pair != null });
303303 try hw.enumValue(signature_scheme);
304304
305305 const signature = switch (signature_scheme) {
@@ -354,9 +354,9 @@ pub const Handshake = struct { renamed throughout
354354 log.err("TLS 1.2 clientFlight2Tls12: Record.decoder failed: {}", .{err});
355355 return err;
356356 };
357 log.info("TLS 1.2 clientFlight2Tls12: got record, content_type={x}", .{@intFromEnum(d.content_type)});
357 log.info("TLS 1.2 clientFlight2Tls12: got record, content_type={x}", .{@backingInt(d.content_type)});
358358 d.expectContentType(.handshake) catch |err| {
359 log.err("TLS 1.2 clientFlight2Tls12: expected handshake but got content_type={x}, payload_len={d}", .{ @intFromEnum(d.content_type), d.payload.len });
359 log.err("TLS 1.2 clientFlight2Tls12: expected handshake but got content_type={x}, payload_len={d}", .{ @backingInt(d.content_type), d.payload.len });
360360 if (d.content_type == .alert and d.payload.len >= 2) {
361361 log.err("TLS 1.2 clientFlight2Tls12: client sent alert: level={d}, desc={d}", .{ d.payload[0], d.payload[1] });
362362 }
@@ -365,7 +365,7 @@ pub const Handshake = struct {
365365 h.transcript.update(d.payload);
366366
367367 const handshake_type = try d.decode(proto.Handshake);
368 log.info("TLS 1.2 clientFlight2Tls12: handshake_type={x} (decimal={d}), expected client_key_exchange={x}", .{ @intFromEnum(handshake_type), @intFromEnum(handshake_type), @intFromEnum(proto.Handshake.client_key_exchange) });
368 log.info("TLS 1.2 clientFlight2Tls12: handshake_type={x} (decimal={d}), expected client_key_exchange={x}", .{ @backingInt(handshake_type), @backingInt(handshake_type), @backingInt(proto.Handshake.client_key_exchange) });
369369 if (handshake_type != .client_key_exchange) {
370370 log.err("TLS 1.2 clientFlight2Tls12: handshake type mismatch! got={s}, expected=client_key_exchange", .{@tagName(handshake_type)});
371371 return error.TlsUnexpectedMessage;
@@ -390,7 +390,7 @@ pub const Handshake = struct {
390390
391391 // Generate pre-master secret and derive keys
392392 if (h.cipher_suite.keyExchange() == .ecdhe) {
393 log.info("TLS 1.2 clientFlight2Tls12: generating shared key, named_group={x}", .{@intFromEnum(h.named_group)});
393 log.info("TLS 1.2 clientFlight2Tls12: generating shared key, named_group={x}", .{@backingInt(h.named_group)});
394394 const pre_master_secret = try h.dh_kp.sharedKey(h.named_group, h.client_pub_key);
395395 log.info("TLS 1.2 clientFlight2Tls12: got pre_master_secret, len={d}", .{pre_master_secret.len});
396396 h.transcript.masterSecret(&h.master_secret, pre_master_secret, h.client_random, h.server_random);
@@ -407,7 +407,7 @@ pub const Handshake = struct {
407407 log.info("TLS 1.2 clientFlight2Tls12: reading ChangeCipherSpec", .{});
408408 {
409409 var d = try Record.decoder(h.input);
410 log.info("TLS 1.2 clientFlight2Tls12: got record, content_type={x}", .{@intFromEnum(d.content_type)});
410 log.info("TLS 1.2 clientFlight2Tls12: got record, content_type={x}", .{@backingInt(d.content_type)});
411411 try d.expectContentType(.change_cipher_spec);
412412 log.info("TLS 1.2 clientFlight2Tls12: ChangeCipherSpec payload_len={d}, payload[0]={d}", .{ d.payload.len, if (d.payload.len > 0) d.payload[0] else 255 });
413413 if (d.payload.len != 1 or d.payload[0] != 1) return error.TlsUnexpectedMessage;
@@ -420,17 +420,17 @@ pub const Handshake = struct { renamed throughout
420420 log.info("TLS 1.2 clientFlight2Tls12: reading encrypted Finished", .{});
421421 {
422422 const rec = try Record.read(h.input);
423 log.info("TLS 1.2 clientFlight2Tls12: got record, content_type={x}", .{@intFromEnum(rec.content_type)});
423 log.info("TLS 1.2 clientFlight2Tls12: got record, content_type={x}", .{@backingInt(rec.content_type)});
424424 // TLS 1.2 encrypted Finished uses handshake (0x16) content type, NOT application_data
425425 if (rec.content_type != .handshake) {
426 log.err("TLS 1.2 clientFlight2Tls12: expected handshake, got {x}", .{@intFromEnum(rec.content_type)});
426 log.err("TLS 1.2 clientFlight2Tls12: expected handshake, got {x}", .{@backingInt(rec.content_type)});
427427 return error.TlsUnexpectedMessage;
428428 }
429429
430430 var cleartext_buf: [128]u8 = undefined;
431431 // For TLS 1.2, decrypt returns the record's content_type (which is handshake)
432432 const content_type, const cleartext = try h.cipher.decrypt(&cleartext_buf, rec);
433 log.info("TLS 1.2 clientFlight2Tls12: decrypted, content_type={x}, cleartext_len={d}", .{ @intFromEnum(content_type), cleartext.len });
433 log.info("TLS 1.2 clientFlight2Tls12: decrypted, content_type={x}, cleartext_len={d}", .{ @backingInt(content_type), cleartext.len });
434434 if (content_type != .handshake) return error.TlsUnexpectedMessage;
435435
436436 // Parse Finished message
@@ -707,8 +707,8 @@ pub const Handshake = struct {
707707 }
708708 // Track cipher suite candidates for both TLS versions separately
709709 // This is needed because we don't know which TLS version will be used yet
710 var tls13_cipher: CipherSuite = @enumFromInt(0);
711 var tls12_cipher: CipherSuite = @enumFromInt(0);
710 var tls13_cipher: CipherSuite = @fromBackingInt(@intCast(0));
711 var tls12_cipher: CipherSuite = @fromBackingInt(@intCast(0));
712712 { // cipher suites
713713 const end_idx = try d.decode(u16) + d.idx;
714714
@@ -717,21 +717,21 @@ pub const Handshake = struct {
717717 if (cipher_suites.includes(supported_cipher_suites, cipher_suite)) {
718718 // Track TLS 1.3 and TLS 1.2 ciphers separately
719719 if (cipher_suites.includes(cipher_suites.tls13, cipher_suite)) {
720 if (@intFromEnum(tls13_cipher) == 0) {
720 if (@backingInt(tls13_cipher) == 0) {
721721 tls13_cipher = cipher_suite;
722722 }
723723 } else if (cipher_suites.includes(cipher_suites.tls12, cipher_suite)) {
724 if (@intFromEnum(tls12_cipher) == 0) {
724 if (@backingInt(tls12_cipher) == 0) {
725725 tls12_cipher = cipher_suite;
726726 }
727727 }
728728 }
729729 }
730730 // Must have at least one supported cipher
731 if (@intFromEnum(tls13_cipher) == 0 and @intFromEnum(tls12_cipher) == 0)
731 if (@backingInt(tls13_cipher) == 0 and @backingInt(tls12_cipher) == 0)
732732 return error.TlsNoSupportedCiphers;
733733 }
734 log.info("readClientHello: tls13_cipher={x}, tls12_cipher={x}", .{ @intFromEnum(tls13_cipher), @intFromEnum(tls12_cipher) });
734 log.info("readClientHello: tls13_cipher={x}, tls12_cipher={x}", .{ @backingInt(tls13_cipher), @backingInt(tls12_cipher) });
735735 try d.skip(2); // compression methods
736736
737737 var key_share_received = false;
@@ -762,7 +762,7 @@ pub const Handshake = struct {
762762 const end_idx = try d.decode(u16) + d.idx;
763763 while (d.idx < end_idx) {
764764 const named_group = try d.decode(proto.NamedGroup);
765 switch (@intFromEnum(named_group)) {
765 switch (@backingInt(named_group)) {
766766 0x0001...0x0016,
767767 0x001a...0x001c,
768768 0xff01...0xff02,
@@ -778,14 +778,14 @@ pub const Handshake = struct { renamed throughout
778778 }
779779 }
780780 }
781 if (@intFromEnum(h.named_group) == 0)
781 if (@backingInt(h.named_group) == 0)
782782 return error.TlsIllegalParameter;
783783 },
784784 .supported_groups => {
785785 const end_idx = try d.decode(u16) + d.idx;
786786 while (d.idx < end_idx) {
787787 const named_group = try d.decode(proto.NamedGroup);
788 switch (@intFromEnum(named_group)) {
788 switch (@backingInt(named_group)) {
789789 // Deprecated/insecure curves - skip silently for TLS 1.2 compatibility
790790 // Some clients (including Apple SecureTransport) may include these
791791 0x0001...0x0016,
@@ -803,7 +803,7 @@ pub const Handshake = struct {
803803 }
804804 },
805805 .signature_algorithms => {
806 if (@intFromEnum(h.signature_scheme) == 0) {
806 if (@backingInt(h.signature_scheme) == 0) {
807807 try d.skip(extension_len);
808808 } else {
809809 var found = false;
@@ -825,12 +825,12 @@ pub const Handshake = struct { renamed throughout
825825
826826 // Determine TLS version based on client capabilities
827827 log.info("readClientHello: tls_1_3_supported={}, key_share_received={}, supported_groups_len={}", .{ tls_1_3_supported, key_share_received, supported_groups_len });
828 if (tls_1_3_supported and key_share_received and @intFromEnum(tls13_cipher) != 0) {
828 if (tls_1_3_supported and key_share_received and @backingInt(tls13_cipher) != 0) {
829829 // TLS 1.3 handshake - requires TLS 1.3 cipher
830830 h.tls_version = .tls_1_3;
831831 h.cipher_suite = tls13_cipher;
832 if (@intFromEnum(h.named_group) == 0) return error.TlsIllegalParameter;
833 } else if (@intFromEnum(tls12_cipher) != 0) {
832 if (@backingInt(h.named_group) == 0) return error.TlsIllegalParameter;
833 } else if (@backingInt(tls12_cipher) != 0) {
834834 // TLS 1.2 handshake - need to select named group from supported_groups
835835 h.tls_version = .tls_1_2;
836836 h.cipher_suite = tls12_cipher;
@@ -855,16 +855,16 @@ pub const Handshake = struct {
855855 break;
856856 }
857857 }
858 if (@intFromEnum(h.named_group) != 0) break;
858 if (@backingInt(h.named_group) != 0) break;
859859 }
860 if (@intFromEnum(h.named_group) == 0) return error.TlsIllegalParameter;
860 if (@backingInt(h.named_group) == 0) return error.TlsIllegalParameter;
861861 }
862 log.info("TLS 1.2 readClientHello: selected named_group={x}", .{@intFromEnum(h.named_group)});
862 log.info("TLS 1.2 readClientHello: selected named_group={x}", .{@backingInt(h.named_group)});
863863 } else {
864864 // No compatible cipher suite found
865865 return error.TlsNoSupportedCiphers;
866866 }
867 log.info("readClientHello complete: tls_version={}, cipher_suite={x}, named_group={x}", .{ h.tls_version, @intFromEnum(h.cipher_suite), @intFromEnum(h.named_group) });
867 log.info("readClientHello complete: tls_version={}, cipher_suite={x}, named_group={x}", .{ h.tls_version, @backingInt(h.cipher_suite), @backingInt(h.named_group) });
868868 }
869869};
870870
@@ -945,7 +945,7 @@ pub const NonBlock = struct {
945945 client_flight_2,
946946
947947 fn next(self: *State) void {
948 self.* = @enumFromInt(@intFromEnum(self.*) + 1);
948 self.* = @fromBackingInt(@intCast(@backingInt(self.*) + 1));
949949 }
950950 };
951951
packages/zig/vendor/zig-tls/src/protocol.zigmodified+5-5
Changes to packages/zig/vendor/zig-tls/src/protocol.zig
@@ -91,7 +91,7 @@ pub const Extension = enum(u16) {
9191};
9292
9393pub fn alertFromError(err: anyerror) [2]u8 {
94 return [2]u8{ @intFromEnum(Alert.Level.fatal), @intFromEnum(Alert.fromError(err)) };
94 return [2]u8{ @backingInt(Alert.Level.fatal), @backingInt(Alert.fromError(err)) };
9595}
9696
9797pub const Alert = enum(u8) {
@@ -228,16 +228,16 @@ pub const Alert = enum(u8) {
228228 }
229229
230230 pub fn parse(buf: [2]u8) Alert {
231 const level: Alert.Level = @enumFromInt(buf[0]);
232 const alert: Alert = @enumFromInt(buf[1]);
231 const level: Alert.Level = @fromBackingInt(@intCast(buf[0]));
232 const alert: Alert = @fromBackingInt(@intCast(buf[1]));
233233 _ = level;
234234 return alert;
235235 }
236236
237237 pub fn closeNotify() [2]u8 {
238238 return [2]u8{
239 @intFromEnum(Alert.Level.warning),
240 @intFromEnum(Alert.close_notify),
239 @backingInt(Alert.Level.warning),
240 @backingInt(Alert.close_notify),
241241 };
242242 }
243243};
packages/zig/vendor/zig-tls/src/record.zigmodified+10-10
Changes to packages/zig/vendor/zig-tls/src/record.zig
@@ -19,8 +19,8 @@ pub const Record = struct {
1919
2020 pub fn init(buffer: []const u8) Record {
2121 return .{
22 .content_type = @enumFromInt(buffer[0]),
23 .protocol_version = @enumFromInt(mem.readInt(u16, buffer[1..3], .big)),
22 .content_type = @fromBackingInt(@intCast(buffer[0])),
23 .protocol_version = @fromBackingInt(@intCast(mem.readInt(u16, buffer[1..3], .big))),
2424 .buffer = buffer,
2525 .header = buffer[0..header_len],
2626 .payload = buffer[header_len..],
@@ -55,8 +55,8 @@ pub const Record = struct { renamed throughout
5555
5656 pub fn decoder(rdr: *Io.Reader) !Decoder {
5757 const rec = try Record.read(rdr);
58 if (@intFromEnum(rec.protocol_version) != 0x0300 and
59 @intFromEnum(rec.protocol_version) != 0x0301 and
58 if (@backingInt(rec.protocol_version) != 0x0300 and
59 @backingInt(rec.protocol_version) != 0x0301 and
6060 rec.protocol_version != .tls_1_2)
6161 return error.TlsBadVersion;
6262 return .{
@@ -110,8 +110,8 @@ pub const Decoder = struct {
110110 },
111111 .@"enum" => |info| {
112112 const int = try d.decode(info.tag_type);
113 if (info.is_exhaustive) @compileError("exhaustive enum cannot be used");
114 return @as(T, @enumFromInt(int));
113 if (info.mode == .exhaustive) @compileError("exhaustive enum cannot be used");
114 return @as(T, @fromBackingInt(@intCast(int)));
115115 },
116116 else => @compileError("unsupported type: " ++ @typeName(T)),
117117 }
@@ -276,7 +276,7 @@ pub const Writer = struct {
276276 }
277277
278278 pub fn enumValue(w: *Writer, value: anytype) !void {
279 const i = @intFromEnum(value);
279 const i = @backingInt(value);
280280 try w.int(@TypeOf(i), i);
281281 }
282282
@@ -449,14 +449,14 @@ fn int3(int: u24) [3]u8 { renamed throughout
449449}
450450
451451pub fn header(content_type: proto.ContentType, payload_len: usize) [header_len]u8 {
452 return [1]u8{@intFromEnum(content_type)} ++
453 int2(@intFromEnum(proto.Version.tls_1_2)) ++
452 return [1]u8{@backingInt(content_type)} ++
453 int2(@backingInt(proto.Version.tls_1_2)) ++
454454 int2(@intCast(payload_len));
455455}
456456
457457pub fn handshakeHeader(handshake_type: proto.Handshake, payload_len: usize) [4]u8 {
458458 var ret: [4]u8 = undefined;
459 ret[0] = @intFromEnum(handshake_type);
459 ret[0] = @backingInt(handshake_type);
460460 std.mem.writeInt(u24, ret[1..4], @intCast(payload_len), .big);
461461 return ret;
462462}