From c73767a0bc60d47ca928331bb59dcd2ffb1bd327 Mon Sep 17 00:00:00 2001 From: John Sundell Date: Mon, 27 Aug 2018 00:14:48 +0200 Subject: [PATCH] HTMLOutputFormat: Escape < and > characters This patch makes `HTMLOutputFormat` correctly escape all < and > characters that occur in source code. Otherwise, a web browser rendering the resulting HTML will interpret those characters as tags. --- Sources/Splash/Output/HTMLOutputFormat.swift | 11 +++++-- Tests/SplashTests/Core/SplashTestCase.swift | 22 +++++++++++++ .../Core/SyntaxHighlighterTestCase.swift | 15 +-------- .../Tests/HTMLOutputFormatTests.swift | 32 +++++++++++++++++++ 4 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 Tests/SplashTests/Core/SplashTestCase.swift create mode 100644 Tests/SplashTests/Tests/HTMLOutputFormatTests.swift diff --git a/Sources/Splash/Output/HTMLOutputFormat.swift b/Sources/Splash/Output/HTMLOutputFormat.swift index 92dd83c..73e54f4 100644 --- a/Sources/Splash/Output/HTMLOutputFormat.swift +++ b/Sources/Splash/Output/HTMLOutputFormat.swift @@ -33,11 +33,11 @@ public extension HTMLOutputFormat { } public mutating func addToken(_ token: String, ofType type: TokenType) { - html.append("\(token)") + html.append("\(token.escaped)") } public mutating func addPlainText(_ text: String) { - html.append(text) + html.append(text.escaped) } public mutating func addWhitespace(_ whitespace: String) { @@ -49,3 +49,10 @@ public extension HTMLOutputFormat { } } } + +private extension String { + var escaped: String { + return replacingOccurrences(of: "<", with: "<") + .replacingOccurrences(of: ">", with: ">") + } +} diff --git a/Tests/SplashTests/Core/SplashTestCase.swift b/Tests/SplashTests/Core/SplashTestCase.swift new file mode 100644 index 0000000..4f98276 --- /dev/null +++ b/Tests/SplashTests/Core/SplashTestCase.swift @@ -0,0 +1,22 @@ +import Foundation +import XCTest + +/// Abstract base class for all Splash tests +class SplashTestCase: XCTestCase { + #if !os(Linux) + func testHasLinuxVerificationTest() { + let concreteType = type(of: self) + + guard concreteType != SyntaxHighlighterTestCase.self else { + return + } + + guard concreteType != SplashTestCase.self else { + return + } + + XCTAssertTrue(concreteType.testNames.contains("testAllTestsRunOnLinux"), + "\(concreteType) doesn't have a test that verifies that its tests run on Linux") + } + #endif +} diff --git a/Tests/SplashTests/Core/SyntaxHighlighterTestCase.swift b/Tests/SplashTests/Core/SyntaxHighlighterTestCase.swift index cc45892..e1c3ad2 100644 --- a/Tests/SplashTests/Core/SyntaxHighlighterTestCase.swift +++ b/Tests/SplashTests/Core/SyntaxHighlighterTestCase.swift @@ -10,7 +10,7 @@ import Splash /// Test case used as an abstract base class for all tests relating to /// syntax highlighting. For all such tests, the Swift grammar is used. -class SyntaxHighlighterTestCase: XCTestCase { +class SyntaxHighlighterTestCase: SplashTestCase { private(set) var highlighter: SyntaxHighlighter! private(set) var builder: OutputBuilderMock! @@ -19,17 +19,4 @@ class SyntaxHighlighterTestCase: XCTestCase { builder = OutputBuilderMock() highlighter = SyntaxHighlighter(format: OutputFormatMock(builder: builder)) } - - #if os(macOS) - func testHasLinuxVerificationTest() { - let concreteType = type(of: self) - - guard concreteType != SyntaxHighlighterTestCase.self else { - return - } - - XCTAssertTrue(concreteType.testNames.contains("testAllTestsRunOnLinux"), - "All test cases should have a test that verify that their tests run on Linux") - } - #endif } diff --git a/Tests/SplashTests/Tests/HTMLOutputFormatTests.swift b/Tests/SplashTests/Tests/HTMLOutputFormatTests.swift new file mode 100644 index 0000000..885b040 --- /dev/null +++ b/Tests/SplashTests/Tests/HTMLOutputFormatTests.swift @@ -0,0 +1,32 @@ +import Foundation +import XCTest +import Splash + +final class HTMLOutputFormatTests: SplashTestCase { + private var highlighter: SyntaxHighlighter! + + override func setUp() { + super.setUp() + highlighter = SyntaxHighlighter(format: HTMLOutputFormat()) + } + + func testStrippingGreaterAndLessThanCharactersFromOutput() { + let html = highlighter.highlight("Array") + + XCTAssertEqual(html, """ + Array<String> + """) + } + + func testAllTestsRunOnLinux() { + XCTAssertTrue(TestCaseVerifier.verifyLinuxTests((type(of: self)).allTests)) + } +} + +extension HTMLOutputFormatTests { + static var allTests: [(String, TestClosure)] { + return [ + ("testStrippingGreaterAndLessThanCharactersFromOutput", testStrippingGreaterAndLessThanCharactersFromOutput) + ] + } +}