From 66fc9f463dbca69529df106338cafcc46f5fa115 Mon Sep 17 00:00:00 2001 From: Go MAEDA Date: Fri, 28 May 2021 03:58:01 +0000 Subject: [PATCH] Gracefully handle invalid query parameters for custom fields (#35312). Patch by Holger Just. git-svn-id: http://svn.redmine.org/redmine/trunk@21012 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/controllers/application_controller.rb | 7 +++++++ app/controllers/issues_controller.rb | 6 ++++++ app/controllers/timelog_controller.rb | 6 ++++++ app/models/query.rb | 7 +++++-- test/integration/issues_test.rb | 11 +++++++++++ 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b5644e89d..f907b1159 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -725,6 +725,13 @@ class ApplicationController < ActionController::Base render_error l(:error_query_statement_invalid) end + def query_error(exception) + Rails.logger.debug "#{exception.class.name}: #{exception.message}" + Rails.logger.debug " #{exception.backtrace.join("\n ")}" + + render_404 + end + # Renders a 204 response for successful updates or deletions via the API def render_api_ok render_api_head :no_content diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 887bcd4bb..0278b3088 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -29,6 +29,7 @@ class IssuesController < ApplicationController accept_api_auth :index, :show, :create, :update, :destroy rescue_from Query::StatementInvalid, :with => :query_statement_invalid + rescue_from Query::QueryError, :with => :query_error helper :journals helper :projects @@ -470,6 +471,11 @@ class IssuesController < ApplicationController private + def query_error(exception) + session.delete(:issue_query) + super + end + def retrieve_previous_and_next_issue_ids if params[:prev_issue_id].present? || params[:next_issue_id].present? @prev_issue_id = params[:prev_issue_id].presence.try(:to_i) diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb index 1b63f3cec..3ccab48e5 100644 --- a/app/controllers/timelog_controller.rb +++ b/app/controllers/timelog_controller.rb @@ -32,6 +32,7 @@ class TimelogController < ApplicationController accept_api_auth :index, :show, :create, :update, :destroy rescue_from Query::StatementInvalid, :with => :query_statement_invalid + rescue_from Query::QueryError, :with => :query_error helper :issues include TimelogHelper @@ -303,4 +304,9 @@ class TimelogController < ApplicationController def retrieve_time_entry_query retrieve_query(TimeEntryQuery, false, :defaults => @default_columns_names) end + + def query_error(exception) + session.delete(:time_entry_query) + super + end end diff --git a/app/models/query.rb b/app/models/query.rb index fad3930aa..50c53c821 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -239,6 +239,9 @@ class Query < ActiveRecord::Base class StatementInvalid < ::ActiveRecord::StatementInvalid end + class QueryError < StandardError + end + include Redmine::SubclassFactory VISIBILITY_PRIVATE = 0 @@ -1143,7 +1146,7 @@ class Query < ActiveRecord::Base assoc = $1 customized_key = "#{assoc}_id" customized_class = queried_class.reflect_on_association(assoc.to_sym).klass.base_class rescue nil - raise "Unknown #{queried_class.name} association #{assoc}" unless customized_class + raise QueryError, "Unknown #{queried_class.name} association #{assoc}" unless customized_class end where = sql_for_field(field, operator, value, db_table, db_field, true) if /[<>]/.match?(operator) @@ -1420,7 +1423,7 @@ class Query < ActiveRecord::Base when "$" sql = sql_contains("#{db_table}.#{db_field}", value.first, :ends_with => true) else - raise "Unknown query operator #{operator}" + raise QueryError, "Unknown query operator #{operator}" end return sql diff --git a/test/integration/issues_test.rb b/test/integration/issues_test.rb index 3dafcf9f6..21b20759a 100644 --- a/test/integration/issues_test.rb +++ b/test/integration/issues_test.rb @@ -322,4 +322,15 @@ class IssuesTest < Redmine::IntegrationTest assert_response 404 end end + + def test_invalid_operators_should_render_404 + get '/projects/ecookbook/issues', :params => { + 'set_filter' => '1', + 'f' => ['status_id', 'cf_9'], + 'op' => {'status_id' => 'o', 'cf_9' => '=6546546546'}, + 'v' => {'cf_9' => ['2021-05-25']} + } + + assert_response 404 + end end