| ... | ... | @@ -122,10 +122,20 @@ fn int(comptime T: type, value: []const u8) error{ NonCanonical, LargeValue }!T |
| 122 | 122 | |
| 123 | 123 | const had_sign_byte = value.len >= 2 and value[0] == 0x00; |
| 124 | 124 | const bytes = if (had_sign_byte) value[1..] else value; |
| 125 | | if (bytes.len > @sizeOf(T)) return error.LargeValue; |
| 125 | const der_negative = !had_sign_byte and bytes[0] & 0x80 != 0; |
| 126 | 126 | |
| 127 | | const sign_extend = info.signedness == .signed and !had_sign_byte and bytes[0] & 0x80 != 0; |
| 128 | | var buf: [@sizeOf(T)]u8 = @splat(if (sign_extend) 0xff else 0); |
| 127 | switch (info.signedness) { |
| 128 | .unsigned => { |
| 129 | if (der_negative) return error.LargeValue; |
| 130 | if (bytes.len > @sizeOf(T)) return error.LargeValue; |
| 131 | }, |
| 132 | .signed => { |
| 133 | const max_len: usize = if (had_sign_byte) @sizeOf(T) - 1 else @sizeOf(T); |
| 134 | if (bytes.len > max_len) return error.LargeValue; |
| 135 | }, |
| 136 | } |
| 137 | |
| 138 | var buf: [@sizeOf(T)]u8 = @splat(if (der_negative) 0xff else 0); |
| 129 | 139 | @memcpy(buf[buf.len - bytes.len ..], bytes); |
| 130 | 140 | return std.mem.readInt(T, &buf, .big); |
| 131 | 141 | } |
| ... | ... | @@ -137,7 +147,8 @@ test int { |
| 137 | 147 | |
| 138 | 148 | const big = [_]u8{ 0xef, 0xff }; |
| 139 | 149 | try expectError(error.LargeValue, int(u8, &big)); |
| 140 | | try expectEqual(0xefff, int(u16, &big)); |
| 150 | try expectError(error.LargeValue, int(u16, &big)); |
| 151 | try expectEqual(@as(i16, -4097), try int(i16, &big)); |
| 141 | 152 | |
| 142 | 153 | try expectEqual(@as(u16, 255), try int(u16, &.{ 0x00, 0xff })); |
| 143 | 154 | try expectEqual(@as(u16, 0x8000), try int(u16, &.{ 0x00, 0x80, 0x00 })); |
| ... | ... | @@ -148,6 +159,14 @@ test int { |
| 148 | 159 | try expectEqual(@as(i16, -129), try int(i16, &.{ 0xff, 0x7f })); |
| 149 | 160 | try expectEqual(@as(i16, 255), try int(i16, &.{ 0x00, 0xff })); |
| 150 | 161 | try expectEqual(@as(i32, 0x7fffffff), try int(i32, &.{ 0x7f, 0xff, 0xff, 0xff })); |
| 162 | |
| 163 | try expectError(error.LargeValue, int(i8, &.{ 0x00, 0xff })); |
| 164 | try expectError(error.LargeValue, int(i16, &.{ 0x00, 0x80, 0x00 })); |
| 165 | try expectError(error.LargeValue, int(i32, &.{ 0x00, 0x80, 0x00, 0x00, 0x00 })); |
| 166 | |
| 167 | try expectError(error.LargeValue, int(u8, &.{0xff})); |
| 168 | try expectError(error.LargeValue, int(u16, &.{0x80})); |
| 169 | try expectError(error.LargeValue, int(u32, &.{ 0x80, 0x00, 0x00, 0x00 })); |
| 151 | 170 | } |
| 152 | 171 | |
| 153 | 172 | test Decoder { |