You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

81 lines
2.5 KiB

/*
* Bug testcase for a Duktape 0.9.0 RegExp quantifier / capture handling bug.
* Captures inside a quantified atom are not reset to undefined when the
* quantifier re-matches the quantified. This was found with test262 suite
* tests:
*
* ch15/15.10/15.10.2/15.10.2.5/S15.10.2.5_A1_T4
* ch15/15.10/15.10.6/15.10.6.2/S15.10.6.2_A1_T6
*/
/*===
type object
index 0
input zaacbbbcac
length 6
0 zaacbbbcac
1 z
2 ac
3 a
4 undefined
5 c
===*/
function regexpQuantifierCaptureTest() {
var re = /(z)((a+)?(b+)?(c))*/;
var m = re.exec("zaacbbbcac");
var i;
// Matching:
//
// - '(z)' should match (into capture 1)
//
// At this point the quantifier '*' (at the end) starts iterating
// over "((a+)?(b+)?(c))".
//
// - Captures 2, 3, 4, 5 are set to undefined
// - '(a+)?' should match 'aa' greedily (into capture 3)
// - '(b+)?' should be skipped (undefined into capture 4)
// - '(c)' should match the first 'c' (into capture 5)
// - 'aac' gets recorded into capture 2
//
// At this point we've matched 'zaac', and the second capture
// group is matched again, at 'bbbcac':
//
// - Captures 2, 3, 4, 5 are set to undefined
// - '(a+)' is skipped (undefined into capture 3)
// - '(b+)' matches 'bbb' (into capture 4)
// - '(c)' matches 'c' (into capture 5)
// - 'bbbc' gets recorded into capture 2
//
// At this point we've matched 'zaac' and 'bbbc', and the second
// capture group is matched again, at 'ac':
//
// - Captures 2, 3, 4, 5 are set to undefined
// - '(a+)' matches 'a' (into capture 3)
// - '(b+)' should be skipped (undefined into capture 4)
// - '(c) should match 'c' (into capture 5)
// - 'ac' gets recorded into capture 2
//
// The bug in Duktape 0.9.0 is that when the second capture group
// (i.e. "((a+)?(b+)?(c))*") gets re-matched by the quantifier,
// the captures inside must be set to undefined at each "loop" of
// the quantifier. See E5.1 Section 15.10.2.5, step 4 of the
// RepeatMatcher algorithm. Because Duktape doesn't do that now,
// the (b+)? matcher, which is skipped on the third iteration,
// retains its value from the second iteration (i.e. 'bbb')
print('type', typeof m);
print('index', m.index);
print('input', m.input);
print('length', m.length);
for (i = 0; i <= 5; i++) {
print(i, m[i]);
}
}
try {
regexpQuantifierCaptureTest();
} catch (e) {
print(e);
}