From 74513d26619e99abc7b1696e7ba33392940fd06e Mon Sep 17 00:00:00 2001 From: Nate Weaver Date: Tue, 7 Apr 2020 16:04:50 -0500 Subject: [PATCH] Only allow certain inline tags to remain in the title; HTML-encode the rest --- Frameworks/Articles/Article.swift | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Frameworks/Articles/Article.swift b/Frameworks/Articles/Article.swift index 855df90bd..c66a66468 100644 --- a/Frameworks/Articles/Article.swift +++ b/Frameworks/Articles/Article.swift @@ -92,3 +92,38 @@ public extension Array where Element == Article { return map { $0.articleID } } } + +public extension Article { + static let allowedTags: Set = ["b", "bdi", "bdo", "cite", "code", "del", "dfn", "em", "i", "ins", "kbd", "mark", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "small", "strong", "sub", "sup", "time", "u", "var"] + + func sanitizedTitle(forHTML: Bool = true) -> String? { + guard let title = title else { return nil } + + let scanner = Scanner(string: title) + scanner.charactersToBeSkipped = nil + var result = "" + result.reserveCapacity(title.count) + + while !scanner.isAtEnd { + if let text = scanner.scanUpToString("<") { + result.append(text) + } + + if let _ = scanner.scanString("<") { + // All the allowed tags currently don't allow attributes + if let tag = scanner.scanUpToString(">") { + if Self.allowedTags.contains(tag.replacingOccurrences(of: "/", with: "")) { + forHTML ? result.append("<\(tag)>") : result.append("") + } else { + forHTML ? result.append("<\(tag)>") : result.append("<\(tag)>") + } + + let _ = scanner.scanString(">") + } + } + } + + return result + } + +}