From cebf29f83e6d1952da4d639e88ace7761ba115c3 Mon Sep 17 00:00:00 2001 From: evazion Date: Mon, 22 May 2017 12:44:36 -0500 Subject: [PATCH] Allow escaping wildcards (\*) in wildcard searches. --- config/initializers/core_extensions.rb | 13 ++++++++++++- test/unit/string_test.rb | 17 +++++++++++++++++ test/unit/user_test.rb | 12 ++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 test/unit/string_test.rb diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index a19ed3011..cc990577f 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -2,7 +2,18 @@ module Danbooru module Extensions module String def to_escaped_for_sql_like - return self.gsub(/\\/, '\0\0').gsub(/(%|_)/, "\\\\\\1").gsub(/\*/, '%') + string = self.gsub(/%|_|\*|\\\*|\\\\|\\/) do |str| + case str + when '%' then '\%' + when '_' then '\_' + when '*' then '%' + when '\*' then '*' + when '\\\\' then '\\\\' + when '\\' then '\\\\' + end + end + + string end def to_escaped_for_tsquery_split diff --git a/test/unit/string_test.rb b/test/unit/string_test.rb new file mode 100644 index 000000000..47224ba77 --- /dev/null +++ b/test/unit/string_test.rb @@ -0,0 +1,17 @@ +require 'test_helper' + +class StringTest < ActiveSupport::TestCase + context "String#to_escaped_for_sql_like" do + should "work" do + assert_equal('foo\%bar', 'foo%bar'.to_escaped_for_sql_like) + assert_equal('foo\_bar', 'foo_bar'.to_escaped_for_sql_like) + assert_equal('foo%bar', 'foo*bar'.to_escaped_for_sql_like) + assert_equal('foo*bar', 'foo\*bar'.to_escaped_for_sql_like) + assert_equal('foo\\\\%bar', 'foo\\\\*bar'.to_escaped_for_sql_like) + assert_equal('foo\\\\bar', 'foo\bar'.to_escaped_for_sql_like) + + assert_equal('%\\\\%', '*\\\\*'.to_escaped_for_sql_like) + assert_equal('%*%', '*\**'.to_escaped_for_sql_like) + end + end +end diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 068774411..c2868596a 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -310,5 +310,17 @@ class UserTest < ActiveSupport::TestCase end end end + + context "when searched by name" do + should "match wildcards" do + user1 = FactoryGirl.create(:user, :name => "foo") + user2 = FactoryGirl.create(:user, :name => "foo*bar") + user3 = FactoryGirl.create(:user, :name => "bar\*baz") + + assert_equal([user2.id, user1.id], User.search(name: "foo*").map(&:id)) + assert_equal([user2.id], User.search(name: "foo\*bar").map(&:id)) + assert_equal([user3.id], User.search(name: "bar\\\*baz").map(&:id)) + end + end end end