[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/kjs
From:       Germain Garand <germain () ebooksfrance ! org>
Date:       2010-02-22 19:12:50
Message-ID: 1266865970.031847.1269.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 1094436 by ggarand:

let's grab more stack room if the operating system agrees.
this will let really ill-designed regexps match +/-32Kb in the worst case
(recursion at each char).

Regular expressions unable to perform their function in such conditions
deserve to die a preposterous death.

BUG: 227080

 M  +33 -4     regexp.cpp  
 M  +3 -0      regexp.h  


--- trunk/KDE/kdelibs/kjs/regexp.cpp #1094435:1094436
@@ -31,8 +31,19 @@
 #include <stdlib.h>
 #include <string.h>
 #include <wtf/Vector.h>
+
+#if defined _WIN32 || defined _WIN64
+#undef HAVE_SYS_TIME_H
+#endif
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
 using WTF::Vector;
 
+static const rlim_t sWantedStackSizeLimit = 32*1024*1024;
+
 // GCC cstring uses these automatically, but not all implementations do.
 using std::strlen;
 using std::strcpy;
@@ -244,6 +255,10 @@
   }
 }
 
+bool RegExp::tryGrowingMaxStackSize = true;
+bool RegExp::didIncreaseMaxStackSize = false;
+int RegExp::availableStackSize = 8*1024*1024;
+
 RegExp::RegExp(const UString &p, char flags)
   : _pat(p), _flags(flags), _valid(true), _numSubPatterns(0), _buffer(0), \
_originalPos(0)  {
@@ -489,15 +504,29 @@
   pcre_config(PCRE_CONFIG_STACKRECURSE, (void*)&stackGlutton);
   pcre_extra limits;
   if (stackGlutton) {
+#if HAVE(SYS_TIME_H)
+    if (tryGrowingMaxStackSize) {
+      rlimit l;
+      getrlimit(RLIMIT_STACK, &l);
+      availableStackSize = l.rlim_cur;
+      if (l.rlim_cur < sWantedStackSizeLimit && 
+          (l.rlim_max > l.rlim_cur || l.rlim_max == RLIM_INFINITY)) {
+        l.rlim_cur = (l.rlim_max == RLIM_INFINITY) ? 
+                     sWantedStackSizeLimit : std::min(l.rlim_max, \
sWantedStackSizeLimit); +        if ((didIncreaseMaxStackSize = !setrlimit( \
RLIMIT_STACK, &l))) +          availableStackSize = l.rlim_cur;
+      }
+      tryGrowingMaxStackSize = false;
+    }
+#endif
+
     limits.flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION;
     // libPCRE docs claim that it munches about 500 bytes per recursion.
     // The crash in #160792 actually showed pcre 7.4 using about 1300 bytes
     // (and I've measured 800 in an another instance)
-    // So the usual 8MiB rlimit on Linux produces about 6452 frames.
-    // We go somewhat conservative, and use about 2/3rds of that, for 4300
+    // We go somewhat conservative, and use about 3/4ths of that,
     // especially since we're not exactly light on the stack, either
-    // ### TODO: get some build system help to use getrlimit.
-    limits.match_limit_recursion = 4300;
+    limits.match_limit_recursion = (availableStackSize/1300)*3/4;
   }
   
   const int numMatches = pcre_exec(_regex, stackGlutton ? &limits : 0, _buffer, \
                _bufferSize, startPos, baseFlags, offsetVector, offsetVectorSize);
--- trunk/KDE/kdelibs/kjs/regexp.h #1094435:1094436
@@ -58,6 +58,9 @@
     void prepareMatch(const UString &s);
     void doneMatch();
 
+    static bool tryGrowingMaxStackSize;
+    static bool didIncreaseMaxStackSize;
+    static int availableStackSize;
   private:
 #ifdef HAVE_PCREPOSIX
     pcre *_regex;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic