Fixed overflow bug in parsing of regexp repetitions.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1231 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
lrn@chromium.org 2009-02-05 12:55:20 +00:00
parent f7f4cb1c33
commit 0070e8c572
3 changed files with 54 additions and 4 deletions

View File

@ -3938,6 +3938,9 @@ bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
// { DecimalDigits }
// { DecimalDigits , }
// { DecimalDigits , DecimalDigits }
//
// Returns true if parsing succeeds, and set the min_out and max_out
// values. Values are truncated to RegExpTree::kInfinity if they overflow.
bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
ASSERT_EQ(current(), '{');
int start = position();
@ -3948,7 +3951,14 @@ bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
return false;
}
while (IsDecimalDigit(current())) {
min = 10 * min + (current() - '0');
int next = current() - '0';
if (min > (RegExpTree::kInfinity - next) / 10) {
// Overflow. Skip past remaining decimal digits and return -1.
do { Advance(); } while (IsDecimalDigit(current()));
min = RegExpTree::kInfinity;
break;
}
min = 10 * min + next;
Advance();
}
int max = 0;
@ -3962,7 +3972,13 @@ bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
Advance();
} else {
while (IsDecimalDigit(current())) {
max = 10 * max + (current() - '0');
int next = current() - '0';
if (max > (RegExpTree::kInfinity - next) / 10) {
do { Advance(); } while (IsDecimalDigit(current()));
max = RegExpTree::kInfinity;;
break;
}
max = 10 * max + next;
Advance();
}
if (current() != '}') {

View File

@ -2110,7 +2110,8 @@ assertEquals(null, res[255].exec("ab\ncd", 463));
assertEquals(null, res[255].exec("AbCd", 464));
assertEquals(null, res[255].exec("** Failers", 465));
assertEquals(null, res[255].exec("abcd", 466));
assertThrows("var re = /(){2,4294967295}/;", 467);
// We are compatible with JSC, and don't throw an exception in this case.
// assertThrows("var re = /(){2,4294967295}/;", 467);
assertEquals(null, res[255].exec("abcdefghijklAkB", 468));
assertEquals(null, res[255].exec("abcdefghijklAkB", 469));
assertEquals(null, res[255].exec("abcdefghijklAkB", 470));

View File

@ -304,11 +304,44 @@ for (var i = 0; i < 128; i++) {
assertFalse(/f(o)$\1/.test('foo'), "backref detects at_end");
// Check decimal escapes doesn't overflow.
// (Note: \214 is interpreted as octal).
assertEquals(/\2147483648/.exec("\x8c7483648"),
["\x8c7483648"],
"Overflow decimal escape");
// Check numbers in quantifiers doesn't overflow and doesn't throw on
// too large numbers.
assertFalse(/a{111111111111111111111111111111111111111111111}/.test('b'),
"overlarge1");
assertFalse(/a{999999999999999999999999999999999999999999999}/.test('b'),
"overlarge2");
assertFalse(/a{1,111111111111111111111111111111111111111111111}/.test('b'),
"overlarge3");
assertFalse(/a{1,999999999999999999999999999999999999999999999}/.test('b'),
"overlarge4");
assertFalse(/a{2147483648}/.test('b'),
"overlarge5");
assertFalse(/a{21474836471}/.test('b'),
"overlarge6");
assertFalse(/a{1,2147483648}/.test('b'),
"overlarge7");
assertFalse(/a{1,21474836471}/.test('b'),
"overlarge8");
assertFalse(/a{2147483648,2147483648}/.test('b'),
"overlarge9");
assertFalse(/a{21474836471,21474836471}/.test('b'),
"overlarge10");
assertFalse(/a{2147483647}/.test('b'),
"overlarge11");
assertFalse(/a{1,2147483647}/.test('b'),
"overlarge12");
assertTrue(/a{1,2147483647}/.test('a'),
"overlarge13");
assertFalse(/a{2147483647,2147483647}/.test('a'),
"overlarge14");
// Check that we don't read past the end of the string.
assertFalse(/f/.test('b'));
assertFalse(/[abc]f/.test('x'));