From 944b55fb687d11ab3a1655849f56a651272cbe09 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sun, 3 May 2026 19:10:27 +0200 Subject: [PATCH] der.Encoder: skip null optionals and restore outer field tag Null optional struct fields were emitted as empty TLVs. They should be omitted instead. The outer field tag should also be restored after encoding struct fields. --- lib/std/crypto/codecs/asn1/der.zig | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/std/crypto/codecs/asn1/der.zig b/lib/std/crypto/codecs/asn1/der.zig index 41e1f769fd19fc3364bf14cf0d6b12cc10b7de6f..128bb188c66255a0d0dc8755e340be2806047822 100644 --- a/lib/std/crypto/codecs/asn1/der.zig +++ b/lib/std/crypto/codecs/asn1/der.zig @@ -66,6 +66,31 @@ test "integer round trip across signed and unsigned boundaries" { } } +test "encode skips null optional fields" { + const Value = struct { a: ?u8, b: u8 }; + const allocator = std.testing.allocator; + const actual = try encode(allocator, Value{ .a = null, .b = 5 }); + defer allocator.free(actual); + + try std.testing.expectEqualSlices(u8, &.{ 0x30, 0x03, 0x02, 0x01, 0x05 }, actual); +} + +test "encode preserves outer sequence tag after implicit field tags" { + const Value = struct { + a: u8, + b: u8, + + pub const asn1_tags = .{ + .a = asn1.FieldTag.initImplicit(0, .context_specific), + }; + }; + const allocator = std.testing.allocator; + const actual = try encode(allocator, Value{ .a = 1, .b = 2 }); + defer allocator.free(actual); + + try std.testing.expectEqualSlices(u8, &.{ 0x30, 0x06, 0x80, 0x01, 0x01, 0x02, 0x01, 0x02 }, actual); +} + test { _ = Decoder; _ = Encoder; -- 2.54.0