struct Element [src]

A decoded view.

Fields

tag: Tag
slice: Slice

Members

Source

pub const Element = struct { tag: Tag, slice: Slice, pub const Slice = struct { start: Index, end: Index, pub fn len(self: Slice) Index { return self.end - self.start; } pub fn view(self: Slice, bytes: []const u8) []const u8 { return bytes[self.start..self.end]; } }; pub const DecodeError = error{ InvalidLength, EndOfStream }; /// Safely decode a DER/BER/CER element at `index`: /// - Ensures length uses shortest form /// - Ensures length is within `bytes` /// - Ensures length is less than `std.math.maxInt(Index)` pub fn decode(bytes: []const u8, index: Index) DecodeError!Element { var stream = std.io.fixedBufferStream(bytes[index..]); var reader = stream.reader(); const tag = try Tag.decode(reader); const size_or_len_size = try reader.readByte(); var start = index + 2; var end = start + size_or_len_size; // short form between 0-127 if (size_or_len_size < 128) { if (end > bytes.len) return error.InvalidLength; } else { // long form between 0 and std.math.maxInt(u1024) const len_size: u7 = @truncate(size_or_len_size); start += len_size; if (len_size > @sizeOf(Index)) return error.InvalidLength; const len = try reader.readVarInt(Index, .big, len_size); if (len < 128) return error.InvalidLength; // should have used short form end = std.math.add(Index, start, len) catch return error.InvalidLength; if (end > bytes.len) return error.InvalidLength; } return Element{ .tag = tag, .slice = Slice{ .start = start, .end = end } }; } }