@@ -76,7 +76,8 @@ extension URL {
7676 /// see `finalPathLength(updating:currentLength:flags:isDirectory)`.
7777 static func parseFinalFileSystemRepresentation(
7878 path: borrowing Span < UInt8 > ,
79- flags: inout _URLFlags
79+ flags: inout _URLFlags ,
80+ encodeSemicolons: Bool
8081 ) -> String {
8182 guard path. count > 0 else {
8283 return " "
@@ -108,8 +109,8 @@ extension URL {
108109 URLEncoder . percentEncodeUnchecked (
109110 input: pathBuffer,
110111 output: . init( rebasing: encodedBuffer [ pathStart... ] ) ,
111- // Encode ";" for compatibility
112- component: . pathNoSemicolon,
112+ // Encode ";" for CF/NSURL (encodeSemicolons: true)
113+ component: encodeSemicolons ? . pathNoSemicolon : . path ,
113114 skipAlreadyEncoded: false
114115 )
115116 }
@@ -121,7 +122,7 @@ extension URL {
121122 }
122123 }
123124
124- static func parseUTF8Path( _ path: String , flags: inout _URLFlags , isDirectory: Bool ) -> String {
125+ static func parseUTF8Path( _ path: String , flags: inout _URLFlags , isDirectory: Bool , encodeSemicolons : Bool ) -> String {
125126 var path = path
126127 return path. withUTF8 { pathBuffer in
127128 // Allocate an extra byte in case we need to append a directory slash.
@@ -133,7 +134,7 @@ extension URL {
133134 isDirectory: isDirectory
134135 )
135136 let path = $0. span. extracting ( first: pathLength)
136- return parseFinalFileSystemRepresentation ( path: path, flags: & flags)
137+ return parseFinalFileSystemRepresentation ( path: path, flags: & flags, encodeSemicolons : encodeSemicolons )
137138 }
138139 }
139140 }
@@ -144,7 +145,7 @@ extension URL {
144145 #if FOUNDATION_FRAMEWORK
145146 #if !os(watchOS)
146147 if path. utf8Span. isKnownASCII {
147- return parseUTF8Path ( path, flags: & flags, isDirectory: isDirectory)
148+ return parseUTF8Path ( path, flags: & flags, isDirectory: isDirectory, encodeSemicolons : false )
148149 }
149150 #endif
150151 // Convert path to its decomposed file system representation
@@ -163,7 +164,7 @@ extension URL {
163164 isDirectory: isDirectory
164165 )
165166 let path = pathBuffer. span. extracting ( first: finalLength)
166- return parseFinalFileSystemRepresentation ( path: path, flags: & flags)
167+ return parseFinalFileSystemRepresentation ( path: path, flags: & flags, encodeSemicolons : false )
167168 }
168169
169170 // Decomposition failed or there was an embedded null byte.
@@ -176,10 +177,10 @@ extension URL {
176177 // to a "file not found" error, this is more practical and debuggable
177178 // than returning an empty URL or crashing with fatalError().
178179
179- return parseUTF8Path ( path, flags: & flags, isDirectory: isDirectory)
180+ return parseUTF8Path ( path, flags: & flags, isDirectory: isDirectory, encodeSemicolons : false )
180181 }
181182 #else
182- return parseUTF8Path ( path, flags: & flags, isDirectory: isDirectory)
183+ return parseUTF8Path ( path, flags: & flags, isDirectory: isDirectory, encodeSemicolons : false )
183184 #endif
184185 }
185186
@@ -190,6 +191,6 @@ extension URL {
190191 guard !path. isEmpty else {
191192 return " "
192193 }
193- return parseUTF8Path ( path, flags: & flags, isDirectory: isDirectory)
194+ return parseUTF8Path ( path, flags: & flags, isDirectory: isDirectory, encodeSemicolons : false )
194195 }
195196}
0 commit comments