ChakraCore icon indicating copy to clipboard operation
ChakraCore copied to clipboard

JS correctness issue when overriding RegExp .exec to be incoherent

Open bakkot opened this issue 3 years ago • 1 comments

(tested with 1.11.24.0 on Mac OS)

This is one of those "I went looking for dumb edge cases" bugs. It didn't come up in real code - it requires code to be very poorly written - and should be prioritized accordingly. Anyway:

let evil = new RegExp;
evil.exec = () => ({ 0: '1234567', length: 1, index: 0 });
'abc'.replace(evil, `$'`);

and

let evil = new RegExp;
evil.exec = () => ({ 0: 'x', length: 1, index: 3 });
print('abc'.replace(evil, `$'`));

both produce abcabc. The correct results are the empty string and abc respectively.

These exercise an extremely dumb case in GetSubstitution: in the $' case, there is a tailPos ≥ stringLength condition. The strict > case there is very strange: it means that you have a match M at position P in string S such that the length of M exceeds the number of code units subsequent to P in S. Obviously this does not make sense, and indeed built-in RegExps can't do this (I am reasonably sure).

But this can be achieved by overriding the exec method on a RegExp (something we have not yet gotten rid of, unfortunately), either (in the first case) by producing a match string which is longer than the input or (in the second case) by producing a nonempty match string at position past where it could have fit in the input.

bakkot avatar Aug 08 '21 06:08 bakkot

Thanks for the report, unfortunately many RegExp edge cases are broken as per this issue: https://github.com/chakra-core/ChakraCore/issues/6390

It's on the to do list but unless we get another contributor or two involved it's not happening any time soon.

rhuanjl avatar Sep 18 '21 22:09 rhuanjl