From 2338f004eb79df6a042b3273e36e9c5eaf39b1b7 Mon Sep 17 00:00:00 2001 From: albert Date: Thu, 7 Mar 2013 16:34:12 -0500 Subject: [PATCH] refactored tsquery sql to use rails escaping mechanisms --- app/logical/post_query_builder.rb | 9 ++------- app/models/artist.rb | 6 +++--- app/models/comment.rb | 4 ++-- app/models/dmail.rb | 2 +- app/models/forum_post.rb | 4 ++-- app/models/forum_topic.rb | 2 +- app/models/note.rb | 4 ++-- app/models/post.rb | 3 +-- app/models/wiki_page.rb | 2 +- config/initializers/core_extensions.rb | 8 ++++++++ 10 files changed, 23 insertions(+), 21 deletions(-) diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index 6b46aafe7..d3712241e 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -1,11 +1,6 @@ class PostQueryBuilder attr_accessor :query_string, :has_constraints - def self.escape_string_for_tsquery(token) - escaped_token = token.gsub(/\\|'/, '\0\0\0\0').gsub("?", "\\\\77").gsub("%", "\\\\37") - "''" + escaped_token + "''" - end - def initialize(query_string) @query_string = query_string @has_constraint = false @@ -53,7 +48,7 @@ class PostQueryBuilder def escape_string_for_tsquery(array) array.map do |token| - PostQueryBuilder.escape_string_for_tsquery(token) + token.to_escaped_for_tsquery end end @@ -75,7 +70,7 @@ class PostQueryBuilder end if tag_query_sql.any? - relation = relation.where("posts.tag_index @@ to_tsquery('danbooru', E'" + tag_query_sql.join(" & ") + "')") + relation = relation.where("posts.tag_index @@ to_tsquery('danbooru', E?)", tag_query_sql.join(" & ")) end relation diff --git a/app/models/artist.rb b/app/models/artist.rb index e55189620..0d025ea5a 100644 --- a/app/models/artist.rb +++ b/app/models/artist.rb @@ -210,7 +210,7 @@ class Artist < ActiveRecord::Base end def other_names_match(string) - where("other_names_index @@ to_tsquery('danbooru', ?)", Artist.normalize_name(string)) + where("other_names_index @@ to_tsquery('danbooru', E?)", Artist.normalize_name(string).to_escaped_for_tsquery) end def group_name_matches(name) @@ -225,8 +225,8 @@ class Artist < ActiveRecord::Base def any_name_matches(name) stripped_name = normalize_name(name).to_escaped_for_sql_like - name_for_tsquery = normalize_name(name).gsub(/\(/, "\\(").gsub(/\)/, "\\)") - where("(name LIKE ? ESCAPE E'\\\\' OR other_names_index @@ to_tsquery('danbooru', ?))", stripped_name, name_for_tsquery) + name_for_tsquery = normalize_name(name).to_escaped_for_tsquery + where("(name LIKE ? ESCAPE E'\\\\' OR other_names_index @@ to_tsquery('danbooru', E?))", stripped_name, name_for_tsquery) end def search(params) diff --git a/app/models/comment.rb b/app/models/comment.rb index 8bb90e71c..ce1e9dfa5 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -16,7 +16,7 @@ class Comment < ActiveRecord::Base end def body_matches(query) - where("body_index @@ plainto_tsquery(?)", query).order("comments.id DESC") + where("body_index @@ plainto_tsquery(?)", query.to_escaped_for_tsquery_split).order("comments.id DESC") end def hidden(user) @@ -28,7 +28,7 @@ class Comment < ActiveRecord::Base end def post_tags_match(query) - joins(:post).where("posts.tag_index @@ to_tsquery('danbooru', E?)", query) + joins(:post).where("posts.tag_index @@ to_tsquery('danbooru', ?)", query.to_escaped_for_tsquery_split) end def for_creator(user_id) diff --git a/app/models/dmail.rb b/app/models/dmail.rb index e7d0bd86d..0f4c4a995 100644 --- a/app/models/dmail.rb +++ b/app/models/dmail.rb @@ -99,7 +99,7 @@ class Dmail < ActiveRecord::Base end def search_message(query) - where("message_index @@ plainto_tsquery(?)", query) + where("message_index @@ plainto_tsquery(?)", query.to_escaped_for_tsquery_split) end def unread diff --git a/app/models/forum_post.rb b/app/models/forum_post.rb index 781c12b20..8184c1128 100644 --- a/app/models/forum_post.rb +++ b/app/models/forum_post.rb @@ -13,7 +13,7 @@ class ForumPost < ActiveRecord::Base module SearchMethods def body_matches(body) - where("forum_posts.text_index @@ plainto_tsquery(?)", body) + where("forum_posts.text_index @@ plainto_tsquery(E?)", body.to_escaped_for_tsquery) end def for_user(user_id) @@ -41,7 +41,7 @@ class ForumPost < ActiveRecord::Base end if params[:topic_title_matches].present? - q = q.joins(:topic).where("forum_topics.text_index @@ plainto_tsquery(?)", params[:topic_title_matches]) + q = q.joins(:topic).where("forum_topics.text_index @@ plainto_tsquery(E?)", params[:topic_title_matches].to_escaped_for_tsquery_split) end if params[:body_matches].present? diff --git a/app/models/forum_topic.rb b/app/models/forum_topic.rb index 2c5fe1724..ec1082901 100644 --- a/app/models/forum_topic.rb +++ b/app/models/forum_topic.rb @@ -14,7 +14,7 @@ class ForumTopic < ActiveRecord::Base module SearchMethods def title_matches(title) - where("text_index @@ plainto_tsquery(?)", title) + where("text_index @@ plainto_tsquery(E?)", title.to_escaped_for_tsquery_split) end def active diff --git a/app/models/note.rb b/app/models/note.rb index 77676a3bb..befbbcfc3 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -19,11 +19,11 @@ class Note < ActiveRecord::Base end def body_matches(query) - where("body_index @@ plainto_tsquery(?)", query.scan(/\S+/).join(" & ")) + where("body_index @@ plainto_tsquery(E?)", query.to_escaped_for_tsquery_split) end def post_tags_match(query) - joins(:post).where("posts.tag_index @@ to_tsquery('danbooru', ?)", query) + joins(:post).where("posts.tag_index @@ to_tsquery('danbooru', E?)", query.to_escaped_for_tsquery_split) end def creator_name(name) diff --git a/app/models/post.rb b/app/models/post.rb index 98e8ae06e..f2719454b 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -938,8 +938,7 @@ class Post < ActiveRecord::Base end def raw_tag_match(tag) - tag = PostQueryBuilder.escape_string_for_tsquery(tag) - where("posts.tag_index @@ to_tsquery('danbooru', E'" + tag + "')") + where("posts.tag_index @@ to_tsquery('danbooru', E?)", tag.to_escaped_for_tsquery) end def tag_match(query) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 2c9c68ecc..30cf559aa 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -21,7 +21,7 @@ class WikiPage < ActiveRecord::Base end def body_matches(query) - where("body_index @@ plainto_tsquery(?)", query.scan(/\S+/).join(" & ")) + where("body_index @@ plainto_tsquery(?)", query.to_escaped_for_tsquery_split) end def search(params = {}) diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index 8cf609b70..650799b4a 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -5,6 +5,14 @@ module Danbooru return self.gsub(/\\/, '\0\0').gsub(/(%|_)/, "\\\\\\1").gsub(/\*/, '%') end + def to_escaped_for_tsquery_split + scan(/\S+/).map {|x| x.to_escaped_for_tsquery}.join(" & ") + end + + def to_escaped_for_tsquery + "'#{gsub(/\\|'/, '\0\0\0\0')}'" + end + def to_escaped_js return self.gsub(/\\/, '\0\0').gsub(/['"]/) {|m| "\\#{m}"}.gsub(/\r\n|\r|\n/, '\\n') end