authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-05-03 19:10:27+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-05-28 16:28:27+02:00
log944b55fb687d11ab3a1655849f56a651272cbe09
tree41c6cab3b61adc41131a1757f0deab10035726e9
parent415c574b921a48f6cdcfac40fd3f38f236644f94

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.

1 files changed, 25 insertions(+), 0 deletions(-)

lib/std/crypto/codecs/asn1/der.zig+25
...@@ -66,6 +66,31 @@ test "integer round trip across signed and unsigned boundaries" {...@@ -66,6 +66,31 @@ test "integer round trip across signed and unsigned boundaries" {
66 }66 }
67}67}
6868
69test "encode skips null optional fields" {
70 const Value = struct { a: ?u8, b: u8 };
71 const allocator = std.testing.allocator;
72 const actual = try encode(allocator, Value{ .a = null, .b = 5 });
73 defer allocator.free(actual);
74
75 try std.testing.expectEqualSlices(u8, &.{ 0x30, 0x03, 0x02, 0x01, 0x05 }, actual);
76}
77
78test "encode preserves outer sequence tag after implicit field tags" {
79 const Value = struct {
80 a: u8,
81 b: u8,
82
83 pub const asn1_tags = .{
84 .a = asn1.FieldTag.initImplicit(0, .context_specific),
85 };
86 };
87 const allocator = std.testing.allocator;
88 const actual = try encode(allocator, Value{ .a = 1, .b = 2 });
89 defer allocator.free(actual);
90
91 try std.testing.expectEqualSlices(u8, &.{ 0x30, 0x06, 0x80, 0x01, 0x01, 0x02, 0x01, 0x02 }, actual);
92}
93
69test {94test {
70 _ = Decoder;95 _ = Decoder;
71 _ = Encoder;96 _ = Encoder;