Skip to content

Commit f9328cc

Browse files
committedApr 11, 2024·
fix: adjusted block html regex to avoid perf issues
Closes #546 Thank you @devbrains-com for contributing the basis of this fix!
1 parent dcc457e commit f9328cc

File tree

3 files changed

+154
-1
lines changed

3 files changed

+154
-1
lines changed
 

‎.changeset/quiet-boxes-flow.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"markdown-to-jsx": patch
3+
---
4+
5+
Improved block html detection regex to handle certain edge cases that cause extreme slowness. Thank you @devbrains-com for the basis for this fix 🤝

‎index.compiler.spec.tsx

+148
Original file line numberDiff line numberDiff line change
@@ -3442,6 +3442,154 @@ Item detail
34423442
</p>
34433443
`)
34443444
})
3445+
3446+
it('#546 perf regression test, self-closing block + block HTML causes exponential degradation', () => {
3447+
render(
3448+
compiler(
3449+
`<span class="oh" data-self-closing="yes" />
3450+
3451+
You can have anything here. But it's best if the self-closing tag also appears in the document as a pair tag multiple times. We have found it when compiling a table with spans that had a self-closing span at the top.
3452+
3453+
<span class="oh">no</span>
3454+
<span class="oh">no</span>
3455+
<span class="oh">no</span>
3456+
<span class="oh">no</span>
3457+
<span class="oh">no</span>
3458+
<span class="oh">no</span>
3459+
<span class="oh">no</span>
3460+
<span class="oh">no</span>
3461+
<span class="oh">no</span>
3462+
<span class="oh">no</span>
3463+
<span class="oh">no</span>
3464+
<span class="oh">no</span>
3465+
<span class="oh">no</span>
3466+
<span class="oh">no</span>
3467+
<span class="oh">no</span>
3468+
<span class="oh">no</span>
3469+
<span class="oh">no</span>
3470+
<span class="oh">no</span>
3471+
<span class="oh">no</span>
3472+
<span class="oh">no</span>
3473+
<span class="oh">no</span>
3474+
<span class="oh">no</span>
3475+
<span class="oh">no</span>
3476+
<span class="oh">no</span>
3477+
<span class="oh">no</span>
3478+
<span class="oh">no</span>
3479+
<span class="oh">no</span>
3480+
<span class="oh">no</span>
3481+
<span class="oh">no</span>
3482+
<span class="oh">no</span>
3483+
3484+
Each span you copy above increases the time it takes by 2. Also, writing text here increases the time.`.trim()
3485+
)
3486+
)
3487+
3488+
expect(root.innerHTML).toMatchInlineSnapshot(`
3489+
<div>
3490+
<span class="oh"
3491+
data-self-closing="yes"
3492+
>
3493+
</span>
3494+
<p>
3495+
You can have anything here. But it's best if the self-closing tag also appears in the document as a pair tag multiple times. We have found it when compiling a table with spans that had a self-closing span at the top.
3496+
</p>
3497+
<span class="oh">
3498+
no
3499+
</span>
3500+
<span class="oh">
3501+
no
3502+
</span>
3503+
<span class="oh">
3504+
no
3505+
</span>
3506+
<span class="oh">
3507+
no
3508+
</span>
3509+
<span class="oh">
3510+
no
3511+
</span>
3512+
<span class="oh">
3513+
no
3514+
</span>
3515+
<span class="oh">
3516+
no
3517+
</span>
3518+
<span class="oh">
3519+
no
3520+
</span>
3521+
<span class="oh">
3522+
no
3523+
</span>
3524+
<span class="oh">
3525+
no
3526+
</span>
3527+
<span class="oh">
3528+
no
3529+
</span>
3530+
<span class="oh">
3531+
no
3532+
</span>
3533+
<span class="oh">
3534+
no
3535+
</span>
3536+
<span class="oh">
3537+
no
3538+
</span>
3539+
<span class="oh">
3540+
no
3541+
</span>
3542+
<span class="oh">
3543+
no
3544+
</span>
3545+
<span class="oh">
3546+
no
3547+
</span>
3548+
<span class="oh">
3549+
no
3550+
</span>
3551+
<span class="oh">
3552+
no
3553+
</span>
3554+
<span class="oh">
3555+
no
3556+
</span>
3557+
<span class="oh">
3558+
no
3559+
</span>
3560+
<span class="oh">
3561+
no
3562+
</span>
3563+
<span class="oh">
3564+
no
3565+
</span>
3566+
<span class="oh">
3567+
no
3568+
</span>
3569+
<span class="oh">
3570+
no
3571+
</span>
3572+
<span class="oh">
3573+
no
3574+
</span>
3575+
<span class="oh">
3576+
no
3577+
</span>
3578+
<span class="oh">
3579+
no
3580+
</span>
3581+
<span class="oh">
3582+
no
3583+
</span>
3584+
<span class="oh">
3585+
no
3586+
</span>
3587+
<p>
3588+
Each span you copy above increases the time it takes by 2. Also, writing text here increases the time.
3589+
</p>
3590+
</div>
3591+
`)
3592+
})
34453593
})
34463594

34473595
describe('horizontal rules', () => {

‎index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ const HEADING_SETEXT_R = /^([^\n]+)\n *(=|-){3,} *(?:\n *)+\n/
254254
* \n*
255255
*/
256256
const HTML_BLOCK_ELEMENT_R =
257-
/^ *(?!<[a-z][^ >/]* ?\/>)<([a-z][^ >/]*) ?([^>]*)>\n?(\s*(?:<\1[^>]*?>[\s\S]*?<\/\1>|(?!<\1\b)[\s\S])*?)<\/\1>(?!<\/\1>)\n*/i
257+
/^ *(?!<[a-z][^ >/]* ?\/>)<([a-z][^ >/]*) ?((?:[^>]*[^/])?)>\n?(\s*(?:<\1[^>]*?>[\s\S]*?<\/\1>|(?!<\1\b)[\s\S])*?)<\/\1>(?!<\/\1>)\n*/i
258258

259259
const HTML_CHAR_CODE_R = /&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-fA-F]{1,6});/gi
260260

0 commit comments

Comments
 (0)
Please sign in to comment.