Skip to content

Commit 8b72144

Browse files
Joe Faberdblock
authored andcommitted
Try to dup non-frozen default params with each use.
Closes #1438.
1 parent 21925fc commit 8b72144

3 files changed

Lines changed: 68 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#### Fixes
1515

1616
* [#1446](https://github.com/ruby-grape/grape/pull/1446): Fix for `env` inside `before` when using not allowed method - [@leifg](https://github.com/leifg).
17+
* [#1438](https://github.com/ruby-grape/grape/pull/1439): Try to dup non-frozen default params with each use - [@jlfaber](https://github.com/jlfaber).
1718
* [#1430](https://github.com/ruby-grape/grape/pull/1430): Fix for `declared(params)` inside `route_param` - [@Arkanain](https://github.com/Arkanain).
1819
* [#1405](https://github.com/ruby-grape/grape/pull/1405): Fix priority of `rescue_from` clauses applying - [@hedgesky](https://github.com/hedgesky).
1920
* [#1365](https://github.com/ruby-grape/grape/pull/1365): Fix finding exception handler in error middleware - [@ktimothy](https://github.com/ktimothy).

lib/grape/validations/validators/default.rb

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@ def initialize(attrs, options, required, scope)
77
end
88

99
def validate_param!(attr_name, params)
10-
params[attr_name] = @default.is_a?(Proc) ? @default.call : @default unless params.key?(attr_name)
10+
return if params.key? attr_name
11+
params[attr_name] = if @default.is_a? Proc
12+
@default.call
13+
elsif @default.frozen? || !duplicatable?(@default)
14+
@default
15+
else
16+
duplicate(@default)
17+
end
1118
end
1219

1320
def validate!(params)
@@ -20,6 +27,24 @@ def validate!(params)
2027
end
2128
end
2229
end
30+
31+
private
32+
33+
# return true if we might be able to dup this object
34+
def duplicatable?(obj)
35+
!obj.nil? &&
36+
obj != true &&
37+
obj != false &&
38+
!obj.is_a?(Symbol) &&
39+
!obj.is_a?(Numeric)
40+
end
41+
42+
# make a best effort to dup the object
43+
def duplicate(obj)
44+
obj.dup
45+
rescue TypeError
46+
obj
47+
end
2348
end
2449
end
2550
end
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
require 'spec_helper'
2+
3+
describe Grape::Endpoint do
4+
subject { Class.new(Grape::API) }
5+
6+
def app
7+
subject
8+
end
9+
10+
before do
11+
subject.namespace :test do
12+
params do
13+
optional :foo, default: '-abcdef'
14+
end
15+
get do
16+
params[:foo].slice!(0)
17+
params[:foo]
18+
end
19+
end
20+
end
21+
22+
context 'when route modifies param value' do
23+
it 'param default should not change' do
24+
get '/test'
25+
expect(last_response.status).to eq 200
26+
expect(last_response.body).to eq 'abcdef'
27+
28+
get '/test'
29+
expect(last_response.status).to eq 200
30+
expect(last_response.body).to eq 'abcdef'
31+
32+
get '/test?foo=-123456'
33+
expect(last_response.status).to eq 200
34+
expect(last_response.body).to eq '123456'
35+
36+
get '/test'
37+
expect(last_response.status).to eq 200
38+
expect(last_response.body).to eq 'abcdef'
39+
end
40+
end
41+
end

0 commit comments

Comments
 (0)