post queries: raise error on invalid searches.

Raise an error if the search is invalid for one of the following reasons:

* It contains multiple conflicting order: metatags (e.g. `order:score order:favcount` or `ordfav:a ordfav:b`).
* It contains a metatag that can't be used more than once: (e.g. `limit:5 limit:10`, `random:5 random:10`).
* It contains a metatag that can't be negated (e.g. `-order:score`, `-limit:20`, or `-random:20`).
* It contains a metatag that can't be used in an OR clause (e.g. ` touhou or order:score`, `touhou or limit:20`, `touhou or random:20`).
This commit is contained in:
evazion
2022-04-09 01:36:44 -05:00
parent c45d1d42c2
commit eca0ab04f7
6 changed files with 123 additions and 29 deletions

View File

@@ -12,8 +12,6 @@ require "strscan"
class PostQueryBuilder
extend Memoist
# Raised when the number of tags exceeds the user's tag limit.
class TagLimitError < StandardError; end
class ParseError < StandardError; end
# How many tags a `blah*` search should match.
@@ -72,9 +70,6 @@ class PostQueryBuilder
COUNT_METATAG_SYNONYMS.flat_map { |str| [str, "#{str}_asc"] } +
CATEGORY_COUNT_METATAGS.flat_map { |str| [str, "#{str}_asc"] }
# Tags that don't count against the user's tag limit.
UNLIMITED_METATAGS = %w[status rating limit]
attr_reader :query_string, :current_user, :tag_limit, :safe_mode, :hide_deleted_posts
alias_method :safe_mode?, :safe_mode
alias_method :hide_deleted_posts?, :hide_deleted_posts
@@ -497,20 +492,6 @@ class PostQueryBuilder
relation.in_order_of(:id, ids)
end
# @raise [TagLimitError] if the number of tags exceeds the user's tag limit
def validate!
tag_count = terms.count { |term| !is_unlimited_tag?(term) }
if tag_limit.present? && tag_count > tag_limit
raise TagLimitError
end
end
# @return [Boolean] true if the metatag doesn't count against the user's tag limit
def is_unlimited_tag?(term)
term.type == :metatag && term.name.in?(UNLIMITED_METATAGS)
end
concerning :ParseMethods do
# Parse the search into a list of search terms. A search term is a tag or a metatag.
# @return [Array<OpenStruct>] a list of terms