Patch #35312 ยป 0001-Gracefully-handle-invalid-query-parameters-for-custo.patch
app/controllers/application_controller.rb | ||
---|---|---|
725 | 725 |
render_error l(:error_query_statement_invalid) |
726 | 726 |
end |
727 | 727 | |
728 |
def query_error(exception) |
|
729 |
Rails.logger.debug "#{exception.class.name}: #{exception.message}" |
|
730 |
Rails.logger.debug " #{exception.backtrace.join("\n ")}" |
|
731 | ||
732 |
render_404 |
|
733 |
end |
|
734 | ||
728 | 735 |
# Renders a 204 response for successful updates or deletions via the API |
729 | 736 |
def render_api_ok |
730 | 737 |
render_api_head :no_content |
app/controllers/issues_controller.rb | ||
---|---|---|
29 | 29 |
accept_api_auth :index, :show, :create, :update, :destroy |
30 | 30 | |
31 | 31 |
rescue_from Query::StatementInvalid, :with => :query_statement_invalid |
32 |
rescue_from Query::QueryError, :with => :query_error |
|
32 | 33 | |
33 | 34 |
helper :journals |
34 | 35 |
helper :projects |
... | ... | |
470 | 471 | |
471 | 472 |
private |
472 | 473 | |
474 |
def query_error(exception) |
|
475 |
session.delete(:issue_query) |
|
476 |
super |
|
477 |
end |
|
478 | ||
473 | 479 |
def retrieve_previous_and_next_issue_ids |
474 | 480 |
if params[:prev_issue_id].present? || params[:next_issue_id].present? |
475 | 481 |
@prev_issue_id = params[:prev_issue_id].presence.try(:to_i) |
app/controllers/timelog_controller.rb | ||
---|---|---|
32 | 32 |
accept_api_auth :index, :show, :create, :update, :destroy |
33 | 33 | |
34 | 34 |
rescue_from Query::StatementInvalid, :with => :query_statement_invalid |
35 |
rescue_from Query::QueryError, :with => :query_error |
|
35 | 36 | |
36 | 37 |
helper :issues |
37 | 38 |
include TimelogHelper |
... | ... | |
303 | 304 |
def retrieve_time_entry_query |
304 | 305 |
retrieve_query(TimeEntryQuery, false, :defaults => @default_columns_names) |
305 | 306 |
end |
307 | ||
308 |
def query_error(exception) |
|
309 |
session.delete(:time_entry_query) |
|
310 |
super |
|
311 |
end |
|
306 | 312 |
end |
app/models/query.rb | ||
---|---|---|
239 | 239 |
class StatementInvalid < ::ActiveRecord::StatementInvalid |
240 | 240 |
end |
241 | 241 | |
242 |
class QueryError < StandardError |
|
243 |
end |
|
244 | ||
242 | 245 |
include Redmine::SubclassFactory |
243 | 246 | |
244 | 247 |
VISIBILITY_PRIVATE = 0 |
... | ... | |
1143 | 1146 |
assoc = $1 |
1144 | 1147 |
customized_key = "#{assoc}_id" |
1145 | 1148 |
customized_class = queried_class.reflect_on_association(assoc.to_sym).klass.base_class rescue nil |
1146 |
raise "Unknown #{queried_class.name} association #{assoc}" unless customized_class |
|
1149 |
raise QueryError, "Unknown #{queried_class.name} association #{assoc}" unless customized_class
|
|
1147 | 1150 |
end |
1148 | 1151 |
where = sql_for_field(field, operator, value, db_table, db_field, true) |
1149 | 1152 |
if /[<>]/.match?(operator) |
... | ... | |
1420 | 1423 |
when "$" |
1421 | 1424 |
sql = sql_contains("#{db_table}.#{db_field}", value.first, :ends_with => true) |
1422 | 1425 |
else |
1423 |
raise "Unknown query operator #{operator}" |
|
1426 |
raise QueryError, "Unknown query operator #{operator}"
|
|
1424 | 1427 |
end |
1425 | 1428 | |
1426 | 1429 |
return sql |
test/integration/issues_test.rb | ||
---|---|---|
322 | 322 |
assert_response 404 |
323 | 323 |
end |
324 | 324 |
end |
325 | ||
326 |
def test_invalid_operators_should_render_404 |
|
327 |
get '/projects/ecookbook/issues', :params => { |
|
328 |
'set_filter' => '1', |
|
329 |
'f' => ['status_id', 'cf_9'], |
|
330 |
'op' => {'status_id' => 'o', 'cf_9' => '=6546546546'}, |
|
331 |
'v' => {'cf_9' => ['2021-05-25']} |
|
332 |
} |
|
333 | ||
334 |
assert_response 404 |
|
335 |
end |
|
325 | 336 |
end |