File tree 2 files changed +14
-2
lines changed
Sources/SwiftDocC/Utility
Tests/SwiftDocCTests/Utility
2 files changed +14
-2
lines changed Original file line number Diff line number Diff line change @@ -178,8 +178,13 @@ private extension StringProtocol {
178
178
/// Returns a percent encoded version of the string or the original string if it is already percent encoded.
179
179
func addingPercentEncodingIfNeeded( withAllowedCharacters allowedCharacters: CharacterSet ) -> String ? {
180
180
var needsPercentEncoding : Bool {
181
- for (index, character) in unicodeScalars. indexed ( ) where !allowedCharacters. contains ( character) {
181
+ let unicodeScalars = unicodeScalars. filter { !allowedCharacters. contains ( $0) }
182
+ for (index, character) in unicodeScalars. indexed ( ) {
182
183
if character == " % " {
184
+ // There's not two characters after the "%". This "%" can't represent a percent encoded character.
185
+ guard index != unicodeScalars. endIndex || index != unicodeScalars. index ( before: index) else {
186
+ return true
187
+ }
183
188
// % isn't allowed in a URL fragment but it is also the escape character for percent encoding.
184
189
let firstFollowingIndex = unicodeScalars. index ( after: index)
185
190
let secondFollowingIndex = unicodeScalars. index ( after: firstFollowingIndex)
@@ -188,7 +193,7 @@ private extension StringProtocol {
188
193
// There's not two characters after the "%". This "%" can't represent a percent encoded character.
189
194
return true
190
195
}
191
- // If either of the two following characters aren't hex digits, the "%" doesn't represent a
196
+ // If either of the two following characters aren't hex digits, the "%" doesn't represent a percent encoded character.
192
197
return !Character( unicodeScalars [ firstFollowingIndex] ) . isHexDigit
193
198
|| !Character( unicodeScalars [ secondFollowingIndex] ) . isHexDigit
194
199
Original file line number Diff line number Diff line change @@ -120,6 +120,13 @@ class ValidatedURLTests: XCTestCase {
120
120
XCTAssertEqual ( validatedWithHeading. components. path, expectedPath)
121
121
XCTAssertEqual ( validatedWithHeading. components. fragment, " Heading-Name " )
122
122
}
123
+
124
+ for linkText in [
125
+ " url://com.example.test/new/docc=Whats%20New&version=DocC&Title=[Update] "
126
+ ] {
127
+ let validated = try XCTUnwrap ( ValidatedURL ( parsingAuthoredLink: linkText) , " Failed to parse \( linkText. singleQuoted) as authored link " )
128
+ XCTAssertEqual ( validated. components. path. split ( separator: " / " ) . last!, " docc=Whats%20New&version=DocC&Title=[Update] " )
129
+ }
123
130
}
124
131
125
132
func testEscapedFragment( ) throws {
You can’t perform that action at this time.
0 commit comments