about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-03-29 20:08:30 +0100
committerbptato <nincsnevem662@gmail.com>2024-03-29 20:20:53 +0100
commitb3cf0be08e9b67361d307e463a907a6b4d35a859 (patch)
treeb2c48e7c70cfcdeab4f9d47b9b2e6c0f6a06f5fe
parentd2a384f20f5555000c8aa9a711bc88a1c3ce2efe (diff)
downloadchawan-b3cf0be08e9b67361d307e463a907a6b4d35a859.tar.gz
buffer: fix markURL in plaintext
We must HTML escape data, or the fragment parser will parse plain text
as markup. (However, just running htmlEscape() on data is not enough;
that would also mark <, ', etc. as &gt, &apos. So we only escape after
the regex is executed.)
-rw-r--r--src/server/buffer.nim34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index 12665334..87926c11 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -1727,17 +1727,45 @@ proc markURL*(buffer: Buffer; schemes: seq[string]) {.proxy.} =
         let text = Text(node)
         var res = regex.exec(text.data)
         if res.success:
-          var data = text.data
           var offset = 0
+          var data = ""
+          var j = 0
           for cap in res.captures.mitems:
             if cap.i != 0:
               continue
+            let capLen = cap.e - cap.s
+            while j < cap.s:
+              case (let c = text.data[j]; c)
+              of '<':
+                data &= "&lt;"
+                offset += 3
+              of '>':
+                data &= "&gt;"
+                offset += 3
+              of '\'':
+                data &= "&apos;"
+                offset += 5
+              of '"':
+                data &= "&quot;"
+                offset += 5
+              else:
+                data &= c
+              inc j
             cap.s += offset
             cap.e += offset
-            let s = data[cap.s..<cap.e]
+            let s = text.data[j ..< j + capLen]
             let news = "<a href=\"" & s & "\">" & s.htmlEscape() & "</a>"
-            data[cap.s..<cap.e] = news
+            data &= news
+            j += cap.e - cap.s
             offset += news.len - (cap.e - cap.s)
+          while j < text.data.len:
+            case (let c = text.data[j]; c)
+            of '<': data &= "&lt;"
+            of '>': data &= "&gt;"
+            of '\'': data &= "&apos;"
+            of '"': data &= "&quot;"
+            else: data &= c
+            inc j
           let replacement = html.fragmentParsingAlgorithm(data)
           discard element.replace(text, replacement)
       elif node of HTMLElement: