Skip to content

Commit 5ce44de

Browse files
authored
Validators bad encoding (#2524)
* Use scrub when possible Add specs for bad encoding. * Fix rubocop Add CHANGELOG.md entry
1 parent 926c28d commit 5ce44de

File tree

9 files changed

+77
-3
lines changed

9 files changed

+77
-3
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* [#2510](https://github.com/ruby-grape/grape/pull/2510): Fix ContractScope's validator inheritance - [@ericproulx](https://github.com/ericproulx).
2222
* [#2521](https://github.com/ruby-grape/grape/pull/2521): Fixed typo in README - [@datpmt](https://github.com/datpmt).
2323
* [#2525](https://github.com/ruby-grape/grape/pull/2525): Require logger before active_support - [@ericproulx](https://github.com/ericproulx).
24+
* [#2524](https://github.com/ruby-grape/grape/pull/2524): Fix validators bad encoding - [@ericproulx](https://github.com/ericproulx).
2425
* Your contribution here.
2526

2627
### 2.2.0 (2024-09-14)

lib/grape/middleware/versioner/accept_version_header.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ module Versioner
1818
# route.
1919
class AcceptVersionHeader < Base
2020
def before
21-
potential_version = env[Grape::Http::Headers::HTTP_ACCEPT_VERSION]&.strip
21+
potential_version = env[Grape::Http::Headers::HTTP_ACCEPT_VERSION]
22+
potential_version = potential_version.scrub unless potential_version.nil?
23+
2224
not_acceptable!('Accept-Version header must be set.') if strict? && potential_version.blank?
2325

2426
return if potential_version.blank?

lib/grape/validations/validators/allow_blank_validator.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def validate_param!(attr_name, params)
88
return if (options_key?(:value) ? @option[:value] : @option) || !params.is_a?(Hash)
99

1010
value = params[attr_name]
11-
value = value.strip if value.respond_to?(:strip)
11+
value = value.scrub if value.respond_to?(:scrub)
1212

1313
return if value == false || value.present?
1414

lib/grape/validations/validators/regexp_validator.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Validators
66
class RegexpValidator < Base
77
def validate_param!(attr_name, params)
88
return unless params.respond_to?(:key?) && params.key?(attr_name)
9-
return if Array.wrap(params[attr_name]).all? { |param| param.nil? || param.to_s.match?((options_key?(:value) ? @option[:value] : @option)) }
9+
return if Array.wrap(params[attr_name]).all? { |param| param.nil? || param.to_s.scrub.match?((options_key?(:value) ? @option[:value] : @option)) }
1010

1111
raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:regexp))
1212
end

lib/grape/validations/validators/values_validator.rb

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ def validate_param!(attr_name, params)
1616

1717
return if val.nil? && !required_for_root_scope?
1818

19+
val = val.scrub if val.respond_to?(:scrub)
20+
1921
# don't forget that +false.blank?+ is true
2022
return if val != false && val.blank? && @allow_blank
2123

spec/grape/middleware/versioner/accept_version_header_spec.rb

+12
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@
1313
}
1414
end
1515

16+
describe '#bad encoding' do
17+
before do
18+
@options[:versions] = %w[v1]
19+
end
20+
21+
it 'does not raise an error' do
22+
expect do
23+
subject.call(Grape::Http::Headers::HTTP_ACCEPT_VERSION => "\x80")
24+
end.to throw_symbol(:error, status: 406, headers: { Grape::Http::Headers::X_CASCADE => 'pass' }, message: 'The requested version is not supported.')
25+
end
26+
end
27+
1628
context 'api.version' do
1729
before do
1830
@options[:versions] = ['v1']

spec/grape/validations/validators/allow_blank_validator_spec.rb

+19
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,25 @@
244244
end
245245
end
246246

247+
describe 'bad encoding' do
248+
let(:app) do
249+
Class.new(Grape::API) do
250+
default_format :json
251+
252+
params do
253+
requires :name, type: String, allow_blank: false
254+
end
255+
get '/bad_encoding'
256+
end
257+
end
258+
259+
context 'when value has bad encoding' do
260+
it 'does not raise an error' do
261+
expect { get('/bad_encoding', { name: "Hello \x80" }) }.not_to raise_error
262+
end
263+
end
264+
end
265+
247266
context 'invalid input' do
248267
it 'refuses empty string' do
249268
get '/disallow_blank', name: ''

spec/grape/validations/validators/regexp_validator_spec.rb

+19
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@
4141
end
4242
end
4343

44+
describe '#bad encoding' do
45+
let(:app) do
46+
Class.new(Grape::API) do
47+
default_format :json
48+
49+
params do
50+
requires :name, regexp: { value: /^[a-z]+$/ }
51+
end
52+
get '/bad_encoding'
53+
end
54+
end
55+
56+
context 'when value as bad encoding' do
57+
it 'does not raise an error' do
58+
expect { get '/bad_encoding', name: "Hello \x80" }.not_to raise_error
59+
end
60+
end
61+
end
62+
4463
context 'custom validation message' do
4564
context 'with invalid input' do
4665
it 'refuses inapppopriate' do

spec/grape/validations/validators/values_validator_spec.rb

+19
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,25 @@ def default_excepts
277277
stub_const('ValuesModel', values_model)
278278
end
279279

280+
describe '#bad encoding' do
281+
let(:app) do
282+
Class.new(Grape::API) do
283+
default_format :json
284+
285+
params do
286+
requires :type, type: String, values: %w[a b]
287+
end
288+
get '/bad_encoding'
289+
end
290+
end
291+
292+
context 'when value as bad encoding' do
293+
it 'does not raise an error' do
294+
expect { get '/bad_encoding', type: "Hello \x80" }.not_to raise_error
295+
end
296+
end
297+
end
298+
280299
context 'with a custom validation message' do
281300
it 'allows a valid value for a parameter' do
282301
get('/custom_message', type: 'valid-type1')

0 commit comments

Comments
 (0)