From 2dd2f43f372b006ce50408977cdd52c5331c01e9 Mon Sep 17 00:00:00 2001 From: Liam Date: Sat, 13 Jul 2024 15:25:36 -0400 Subject: [PATCH] Perform coercion for query strings in parser module --- lib/philomena/comments/query.ex | 1 - lib/philomena/filters/query.ex | 1 - lib/philomena/galleries/query.ex | 2 -- lib/philomena/images/query.ex | 1 - lib/philomena/posts/query.ex | 1 - lib/philomena/reports/query.ex | 2 +- lib/philomena/tags/query.ex | 2 +- lib/philomena_query/parse/parser.ex | 19 +++++++++++++------ .../api/json/search/gallery_controller.ex | 2 +- .../api/json/search/tag_controller.ex | 2 +- 10 files changed, 17 insertions(+), 16 deletions(-) diff --git a/lib/philomena/comments/query.ex b/lib/philomena/comments/query.ex index de2fee03..49ec6d68 100644 --- a/lib/philomena/comments/query.ex +++ b/lib/philomena/comments/query.ex @@ -94,7 +94,6 @@ defmodule Philomena.Comments.Query do def compile(query_string, opts \\ []) do user = Keyword.get(opts, :user) - query_string = query_string || "" case user do nil -> diff --git a/lib/philomena/filters/query.ex b/lib/philomena/filters/query.ex index 1741103c..3460a459 100644 --- a/lib/philomena/filters/query.ex +++ b/lib/philomena/filters/query.ex @@ -35,7 +35,6 @@ defmodule Philomena.Filters.Query do def compile(query_string, opts \\ []) do user = Keyword.get(opts, :user) - query_string = query_string || "" case user do nil -> diff --git a/lib/philomena/galleries/query.ex b/lib/philomena/galleries/query.ex index e04ceecc..ddfa1e8b 100644 --- a/lib/philomena/galleries/query.ex +++ b/lib/philomena/galleries/query.ex @@ -15,8 +15,6 @@ defmodule Philomena.Galleries.Query do end def compile(query_string) do - query_string = query_string || "" - fields() |> Parser.new() |> Parser.parse(query_string) diff --git a/lib/philomena/images/query.ex b/lib/philomena/images/query.ex index 2c987d1b..74d1b835 100644 --- a/lib/philomena/images/query.ex +++ b/lib/philomena/images/query.ex @@ -147,7 +147,6 @@ defmodule Philomena.Images.Query do def compile(query_string, opts \\ []) do user = Keyword.get(opts, :user) watch = Keyword.get(opts, :watch, false) - query_string = query_string || "" case user do nil -> diff --git a/lib/philomena/posts/query.ex b/lib/philomena/posts/query.ex index 0722b10c..58d94d6c 100644 --- a/lib/philomena/posts/query.ex +++ b/lib/philomena/posts/query.ex @@ -92,7 +92,6 @@ defmodule Philomena.Posts.Query do def compile(query_string, opts \\ []) do user = Keyword.get(opts, :user) - query_string = query_string || "" case user do nil -> diff --git a/lib/philomena/reports/query.ex b/lib/philomena/reports/query.ex index c9d9be44..e88e2172 100644 --- a/lib/philomena/reports/query.ex +++ b/lib/philomena/reports/query.ex @@ -17,6 +17,6 @@ defmodule Philomena.Reports.Query do def compile(query_string) do fields() |> Parser.new() - |> Parser.parse(query_string || "", %{}) + |> Parser.parse(query_string, %{}) end end diff --git a/lib/philomena/tags/query.ex b/lib/philomena/tags/query.ex index da148da4..6af25454 100644 --- a/lib/philomena/tags/query.ex +++ b/lib/philomena/tags/query.ex @@ -20,6 +20,6 @@ defmodule Philomena.Tags.Query do def compile(query_string) do fields() |> Parser.new() - |> Parser.parse(query_string || "") + |> Parser.parse(query_string) end end diff --git a/lib/philomena_query/parse/parser.ex b/lib/philomena_query/parse/parser.ex index a89434d2..e615653f 100644 --- a/lib/philomena_query/parse/parser.ex +++ b/lib/philomena_query/parse/parser.ex @@ -184,18 +184,18 @@ defmodule PhilomenaQuery.Parse.Parser do @spec parse(t(), String.t(), context()) :: {:ok, query()} | {:error, String.t()} def parse(parser, input, context \\ nil) - # Empty search should emit a match_none. - def parse(_parser, "", _context) do - {:ok, %{match_none: %{}}} - end - def parse(%Parser{} = parser, input, context) do parser = %{parser | __data__: context} - with {:ok, tokens, _1, _2, _3, _4} <- Lexer.lex(input), + with {:ok, input} <- coerce_string(input), + {:ok, tokens, _1, _2, _3, _4} <- Lexer.lex(input), + {:ok, tokens} <- convert_empty_token_list(tokens), {:ok, {tree, []}} <- search_top(parser, tokens) do {:ok, tree} else + {:error, :empty_query} -> + {:ok, %{match_none: %{}}} + {:ok, {_tree, tokens}} -> {:error, "junk at end of expression: " <> debug_tokens(tokens)} @@ -211,6 +211,13 @@ defmodule PhilomenaQuery.Parse.Parser do end end + defp coerce_string(term) when is_binary(term), do: {:ok, term} + defp coerce_string(nil), do: {:ok, ""} + defp coerce_string(_), do: {:error, "search query is not a string"} + + defp convert_empty_token_list([]), do: {:error, :empty_query} + defp convert_empty_token_list(tokens), do: {:ok, tokens} + defp debug_tokens(tokens) do Enum.map_join(tokens, fn {_k, v} -> v end) end diff --git a/lib/philomena_web/controllers/api/json/search/gallery_controller.ex b/lib/philomena_web/controllers/api/json/search/gallery_controller.ex index 8b2f247b..e1b999bb 100644 --- a/lib/philomena_web/controllers/api/json/search/gallery_controller.ex +++ b/lib/philomena_web/controllers/api/json/search/gallery_controller.ex @@ -7,7 +7,7 @@ defmodule PhilomenaWeb.Api.Json.Search.GalleryController do import Ecto.Query def index(conn, params) do - case Query.compile(params["q"] || "") do + case Query.compile(params["q"]) do {:ok, query} -> galleries = Gallery diff --git a/lib/philomena_web/controllers/api/json/search/tag_controller.ex b/lib/philomena_web/controllers/api/json/search/tag_controller.ex index 8cdaf7f4..b860cf46 100644 --- a/lib/philomena_web/controllers/api/json/search/tag_controller.ex +++ b/lib/philomena_web/controllers/api/json/search/tag_controller.ex @@ -7,7 +7,7 @@ defmodule PhilomenaWeb.Api.Json.Search.TagController do import Ecto.Query def index(conn, params) do - case Query.compile(params["q"] || "") do + case Query.compile(params["q"]) do {:ok, query} -> tags = Tag