As mentioned, the issue here is catastrophic backtracking on that huge
data string. I think addressing this in the general case may be a bit difficult (with the obvious solution being not to shove that much code into a single block), since unfortunately we're playing with fire here.
That said, in this particular scenario Markdown shoots itself in the foot a bit by rendering 4-space indented code blocks as
which causes the subsequent recalling of
HashHTMLBlocks to use the far less efficient "
</tag>\n" block matching regular expression.
DoCodeBlocks performed the replacement as
codeblock = "<pre><code>" + codeblock + "</code>\n</pre>";
// ^------^ shift newline
HashHTMLBlocks would be able to make use of the first, more strict block matching expression, which, while still involving a lot of iterations, is significantly more efficient for cases like this.
Of course, unlike Chrome/Firefox/Opera, IE opts to display
incorrectly, preserving the newline between
</pre>, so this may not be a viable solution.
There are some other, more complex changes that might be able to address this as well, but I'm not sure it makes sense to make drastic modifications for such an irrational edge case. Of course, the fact that this inconvenienced you as an editor going in to attempt to fix the problem(s) does make it seem a little more worthwhile from my perspective.
As a side note, I believe that the stricter expression can be modified to match in significantly fewer steps as well, by transforming
unless I'm mistaken and there's a reason they aren't functionally equivalent.
And actually, I think similar treatment can be applied to the looser expression as well (which would solve the general case reasonably) where
and completes against the generated
<pre> element as-is in ~84,000 steps, versus the multiple millions currently required.