Commit 287f42dc authored by ggaren@apple.com's avatar ggaren@apple.com
Browse files

JavaScriptCore:

2009-03-19  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Sam Weinig.
        
        Fixed <rdar://problem/6603562> REGRESSION (Safari 4): regular expression
        pattern size limit lower than Safari 3.2, other browsers, breaks SAP (14873)
        
        Bumped the pattern size limit to 1MB, and standardized it between PCRE
        and WREC. (Empirical testing says that we can easily compile a 1MB regular
        expression without risking a hang. Other browsers support bigger regular
        expressions, but also hang.)
        
        SunSpider reports no change.
        
        I started with a patch posted to Bugzilla by Erik Corry (erikcorry@google.com).
        
        * pcre/pcre_internal.h:
        (put3ByteValue):
        (get3ByteValue):
        (put3ByteValueAndAdvance):
        (putLinkValueAllowZero):
        (getLinkValueAllowZero): Made PCRE's "LINK_SIZE" (the number of bytes
        used to record jumps between bytecodes) 3, to accomodate larger potential
        jumps. Bumped PCRE's "MAX_PATTERN_SIZE" to 1MB. (Technically, at this
        LINK_SIZE, we can support even larger patterns, but we risk a hang during
        compilation, and it's not clear that such large patterns are important
        on the web.)

        * wrec/WREC.cpp:
        (JSC::WREC::Generator::compileRegExp): Match PCRE's maximum pattern size,
        to avoid quirks between platforms.

LayoutTests:

2009-03-19  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Sam Weinig.
        
        Made two layout tests less agressive, to accomodate a change I made
        for <rdar://problem/6603562> REGRESSION (Safari 4): regular expression
        pattern size limit lower than Safari 3.2, other browsers, breaks SAP (14873)

        * fast/js/regexp-charclass-crash-expected.txt:
        * fast/js/regexp-charclass-crash.html: Explicitly limit the number of iterations
        in the test loop. Otherwise, regular expression engines supporting very
        long patterns take a very very very long time to run this test.

        * fast/js/resources/regexp-overflow.js: Made the "too big" regexp in
        this test even bigger, to match our new limit.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@41842 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 12aadcea
2009-03-19 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
Fixed <rdar://problem/6603562> REGRESSION (Safari 4): regular expression
pattern size limit lower than Safari 3.2, other browsers, breaks SAP (14873)
Bumped the pattern size limit to 1MB, and standardized it between PCRE
and WREC. (Empirical testing says that we can easily compile a 1MB regular
expression without risking a hang. Other browsers support bigger regular
expressions, but also hang.)
SunSpider reports no change.
I started with a patch posted to Bugzilla by Erik Corry (erikcorry@google.com).
* pcre/pcre_internal.h:
(put3ByteValue):
(get3ByteValue):
(put3ByteValueAndAdvance):
(putLinkValueAllowZero):
(getLinkValueAllowZero): Made PCRE's "LINK_SIZE" (the number of bytes
used to record jumps between bytecodes) 3, to accomodate larger potential
jumps. Bumped PCRE's "MAX_PATTERN_SIZE" to 1MB. (Technically, at this
LINK_SIZE, we can support even larger patterns, but we risk a hang during
compilation, and it's not clear that such large patterns are important
on the web.)
* wrec/WREC.cpp:
(JSC::WREC::Generator::compileRegExp): Match PCRE's maximum pattern size,
to avoid quirks between platforms.
2009-03-18 Ada Chan <adachan@apple.com>
 
