Meta Stack Exchange is where users like you discuss bugs, features, and support issues that affect the software powering all 153 Stack Exchange communities.

What is meta?
Here's how it works:
  1. Any Stack Exchange user can ask a question
  2. The community provides support, votes on ideas, and reports bugs
  3. Your voice helps shape the way Stack Exchange operates

I'm trying to edit: BYTE to python C-Type structure Conversion Issue

However, every time I click on edit, Firefox (16.0.1 - Ubuntu 12.10) hangs for about 10 seconds, then prompts the usual "debug script", "stop script", "continue" - after hitting continue, it does appear to then present the data. I've not noticed this before on any other posts (and in fact can edit elsewhere fine), so just thought I'd raise it just in case. Screenshot attached of what the result is when attempting to do an edit.

enter image description here

Script name displayed is: (something to do with MarkDown perhaps?)

share|improve this question
Hmm, running the block element regex is super expensive there for some reason, maybe some sort of backtracking. – Tim Stone Dec 24 '12 at 17:13
I can get to the edit screen, but the link does hang for a couple seconds while it tries to process. – asteri Dec 24 '12 at 17:14
It had about a Gigabyte of "\x00...\x00", that could have caused it. I snipped most of it. Should be okay now. – Daniel Fischer Dec 24 '12 at 17:17
@DanielFischer yup - works fine now - thank you - just slightly worrying it's possible to create a post that can hang browsers :( – Jon Clements Dec 24 '12 at 17:21
Behold the power of regex and backtracking. – Daniel Fischer Dec 24 '12 at 17:25
@DanielFischer I would suggest posting the comment as an answer. – AsheeshR Dec 24 '12 at 17:42
up vote 6 down vote accepted

The code block for the file contained a very long string literal


going on with some nonzero entries for a while, then ending in an estimated 80KB of \x00. All on one line.

That led to the parsing of the code block taking unusually long.

share|improve this answer
Yeah, the backtracking that caused is a bit insane. – Tim Stone Dec 24 '12 at 18:35

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 "\n<tag> to </tag>\n" block matching regular expression.

If instead DoCodeBlocks performed the replacement as

codeblock = "<pre><code>" + codeblock + "</code>\n</pre>";
//                                       ^------^  shift newline

then 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 </code> and </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

^(<(...)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))


^(<(...)\b([^\r\n]*\n)+?\n<\/\2>[ \t]*(?=\n+))

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

^(<(...)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)


^(<(...)\b([^\r\n]*\n)*?[^\n]*<\/\2>[ \t]*(?=\n+)\n)

and completes against the generated <pre> element as-is in ~84,000 steps, versus the multiple millions currently required.

share|improve this answer
How the code works (even though being a developer) really doesn't concern me to be honest. When I use a site, especially as one as well established as SO - it's umm, how best to put it - disappointing. I understand regex (can't say I'm a lover of it - but it's absolutely necessary sometimes) has it's down falls, if it's ill-written or whatever, but still... Anyway, my immediate issue was solved, but regardless of that - I'm also pondering why an 80kb post is allowed in the first place. Really do appreciate further info. about this - so don't get me wrong - sincerely appreciate your answer. – Jon Clements Dec 25 '12 at 0:05
Yeah, it's more or less supplemental information in the event that balpha decides to try and fix this :) – Tim Stone Dec 25 '12 at 0:13
@JonClements Nobody is exempt from having bugs in their software, and that includes us. And when our users help us -- both by reporting bugs, like you did, and by digging into the code, like Tim did -- I personally think that's awesome. Thanks, Tim! I'll have a look. – balpha Dec 25 '12 at 7:39
Good analysis - thanks Tim. And @balpha good luck! Merry xmas to you both. – Jon Clements Dec 25 '12 at 9:08
Excellent work from Tim Stone once again! – The Unhandled Exception Dec 25 '12 at 14:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .