0003-use-sanitize_sql_like-in-like-scopes.patch

Jens Krämer, 2021-04-12 08:44

Download (6.13 KB)

View differences:

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',
306
-