2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-03-04 01:15:08 +08:00
discourse/app/serializers/watched_word_list_serializer.rb
Régis Hanol d01d060a8b
FIX: unify watched word boundary regex across Ruby and JS engines (#37965)
The CJK fix (d7a53ada16) introduced separate boundary patterns for Ruby
and JS engines in `match_word_regexp`. The Ruby engine used `[:word:]`
(which includes digits), while the JS engine used `\P{L}` (non-Letter).
Since digits are not letters, the JS pattern treated them as valid word
boundaries — causing "123Test" to match as "3Test" and standalone number
watched words like "123" to match inside "abc123".

Replace both engine-specific patterns with a single unified pattern
using Unicode property classes (`\p{L}`, `\p{M}`, `\p{N}`, `\p{Pc}`)
that work identically in Ruby and JavaScript. This treats letters,
marks, numbers, and connector punctuation as word characters in boundary
checks, which fixes the number-matching bug for JS consumers while
preserving the existing correct behavior on the Ruby side.

Since `match_word_regexp` no longer branches on engine, remove the
now-dead `engine:` parameter from all 5 method signatures that threaded
it through (`match_word_regexp`, `word_to_regexp`, `regexps_for_action`,
`compiled_regexps_for_action`, `serialized_regexps_for_action`) and all
call sites passing `engine: :js` (serializers, pretty_text).

https://meta.discourse.org/t/396110
https://meta.discourse.org/t/396109

Follow-up to d7a53ada16 (#37844)
2026-02-23 16:30:10 +01:00

25 lines
596 B
Ruby

# frozen_string_literal: true
class WatchedWordListSerializer < ApplicationSerializer
attributes :actions, :words, :compiled_regular_expressions
def actions
if SiteSetting.tagging_enabled
WatchedWord.actions.keys
else
WatchedWord.actions.keys.filter { |k| k != :tag }
end
end
def words
object.map { |word| WatchedWordSerializer.new(word, root: false) }
end
def compiled_regular_expressions
expressions = {}
actions.each do |action|
expressions[action] = WordWatcher.serialized_regexps_for_action(action)
end
expressions
end
end