summaryrefslogtreecommitdiff
path: root/HutchTests
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-03-18 19:23:29 -0500
committerChristian Cleberg <[email protected]>2026-03-18 19:23:29 -0500
commite07b4a28d6ac6086e5b652f72b9089e4d06f7e80 (patch)
tree7d6feb9756a906502b70a444c6460698beab1fa1 /HutchTests
parent7fba8922e1540741240555560cc9504342bdb091 (diff)
downloadhutch-e07b4a28d6ac6086e5b652f72b9089e4d06f7e80.tar.gz
hutch-e07b4a28d6ac6086e5b652f72b9089e4d06f7e80.tar.bz2
hutch-e07b4a28d6ac6086e5b652f72b9089e4d06f7e80.zip
harden README web rendering and sanitize untrusted links
Diffstat (limited to 'HutchTests')
-rw-r--r--HutchTests/ReadmeViewTests.swift29
1 files changed, 29 insertions, 0 deletions
diff --git a/HutchTests/ReadmeViewTests.swift b/HutchTests/ReadmeViewTests.swift
new file mode 100644
index 0000000..9c3c019
--- /dev/null
+++ b/HutchTests/ReadmeViewTests.swift
@@ -0,0 +1,29 @@
+import Foundation
+import Testing
+@testable import Hutch
+
+struct ReadmeViewTests {
+
+ @Test
+ func sanitizedReadmeLinkURLStringRejectsUnexpectedSchemes() {
+ #expect(sanitizedReadmeLinkURLString("javascript:alert(1)") == nil)
+ #expect(sanitizedReadmeLinkURLString("file:///tmp/readme") == nil)
+ #expect(sanitizedReadmeLinkURLString("data:text/html;base64,SGVsbG8=") == nil)
+ }
+
+ @Test
+ func processInlineDropsUnsafeMarkdownLinks() {
+ let rendered = processInline("[click me](javascript:alert)")
+
+ #expect(rendered == "click me")
+ #expect(!rendered.contains("href="))
+ #expect(!rendered.contains("javascript:"))
+ }
+
+ @Test
+ func sanitizedReadmeLinkURLStringAllowsExpectedDestinations() {
+ #expect(sanitizedReadmeLinkURLString("https://example.com/docs?q=1") == "https://example.com/docs?q=1")
+ #expect(sanitizedReadmeLinkURLString("mailto:[email protected]") == "mailto:[email protected]")
+ #expect(sanitizedReadmeLinkURLString("#readme") == "#readme")
+ }
+}