Feature #35073 » 0003-use-sanitize_sql_like-in-like-scopes.patch
app/models/issue.rb | ||
---|---|---|
102 | 102 |
scope :like, (lambda do |q| |
103 | 103 |
q = q.to_s |
104 | 104 |
if q.present? |
105 |
where("LOWER(#{table_name}.subject) LIKE LOWER(?)", "%#{q}%") |
|
105 |
where("LOWER(#{table_name}.subject) LIKE LOWER(?)", "%#{sanitize_sql_like q}%")
|
|
106 | 106 |
end |
107 | 107 |
end) |
108 | 108 |
app/models/principal.rb | ||
---|---|---|
71 | 71 |
if q.blank? |
72 | 72 |
where({}) |
73 | 73 |
else |
74 |
pattern = "%#{q}%" |
|
74 |
pattern = "%#{sanitize_sql_like q}%"
|
|
75 | 75 |
sql = +"LOWER(#{table_name}.login) LIKE LOWER(:p)" |
76 | 76 |
sql << " OR #{table_name}.id IN (SELECT user_id FROM #{EmailAddress.table_name} WHERE LOWER(address) LIKE LOWER(:p))" |
77 | 77 |
params = {:p => pattern} |
78 | 78 | |
79 |
tokens = q.split(/\s+/).reject(&:blank?).map {|token| "%#{token}%"} |
|
79 |
tokens = q.split(/\s+/).reject(&:blank?).map {|token| "%#{sanitize_sql_like token}%"}
|
|
80 | 80 |
if tokens.present? |
81 | 81 |
sql << ' OR (' |
82 | 82 |
sql << tokens.map.with_index do |token, index| |
app/models/project.rb | ||
---|---|---|
105 | 105 |
end) |
106 | 106 |
scope :like, (lambda do |arg| |
107 | 107 |
if arg.present? |
108 |
pattern = "%#{arg.to_s.strip}%" |
|
108 |
pattern = "%#{sanitize_sql_like arg.to_s.strip}%"
|
|
109 | 109 |
where("LOWER(identifier) LIKE LOWER(:p) OR LOWER(name) LIKE LOWER(:p)", :p => pattern) |
110 | 110 |
end |
111 | 111 |
end) |
app/models/version.rb | ||
---|---|---|
137 | 137 |
scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)} |
138 | 138 |
scope :like, (lambda do |arg| |
139 | 139 |
if arg.present? |
140 |
pattern = "%#{arg.to_s.strip}%" |
|
140 |
pattern = "%#{sanitize_sql_like arg.to_s.strip}%"
|
|
141 | 141 |
where([Redmine::Database.like("#{Version.table_name}.name", '?'), pattern]) |
142 | 142 |
end |
143 | 143 |
end) |
test/unit/issue_test.rb | ||
---|---|---|
3406 | 3406 | |
3407 | 3407 |
assert_equal [5], issue2.filter_projects_scope('').ids.sort |
3408 | 3408 |
end |
3409 | ||
3410 |
def test_like_should_escape_query |
|
3411 |
issue = Issue.generate!(:subject => "asdf") |
|
3412 |
r = Issue.like('as_f') |
|
3413 |
assert_not_include issue, r |
|
3414 |
r = Issue.like('as%f') |
|
3415 |
assert_not_include issue, r |
|
3416 | ||
3417 |
issue = Issue.generate!(:subject => "as%f") |
|
3418 |
r = Issue.like('as%f') |
|
3419 |
assert_include issue, r |
|
3420 | ||
3421 |
issue = Issue.generate!(:subject => "as_f") |
|
3422 |
r = Issue.like('as_f') |
|
3423 |
assert_include issue, r |
|
3424 |
end |
|
3409 | 3425 |
end |
test/unit/principal_test.rb | ||
---|---|---|
147 | 147 |
assert_equal 1, results.count |
148 | 148 |
assert_equal user, results.first |
149 | 149 |
end |
150 | ||
151 |
def test_like_scope_should_escape_query |
|
152 |
user = User.generate!(:firstname => 'Leonardo', :lastname => 'da Vinci') |
|
153 |
r = Principal.like('Vi_ci') |
|
154 |
assert_not_include user, r |
|
155 |
r = Principal.like('Vi%ci') |
|
156 |
assert_not_include user, r |
|
157 | ||
158 |
user.update_column :lastname, 'da Vi%ci' |
|
159 |
r = Principal.like('vi%ci') |
|
160 |
assert_include user, r |
|
161 | ||
162 |
user.update_column :lastname, 'da Vi_ci' |
|
163 |
r = Principal.like('vi_ci') |
|
164 |
assert_include user, r |
|
165 |
end |
|
150 | 166 |
end |
test/unit/project_test.rb | ||
---|---|---|
1120 | 1120 |
assert_equal 'valuea', project.custom_field_value(cf1) |
1121 | 1121 |
assert_nil project.custom_field_value(cf2) |
1122 | 1122 |
end |
1123 | ||
1124 |
def test_like_scope_should_escape_query |
|
1125 |
project = Project.find 'ecookbook' |
|
1126 |
r = Project.like('eco_k') |
|
1127 |
assert_not_include project, r |
|
1128 |
r = Project.like('eco%k') |
|
1129 |
assert_not_include project, r |
|
1130 | ||
1131 |
project.update_column :name, 'Eco%kbook' |
|
1132 |
r = Project.like('eco%k') |
|
1133 |
assert_include project, r |
|
1134 | ||
1135 |
project.update_column :name, 'Eco_kbook' |
|
1136 |
r = Project.like('eco_k') |
|
1137 |
assert_include project, r |
|
1138 |
end |
|
1123 | 1139 |
end |
test/unit/version_test.rb | ||
---|---|---|
300 | 300 |
assert_includes Version.like('like scope'), version |
301 | 301 |
end |
302 | 302 | |
303 |
def test_like_scope_should_escape_query |
|
304 |
version = Version.create!(:project => Project.find(1), :name => 'Version for like scope test') |
|
305 |
r = Version.like('Ver_ion') |
|
306 |
assert_not_include version, r |
|
307 |
r = Version.like('Ver%ion') |
|
308 |
assert_not_include version, r |
|
309 | ||
310 |
version.update_column :name, 'Ver%ion' |
|
311 |
r = Version.like('ver%i') |
|
312 |
assert_include version, r |
|
313 | ||
314 |
version.update_column :name, 'Ver_ion' |
|
315 |
r = Version.like('ver_i') |
|
316 |
assert_include version, r |
|
317 |
end |
|
318 | ||
303 | 319 |
def test_safe_attributes_should_include_only_custom_fields_visible_to_user |
304 | 320 |
cf1 = VersionCustomField.create!(:name => 'Visible field', |
305 | 321 |
:field_format => 'string', |