Land #7647, Search with an intersect instead of a union
commit
7ee9408da3
|
@ -25,11 +25,7 @@ module Msf::DBManager::ModuleCache
|
||||||
# @param values [Set<String>, #each] a list of strings.
|
# @param values [Set<String>, #each] a list of strings.
|
||||||
# @return [Arrray<String>] strings wrapped like %<string>%
|
# @return [Arrray<String>] strings wrapped like %<string>%
|
||||||
def match_values(values)
|
def match_values(values)
|
||||||
wrapped_values = values.collect { |value|
|
values.collect { |value| "%#{value}%" }
|
||||||
"%#{value}%"
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapped_values
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def module_to_details_hash(m)
|
def module_to_details_hash(m)
|
||||||
|
@ -200,102 +196,65 @@ module Msf::DBManager::ModuleCache
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
query = Mdm::Module::Detail.all
|
|
||||||
|
|
||||||
ActiveRecord::Base.connection_pool.with_connection do
|
ActiveRecord::Base.connection_pool.with_connection do
|
||||||
# Although AREL supports taking the union or two queries, the ActiveRecord where syntax only supports
|
@query = Mdm::Module::Detail.all
|
||||||
# intersection, so creating the where clause has to be delayed until all conditions can be or'd together and
|
|
||||||
# passed to one call ot where.
|
@archs = Set.new
|
||||||
union_conditions = []
|
@authors = Set.new
|
||||||
|
@names = Set.new
|
||||||
|
@os = Set.new
|
||||||
|
@refs = Set.new
|
||||||
|
@stances = Set.new
|
||||||
|
@text = Set.new
|
||||||
|
@types = Set.new
|
||||||
|
|
||||||
value_set_by_keyword.each do |keyword, value_set|
|
value_set_by_keyword.each do |keyword, value_set|
|
||||||
|
formatted_values = match_values(value_set)
|
||||||
|
|
||||||
case keyword
|
case keyword
|
||||||
when 'author'
|
|
||||||
formatted_values = match_values(value_set)
|
|
||||||
|
|
||||||
query = query.includes(:authors).references(:authors)
|
|
||||||
module_authors = Mdm::Module::Author.arel_table
|
|
||||||
union_conditions << module_authors[:email].matches_any(formatted_values)
|
|
||||||
union_conditions << module_authors[:name].matches_any(formatted_values)
|
|
||||||
when 'name'
|
|
||||||
formatted_values = match_values(value_set)
|
|
||||||
|
|
||||||
module_details = Mdm::Module::Detail.arel_table
|
|
||||||
union_conditions << module_details[:fullname].matches_any(formatted_values)
|
|
||||||
union_conditions << module_details[:name].matches_any(formatted_values)
|
|
||||||
when 'os', 'platform'
|
|
||||||
formatted_values = match_values(value_set)
|
|
||||||
|
|
||||||
query = query.includes(:platforms).references(:platforms)
|
|
||||||
union_conditions << Mdm::Module::Platform.arel_table[:name].matches_any(formatted_values)
|
|
||||||
|
|
||||||
query = query.includes(:targets).references(:targets)
|
|
||||||
union_conditions << Mdm::Module::Target.arel_table[:name].matches_any(formatted_values)
|
|
||||||
when 'text'
|
|
||||||
formatted_values = match_values(value_set)
|
|
||||||
|
|
||||||
module_details = Mdm::Module::Detail.arel_table
|
|
||||||
union_conditions << module_details[:description].matches_any(formatted_values)
|
|
||||||
union_conditions << module_details[:fullname].matches_any(formatted_values)
|
|
||||||
union_conditions << module_details[:name].matches_any(formatted_values)
|
|
||||||
|
|
||||||
query = query.includes(:actions).references(:actions)
|
|
||||||
union_conditions << Mdm::Module::Action.arel_table[:name].matches_any(formatted_values)
|
|
||||||
|
|
||||||
query = query.includes(:archs).references(:archs)
|
|
||||||
union_conditions << Mdm::Module::Arch.arel_table[:name].matches_any(formatted_values)
|
|
||||||
|
|
||||||
query = query.includes(:authors).references(:authors)
|
|
||||||
union_conditions << Mdm::Module::Author.arel_table[:name].matches_any(formatted_values)
|
|
||||||
|
|
||||||
query = query.includes(:platforms).references(:platforms)
|
|
||||||
union_conditions << Mdm::Module::Platform.arel_table[:name].matches_any(formatted_values)
|
|
||||||
|
|
||||||
query = query.includes(:refs).references(:refs)
|
|
||||||
union_conditions << Mdm::Module::Ref.arel_table[:name].matches_any(formatted_values)
|
|
||||||
|
|
||||||
query = query.includes(:targets).references(:targets)
|
|
||||||
union_conditions << Mdm::Module::Target.arel_table[:name].matches_any(formatted_values)
|
|
||||||
when 'type'
|
|
||||||
formatted_values = match_values(value_set)
|
|
||||||
union_conditions << Mdm::Module::Detail.arel_table[:mtype].matches_any(formatted_values)
|
|
||||||
when 'app'
|
when 'app'
|
||||||
formatted_values = value_set.collect { |value|
|
formatted_values = value_set.collect { |value|
|
||||||
formatted_value = 'aggressive'
|
formatted_value = 'aggressive'
|
||||||
|
|
||||||
if value == 'client'
|
if value == 'client'
|
||||||
formatted_value = 'passive'
|
formatted_value = 'passive'
|
||||||
end
|
end
|
||||||
|
|
||||||
formatted_value
|
formatted_value
|
||||||
}
|
}
|
||||||
|
@stances << formatted_values
|
||||||
union_conditions << Mdm::Module::Detail.arel_table[:stance].eq_any(formatted_values)
|
when 'arch'
|
||||||
|
@archs << formatted_values
|
||||||
|
when 'author'
|
||||||
|
@authors << formatted_values
|
||||||
|
when 'name'
|
||||||
|
@names << formatted_values
|
||||||
|
when 'os', 'platform'
|
||||||
|
@os << formatted_values
|
||||||
when 'ref'
|
when 'ref'
|
||||||
formatted_values = match_values(value_set)
|
@refs << formatted_values
|
||||||
|
|
||||||
query = query.includes(:refs).references(:refs)
|
|
||||||
union_conditions << Mdm::Module::Ref.arel_table[:name].matches_any(formatted_values)
|
|
||||||
when 'cve', 'bid', 'edb'
|
when 'cve', 'bid', 'edb'
|
||||||
formatted_values = value_set.collect { |value|
|
formatted_values = value_set.collect { |value|
|
||||||
prefix = keyword.upcase
|
prefix = keyword.upcase
|
||||||
|
|
||||||
"#{prefix}-%#{value}%"
|
"#{prefix}-%#{value}%"
|
||||||
}
|
}
|
||||||
|
@refs << formatted_values
|
||||||
query = query.includes(:refs).references(:refs)
|
when 'text'
|
||||||
union_conditions << Mdm::Module::Ref.arel_table[:name].matches_any(formatted_values)
|
@text << formatted_values
|
||||||
|
when 'type'
|
||||||
|
@types << formatted_values
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
unioned_conditions = union_conditions.inject { |union, condition|
|
@query = @query.module_arch( @archs.to_a.flatten ) if @archs.any?
|
||||||
union.or(condition)
|
@query = @query.module_author( @authors.to_a.flatten ) if @authors.any?
|
||||||
}
|
@query = @query.module_name( @names.to_a.flatten ) if @names.any?
|
||||||
|
@query = @query.module_os_or_platform( @os.to_a.flatten ) if @os.any?
|
||||||
|
@query = @query.module_text( @text.to_a.flatten ) if @text.any?
|
||||||
|
@query = @query.module_type( @types.to_a.flatten ) if @types.any?
|
||||||
|
@query = @query.module_stance( @stances.to_a.flatten ) if @stances.any?
|
||||||
|
@query = @query.module_ref( @refs.to_a.flatten ) if @refs.any?
|
||||||
|
|
||||||
query = query.where(unioned_conditions).to_a.uniq { |m| m.fullname }
|
@query.uniq
|
||||||
end
|
|
||||||
|
|
||||||
query
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Destroys the old Mdm::Module::Detail and creates a new Mdm::Module::Detail for
|
# Destroys the old Mdm::Module::Detail and creates a new Mdm::Module::Detail for
|
||||||
|
|
Loading…
Reference in New Issue