Commit 7b36894483721a5d02d0c561a86d587bbf8f2b67

Authored by Andrew Kane
1 parent 7ca2b43d

Fixed like queries with " character - #1365

CHANGELOG.md
  1 +## 4.2.2 (unreleased)
  2 +
  3 +- Fixed `like` queries with `"` character
  4 +
1 5 ## 4.2.1 (2020-01-27)
2 6  
3 7 - Fixed deprecation warnings with Elasticsearch
... ...
lib/searchkick/query.rb
... ... @@ -953,7 +953,14 @@ module Searchkick
953 953 # % matches zero or more characters
954 954 # _ matches one character
955 955 # \ is escape character
956   - regex = Regexp.escape(op_value).gsub(/(?<!\\)%/, ".*").gsub(/(?<!\\)_/, ".").gsub("\\%", "%").gsub("\\_", "_")
  956 + # escape Lucene reserved characters
  957 + # https://www.elastic.co/guide/en/elasticsearch/reference/current/regexp-syntax.html#regexp-optional-operators
  958 + reserved = %w(. ? + * | { } [ ] ( ) " \\)
  959 + regex = op_value.dup
  960 + reserved.each do |v|
  961 + regex.gsub!(v, "\\" + v)
  962 + end
  963 + regex = regex.gsub(/(?<!\\)%/, ".*").gsub(/(?<!\\)_/, ".").gsub("\\%", "%").gsub("\\_", "_")
957 964 filters << {regexp: {field => {value: regex}}}
958 965 when :prefix
959 966 filters << {prefix: {field => op_value}}
... ...
test/where_test.rb
... ... @@ -161,6 +161,13 @@ class WhereTest &lt; Minitest::Test
161 161 assert_search "product", ["Product 100%"], where: {name: {like: "% 100\\%"}}
162 162 end
163 163  
  164 + def test_like_special_characters
  165 + store_names ["Product ABC\"", "Product B"]
  166 + like = "%ABC\""
  167 + assert_equal 1, Product.where("name LIKE ?", like).count
  168 + assert_search "product", ["Product ABC\""], where: {name: {like: like}}
  169 + end
  170 +
164 171 # def test_script
165 172 # store [
166 173 # {name: "Product A", store_id: 1},
... ...