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:
parent
f7f4cb1c33
commit
0070e8c572
@ -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() != '}') {
|
||||
|
@ -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));
|
||||
|
@ -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'));
|
||||
|
Loading…
Reference in New Issue
Block a user