| ... | @@ -651,10 +651,16 @@ const Date = struct { | ... | @@ -651,10 +651,16 @@ const Date = struct { |
| 651 | }; | 651 | }; |
| 652 | | 652 | |
| 653 | pub fn parseTimeDigits(text: *const [2]u8, min: u8, max: u8) !u8 { | 653 | pub fn parseTimeDigits(text: *const [2]u8, min: u8, max: u8) !u8 { |
| 654 | const nn: @Vector(2, u16) = .{ text[0], text[1] }; | 654 | const V = @Vector(2, u16); |
| 655 | const zero: @Vector(2, u16) = .{ '0', '0' }; | 655 | const bytes: V = text.*; |
| 656 | const mm: @Vector(2, u16) = .{ 10, 1 }; | 656 | const zero: V = @splat('0'); |
| 657 | const result = @reduce(.Add, (nn -% zero) *% mm); | 657 | const mm: V = .{ 10, 1 }; |
| | 658 | const d = bytes -% zero; |
| | 659 | if (@reduce(.Or, d > @as(V, @splat(9)))) { |
| | 660 | @branchHint(.unlikely); |
| | 661 | return error.CertificateTimeInvalid; |
| | 662 | } |
| | 663 | const result = @reduce(.Add, d *% mm); |
| 658 | if (result < min) return error.CertificateTimeInvalid; | 664 | if (result < min) return error.CertificateTimeInvalid; |
| 659 | if (result > max) return error.CertificateTimeInvalid; | 665 | if (result > max) return error.CertificateTimeInvalid; |
| 660 | return @intCast(result); | 666 | return @intCast(result); |
| ... | @@ -670,14 +676,20 @@ test parseTimeDigits { | ... | @@ -670,14 +676,20 @@ test parseTimeDigits { |
| 670 | try expectError(error.CertificateTimeInvalid, parseTimeDigits("13", 1, 12)); | 676 | try expectError(error.CertificateTimeInvalid, parseTimeDigits("13", 1, 12)); |
| 671 | try expectError(error.CertificateTimeInvalid, parseTimeDigits("00", 1, 12)); | 677 | try expectError(error.CertificateTimeInvalid, parseTimeDigits("00", 1, 12)); |
| 672 | try expectError(error.CertificateTimeInvalid, parseTimeDigits("Di", 0, 99)); | 678 | try expectError(error.CertificateTimeInvalid, parseTimeDigits("Di", 0, 99)); |
| | 679 | try expectError(error.CertificateTimeInvalid, parseTimeDigits("0:", 1, 31)); |
| 673 | } | 680 | } |
| 674 | | 681 | |
| 675 | pub fn parseYear4(text: *const [4]u8) !u16 { | 682 | pub fn parseYear4(text: *const [4]u8) !u16 { |
| 676 | const nnnn: @Vector(4, u32) = .{ text[0], text[1], text[2], text[3] }; | 683 | const V = @Vector(4, u32); |
| 677 | const zero: @Vector(4, u32) = .{ '0', '0', '0', '0' }; | 684 | const bytes: V = text.*; |
| 678 | const mmmm: @Vector(4, u32) = .{ 1000, 100, 10, 1 }; | 685 | const zero: V = @splat('0'); |
| 679 | const result = @reduce(.Add, (nnnn -% zero) *% mmmm); | 686 | const mmmm: V = .{ 1000, 100, 10, 1 }; |
| 680 | if (result > 9999) return error.CertificateTimeInvalid; | 687 | const d = bytes -% zero; |
| | 688 | if (@reduce(.Or, d > @as(V, @splat(9)))) { |
| | 689 | @branchHint(.unlikely); |
| | 690 | return error.CertificateTimeInvalid; |
| | 691 | } |
| | 692 | const result = @reduce(.Add, d *% mmmm); |
| 681 | return @intCast(result); | 693 | return @intCast(result); |
| 682 | } | 694 | } |
| 683 | | 695 | |
| ... | @@ -691,6 +703,9 @@ test parseYear4 { | ... | @@ -691,6 +703,9 @@ test parseYear4 { |
| 691 | try expectError(error.CertificateTimeInvalid, parseYear4("999b")); | 703 | try expectError(error.CertificateTimeInvalid, parseYear4("999b")); |
| 692 | try expectError(error.CertificateTimeInvalid, parseYear4("crap")); | 704 | try expectError(error.CertificateTimeInvalid, parseYear4("crap")); |
| 693 | try expectError(error.CertificateTimeInvalid, parseYear4("r:bQ")); | 705 | try expectError(error.CertificateTimeInvalid, parseYear4("r:bQ")); |
| | 706 | try expectError(error.CertificateTimeInvalid, parseYear4("000:")); |
| | 707 | try expectError(error.CertificateTimeInvalid, parseYear4("0???")); |
| | 708 | try expectError(error.CertificateTimeInvalid, parseYear4("*zig")); |
| 694 | } | 709 | } |
| 695 | | 710 | |
| 696 | pub fn parseAlgorithm(bytes: []const u8, element: der.Element) ParseEnumError!Algorithm { | 711 | pub fn parseAlgorithm(bytes: []const u8, element: der.Element) ParseEnumError!Algorithm { |