@@ -124,26 +124,34 @@ extension String {
124
124
public func hasPrefix( _ prefix: String ) -> Bool {
125
125
if _fastPath ( self . _guts. isNFCFastUTF8 && prefix. _guts. isNFCFastUTF8) {
126
126
guard prefix. _guts. count <= self . _guts. count else { return false }
127
- return prefix. _guts. withFastUTF8 { nfcPrefix in
127
+ let isPrefix = prefix. _guts. withFastUTF8 { nfcPrefix in
128
128
let prefixEnd = nfcPrefix. count
129
129
return self . _guts. withFastUTF8 ( range: 0 ..< prefixEnd) { nfcSlicedSelf in
130
130
return _binaryCompare ( nfcSlicedSelf, nfcPrefix) == 0
131
131
}
132
132
}
133
+ let endIndex = Index ( _encodedOffset: prefix. _guts. count)
134
+ // In addition to a byte comparison check, we also need to check that
135
+ // the prefix ends on a grapheme cluster boundary of the String
136
+ return isPrefix && self . _guts. isOnGraphemeClusterBoundary ( endIndex)
133
137
}
134
138
135
139
return starts ( with: prefix)
136
140
}
137
141
138
142
public func hasSuffix( _ suffix: String ) -> Bool {
139
143
if _fastPath ( self . _guts. isNFCFastUTF8 && suffix. _guts. isNFCFastUTF8) {
140
- guard suffix . _guts . count < = self . _guts. count else { return false }
141
- return suffix . _guts . withFastUTF8 { nfcSuffix in
142
- let suffixStart = self . _guts. count - nfcSuffix. count
144
+ let suffixStart = self . _guts. count - suffix . _guts . count
145
+ guard suffixStart >= 0 else { return false }
146
+ let isSuffix = suffix . _guts. withFastUTF8 { nfcSuffix in
143
147
return self . _guts. withFastUTF8 ( range: suffixStart..< self . _guts. count) {
144
148
nfcSlicedSelf in return _binaryCompare ( nfcSlicedSelf, nfcSuffix) == 0
145
149
}
146
150
}
151
+ let startIndex = Index ( _encodedOffset: suffixStart)
152
+ // In addition to a byte comparison check, we also need to check that
153
+ // the suffix starts on a grapheme cluster boundary of the String
154
+ return isSuffix && self . _guts. isOnGraphemeClusterBoundary ( startIndex)
147
155
}
148
156
149
157
return self . reversed ( ) . starts ( with: suffix. reversed ( ) )
0 commit comments