summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Tests/LibRegex/Regex.cpp11
-rw-r--r--Userland/Libraries/LibRegex/RegexByteCode.cpp11
2 files changed, 20 insertions, 2 deletions
diff --git a/Tests/LibRegex/Regex.cpp b/Tests/LibRegex/Regex.cpp
index 50420c504a..41c7d1c355 100644
--- a/Tests/LibRegex/Regex.cpp
+++ b/Tests/LibRegex/Regex.cpp
@@ -1034,3 +1034,14 @@ TEST_CASE(single_match_flag)
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);
+}
diff --git a/Userland/Libraries/LibRegex/RegexByteCode.cpp b/Userland/Libraries/LibRegex/RegexByteCode.cpp
index 4a1021ff77..c1dd64f2b3 100644
--- a/Userland/Libraries/LibRegex/RegexByteCode.cpp
+++ b/Userland/Libraries/LibRegex/RegexByteCode.cpp
@@ -458,16 +458,18 @@ ALWAYS_INLINE ExecutionResult OpCode_Compare::execute(MatchInput const& input, M
auto compare_type = (CharacterCompareType)m_bytecode->at(offset++);
- if (compare_type == CharacterCompareType::Inverse)
+ if (compare_type == CharacterCompareType::Inverse) {
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.
// it follows that this cannot be the last compare element.
VERIFY(i != arguments_count() - 1);
temporary_inverse = true;
reset_temp_inverse = false;
+ continue;
} else if (compare_type == CharacterCompareType::Char) {
u32 ch = m_bytecode->at(offset++);
@@ -598,6 +600,11 @@ ALWAYS_INLINE ExecutionResult OpCode_Compare::execute(MatchInput const& input, M
VERIFY_NOT_REACHED();
break;
}
+
+ if (current_inversion_state() && !inverse_matched) {
+ advance_string_position(state, input.view);
+ inverse_matched = true;
+ }
}
if (current_inversion_state() && !inverse_matched)