diff --git a/Libraries/LibRegex/RegexMatch.h b/Libraries/LibRegex/RegexMatch.h index 7a81f61834d..6da85b57f4d 100644 --- a/Libraries/LibRegex/RegexMatch.h +++ b/Libraries/LibRegex/RegexMatch.h @@ -418,7 +418,8 @@ struct MatchState { auto combine = [&hash](auto value) { hash ^= value + 0x9e3779b97f4a7c15 + (hash << 6) + (hash >> 2); }; - auto combine_vector = [&hash](auto const& vector) { + auto combine_vector = [&hash](auto const& vector, auto tag) { + hash ^= tag * (vector.size() + 1); for (auto& value : vector) { hash ^= value; hash *= 0x100000001b3; @@ -431,8 +432,8 @@ struct MatchState { combine(instruction_position); combine(fork_at_position); combine(initiating_fork.value_or(0) + initiating_fork.has_value()); - combine_vector(repetition_marks); - combine_vector(checkpoints); + combine_vector(repetition_marks, 0xbeefbeefbeefbeef); + combine_vector(checkpoints, 0xfacefacefaceface); return hash; } diff --git a/Libraries/LibRegex/RegexMatcher.cpp b/Libraries/LibRegex/RegexMatcher.cpp index ee2b2a29183..d5c9784be52 100644 --- a/Libraries/LibRegex/RegexMatcher.cpp +++ b/Libraries/LibRegex/RegexMatcher.cpp @@ -467,11 +467,18 @@ private: Node* m_last { nullptr }; }; +struct SufficientlyUniformValueTraits : DefaultTraits { + static constexpr unsigned hash(u64 value) + { + return (value >> 32) ^ value; + } +}; + template bool Matcher::execute(MatchInput const& input, MatchState& state, size_t& operations) const { BumpAllocatedLinkedList states_to_try_next; - HashTable seen_state_hashes; + HashTable seen_state_hashes; #if REGEX_DEBUG size_t recursion_level = 0; #endif