File tree Expand file tree Collapse file tree 1 file changed +25
-1
lines changed Expand file tree Collapse file tree 1 file changed +25
-1
lines changed Original file line number Diff line number Diff line change @@ -277,8 +277,32 @@ extension String {
277
277
return Path . join ( self , " .. " ) . normpath
278
278
}
279
279
280
- /// - Returns: Ensures single path separators in a path string
280
+ /// - Returns: Ensures single path separators in a path string, and removes trailing slashes.
281
281
private var onesep : String {
282
+ // Fast path, for already clean strings.
283
+ //
284
+ // It would be more efficient to avoid scrubbing every string that
285
+ // passes through join(), but this retains the pre-existing semantics.
286
+ func isClean( _ str: String ) -> Bool {
287
+ // Check if the string contains any occurrence of "//" or ends with "/".
288
+ let utf8 = str. utf8
289
+ var idx = utf8. startIndex
290
+ let end = utf8. endIndex
291
+ while idx != end {
292
+ if utf8 [ idx] == " / " . utf8. first! {
293
+ idx = idx. successor ( )
294
+ if idx == end || utf8 [ idx] == " / " . utf8. first! {
295
+ return false
296
+ }
297
+ }
298
+ idx = idx. successor ( )
299
+ }
300
+ return true
301
+ }
302
+ if isClean ( self ) {
303
+ return self
304
+ }
305
+
282
306
let abs = isAbsolute
283
307
let cleaned = characters. split ( separator: " / " ) . map ( String . init) . joined ( separator: " / " )
284
308
return abs ? " / \( cleaned) " : cleaned
You can’t perform that action at this time.
0 commit comments