1
0
mirror of https://github.com/meineerde/redmine.git synced 2026-02-05 00:23:24 +00:00

Use sanitize_sql_like in like scopes (#35073).

Patch Jens Krämer.

git-svn-id: http://svn.redmine.org/redmine/trunk@21231 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Marius Balteanu 2021-10-03 19:44:39 +00:00
parent 65f31d52cd
commit 05e9d7883b
8 changed files with 69 additions and 5 deletions

View File

@ -102,7 +102,7 @@ class Issue < ActiveRecord::Base
scope :like, (lambda do |q|
q = q.to_s
if q.present?
where("LOWER(#{table_name}.subject) LIKE LOWER(?)", "%#{q}%")
where("LOWER(#{table_name}.subject) LIKE LOWER(?)", "%#{sanitize_sql_like q}%")
end
end)

View File

@ -71,12 +71,12 @@ class Principal < ActiveRecord::Base
if q.blank?
where({})
else
pattern = "%#{q}%"
pattern = "%#{sanitize_sql_like q}%"
sql = +"LOWER(#{table_name}.login) LIKE LOWER(:p)"
sql << " OR #{table_name}.id IN (SELECT user_id FROM #{EmailAddress.table_name} WHERE LOWER(address) LIKE LOWER(:p))"
params = {:p => pattern}
tokens = q.split(/\s+/).reject(&:blank?).map {|token| "%#{token}%"}
tokens = q.split(/\s+/).reject(&:blank?).map {|token| "%#{sanitize_sql_like token}%"}
if tokens.present?
sql << ' OR ('
sql << tokens.map.with_index do |token, index|

View File

@ -107,7 +107,7 @@ class Project < ActiveRecord::Base
end)
scope :like, (lambda do |arg|
if arg.present?
pattern = "%#{arg.to_s.strip}%"
pattern = "%#{sanitize_sql_like arg.to_s.strip}%"
where("LOWER(identifier) LIKE LOWER(:p) OR LOWER(name) LIKE LOWER(:p)", :p => pattern)
end
end)

View File

@ -137,7 +137,7 @@ class Version < ActiveRecord::Base
scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
scope :like, (lambda do |arg|
if arg.present?
pattern = "%#{arg.to_s.strip}%"
pattern = "%#{sanitize_sql_like arg.to_s.strip}%"
where([Redmine::Database.like("#{Version.table_name}.name", '?'), pattern])
end
end)

View File

@ -3406,4 +3406,20 @@ class IssueTest < ActiveSupport::TestCase
assert_equal [5], issue2.filter_projects_scope('').ids.sort
end
def test_like_should_escape_query
issue = Issue.generate!(:subject => "asdf")
r = Issue.like('as_f')
assert_not_include issue, r
r = Issue.like('as%f')
assert_not_include issue, r
issue = Issue.generate!(:subject => "as%f")
r = Issue.like('as%f')
assert_include issue, r
issue = Issue.generate!(:subject => "as_f")
r = Issue.like('as_f')
assert_include issue, r
end
end

View File

@ -147,4 +147,20 @@ class PrincipalTest < ActiveSupport::TestCase
assert_equal 1, results.count
assert_equal user, results.first
end
def test_like_scope_should_escape_query
user = User.generate!(:firstname => 'Leonardo', :lastname => 'da Vinci')
r = Principal.like('Vi_ci')
assert_not_include user, r
r = Principal.like('Vi%ci')
assert_not_include user, r
user.update_column :lastname, 'da Vi%ci'
r = Principal.like('vi%ci')
assert_include user, r
user.update_column :lastname, 'da Vi_ci'
r = Principal.like('vi_ci')
assert_include user, r
end
end

View File

@ -1127,4 +1127,20 @@ class ProjectTest < ActiveSupport::TestCase
assert_equal 'valuea', project.custom_field_value(cf1)
assert_nil project.custom_field_value(cf2)
end
def test_like_scope_should_escape_query
project = Project.find 'ecookbook'
r = Project.like('eco_k')
assert_not_include project, r
r = Project.like('eco%k')
assert_not_include project, r
project.update_column :name, 'Eco%kbook'
r = Project.like('eco%k')
assert_include project, r
project.update_column :name, 'Eco_kbook'
r = Project.like('eco_k')
assert_include project, r
end
end

View File

@ -300,6 +300,22 @@ class VersionTest < ActiveSupport::TestCase
assert_includes Version.like('like scope'), version
end
def test_like_scope_should_escape_query
version = Version.create!(:project => Project.find(1), :name => 'Version for like scope test')
r = Version.like('Ver_ion')
assert_not_include version, r
r = Version.like('Ver%ion')
assert_not_include version, r
version.update_column :name, 'Ver%ion'
r = Version.like('ver%i')
assert_include version, r
version.update_column :name, 'Ver_ion'
r = Version.like('ver_i')
assert_include version, r
end
def test_safe_attributes_should_include_only_custom_fields_visible_to_user
cf1 = VersionCustomField.create!(:name => 'Visible field',
:field_format => 'string',