Skip to content

Commit

Permalink
Try to dup non-frozen default params with each use (#1438)
Browse files Browse the repository at this point in the history
  • Loading branch information
Joe Faber committed Jul 18, 2016
1 parent 3802f81 commit ad2ff64
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#### Fixes

* [#1438](/~https://github.com/ruby-grape/grape/pull/1439): Try to dup non-frozen default params with each use - [@jlfaber](/~https://github.com/jlfaber).
* [#1430](/~https://github.com/ruby-grape/grape/pull/1430): Fix for `declared(params)` inside `route_param` - [@Arkanain](/~https://github.com/Arkanain).
* [#1405](/~https://github.com/ruby-grape/grape/pull/1405): Fix priority of `rescue_from` clauses applying - [@hedgesky](/~https://github.com/hedgesky).
* [#1365](/~https://github.com/ruby-grape/grape/pull/1365): Fix finding exception handler in error middleware - [@ktimothy](/~https://github.com/ktimothy).
Expand Down
24 changes: 23 additions & 1 deletion lib/grape/validations/validators/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,30 @@ def initialize(attrs, options, required, scope)
super
end

# return true if we know we cannot dup this object
private def cannot_dup(obj)
obj.nil? ||
obj == true ||
obj == false ||
obj.is_a?(Symbol) ||
obj.is_a?(Numeric)
end

private def dup_if_possible(obj)
obj.dup
rescue TypeError
obj
end

def validate_param!(attr_name, params)
params[attr_name] = @default.is_a?(Proc) ? @default.call : @default unless params.key?(attr_name)
return if params.key? attr_name
params[attr_name] = if @default.is_a? Proc
@default.call
elsif @default.frozen? || cannot_dup(@default)
@default
else
dup_if_possible(@default)
end
end

def validate!(params)
Expand Down
41 changes: 41 additions & 0 deletions spec/grape/api/parameters_modification_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'spec_helper'

describe Grape::Endpoint do
subject { Class.new(Grape::API) }

def app
subject
end

before do
subject.namespace :test do
params do
optional :foo, default: '-abcdef'
end
get do
params[:foo].slice!(0)
params[:foo]
end
end
end

context 'when route modifies param value' do
it 'param default should not change' do
get '/test'
expect(last_response.status).to eq 200
expect(last_response.body).to eq 'abcdef'

get '/test'
expect(last_response.status).to eq 200
expect(last_response.body).to eq 'abcdef'

get '/test?foo=-123456'
expect(last_response.status).to eq 200
expect(last_response.body).to eq '123456'

get '/test'
expect(last_response.status).to eq 200
expect(last_response.body).to eq 'abcdef'
end
end
end

0 comments on commit ad2ff64

Please sign in to comment.