From cca9048760cd80f5068ec959e6239a6260855191 Mon Sep 17 00:00:00 2001 From: Declan McGrath Date: Tue, 23 Feb 2016 15:17:42 +0000 Subject: [PATCH 1/2] Added test and potential fix for #628. --- lib/jsonapi/resource.rb | 6 +++++- test/integration/requests/request_test.rb | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/jsonapi/resource.rb b/lib/jsonapi/resource.rb index 05b098b88..74ad21016 100644 --- a/lib/jsonapi/resource.rb +++ b/lib/jsonapi/resource.rb @@ -807,7 +807,11 @@ def is_filter_relationship?(filter) def verify_filter(filter, raw, context = nil) filter_values = [] if raw.present? - filter_values += raw.is_a?(String) ? CSV.parse_line(raw) : [raw] + begin + filter_values += raw.is_a?(String) ? CSV.parse_line(raw) : [raw] + rescue CSV::MalformedCSVError + filter_values << raw + end end strategy = _allowed_filters.fetch(filter, Hash.new)[:verify] diff --git a/test/integration/requests/request_test.rb b/test/integration/requests/request_test.rb index dc10b78e8..d3c3c4e01 100644 --- a/test/integration/requests/request_test.rb +++ b/test/integration/requests/request_test.rb @@ -45,6 +45,15 @@ def test_get_underscored_key JSONAPI.configuration = original_config end + def test_filter_with_value_containing_double_quote + original_config = JSONAPI.configuration.dup + JSONAPI.configuration.json_key_format = :underscored_key + get '/iso_currencies?filter[country_name]="' + assert_jsonapi_response 200 + ensure + JSONAPI.configuration = original_config + end + def test_get_underscored_key_filtered original_config = JSONAPI.configuration.dup JSONAPI.configuration.json_key_format = :underscored_key From dcc517ffb59ff0d1ef260a8590637f644ac41a09 Mon Sep 17 00:00:00 2001 From: Larry Gebhardt Date: Tue, 20 Dec 2016 11:51:10 -0500 Subject: [PATCH 2/2] Add handling for CSV parsing errors. --- lib/jsonapi/request_parser.rb | 20 +++++++++++++++++--- test/integration/requests/request_test.rb | 22 +++++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/lib/jsonapi/request_parser.rb b/lib/jsonapi/request_parser.rb index fb80e5072..09ce48712 100644 --- a/lib/jsonapi/request_parser.rb +++ b/lib/jsonapi/request_parser.rb @@ -217,8 +217,14 @@ def parse_include_directives(raw_include) fail JSONAPI::Exceptions::ParametersNotAllowed.new([:include]) end - included_resources = CSV.parse_line(raw_include) - return if included_resources.nil? + included_resources = [] + begin + included_resources += CSV.parse_line(raw_include) + rescue CSV::MalformedCSVError + fail JSONAPI::Exceptions::InvalidInclude.new(format_key(@resource_klass._type), raw_include) + end + + return if included_resources.empty? result = included_resources.map do |included_resource| check_include(@resource_klass, included_resource.partition('.')) @@ -264,7 +270,15 @@ def parse_sort_criteria(sort_criteria) fail JSONAPI::Exceptions::ParametersNotAllowed.new([:sort]) end - @sort_criteria = CSV.parse_line(URI.unescape(sort_criteria)).collect do |sort| + sorts = [] + begin + raw = URI.unescape(sort_criteria) + sorts += CSV.parse_line(raw) + rescue CSV::MalformedCSVError + fail JSONAPI::Exceptions::InvalidSortCriteria.new(format_key(@resource_klass._type), raw) + end + + @sort_criteria = sorts.collect do |sort| if sort.start_with?('-') sort_criteria = { field: unformat_key(sort[1..-1]).to_s } sort_criteria[:direction] = :desc diff --git a/test/integration/requests/request_test.rb b/test/integration/requests/request_test.rb index d3c3c4e01..31821f8fd 100644 --- a/test/integration/requests/request_test.rb +++ b/test/integration/requests/request_test.rb @@ -48,7 +48,7 @@ def test_get_underscored_key def test_filter_with_value_containing_double_quote original_config = JSONAPI.configuration.dup JSONAPI.configuration.json_key_format = :underscored_key - get '/iso_currencies?filter[country_name]="' + get '/iso_currencies?filter[country_name]=%22' assert_jsonapi_response 200 ensure JSONAPI.configuration = original_config @@ -1072,6 +1072,26 @@ def test_sort_parameter_not_allowed JSONAPI.configuration.allow_sort = true end + def test_sort_parameter_quoted + get '/api/v2/books?sort=%22title%22', headers: { 'Accept' => JSONAPI::MEDIA_TYPE } + assert_jsonapi_response 200 + end + + def test_sort_parameter_openquoted + get '/api/v2/books?sort=%22title', headers: { 'Accept' => JSONAPI::MEDIA_TYPE } + assert_jsonapi_response 400 + end + + def test_include_parameter_quoted + get '/api/v2/posts?include=%22author%22', headers: { 'Accept' => JSONAPI::MEDIA_TYPE } + assert_jsonapi_response 200 + end + + def test_include_parameter_openquoted + get '/api/v2/posts?include=%22author', headers: { 'Accept' => JSONAPI::MEDIA_TYPE } + assert_jsonapi_response 400 + end + def test_getting_different_resources_when_sti assert_cacheable_jsonapi_get '/vehicles' types = json_response['data'].map{|r| r['type']}.sort