From d38b5943af2552a8fd646da7f48c9578c0afa79e Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 16 Mar 2020 22:20:09 -0700 Subject: [PATCH] Avoid coercing parameter with multiple types to an empty Array If an optional parameter has multiple types (e.g. [File, String]) and a nil parameter is passed, Grape would previously coerce the value to an empty Array. This can break certain APIs that treat nil values differently from an empty Array. Closes #2018 --- CHANGELOG.md | 1 + lib/grape/validations/validators/coerce.rb | 3 ++- spec/grape/validations/validators/coerce_spec.rb | 13 +++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1203fafc36..6dd5812c3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ #### Features * Your contribution here. +* [#2019](https://github.com/ruby-grape/grape/pull/2018): Avoid coercing parameter with multiple types to an empty Array - [@stanhu](https://github.com/stanhu). * [#2015](https://github.com/ruby-grape/grape/pull/2014): Reduce MatchData allocation - [@ericproulx](https://github.com/ericproulx). * [#2014](https://github.com/ruby-grape/grape/pull/2014): Reduce total allocated arrays - [@ericproulx](https://github.com/ericproulx). * [#2011](https://github.com/ruby-grape/grape/pull/2011): Reduce total retained regexes - [@ericproulx](https://github.com/ericproulx). diff --git a/lib/grape/validations/validators/coerce.rb b/lib/grape/validations/validators/coerce.rb index 561ec1bcf2..fcad312b53 100644 --- a/lib/grape/validations/validators/coerce.rb +++ b/lib/grape/validations/validators/coerce.rb @@ -68,9 +68,10 @@ def coerce_value(val) # define default values for structures, the dry-types lib which is used # for coercion doesn't accept nil as a value, so it would fail if val.nil? - return [] if type == Array || type.is_a?(Array) + return [] if type == Array return Set.new if type == Set return {} if type == Hash + return val if type.is_a?(Array) end converter.call(val) diff --git a/spec/grape/validations/validators/coerce_spec.rb b/spec/grape/validations/validators/coerce_spec.rb index dbf57c9d57..cb2cca5f95 100644 --- a/spec/grape/validations/validators/coerce_spec.rb +++ b/spec/grape/validations/validators/coerce_spec.rb @@ -647,6 +647,19 @@ def self.parsed?(value) expect(last_response.body).to eq('String') end + it 'respects nil values' do + subject.params do + optional :a, types: [File, String] + end + subject.get '/' do + params[:a].class.to_s + end + + get '/', a: nil + expect(last_response.status).to eq(200) + expect(last_response.body).to eq('NilClass') + end + it 'fails when no coercion is possible' do subject.params do requires :a, types: [Boolean, Integer]