TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Stack Overflow Outage Postmortem

862 pointsby gbrayutalmost 9 years ago

71 comments

dkopialmost 9 years ago
Perfect. Awesome bug. Awesome Post Mortem. This was just fun to read.<p>While this might have been caused by mistake - these types of bugs can be (and are) abused by hackers.<p><a href="https:&#x2F;&#x2F;www.owasp.org&#x2F;index.php&#x2F;Regular_expression_Denial_of_Service_-_ReDoS" rel="nofollow">https:&#x2F;&#x2F;www.owasp.org&#x2F;index.php&#x2F;Regular_expression_Denial_of...</a> <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;ReDoS" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;ReDoS</a><p>The post also links to this video: <a href="https:&#x2F;&#x2F;vimeo.com&#x2F;112065252" rel="nofollow">https:&#x2F;&#x2F;vimeo.com&#x2F;112065252</a>
评论 #12132182 未加载
评论 #12133300 未加载
chubotalmost 9 years ago
Ha! The same bug happened internally at my company. In that case it was a regex matching a URL taking so much CPU as to cause a DOS of a proxy server. I won&#x27;t be surprised if it&#x27;s happened to someone here too.<p>This is very timely, because minutes ago, I made a link to Russ Cox&#x27;s articles in my Kernighan awk repo:<p><a href="https:&#x2F;&#x2F;github.com&#x2F;andychu&#x2F;bwk" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;andychu&#x2F;bwk</a><p><a href="https:&#x2F;&#x2F;swtch.com&#x2F;~rsc&#x2F;regexp&#x2F;regexp1.html" rel="nofollow">https:&#x2F;&#x2F;swtch.com&#x2F;~rsc&#x2F;regexp&#x2F;regexp1.html</a><p>If you are not familiar with this issue, basically Perl popularized bad computer science... &quot;regexes&quot; are not regular languages.<p>They say that this particular case triggered quadratic behavior, not exponential, but the point is that there is a linear time algorithm to do this.<p>The file b.c in the awk repo implements the linear time algorithm:<p><a href="https:&#x2F;&#x2F;github.com&#x2F;andychu&#x2F;bwk&#x2F;blob&#x2F;master&#x2F;b.c" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;andychu&#x2F;bwk&#x2F;blob&#x2F;master&#x2F;b.c</a><p>(and rsc&#x27;s site has some nice sample code too, as well as caveats with regard to capturing and so forth)
评论 #12132349 未加载
评论 #12132584 未加载
评论 #12133655 未加载
评论 #12132313 未加载
评论 #12132334 未加载
smrtinsertalmost 9 years ago
&quot;This regular expression has been replaced with a substring function.&quot;<p>This should be the title of a book on software engineering.
评论 #12132870 未加载
评论 #12132570 未加载
评论 #12132422 未加载
评论 #12133448 未加载
评论 #12134185 未加载
StevePerkinsalmost 9 years ago
I&#x27;m surprised that a developer was able to fix StackOverflow without being able to look up the error message on StackOverflow.
评论 #12132878 未加载
评论 #12132431 未加载
redbeard0x0aalmost 9 years ago
In the past, I have done Load Balancer status checks against a special &#x2F;status endpoint. I queried all the connected services (i.e. DB, Redis, etc) with a super fast query (i.e. `SELECT version();`). Monitoring CPU&#x2F;MEM usage for scaling was separate.<p>Comparing this to checking the home page, what is the best way to setup a health check for your load balancers?
评论 #12132137 未加载
评论 #12133539 未加载
评论 #12132675 未加载
alexbeckeralmost 9 years ago
I remember the day I learned that Python&#x27;s &quot;re&quot; module uses backtracking for non-extended regexes. My tests covered lots of corner cases in the regex logic, but were too short for me to notice the performance penalty. Luckily I only caused a partial outage in production.<p>I actually got to talk to Raymond Hettinger (Python core team) about why re uses a potentially exponential-time algorithm for regexes when there is a famous linear-time algorithm, and (I suspect) most programmers would assume linear complexity. As it turns out, there was an attempt to re-write re to fix this, but the re-write never managed to present exactly the same (extremely large) API as the existing module. He advised me that &quot;the standard library is where code goes to die.&quot;
评论 #12132831 未加载
评论 #12132406 未加载
评论 #12135184 未加载
mwpmaybealmost 9 years ago
This is why I always do:<p><pre><code> s&#x2F;^\s+&#x2F;&#x2F;; s&#x2F;\s+$&#x2F;&#x2F;; </code></pre> Instead of:<p><pre><code> s&#x2F;^\s+|\s+$&#x2F;&#x2F;; </code></pre> Weirdly, I&#x27;ve &quot;known&quot; this since I started writing Perl in the mid-&#x27;90. Not sure where I originally read it (or was told it). Funny how that works.<p>I try to write my regexes such that they anchor at the front of the strong or the back, or they describe the whole string; never an either-or anchoring type situation like this example.<p>Spaces at beginning of string (100,000 iterations):<p><pre><code> Rate onestep twostep onestep 62500&#x2F;s -- -2% twostep 63694&#x2F;s 2% -- real 0m3.093s user 0m3.066s sys 0m0.018s </code></pre> Spaces at end of string (100,000 iterations):<p><pre><code> Rate twostep onestep twostep 55249&#x2F;s -- -9% onestep 60976&#x2F;s 10% -- real 0m3.453s user 0m3.421s sys 0m0.022s </code></pre> Spaces in middle of string (only 500 iterations because I don&#x27;t want to sit here for four hours):<p><pre><code> Rate onestep twostep onestep 7.11&#x2F;s -- -100% twostep 16667&#x2F;s 234333% -- real 1m10.741s user 1m10.207s sys 0m0.228s</code></pre>
评论 #12132892 未加载
StavrosKalmost 9 years ago
I don&#x27;t understand something: the regex expected a space character, followed by the end of the string. If the last character wasn&#x27;t a space, this could never match. Why did the engine keep backtracking, even though it&#x27;s easy to figure out that it could never match the regex?
评论 #12132345 未加载
评论 #12132175 未加载
评论 #12132202 未加载
评论 #12132377 未加载
评论 #12132405 未加载
selckinalmost 9 years ago
Is this the sort of thing that <a href="https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;re2" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;re2</a> was made to solve?
评论 #12132069 未加载
评论 #12132449 未加载
评论 #12132397 未加载
mplewisalmost 9 years ago
I think this might have been the post they quoted.<p><a href="http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;38484433&#x2F;in-corona-sdk-how-to-join-tiles-into-one-word-using-matrix-game-breakout" rel="nofollow">http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;38484433&#x2F;in-corona-sdk-ho...</a>
评论 #12132315 未加载
评论 #12132352 未加载
评论 #12134127 未加载
johncoltranealmost 9 years ago
A few months ago, a Stack Overflow representative asked me if their presence at a dev conference was justified. My positive answer more or less revolved around the importance SO took in the daily life of programmers everywhere.<p>If only she was there to witness the effect of a 34 minute downtime on an open space full of mobile&#x2F;back&#x2F;front developers.
评论 #12133158 未加载
评论 #12135528 未加载
junkealmost 9 years ago
Nice bug. I tried to replicate this and indeed, the time to notice that no match is found is growing very fast with the length of the input. Using a substring check is a good fix, but I tried to change the regex to fix this and: if instead of an end anchor, you can add an optional non-whitespace character at the end of the pattern, then you only have to check whether the optional part is empty. Testing with very long strings which respectively match and don&#x27;t match shows that the result is immediate in both cases.<p><pre><code> (defparameter *scanner* (ppcre:create-scanner &#x27;(:sequence (:register (:greedy-repetition 1 nil :whitespace-char-class)) (:register (:greedy-repetition 0 1 :non-whitespace-char-class))))) (let ((length 40000)) (defparameter *no-match* (let ((string (make-string length :initial-element #\space))) (setf (char string (1- (length string))) #\+) string)) (defparameter *match* (make-string length :initial-element #\space))) (defun end-white-match (string) (ppcre:do-scans (ms me rs re *scanner* string) (when (and ms (= (aref re 1) (aref rs 1))) (return (values ms me))))) (time (end-white-match *match*)) 0, 40000 ;; Evaluation took: ;; 0.000 seconds of real time ;; 0.000000 seconds of total run time (0.000000 user, 0.000000 system) ;; 100.00% CPU ;; 25,139,832 processor cycles ;; 0 bytes consed (time (end-white-match *no-match*)) NIL ;; Evaluation took: ;; 0.000 seconds of real time ;; 0.000000 seconds of total run time (0.000000 user, 0.000000 system) ;; 100.00% CPU ;; 11,105,364 processor cycles ;; 0 bytes consed</code></pre>
评论 #12132493 未加载
lambdaalmost 9 years ago
Hmm. I wonder why one of the followup mitigations is not to move to a non-backtracking regex engine by default.<p>Most of what you want to do with a regex can be done with an NFA or DFA based engine. That which can&#x27;t be done with an NFA or DFA based engine is generally better handled with a parser than a regex.<p>There are plenty of good DFA based regex matchers out there; RE2, the Rust regex crate, GNU grep, etc. At a glance, it even looks like glibc uses a DFA, though it supports POSIX REs which support backreferences so it must use backtracking at least for REs that contain backreferences.<p>Predictable hash collisions were a big sources of DOS attacks in web scripting languages which use tables a lot, until they started rolling out randomized hashing algorithms to prevent easily predictable hash collisions. It seems like it would be best for languages and libraries to move to DFA based regexps, at least for anything that doesn&#x27;t contain backreferences, to mitigate these kinds of issues from being easy to exploit.
kilroy123almost 9 years ago
&gt; It took 10 minutes to identify the cause.<p>I&#x27;m impressed they were able to do this so quickly.
评论 #12132237 未加载
评论 #12132160 未加载
评论 #12133423 未加载
评论 #12132382 未加载
评论 #12132293 未加载
brongondwanaalmost 9 years ago
Time to pop this old chestnut out:<p><a href="https:&#x2F;&#x2F;blog.fastmail.com&#x2F;2014&#x2F;12&#x2F;14&#x2F;on-duty&#x2F;" rel="nofollow">https:&#x2F;&#x2F;blog.fastmail.com&#x2F;2014&#x2F;12&#x2F;14&#x2F;on-duty&#x2F;</a><p>&quot;At one stage, we decided to try to avoid having to be woken for some types of failure by using Heartbeat, a high availability solution for Linux, on our frontend servers. The thing is, our servers are actually really reliable, and we found that heartbeat failed more often than our systems - so the end result was reduced reliability! It&#x27;s counter-intuitive, but automated high-availability often isn&#x27;t.&quot;<p>One of these days we&#x27;ll finish our new system and I&#x27;ll blog about that, which is that the automated systems are allowed to take ONE corrective action without paging, at which point they flag that the system is in compromised state. Any further test failures trigger an immediate wake of the on-call.
tibiapejagalaalmost 9 years ago
I wondered about this for some time.<p>Simple regex (as in formal language theory) are matched in O(n) time by finite automaton.<p>Extended regex like PCRE are more powerful, but most of the time are implemented by backtracking engines, where really bad regex pattern might go exponential, but even simple pattern as in postmortem can go O(n^2).<p>Do implementations optimize simple regex patterns to O(n) matching? Even I wrote x86 JIT regex compiler for fun some time ago. Compilation time was really bad, but matching was O(n).
评论 #12135151 未加载
nanisalmost 9 years ago
As perlfaq4[1] shows:<p><pre><code> &gt; You can do that with a pair of substitutions: &gt; s&#x2F;^\s+&#x2F;&#x2F;; &gt; s&#x2F;\s+$&#x2F;&#x2F;; </code></pre> It then notes, in an understated manner:<p><pre><code> &gt; You can also write that as a single substitution, &gt; although it turns out the combined statement is &gt; slower than the separate ones. That might not &gt; matter to you, though: &gt; s&#x2F;^\s+|\s+$&#x2F;&#x2F;g; </code></pre> [1]: <a href="http:&#x2F;&#x2F;perldoc.perl.org&#x2F;perlfaq4.html#How-do-I-strip-blank-space-from-the-beginning%2fend-of-a-string%3f" rel="nofollow">http:&#x2F;&#x2F;perldoc.perl.org&#x2F;perlfaq4.html#How-do-I-strip-blank-s...</a>
评论 #12136435 未加载
jakozauralmost 9 years ago
Experienced something similar myself. Was even thinking about creating regular expression library which just allow &quot;safe&quot; and fast expression.<p>The trick would be to not allow only expression that can be translated easily to state automate.<p>Good regex: &quot;Phone number [0-9]* &quot;<p>Bad regex: &quot;;Name=.<i>;&quot; as . can also match &quot;;&quot; and it can lead to bad backtracking. You should rewrite this regex to &quot;;Name=[^;]</i>;&quot;<p>RE2 is probably best implementation so far, but because it&#x27;s tries so hard to preserve backward compatibility with all regular expression it is not that fast in average case: <a href="https:&#x2F;&#x2F;swtch.com&#x2F;~rsc&#x2F;regexp&#x2F;regexp1.html" rel="nofollow">https:&#x2F;&#x2F;swtch.com&#x2F;~rsc&#x2F;regexp&#x2F;regexp1.html</a>
lazyantalmost 9 years ago
&quot;the entire site became unavailable since the load balancer took the servers out of rotation.&quot; I don&#x27;t care about the regexp, this is bad SRE, you can&#x27;t just take servers out of rotation without some compensation action.<p>Never mind that it looks like all web servers where taken out of rotation, even one server down could cause a cascading effect (more traffic directed to the healthy ones that end up dying, in a traffic-based failure). One action for example after n servers have gone down, (besides getting up other m servers) is to put (at least some) servers in a more basic mode (read only&#x2F;static, some features disabled), not guaranteed but that could have prevented this and other type of down times.
评论 #12143470 未加载
评论 #12133845 未加载
shanemhansenalmost 9 years ago
Yesterday I couldn&#x27;t use hipchat for a couple hours because it would lock up a cpu and fail to load. After doing some free debugging for them I realized they were locking up trying to extract urls out of some text with a regex. Simplified code: <a href="https:&#x2F;&#x2F;gist.github.com&#x2F;shanemhansen&#x2F;c4e5580f7d4c6265769b0df61d6d8759" rel="nofollow">https:&#x2F;&#x2F;gist.github.com&#x2F;shanemhansen&#x2F;c4e5580f7d4c6265769b0df...</a><p>Pasting that content into hipchat will probably lock up your browser and webview based clients. Beware.<p>Lesson learned: don&#x27;t parse user input with a regex.
antoineMoPaalmost 9 years ago
Google cache saved me during these 34 minutes.
评论 #12132712 未加载
onetwotreealmost 9 years ago
It seems like there should be a way to determine whether a regex can be compiled using the classic O(n) DFA algorithm or with whatever madness PCREs use to support backtracking and so on.<p>Anybody know if any regex engines attempt this?<p>Obviously you can still shoot yourself in the foot, but it&#x27;s somewhat more difficult to do so in a situation like this where the regex in question &quot;looks&quot; cheap.
评论 #12132847 未加载
评论 #12133746 未加载
评论 #12132582 未加载
rixedalmost 9 years ago
Regex was not the main issue. The main issues were:<p>1. Rendering a page fails&#x2F;does not terminate if some non essential subtask (rendering a single code block) fails&#x2F;does not terminate.<p>2. They do not try to detect bad data (the way they certainly try to detect bad code)<p>3. Load balancing based on the rendering time of a single page<p>Code bugs triggered by bad data will happen again, with or without regular expressions.
评论 #12177786 未加载
laurenceialmost 9 years ago
Could this has been a deliberate&#x2F;malicious act? Why else would someone post 20,000 consecutive characters of whitespace on a comment line?<p>Also, the &quot;homepage&quot; of StackOverflow does not show any &#x27;comments&#x27; - it is just the top questions? Why was the page loading any comments in the first place?
评论 #12132076 未加载
评论 #12132088 未加载
评论 #12132064 未加载
评论 #12132017 未加载
animexalmost 9 years ago
We had a similar issue arising from regex parsing of our SES routes on our SaaS Platform. We had made some changes to our generated SES file which caused it to balloon to 4x in size (tens of thousands of lines). Our only clue that something had gone wrong was suddenly extremely high IIS usage. With some help from Microsoft support, we managed to trace the stack during the high-cpu event to an ISAPI filter and ultimately our 3rd party SES plugin. We managed to fix the problem by being more efficient with our regex generation and reduce the number of rules the plugin was processing but it was eye-opening how much CPU was being consumed by regex processing.
Scea91almost 9 years ago
I like this because it shows how important it is to understand the inner workings of the tools in your toolbox. It could serve as a nice example in some &#x27;Languages and Grammars&#x27; course at the University for additional motivation.
revelationalmost 9 years ago
They implemented trim with a regex? Neither Java nor .NET do that.<p>The postmortem here should probably be &quot;why are you reimplementing trim&quot;.
评论 #12132398 未加载
评论 #12132264 未加载
评论 #12132289 未加载
评论 #12132869 未加载
grashalmalmost 9 years ago
Easy to reproduce [1]. Just remove the a in the end and your timeout disappears. Anybody knows which regex engine they used?<p>[1] <a href="http:&#x2F;&#x2F;regexr.com&#x2F;3drn3" rel="nofollow">http:&#x2F;&#x2F;regexr.com&#x2F;3drn3</a>
评论 #12132418 未加载
评论 #12133188 未加载
评论 #12132432 未加载
cypharalmost 9 years ago
I&#x27;m still confused why people would use a backtracking regex engine in cases when they don&#x27;t need recursive regex extensions (or other questionable extensions like back references). A &quot;correct&quot; (from the CS perspective) regex engine wouldn&#x27;t have had this or many other problems that people encounter when doing regular expression matching. If they had piped out to sed or awk this wouldn&#x27;t have happened, since GNU grep, sed and awk use a proper regex engine.
oztenalmost 9 years ago
My blog post[1] on how to test for catastrophic backtracking using RegEx buddy.<p>[1] <a href="https:&#x2F;&#x2F;blog.mozilla.org&#x2F;webdev&#x2F;2010&#x2F;11&#x2F;15&#x2F;avoiding-catastrophic-backtracking-in-apache-rewriterule-patterns&#x2F;" rel="nofollow">https:&#x2F;&#x2F;blog.mozilla.org&#x2F;webdev&#x2F;2010&#x2F;11&#x2F;15&#x2F;avoiding-catastro...</a>
adrianratnapalaalmost 9 years ago
Backtracking regexes matchers are a Bad Idea.<p>It&#x27;s true you need them to implement backreferences. But I&#x27;ve never used such a thing. If I were creating a runtime for some new language, I would simply ignore that part of the POSIX standard.
davidronalmost 9 years ago
The whole postmortem focuses on a regular expression bug and how that bug was fixes and completely ignores the fact that if the home page becomes unavailable, the load balancer logic will shut down the entire site.
评论 #12177804 未加载
wfunctionalmost 9 years ago
I still haven&#x27;t figured out why regex engines font use state machines where possible (i.e. in the absence of back references and such). Is that not an obvious optimization?
johnwheeleralmost 9 years ago
ugh. i would&#x27;ve just sat there wondering WTF. then proceed to initiate daily backup recovery.
评论 #12132410 未加载
OJFordalmost 9 years ago
<p><pre><code> &gt; It took 10 minutes to identify the cause, </code></pre> Impressive, considering:<p><pre><code> &gt; cause was a malformed post that caused one of our &gt; regular expressions to consume high CPU ... called on &gt; each home page view ... Since the home page is what our &gt; load balancer uses for the health check, the entire site &gt; became unavailable since the load balancer took the &gt; servers out of rotation.</code></pre>
unethical_banalmost 9 years ago
Not understanding why backtracking happened. Once it hit a non space, non end character, move on. Nothing before can match the regex.
评论 #12132168 未加载
zzzcpanalmost 9 years ago
Seems like there is still no better way to deal with these kind of mistakes than preemptive Erlang-style lightweight processes.
NetStrikeForcealmost 9 years ago
Someone wiser than me said once that if you have a problem and want to fix it with a regex then you now have two problems :-)
rochoalmost 9 years ago
By the way, this is the post that broke StackOverflow: <a href="http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;38484433&#x2F;join-tiles-in-corona-sdk-into-one-word-for-a-breakout-game-grid" rel="nofollow">http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;38484433&#x2F;join-tiles-in-co...</a>
ozimalmost 9 years ago
For me awesome part is cliché that is quite popular on SO takes down SO. And resolution to replace RegExp with substring completes the picture. Just cannot stop laughing.<p>&quot;Some people, when confronted with a problem, think &#x27;I know, I&#x27;ll use regular expressions.&#x27; Now they have two problems.&quot;
porjoalmost 9 years ago
<p><pre><code> &gt; 20,000+19,999+19,998+…+3+2+1 = 199,990,000</code></pre> = 200,010,000, not that anyone&#x27;s counting :)
bshimminalmost 9 years ago
In reading this post, I realised this was the first time I&#x27;d ever visited the Stack Overflow homepage.
random3almost 9 years ago
&gt; Add controls to our load balancer to disable the healthcheck – as we believe everything but the home page would have been accessible if it wasn’t for the the health check<p>Wouldn&#x27;t regular users, trying to access the homepage have yielded the same effect?
babuskovalmost 9 years ago
&gt; This regular expression has been replaced with a substring function.<p>I always cringe when I see regex used for such simple string checks. In fact, Stackoverflow is full of accepted answers that &quot;solve&quot; problems that way.
jimjimjimalmost 9 years ago
paging jwz. something something two problems.
JBiserkovalmost 9 years ago
The Stack status page contains 3 script tags <i>before</i> the HTML tag.<p>This is what I saw on my Kindle 3 Keyboard:<p>This page contains the following errors:<p>error on line 2 at column 36: Extra content at the end of the document<p>Below is a rendering of the page up to the first error.<p>var __pbpa = true;
_RPMalmost 9 years ago
They have limits on everything (comments per second, edits per second, upvotes per day, reputation earned per day, etc), it seems like they should have an upper bound character limit on what they accept too.
评论 #12132488 未加载
评论 #12133268 未加载
Retr0spectrumalmost 9 years ago
For more bugs caused by quadratic complexity:<p><a href="http:&#x2F;&#x2F;accidentallyquadratic.tumblr.com&#x2F;" rel="nofollow">http:&#x2F;&#x2F;accidentallyquadratic.tumblr.com&#x2F;</a>
jngalmost 9 years ago
Any more proof needed that caching should become a system-provided service over the next 10-20 years, the same way memory management did in the past 10-20 years?
berkutalmost 9 years ago
If it was in a comment, why was the home page loading it?<p>preemptive caching?
mtokunagaalmost 9 years ago
&quot; This regular expression has been replaced with a substring function.&quot; I came to rely on Regex so much that I almost feel we&#x27;d be the next.
zkhaliquealmost 9 years ago
This is great. I just want to add something that might not be well-known: StackOverflow is all hosted from ONE web app server! It handles all the writes.
perceptalmost 9 years ago
Productivity plummets worldwide (regex attack vector)
brokencubealmost 9 years ago
Correct me if I&#x27;m wrong, but couldn&#x27;t this could have been fixed by making the match possessive:<p>^[\s\u200c]++|[\s\u200c]++$<p>That should stop any runaway backtracking?
hamzalivealmost 9 years ago
200010000 not 199990000 probably the author looped on a 0-based index. n*(n+1)&#x2F;2 is even better ^^ Nice post mortem though
estrabdalmost 9 years ago
TIL what language Stack Overflow is written in.
评论 #12133850 未加载
stop1234almost 9 years ago
Yes, one of the best postmortems, especially the technical part.<p>Am sure it was simple but curious to know what the replacement substr code is.
GnarlyWhalealmost 9 years ago
Favourite comment from the Reddit thread on the matter:<p>&quot;Well, that should stave off the imposer syndrome for another couple of days.&quot;<p>-u&#x2F;minno
rmdossalmost 9 years ago
Very interesting bug. People forget some times how expensive a regex can be compared to simple pattern matching.
Osirisalmost 9 years ago
Why isn&#x27;t the trim applied when the post is created and not every time that it&#x27;s displayed?
MalcolmDiggsalmost 9 years ago
Regex: ruining your life since 1956.
Waterluvianalmost 9 years ago
I want to believe that a cat fell asleep on the space bar. Then eventually woke up and posted.
davidwparkeralmost 9 years ago
This is great- regex errors always reminds me of this classic Jeff Atwood post (cofounder of StackOverflow): <a href="https:&#x2F;&#x2F;blog.codinghorror.com&#x2F;regular-expressions-now-you-have-two-problems&#x2F;" rel="nofollow">https:&#x2F;&#x2F;blog.codinghorror.com&#x2F;regular-expressions-now-you-ha...</a>
dear1777almost 9 years ago
Hmmn, if it was one request, how did it cause other web servers in the farm go down?
rosstexalmost 9 years ago
Wow, I didn&#x27;t notice today! I must not have been coding very much.
hstunalmost 9 years ago
But... how did they search for a fix without resorting to Stack Overflow? :)
smegelalmost 9 years ago
&gt; If the string to be matched against contains 20,000 space characters in a row, but not at the end, then the Regex engine will start at the first space, check that it belongs to the \s character class, move to the second space, make the same check, etc. After the 20,000th space, there is a different character, but the Regex engine expected a space or the end of the string. Realizing it cannot match like this it backtracks, and tries matching \s+$ starting from the second space, checking 19,999 characters. The match fails again, and it backtracks to start at the third space, etc.<p>That&#x27;s not how backtracking works. A regex engine will only backtrack to try and make the rest of the regex match, i.e. it will take characters of the RHS of the string, not try and start &quot;from the second character off the start of the string&quot;. I mean, if the engine tried matching from the second space, what would be matching the first space? Something has to.<p>Which meant, that even if the regex engine was incredibly stupid and could not figure out that a greedy block of \s was never going to contain a non-\s, it would only have to check 20,001 times, not 199000 (or whatever it was).<p>I can&#x27;t reproduce this &quot;bug&quot; in either Perl or Python. The time taken to match a 30,000 block of space either followed by $ or XX$ was basically identical for \s+$.<p>There does appear to be normal backtracking going on, roughly doubling the search time for large strings terminating in non-\s. This is expected, as it has to check 20,000 during the first gobble, then 20,000 as it backtracks <i>from the right</i> 20,000 times.<p><pre><code> $ time perl -e &#x27;(&quot; &quot; x 100000000 . &quot;X&quot;) =~ &#x2F;\s+$&#x2F; &amp;&amp; print &quot;MATCH&quot;&#x27; real 0m0.604s user 0m0.509s sys 0m0.094s $ time perl -e &#x27;(&quot; &quot; x 100000000) =~ &#x2F;\s+$&#x2F; &amp;&amp; print &quot;MATCH&quot;&#x27; MATCH real 0m0.286s user 0m0.197s sys 0m0.089s</code></pre>
评论 #12132470 未加载
评论 #12132950 未加载
评论 #12136530 未加载
评论 #12135952 未加载
评论 #12132618 未加载
monochromaticalmost 9 years ago
&gt; So the Regex engine has to perform a “character belongs to a certain character class” check (plus some additional things) 20,000+19,999+19,998+…+3+2+1 = 199,990,000 times, and that takes a while.<p>199,990,000 isn&#x27;t really <i>all</i> that many. I&#x27;m a little surprised it didn&#x27;t just cause a momentary blip in performance.<p>edit: whoops, i guess that&#x27;s per page load
评论 #12132090 未加载
评论 #12132135 未加载
评论 #12132063 未加载
评论 #12132099 未加载
评论 #12132187 未加载
评论 #12132089 未加载
评论 #12132071 未加载
fweespeechalmost 9 years ago
The lesson seems to be &quot;Always run trim() before running regex&quot; and &quot;validate content as much as possible before running regex&quot;.
评论 #12132186 未加载
评论 #12132194 未加载
yeukhonalmost 9 years ago
This seems like a hard-to-expect edge case for real. I think catching edge case is needed (means more rigorous testing). This is the equivalence of algorithm complexity analysis. How bad can my algorithm be? But regular expression, to be honest, is usually something I hardly think about performance. I don&#x27;t know about others, but most of the my input are small enough. How big of an input should I test? If I were to deal with a lot of characters, I would be doing substring replacement.
评论 #12132123 未加载
avaralmost 9 years ago
My rephrasing of their follow-up actions:<p>* &quot;Audit our regular expressions and post validation workflow for any similar issues&quot;<p>* ==&gt; &quot;Not even people who&#x27;ve worked for years on the guts of regex engines can easily predict the runtime of a given regex, but somehow our engineers will be expected to do that&quot;.<p>* &quot;Add controls to our load balancer to disable the healthcheck – as we believe everything but the home page would have been accessible if it wasn’t for the the health check&quot;<p>* ==&gt; &quot;Our lb check was checking &#x2F;index, that failed because &#x2F;index was slow: Lesson learned, let&#x27;s not lb check anything at all&quot;
评论 #12132786 未加载
评论 #12132676 未加载
评论 #12133164 未加载