refactor(strip_html): treat '<...>' as a catch-all block kind

Adding ['<', '>'] as the lowest-priority entry of `blocks` lets the
inner loop subsume the generic-tag fallback: the `end` sentinel and
its `< 0` / `<= 0` follow-up checks disappear, the "no terminator"
exit becomes a single `i === lt` test, and Set<[string, string]>
collapses to Map<string, string>.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Yang Jun
2026-05-11 23:36:31 +08:00
co-authored by Cursor
parent 7a77fa4f64
commit 5e5d0cc9a1
+7 -11
View File
@@ -42,29 +42,25 @@ export function newline_to_br (this: FilterImpl, v: string) {
return str.replace(/\r?\n/gm, '<br />\n') return str.replace(/\r?\n/gm, '<br />\n')
} }
// Raw-text blocks (HTML5): a regex equivalent is O(n^2) in V8 on unclosed openers. // Raw-text blocks (HTML5) plus '<...>' as the catch-all kind; a regex
// equivalent is O(n^2) in V8 on unclosed openers.
export function strip_html (this: FilterImpl, v: string) { export function strip_html (this: FilterImpl, v: string) {
const str = stringify(v) const str = stringify(v)
this.context.memoryLimit.use(str.length) this.context.memoryLimit.use(str.length)
const blocks = new Set<[string, string]>([['<script', '</script>'], ['<style', '</style>'], ['<!--', '-->']]) const blocks = new Map([['<script', '</script>'], ['<style', '</style>'], ['<!--', '-->'], ['<', '>']])
let out = '' let out = ''
let i = 0 let i = 0
while (i < str.length) { while (i < str.length) {
const lt = str.indexOf('<', i) const lt = str.indexOf('<', i)
if (lt < 0) return out + str.slice(i) if (lt < 0) return out + str.slice(i)
out += str.slice(i, lt) out += str.slice(i, lt)
let end = -1 for (const [opener, closer] of blocks) {
for (const block of blocks) {
const [opener, closer] = block
if (!str.startsWith(opener, lt)) continue if (!str.startsWith(opener, lt)) continue
const e = str.indexOf(closer, lt + opener.length) const e = str.indexOf(closer, lt + opener.length)
if (e < 0) blocks.delete(block) if (e >= 0) { i = e + closer.length; break }
else end = e + closer.length blocks.delete(opener)
break
} }
if (end < 0) end = str.indexOf('>', lt + 1) + 1 if (i === lt) return out + str.slice(lt)
if (end <= 0) return out + str.slice(lt)
i = end
} }
return out return out
} }