FIX: Prevent tricking the search from ignoring minimum lengths

This commit is contained in:
Robin Ward 2016-08-09 14:48:39 -04:00
parent c1125c8649
commit 28436a604a
3 changed files with 47 additions and 10 deletions

View File

@ -70,7 +70,7 @@ export function translateResults(results, opts) {
return noResults ? null : Em.Object.create(results); return noResults ? null : Em.Object.create(results);
} }
function searchForTerm(term, opts) { export function searchForTerm(term, opts) {
if (!opts) opts = {}; if (!opts) opts = {};
// Only include the data we have // Only include the data we have
@ -94,7 +94,7 @@ function searchForTerm(term, opts) {
return promise; return promise;
} }
const searchContextDescription = function(type, name){ export function searchContextDescription(type, name) {
if (type) { if (type) {
switch(type) { switch(type) {
case 'topic': case 'topic':
@ -109,17 +109,15 @@ const searchContextDescription = function(type, name){
} }
}; };
const getSearchKey = function(args){ export function getSearchKey(args) {
return args.q + "|" + ((args.searchContext && args.searchContext.type) || "") + "|" + return args.q + "|" + ((args.searchContext && args.searchContext.type) || "") + "|" +
((args.searchContext && args.searchContext.id) || ""); ((args.searchContext && args.searchContext.id) || "");
}; };
const isValidSearchTerm = function(searchTerm) { export function isValidSearchTerm(searchTerm) {
if (searchTerm) { if (searchTerm) {
return searchTerm.trim().length >= Discourse.SiteSettings.min_search_term_length; return searchTerm.trim().length >= Discourse.SiteSettings.min_search_term_length;
} else { } else {
return false; return false;
} }
}; };
export { searchForTerm, searchContextDescription, getSearchKey, isValidSearchTerm };

View File

@ -128,6 +128,8 @@ class Search
end end
end end
attr_accessor :term
def initialize(term, opts=nil) def initialize(term, opts=nil)
@opts = opts || {} @opts = opts || {}
@guardian = @opts[:guardian] || Guardian.new @guardian = @opts[:guardian] || Guardian.new
@ -135,6 +137,7 @@ class Search
@include_blurbs = @opts[:include_blurbs] || false @include_blurbs = @opts[:include_blurbs] || false
@blurb_length = @opts[:blurb_length] @blurb_length = @opts[:blurb_length]
@limit = Search.per_facet @limit = Search.per_facet
@valid = true
term = process_advanced_search!(term) term = process_advanced_search!(term)
@ -155,14 +158,27 @@ class Search
@results = GroupedSearchResults.new(@opts[:type_filter], term, @search_context, @include_blurbs, @blurb_length) @results = GroupedSearchResults.new(@opts[:type_filter], term, @search_context, @include_blurbs, @blurb_length)
end end
def valid?
@valid
end
def self.execute(term, opts=nil) def self.execute(term, opts=nil)
self.new(term, opts).execute self.new(term, opts).execute
end end
# Query a term # Query a term
def execute def execute
if @term.blank? || @term.length < (@opts[:min_search_term_length] || SiteSetting.min_search_term_length)
return nil unless @filters.present? unless @filters.present?
min_length = @opts[:min_search_term_length] || SiteSetting.min_search_term_length
terms = (@term || '').split(/\s(?=(?:[^"]|"[^"]*")*$)/).reject {|t| t.length < min_length }
if terms.blank?
@term = ''
@valid = false
return
end
@term = terms.join(' ')
end end
# If the term is a number or url to a topic, just include that topic # If the term is a number or url to a topic, just include that topic

View File

@ -61,8 +61,31 @@ describe Search do
end end
it 'does not search when the search term is too small' do it 'does not search when the search term is too small' do
ActiveRecord::Base.expects(:exec_sql).never search = Search.new('evil', min_search_term_length: 5)
Search.execute('evil', min_search_term_length: 5) search.execute
expect(search.valid?).to eq(false)
expect(search.term).to eq('')
end
it 'does not search for multiple small terms' do
search = Search.new('a b c d', min_search_term_length: 5)
search.execute
expect(search.valid?).to eq(false)
expect(search.term).to eq('')
end
it 'searches for quoted short terms' do
search = Search.new('"a b c d"', min_search_term_length: 5)
search.execute
expect(search.valid?).to eq(true)
expect(search.term).to eq('"a b c d"')
end
it 'discards short terms' do
search = Search.new('a b c okaylength', min_search_term_length: 5)
search.execute
expect(search.valid?).to eq(true)
expect(search.term).to eq('okaylength')
end end
it 'escapes non alphanumeric characters' do it 'escapes non alphanumeric characters' do