]> source.dussan.org Git - redmine.git/commitdiff
Gracefully handle invalid query parameters for custom fields (#35312).
authorGo MAEDA <maeda@farend.jp>
Fri, 28 May 2021 03:58:01 +0000 (03:58 +0000)
committerGo MAEDA <maeda@farend.jp>
Fri, 28 May 2021 03:58:01 +0000 (03:58 +0000)
Patch by Holger Just.

git-svn-id: http://svn.redmine.org/redmine/trunk@21012 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/application_controller.rb
app/controllers/issues_controller.rb
app/controllers/timelog_controller.rb
app/models/query.rb
test/integration/issues_test.rb

index b5644e89dd6f62f8b561b297a5701ccea84fe04d..f907b115983916c421f0f836ceb45f166f40f15b 100644 (file)
@@ -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
index 887bcd4bb62209291ce09b86fa453666c3b0ee2b..0278b30888abb530eaeb148063d4bb274dde4120 100644 (file)
@@ -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)
index 1b63f3cec0a2d81bf1d6e6719c239c7503667a1a..3ccab48e534bbc5d03dd44e5bbaaffab32e651c6 100644 (file)
@@ -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
index fad3930aa6690482cc9f22f2bdc0b76b283a90ec..50c53c821672c1c0541b50bc02b377a22ad5c9bf 100644 (file)
@@ -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
index 3dafcf9f6d8cbe4b47d082cf82259f6521e1e800..21b20759a06329aa64299962462c9cd78bc82510 100644 (file)
@@ -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