Rolling out r41818 since it broke the windows build.
......@@ -85,7 +85,7 @@ total length. */
offsets within the compiled regex. The default is 2, which allows for compiled
patterns up to 64K long. */
#define LINK_SIZE 2
#define LINK_SIZE 3
/* Define DEBUG to get debugging output on stdout. */
......@@ -124,28 +124,60 @@ static inline void put2ByteValue(unsigned char* opcodePtr, int value)
opcodePtr[1] = value;
}
static inline void put3ByteValue(unsigned char* opcodePtr, int value)
{
ASSERT(value >= 0 && value <= 0xFFFFFF);
opcodePtr[0] = value >> 16;
opcodePtr[1] = value >> 8;
opcodePtr[2] = value;
}
static inline int get2ByteValue(const unsigned char* opcodePtr)
{
return (opcodePtr[0] << 8) | opcodePtr[1];
}
static inline int get3ByteValue(const unsigned char* opcodePtr)
{
return (opcodePtr[0] << 16) | (opcodePtr[1] << 8) | opcodePtr[2];
}
static inline void put2ByteValueAndAdvance(unsigned char*& opcodePtr, int value)
{
put2ByteValue(opcodePtr, value);
opcodePtr += 2;
}
static inline void put3ByteValueAndAdvance(unsigned char*& opcodePtr, int value)
{
put3ByteValue(opcodePtr, value);
opcodePtr += 3;
}
static inline void putLinkValueAllowZero(unsigned char* opcodePtr, int value)
{
#if LINK_SIZE == 3
put3ByteValue(opcodePtr, value);
#elif LINK_SIZE == 2
put2ByteValue(opcodePtr, value);
#else
# error LINK_SIZE not supported.
#endif
}
static inline int getLinkValueAllowZero(const unsigned char* opcodePtr)
{
#if LINK_SIZE == 3
return get3ByteValue(opcodePtr);
#elif LINK_SIZE == 2
return get2ByteValue(opcodePtr);
#else
# error LINK_SIZE not supported.
#endif
}
#define MAX_PATTERN_SIZE (1 << 16)
#define MAX_PATTERN_SIZE 1024 * 1024 // Derived by empirical testing of compile time in PCRE and WREC.
COMPILE_ASSERT(MAX_PATTERN_SIZE < (1 << (8 * LINK_SIZE)), pcre_max_pattern_fits_in_bytecode);
static inline void putLinkValue(unsigned char* opcodePtr, int value)
{
......
......@@ -40,12 +40,9 @@ using namespace WTF;
namespace JSC { namespace WREC {
// Patterns longer than this can hang the compiler.
static const int MaxPatternSize = (1 << 13);
CompiledRegExp Generator::compileRegExp(JSGlobalData* globalData, const UString& pattern, unsigned* numSubpatterns_ptr, const char** error_ptr, RefPtr<ExecutablePool>& pool, bool ignoreCase, bool multiline)
{
if (pattern.size() > MaxPatternSize) {
if (pattern.size() > MAX_PATTERN_SIZE) {
*error_ptr = "regular expression too large";
return 0;
}
......
2009-03-19 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
Made two layout tests less agressive, to accomodate a change I made
for <rdar://problem/6603562> REGRESSION (Safari 4): regular expression
pattern size limit lower than Safari 3.2, other browsers, breaks SAP (14873)
* fast/js/regexp-charclass-crash-expected.txt:
* fast/js/regexp-charclass-crash.html: Explicitly limit the number of iterations
in the test loop. Otherwise, regular expression engines supporting very
long patterns take a very very very long time to run this test.
* fast/js/resources/regexp-overflow.js: Made the "too big" regexp in
this test even bigger, to match our new limit.
2009-03-19 Simon Fraser <simon.fraser@apple.com>
 
Reviewed by Dave Hyatt
......
Tests a crash in the regular expression engine. If this stops with a single "regular expression too large" exception, then the test succeeded.
Tests a crash in the regular expression engine. If this test prints a PASS message, then it succeeded.
Got over 1000 iterations and then got this exception: SyntaxError: Invalid regular expression: regular expression too large.
PASS: Got to pattern length of 8192 without crashing.
<p>Tests a crash in the regular expression engine.
If this stops with a single "regular expression too large" exception, then the test succeeded.</p>
<p>Tests a crash in the regular expression engine. If this test prints a PASS message, then it succeeded.</p>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
var string = "";
for (i = 0; i < 1000; ++i) // >
for (i = 0; i < 1000; ++i)
string += "[[**]]";
for (; i < 10000; ++i) { // >
while (string.length < 8192) {
string += "[[**]]";
try {
new RegExp(string);
} catch (exception) {
if (/too large/.test(exception) && i > 1000) {
document.writeln("<div>Got over 1000 iterations and then got this exception: " + exception + ".</div>");
break;
}
}
new RegExp(string);
}
document.writeln("<div>PASS: Got to pattern length of 8192 without crashing.</div>");
</script>
......@@ -21,7 +21,7 @@ shouldBe('/{([\\D-\\ca]]„£µ+?)}|[[\\B-\\u00d4]√π- ]]]{0,3}/i.exec("B√π
shouldBe('/|[x\\B-\\u00b5]/i.exec("").toString()', '""');
var s = "a";
for (var i = 0; i < 17; i++)
for (var i = 0; i < 21; i++)
s += s;
shouldThrow('new RegExp(s);');
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment