mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 17:17:42 +00:00
LibRegex: Check inverse_matched after every op, not just at the end
Fixes #13755. Co-Authored-By: Damien Firmenich <fir.damien@gmail.com>
This commit is contained in:
parent
a79896bb44
commit
1409a48da6
2 changed files with 20 additions and 2 deletions
|
@ -1034,3 +1034,14 @@ TEST_CASE(single_match_flag)
|
||||||
EXPECT_EQ(result.matches.first().view.to_string(), "A"sv);
|
EXPECT_EQ(result.matches.first().view.to_string(), "A"sv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(inversion_state_in_char_class)
|
||||||
|
{
|
||||||
|
// #13755, /[\S\s]/.exec("hello") should be [ "h" ], not null.
|
||||||
|
Regex<ECMA262> re("[\\S\\s]", ECMAScriptFlags::Global | (ECMAScriptFlags)regex::AllFlags::SingleMatch);
|
||||||
|
|
||||||
|
auto result = re.match("hello");
|
||||||
|
EXPECT_EQ(result.success, true);
|
||||||
|
EXPECT_EQ(result.matches.size(), 1u);
|
||||||
|
EXPECT_EQ(result.matches.first().view.to_string(), "h"sv);
|
||||||
|
}
|
||||||
|
|
|
@ -458,16 +458,18 @@ ALWAYS_INLINE ExecutionResult OpCode_Compare::execute(MatchInput const& input, M
|
||||||
|
|
||||||
auto compare_type = (CharacterCompareType)m_bytecode->at(offset++);
|
auto compare_type = (CharacterCompareType)m_bytecode->at(offset++);
|
||||||
|
|
||||||
if (compare_type == CharacterCompareType::Inverse)
|
if (compare_type == CharacterCompareType::Inverse) {
|
||||||
inverse = true;
|
inverse = true;
|
||||||
|
continue;
|
||||||
|
|
||||||
else if (compare_type == CharacterCompareType::TemporaryInverse) {
|
} else if (compare_type == CharacterCompareType::TemporaryInverse) {
|
||||||
// If "TemporaryInverse" is given, negate the current inversion state only for the next opcode.
|
// If "TemporaryInverse" is given, negate the current inversion state only for the next opcode.
|
||||||
// it follows that this cannot be the last compare element.
|
// it follows that this cannot be the last compare element.
|
||||||
VERIFY(i != arguments_count() - 1);
|
VERIFY(i != arguments_count() - 1);
|
||||||
|
|
||||||
temporary_inverse = true;
|
temporary_inverse = true;
|
||||||
reset_temp_inverse = false;
|
reset_temp_inverse = false;
|
||||||
|
continue;
|
||||||
|
|
||||||
} else if (compare_type == CharacterCompareType::Char) {
|
} else if (compare_type == CharacterCompareType::Char) {
|
||||||
u32 ch = m_bytecode->at(offset++);
|
u32 ch = m_bytecode->at(offset++);
|
||||||
|
@ -598,6 +600,11 @@ ALWAYS_INLINE ExecutionResult OpCode_Compare::execute(MatchInput const& input, M
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (current_inversion_state() && !inverse_matched) {
|
||||||
|
advance_string_position(state, input.view);
|
||||||
|
inverse_matched = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_inversion_state() && !inverse_matched)
|
if (current_inversion_state() && !inverse_matched)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue