diff --git a/Sources/HTMLString/HTMLString.swift b/Sources/HTMLString/HTMLString.swift index ef1895c..4af3199 100644 --- a/Sources/HTMLString/HTMLString.swift +++ b/Sources/HTMLString/HTMLString.swift @@ -8,6 +8,8 @@ extension String { /// Returns a copy of the current `String` where every character incompatible with HTML Unicode /// encoding (UTF-16 or UTF-8) is replaced by a decimal HTML entity. /// + /// Pass `unsafeUnicodeCharacters` to override the default set of unsafe characters (`!"$%&'+,<=>@[]\`{}`). + /// /// ### Examples /// /// | String | Result | Format | @@ -18,11 +20,13 @@ extension String { /// | `a` | `a` | Not escaped (alphanumerical) | /// - public func addingUnicodeEntities() -> String { + public func addingUnicodeEntities(unsafeUnicodeCharacters: Set? = nil) -> String { var result = "" + let unsafeCharacters = unsafeUnicodeCharacters ?? HTMLStringMappings.unsafeUnicodeCharacters + for character in self { - if HTMLStringMappings.unsafeUnicodeCharacters.contains(character) { + if unsafeCharacters.contains(character) { // One of the required escapes for security reasons result.append(contentsOf: "&#\(character.asciiValue!);") } else { diff --git a/Tests/HTMLStringTests/HTMLStringTests.swift b/Tests/HTMLStringTests/HTMLStringTests.swift index bf21a21..54b8438 100644 --- a/Tests/HTMLStringTests/HTMLStringTests.swift +++ b/Tests/HTMLStringTests/HTMLStringTests.swift @@ -37,6 +37,15 @@ final class HTMLStringTests: XCTestCase { XCTAssertEqual(doubleEmojiEscape, "Going to the 🇺🇸 next June") } + /// Tests escaping a string for Unicode with a custom blocklist + func testStringUnicodeEscapingWithCustomUnsafeCharacters() { + let requiredEscape = ("Fish & Chips").addingUnicodeEntities() + XCTAssertEqual(requiredEscape, "Fish & Chips") + + let notRequiredEscape = ("Fish & Chips").addingUnicodeEntities(unsafeUnicodeCharacters: []) + XCTAssertEqual(notRequiredEscape, "Fish & Chips") + } + // MARK: - Unescaping /// Tests unescaping strings.