FIX: Escape regexp chars in SiteSetting.censored_words.

This commit is contained in:
Rimian Perkins
2017-01-16 16:24:47 +11:00
committed by Guo Xiang Tan
parent 8fc7420f83
commit 25516874b5
3 changed files with 43 additions and 17 deletions

View File

@ -1,7 +1,7 @@
class CensoredWordsValidator < ActiveModel::EachValidator class CensoredWordsValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value) def validate_each(record, attribute, value)
if !SiteSetting.censored_words.blank? && if !SiteSetting.censored_words.blank? &&
!(censored_words = value.scan(/#{SiteSetting.censored_words}/i)).empty? !(censored_words = value.scan(censored_words_regexp)).empty?
record.errors.add( record.errors.add(
attribute, :contains_censored_words, attribute, :contains_censored_words,
@ -22,6 +22,13 @@ class CensoredWordsValidator < ActiveModel::EachValidator
def join_censored_words(censored_words) def join_censored_words(censored_words)
censored_words.map!(&:downcase) censored_words.map!(&:downcase)
censored_words.uniq! censored_words.uniq!
censored_words.join(", ") censored_words.join(", ".freeze)
end
def censored_words_regexp
Regexp.new(
SiteSetting.censored_words.split('|'.freeze).map! { |w| Regexp.escape(w) }.join('|'.freeze),
true
)
end end
end end

View File

@ -493,7 +493,7 @@ describe Post do
expect(Fabricate.build(:post, post_args)).to be_valid expect(Fabricate.build(:post, post_args)).to be_valid
end end
it 'treate blank posts as invalid' do it 'create blank posts as invalid' do
expect(Fabricate.build(:post, raw: "")).not_to be_valid expect(Fabricate.build(:post, raw: "")).not_to be_valid
end end
end end

View File

@ -13,6 +13,22 @@ describe Topic do
context "#title" do context "#title" do
it { is_expected.to validate_presence_of :title } it { is_expected.to validate_presence_of :title }
describe 'censored pattern' do
describe 'when title matches censored pattern' do
it 'should not be valid' do
SiteSetting.censored_pattern = 'orange.*'
topic.title = 'I have orangEjuice orange monkey orange stuff'
expect(topic).to_not be_valid
expect(topic.errors.full_messages.first).to include(I18n.t(
'errors.messages.matches_censored_pattern', censored_words: 'orangejuice orange monkey orange stuff'
))
end
end
end
describe 'censored words' do describe 'censored words' do
describe 'when title contains censored words' do describe 'when title contains censored words' do
it 'should not be valid' do it 'should not be valid' do
@ -28,20 +44,6 @@ describe Topic do
end end
end end
describe 'when title matches censored pattern' do
it 'should not be valid' do
SiteSetting.censored_pattern = 'orange.*'
topic.title = 'I have orangEjuice orange monkey orange stuff'
expect(topic).to_not be_valid
expect(topic.errors.full_messages.first).to include(I18n.t(
'errors.messages.matches_censored_pattern', censored_words: 'orangejuice orange monkey orange stuff'
))
end
end
describe 'when title does not contain censored words' do describe 'when title does not contain censored words' do
it 'should be valid' do it 'should be valid' do
topic.title = 'The cake is a lie' topic.title = 'The cake is a lie'
@ -49,6 +51,23 @@ describe Topic do
expect(topic).to be_valid expect(topic).to be_valid
end end
end end
describe 'escape special characters in censored words' do
before do
SiteSetting.censored_words = 'co(onut|coconut|a**le'
end
it 'should not valid' do
topic.title = "I have a co(onut a**le"
expect(topic.valid?).to eq(false)
expect(topic.errors.full_messages.first).to include(I18n.t(
'errors.messages.contains_censored_words',
censored_words: 'co(onut, a**le'
))
end
end
end end
end end
end end