1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:48:10 +00:00

LibRegex: Clear previous capture group contents in ECMA262 mode

ECMA262 requires that the capture groups only contain the values from
the last iteration, e.g. `((c)(a)?(b))` should _not_ contain 'a' in the
second capture group when matching "cabcb".
This commit is contained in:
Ali Mohammad Pur 2021-07-23 19:37:18 +04:30 committed by Ali Mohammad Pur
parent 34ec0fa8ad
commit c8b2199251
4 changed files with 109 additions and 1 deletions

View file

@ -132,6 +132,12 @@ void ByteCode::ensure_opcodes_initialized()
case OpCodeId::CheckBegin:
s_opcodes[i] = make<OpCode_CheckBegin>();
break;
case OpCodeId::ClearCaptureGroup:
s_opcodes[i] = make<OpCode_ClearCaptureGroup>();
break;
case OpCodeId::ClearNamedCaptureGroup:
s_opcodes[i] = make<OpCode_ClearNamedCaptureGroup>();
break;
case OpCodeId::SaveLeftCaptureGroup:
s_opcodes[i] = make<OpCode_SaveLeftCaptureGroup>();
break;
@ -288,6 +294,16 @@ ALWAYS_INLINE ExecutionResult OpCode_CheckEnd::execute(const MatchInput& input,
return ExecutionResult::Failed_ExecuteLowPrioForks;
}
ALWAYS_INLINE ExecutionResult OpCode_ClearCaptureGroup::execute(const MatchInput& input, MatchState& state, MatchOutput&) const
{
if (input.match_index < state.capture_group_matches.size()) {
auto& group = state.capture_group_matches[input.match_index];
if (id() < group.size())
group[id()] = {};
}
return ExecutionResult::Continue;
}
ALWAYS_INLINE ExecutionResult OpCode_SaveLeftCaptureGroup::execute(const MatchInput& input, MatchState& state, MatchOutput&) const
{
if (input.match_index >= state.capture_group_matches.size()) {
@ -333,6 +349,15 @@ ALWAYS_INLINE ExecutionResult OpCode_SaveRightCaptureGroup::execute(const MatchI
return ExecutionResult::Continue;
}
ALWAYS_INLINE ExecutionResult OpCode_ClearNamedCaptureGroup::execute(const MatchInput& input, MatchState& state, MatchOutput&) const
{
if (input.match_index < state.capture_group_matches.size()) {
auto& group = state.named_capture_group_matches[input.match_index];
group.remove(name());
}
return ExecutionResult::Continue;
}
ALWAYS_INLINE ExecutionResult OpCode_SaveLeftNamedCaptureGroup::execute(const MatchInput& input, MatchState& state, MatchOutput&) const
{
if (input.match_index >= state.named_capture_group_matches.size()) {