Skip to content

Commit c061898

Browse files
committed
Check for dry-types type existence and prevent top level const lookup
1 parent 0706fe1 commit c061898

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* [#2249](https://github.com/ruby-grape/grape/pull/2251): Upgraded to RuboCop 1.25.1 - [@dblock](https://github.com/dblock).
1010
* [#2271](https://github.com/ruby-grape/grape/pull/2271): Fixed validation regression on Numeric type introduced in 1.3 - [@vasfed](https://github.com/Vasfed).
1111
* [#2267](https://github.com/ruby-grape/grape/pull/2267): Standardized English error messages - [@dblock](https://github.com/dblock).
12+
* [#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).
1213
* Your contribution here.
1314

1415
#### Fixes

lib/grape/validations/types/primitive_coercer.rb

+12-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class PrimitiveCoercer < DryTypeCoercer
1313
Grape::API::Boolean => DryTypes::Params::Bool,
1414
BigDecimal => DryTypes::Params::Decimal,
1515
Numeric => DryTypes::Params::Integer | DryTypes::Params::Float | DryTypes::Params::Decimal,
16+
TrueClass => DryTypes::Params::Bool.constrained(eql: true),
17+
FalseClass => DryTypes::Params::Bool.constrained(eql: false),
1618

1719
# unfortunately, a +Params+ scope doesn't contain String
1820
String => DryTypes::Coercible::String
@@ -21,19 +23,23 @@ class PrimitiveCoercer < DryTypeCoercer
2123
STRICT_MAPPING = {
2224
Grape::API::Boolean => DryTypes::Strict::Bool,
2325
BigDecimal => DryTypes::Strict::Decimal,
24-
Numeric => DryTypes::Strict::Integer | DryTypes::Strict::Float | DryTypes::Strict::Decimal
26+
Numeric => DryTypes::Strict::Integer | DryTypes::Strict::Float | DryTypes::Strict::Decimal,
27+
TrueClass => DryTypes::Strict::Bool.constrained(eql: true),
28+
FalseClass => DryTypes::Strict::Bool.constrained(eql: false)
2529
}.freeze
2630

2731
def initialize(type, strict = false)
2832
super
2933

3034
@type = type
3135

32-
@coercer = if strict
33-
STRICT_MAPPING.fetch(type) { scope.const_get(type.name) }
34-
else
35-
MAPPING.fetch(type) { scope.const_get(type.name) }
36-
end
36+
@coercer = (strict ? STRICT_MAPPING : MAPPING).fetch(type) do
37+
scope.const_get(type.name, false)
38+
rescue NameError
39+
raise ArgumentError, "type #{type} should support coercion via `[]`" unless type.respond_to?(:[])
40+
41+
type
42+
end
3743
end
3844

3945
def call(val)

spec/grape/validations/types/primitive_coercer_spec.rb

+9
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,15 @@
110110
end
111111
end
112112

113+
context 'a type unknown in Dry-types' do
114+
let(:type) { Complex }
115+
116+
it 'raises error on init' do
117+
expect(DryTypes::Params.constants).not_to include(type.name.to_sym)
118+
expect { subject }.to raise_error(/type Complex should support coercion/)
119+
end
120+
end
121+
113122
context 'the strict mode' do
114123
let(:strict) { true }
115124

0 commit comments

Comments
 (0)