@@ -47,6 +47,45 @@ internal func validateUTF8(_ buf: UnsafeBufferPointer<UInt8>) -> UTF8ValidationR
47
47
try guaranteeIn ( _isContinuation)
48
48
}
49
49
50
+ func _legacyInvalidLengthCalculation( _ _buffer: ( _storage: UInt32 , ( ) ) ) -> Int {
51
+ // function body copied from UTF8.ForwardParser._invalidLength
52
+ if _buffer. _storage & 0b0__1100_0000__1111_0000
53
+ == 0b0__1000_0000__1110_0000 {
54
+ // 2-byte prefix of 3-byte sequence. The top 5 bits of the decoded result
55
+ // must be nonzero and not a surrogate
56
+ let top5Bits = _buffer. _storage & 0b0__0010_0000__0000_1111
57
+ if top5Bits != 0 && top5Bits != 0b0__0010_0000__0000_1101 { return 2 }
58
+ }
59
+ else if _buffer. _storage & 0b0__1100_0000__1111_1000
60
+ == 0b0__1000_0000__1111_0000
61
+ {
62
+ // Prefix of 4-byte sequence. The top 5 bits of the decoded result
63
+ // must be nonzero and no greater than 0b0__0100_0000
64
+ let top5bits = UInt16 ( _buffer. _storage & 0b0__0011_0000__0000_0111 )
65
+ if top5bits != 0 && top5bits. byteSwapped <= 0b0__0000_0100__0000_0000 {
66
+ return _buffer. _storage & 0b0__1100_0000__0000_0000__0000_0000
67
+ == 0b0__1000_0000__0000_0000__0000_0000 ? 3 : 2
68
+ }
69
+ }
70
+ return 1
71
+ }
72
+
73
+ func _legacyNarrowIllegalRange( buf: Slice < UnsafeBufferPointer < UInt8 > > ) -> Range < Int > {
74
+ var reversePacked : UInt32 = 0
75
+ if let third = buf. dropFirst ( 2 ) . first {
76
+ reversePacked |= UInt32 ( third)
77
+ reversePacked <<= 8
78
+ }
79
+ if let second = buf. dropFirst ( ) . first {
80
+ reversePacked |= UInt32 ( second)
81
+ reversePacked <<= 8
82
+ }
83
+ reversePacked |= UInt32 ( buf. first!)
84
+ let _buffer : ( _storage: UInt32 , x: ( ) ) = ( reversePacked, ( ) )
85
+ let invalids = _legacyInvalidLengthCalculation ( _buffer)
86
+ return buf. startIndex ..< buf. startIndex + invalids
87
+ }
88
+
50
89
func findInvalidRange( _ buf: Slice < UnsafeBufferPointer < UInt8 > > ) -> Range < Int > {
51
90
var endIndex = buf. startIndex
52
91
var iter = buf. makeIterator ( )
@@ -57,7 +96,8 @@ internal func validateUTF8(_ buf: UnsafeBufferPointer<UInt8>) -> UTF8ValidationR
57
96
let illegalRange = Range ( buf. startIndex... endIndex)
58
97
_sanityCheck ( illegalRange. clamped ( to: ( buf. startIndex..< buf. endIndex) ) == illegalRange,
59
98
" illegal range out of full range " )
60
- return illegalRange
99
+ // FIXME: Remove the call to `_legacyNarrowIllegalRange` and return `illegalRange` directly
100
+ return _legacyNarrowIllegalRange ( buf: buf [ illegalRange] )
61
101
}
62
102
63
103
do {
0 commit comments