fix(filters): treat phrases as literal text in the regex
Phrases went into the Postgres and Elixir regexes as they were, so a
phrase like "(" broke the timeline and notification queries. The :re
form also put the word boundaries only around the whole alternation.
Escape each phrase and, as Mastodon does, add a word boundary only where
the phrase starts or ends with a word character.
Reported in Akkoma (d6209837b).
This commit is contained in:
parent
90eb5e4015
commit
f975db8719
3 changed files with 66 additions and 6 deletions
|
|
@ -190,4 +190,55 @@ defmodule Pleroma.FilterTest do
|
|||
|
||||
{:error, _} = Filter.update(filter, changes)
|
||||
end
|
||||
|
||||
describe "compose_regex/2" do
|
||||
defp filters(phrases), do: Enum.map(phrases, &%Filter{phrase: &1})
|
||||
|
||||
defp pg_match?(regex, text) do
|
||||
%{rows: [[match]]} = Repo.query!("SELECT $1::text ~* $2", [text, regex])
|
||||
match
|
||||
end
|
||||
|
||||
test "treats phrases as literal text in Postgres" do
|
||||
regex = Filter.compose_regex(filters(["a.b", "(c"]))
|
||||
|
||||
assert pg_match?(regex, "see a.b here")
|
||||
refute pg_match?(regex, "see axb here")
|
||||
assert pg_match?(regex, "see (c here")
|
||||
end
|
||||
|
||||
test "treats phrases as literal text in Elixir" do
|
||||
regex = Filter.compose_regex(filters(["a.b", "(c"]), :re)
|
||||
|
||||
assert Regex.match?(regex, "see a.b here")
|
||||
refute Regex.match?(regex, "see axb here")
|
||||
assert Regex.match?(regex, "see (c here")
|
||||
end
|
||||
|
||||
test "keeps word boundaries for every phrase in Postgres" do
|
||||
regex = Filter.compose_regex(filters(["cat", "dog"]))
|
||||
|
||||
assert pg_match?(regex, "a dog barks")
|
||||
refute pg_match?(regex, "a catalog")
|
||||
refute pg_match?(regex, "a hotdog")
|
||||
end
|
||||
|
||||
test "only adds word boundaries next to word characters" do
|
||||
pg = Filter.compose_regex(filters(["#tag"]))
|
||||
re = Filter.compose_regex(filters(["#tag"]), :re)
|
||||
|
||||
for {text, expected} <- [{"a #tag here", true}, {"a#tag", true}, {"some #tags", false}] do
|
||||
assert pg_match?(pg, text) == expected
|
||||
assert Regex.match?(re, text) == expected
|
||||
end
|
||||
end
|
||||
|
||||
test "keeps word boundaries for every phrase in Elixir" do
|
||||
regex = Filter.compose_regex(filters(["cat", "dog"]), :re)
|
||||
|
||||
assert Regex.match?(regex, "a dog barks")
|
||||
refute Regex.match?(regex, "a catalog")
|
||||
refute Regex.match?(regex, "a hotdog")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue