diff options
author | bptato <nincsnevem662@gmail.com> | 2024-03-29 20:08:30 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-03-29 20:20:53 +0100 |
commit | b3cf0be08e9b67361d307e463a907a6b4d35a859 (patch) | |
tree | b2c48e7c70cfcdeab4f9d47b9b2e6c0f6a06f5fe | |
parent | d2a384f20f5555000c8aa9a711bc88a1c3ce2efe (diff) | |
download | chawan-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 >, &apos. So we only escape after the regex is executed.)
-rw-r--r-- | src/server/buffer.nim | 34 |
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 &= "<" + offset += 3 + of '>': + data &= ">" + offset += 3 + of '\'': + data &= "'" + offset += 5 + of '"': + data &= """ + 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 &= "<" + of '>': data &= ">" + of '\'': data &= "'" + of '"': data &= """ + else: data &= c + inc j let replacement = html.fragmentParsingAlgorithm(data) discard element.replace(text, replacement) elif node of HTMLElement: |