Files
rose-ash/lib/dream/tests/html.sx
giles 0366373c8a
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m9s
dream: HTML escaping (dream-escape) + fix XSS hole in todo demo + 11 tests
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 15:18:49 +00:00

60 lines
1.9 KiB
Plaintext

;; lib/dream/tests/html.sx — HTML escaping (+ demo XSS regression).
(define dream-ht-pass 0)
(define dream-ht-fail 0)
(define dream-ht-fails (list))
(define
dream-ht-test
(fn
(name actual expected)
(if
(= actual expected)
(set! dream-ht-pass (+ dream-ht-pass 1))
(begin
(set! dream-ht-fail (+ dream-ht-fail 1))
(append! dream-ht-fails {:name name :actual actual :expected expected})))))
(dream-ht-test "escape ampersand" (dream-escape "a & b") "a &amp; b")
(dream-ht-test "escape lt gt" (dream-escape "<b>") "&lt;b&gt;")
(dream-ht-test "escape quote" (dream-escape "say \"hi\"") "say &quot;hi&quot;")
(dream-ht-test "escape apostrophe" (dream-escape "it's") "it&#39;s")
(dream-ht-test
"escape script tag"
(dream-escape "<script>alert(1)</script>")
"&lt;script&gt;alert(1)&lt;/script&gt;")
(dream-ht-test
"ampersand first (no double-escape)"
(dream-escape "&lt;")
"&amp;lt;")
(dream-ht-test
"safe string unchanged"
(dream-escape "hello world")
"hello world")
(dream-ht-test
"attr escapes value"
(dream-attr "title" "a\"b")
"title=\"a&quot;b\"")
(dream-ht-test
"escape-join"
(dream-escape-join " " (list "<a>" "<b>"))
"&lt;a&gt; &lt;b&gt;")
;; ── todo demo escapes user input (XSS regression) ──────────────────
(define dream-ht-store (dream-todo-store))
((get dream-ht-store :add) "<script>alert(1)</script>")
(define
dream-ht-ctx
(assoc (dream-request "GET" "/" {} "") :dream-csrf {:sign dream-csrf-sign-default :sid "s1" :secret "k"}))
(define dream-ht-rendered (dr/todo-render dream-ht-store dream-ht-ctx))
(dream-ht-test
"todo escapes script"
(contains? dream-ht-rendered "&lt;script&gt;")
true)
(dream-ht-test
"todo has no raw script"
(contains? dream-ht-rendered "<script>")
false)
(define dream-ht-tests-run! (fn () {:total (+ dream-ht-pass dream-ht-fail) :passed dream-ht-pass :failed dream-ht-fail :fails dream-ht-fails}))