Skip to content

Commit

Permalink
Check for dry-types type existence and prevent top level const lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
Vasfed committed Jul 22, 2022
1 parent 0706fe1 commit c061898
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [#2249](https://github.com/ruby-grape/grape/pull/2251): Upgraded to RuboCop 1.25.1 - [@dblock](https://github.com/dblock).
* [#2271](https://github.com/ruby-grape/grape/pull/2271): Fixed validation regression on Numeric type introduced in 1.3 - [@vasfed](https://github.com/Vasfed).
* [#2267](https://github.com/ruby-grape/grape/pull/2267): Standardized English error messages - [@dblock](https://github.com/dblock).
* [#2272](https://github.com/ruby-grape/grape/pull/2272): Added error on param init when provided type does not have `[]` coercion method, previously validation silently failed for any value - [@vasfed](https://github.com/Vasfed).
* Your contribution here.

#### Fixes
Expand Down
18 changes: 12 additions & 6 deletions lib/grape/validations/types/primitive_coercer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class PrimitiveCoercer < DryTypeCoercer
Grape::API::Boolean => DryTypes::Params::Bool,
BigDecimal => DryTypes::Params::Decimal,
Numeric => DryTypes::Params::Integer | DryTypes::Params::Float | DryTypes::Params::Decimal,
TrueClass => DryTypes::Params::Bool.constrained(eql: true),
FalseClass => DryTypes::Params::Bool.constrained(eql: false),

# unfortunately, a +Params+ scope doesn't contain String
String => DryTypes::Coercible::String
Expand All @@ -21,19 +23,23 @@ class PrimitiveCoercer < DryTypeCoercer
STRICT_MAPPING = {
Grape::API::Boolean => DryTypes::Strict::Bool,
BigDecimal => DryTypes::Strict::Decimal,
Numeric => DryTypes::Strict::Integer | DryTypes::Strict::Float | DryTypes::Strict::Decimal
Numeric => DryTypes::Strict::Integer | DryTypes::Strict::Float | DryTypes::Strict::Decimal,
TrueClass => DryTypes::Strict::Bool.constrained(eql: true),
FalseClass => DryTypes::Strict::Bool.constrained(eql: false)
}.freeze

def initialize(type, strict = false)
super

@type = type

@coercer = if strict
STRICT_MAPPING.fetch(type) { scope.const_get(type.name) }
else
MAPPING.fetch(type) { scope.const_get(type.name) }
end
@coercer = (strict ? STRICT_MAPPING : MAPPING).fetch(type) do
scope.const_get(type.name, false)
rescue NameError
raise ArgumentError, "type #{type} should support coercion via `[]`" unless type.respond_to?(:[])

type
end
end

def call(val)
Expand Down
9 changes: 9 additions & 0 deletions spec/grape/validations/types/primitive_coercer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@
end
end

context 'a type unknown in Dry-types' do
let(:type) { Complex }

it 'raises error on init' do
expect(DryTypes::Params.constants).not_to include(type.name.to_sym)
expect { subject }.to raise_error(/type Complex should support coercion/)
end
end

context 'the strict mode' do
let(:strict) { true }

Expand Down

0 comments on commit c061898

Please sign in to comment.