grape 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grape might be problematic. Click here for more details.

data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,9 @@
1
+ 0.2.6 (01/11/2013)
2
+ ==================
3
+
4
+ * Fix: support content-type with character set when parsing POST and PUT input - [@dblock](http://github.com/dblock).
5
+ * Fix: CVE-2013-0175, multi_xml parse vulnerability, require multi_xml 0.5.2 - [@dblock](http://github.com/dblock).
6
+
1
7
  0.2.5 (01/10/2013)
2
8
  ==================
3
9
 
data/README.markdown CHANGED
@@ -10,11 +10,6 @@ content negotiation, versioning and much more.
10
10
 
11
11
  [![Build Status](https://travis-ci.org/intridea/grape.png?branch=master)](http://travis-ci.org/intridea/grape)
12
12
 
13
- ## Stable Release
14
-
15
- You're reading the documentation for the next release of Grape, which should be 0.2.5.
16
- The current stable release is [0.2.4](https://github.com/intridea/grape/blob/v0.2.4/README.markdown).
17
-
18
13
  ## Project Tracking
19
14
 
20
15
  * [Grape Google Group](http://groups.google.com/group/ruby-grape)
data/grape.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.add_runtime_dependency 'activesupport'
21
21
  # s.add_runtime_dependency 'rack-jsonp'
22
22
  s.add_runtime_dependency 'multi_json', '>= 1.3.2'
23
- s.add_runtime_dependency 'multi_xml'
23
+ s.add_runtime_dependency 'multi_xml', '>= 0.5.2'
24
24
  s.add_runtime_dependency 'hashie', '~> 1.2'
25
25
  s.add_runtime_dependency 'virtus'
26
26
  s.add_runtime_dependency 'builder'
@@ -34,11 +34,10 @@ module Grape
34
34
  private
35
35
 
36
36
  def read_body_input
37
- request_method = request.request_method.to_s.upcase
38
- if [ 'POST', 'PUT' ].include?(request_method) && (! request.form_data?) && (request.content_length.to_i > 0)
39
- if env['rack.input'] && (body = env['rack.input'].read).strip.length > 0
37
+ if (request.post? || request.put?) && (! request.form_data?) && (! request.parseable_data?) && (request.content_length.to_i > 0)
38
+ if env['rack.input'] && (body = env['rack.input'].read).length > 0
40
39
  begin
41
- fmt = mime_types[format_from_content_type]
40
+ fmt = mime_types[request.media_type] if request.media_type
42
41
  if content_type_for(fmt)
43
42
  parser = Grape::Parser::Base.parser_for fmt, options
44
43
  unless parser.nil?
@@ -46,8 +45,8 @@ module Grape
46
45
  body = parser.call body, env
47
46
  env['rack.request.form_hash'] = env['rack.request.form_hash'] ? env['rack.request.form_hash'].merge(body) : body
48
47
  env['rack.request.form_input'] = env['rack.input']
49
- rescue
50
- # It's possible that it's just regular POST content -- just back off
48
+ rescue Exception => e
49
+ throw :error, :status => 400, :message => e.message
51
50
  end
52
51
  end
53
52
  else
@@ -69,13 +68,6 @@ module Grape
69
68
  end
70
69
  end
71
70
 
72
- def format_from_content_type
73
- fmt = env['CONTENT_TYPE']
74
- # avoid symbol memory leak on an unknown format
75
- return fmt.to_sym if content_type_for(fmt)
76
- fmt
77
- end
78
-
79
71
  def format_from_extension
80
72
  parts = request.path.split('.')
81
73
 
data/lib/grape/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Grape
2
- VERSION = '0.2.5'
2
+ VERSION = '0.2.6'
3
3
  end
@@ -1088,10 +1088,12 @@ describe Grape::API do
1088
1088
  params[:simple]
1089
1089
  end
1090
1090
  end
1091
- it 'uses parser' do
1092
- put '/simple', "simple", "CONTENT_TYPE" => "text/custom"
1093
- last_response.status.should == 200
1094
- last_response.body.should eql "elpmis"
1091
+ [ "text/custom", "text/custom; charset=UTF-8" ].each do |content_type|
1092
+ it "uses parser for #{content_type}" do
1093
+ put '/simple', "simple", "CONTENT_TYPE" => content_type
1094
+ last_response.status.should == 200
1095
+ last_response.body.should eql "elpmis"
1096
+ end
1095
1097
  end
1096
1098
  end
1097
1099
  context 'custom parser class' do
@@ -1114,6 +1116,16 @@ describe Grape::API do
1114
1116
  last_response.body.should eql "elpmis"
1115
1117
  end
1116
1118
  end
1119
+ context "muti_xml" do
1120
+ it "doesn't parse yaml" do
1121
+ subject.put :yaml do
1122
+ params[:tag]
1123
+ end
1124
+ put '/yaml', '<tag type="symbol">a123</tag>', "CONTENT_TYPE" => "application/xml"
1125
+ last_response.status.should == 400
1126
+ last_response.body.should eql 'Disallowed type attribute: "symbol"'
1127
+ end
1128
+ end
1117
1129
  end
1118
1130
 
1119
1131
  describe '.default_error_status' do
@@ -67,7 +67,7 @@ describe Grape::Middleware::Formatter do
67
67
  end
68
68
  end
69
69
 
70
- context 'Accept header detection' do
70
+ context 'accept header detection' do
71
71
  it 'detects from the Accept header' do
72
72
  subject.call({'PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/xml'})
73
73
  subject.env['api.format'].should == :xml
@@ -106,7 +106,7 @@ describe Grape::Middleware::Formatter do
106
106
  end
107
107
  end
108
108
 
109
- context 'Content-type' do
109
+ context 'content-type' do
110
110
  it 'is set for json' do
111
111
  _, headers, _ = subject.call({'PATH_INFO' => '/info.json'})
112
112
  headers['Content-type'].should == 'application/json'
@@ -127,7 +127,7 @@ describe Grape::Middleware::Formatter do
127
127
  end
128
128
  end
129
129
 
130
- context 'Format' do
130
+ context 'format' do
131
131
  it 'uses custom formatter' do
132
132
  subject.options[:content_types] = {}
133
133
  subject.options[:content_types][:custom] = "don't care"
@@ -147,18 +147,20 @@ describe Grape::Middleware::Formatter do
147
147
  end
148
148
  end
149
149
 
150
- context 'Input' do
151
- it 'parses the body from a POST/PUT and put the contents into rack.request.form_hash' do
152
- io = StringIO.new('{"is_boolean":true,"string":"thing"}')
153
- subject.call({
154
- 'PATH_INFO' => '/info',
155
- 'REQUEST_METHOD' => 'POST',
156
- 'CONTENT_TYPE' => 'application/json',
157
- 'rack.input' => io,
158
- 'CONTENT_LENGTH' => io.length
159
- })
160
- subject.env['rack.request.form_hash']['is_boolean'].should be_true
161
- subject.env['rack.request.form_hash']['string'].should == 'thing'
150
+ context 'input' do
151
+ [ "application/json", "application/json; charset=utf-8" ].each do |content_type|
152
+ it 'parses the body from a POST/PUT and put the contents into rack.request.form_hash for #{content_type}' do
153
+ io = StringIO.new('{"is_boolean":true,"string":"thing"}')
154
+ subject.call({
155
+ 'PATH_INFO' => '/info',
156
+ 'REQUEST_METHOD' => 'POST',
157
+ 'CONTENT_TYPE' => content_type,
158
+ 'rack.input' => io,
159
+ 'CONTENT_LENGTH' => io.length
160
+ })
161
+ subject.env['rack.request.form_hash']['is_boolean'].should be_true
162
+ subject.env['rack.request.form_hash']['string'].should == 'thing'
163
+ end
162
164
  end
163
165
  it 'parses the body from an xml POST/PUT and put the contents into rack.request.from_hash' do
164
166
  io = StringIO.new('<thing><name>Test</name></thing>')
@@ -171,16 +173,18 @@ describe Grape::Middleware::Formatter do
171
173
  })
172
174
  subject.env['rack.request.form_hash']['thing']['name'].should == 'Test'
173
175
  end
174
- it 'is able to fail gracefully if the body is regular POST content' do
175
- io = StringIO.new('name=Other+Test+Thing')
176
- subject.call({
177
- 'PATH_INFO' => '/info',
178
- 'REQUEST_METHOD' => 'POST',
179
- 'CONTENT_TYPE' => 'application/json',
180
- 'rack.input' => io,
181
- 'CONTENT_LENGTH' => io.length
182
- })
183
- subject.env['rack.request.form_hash'].should be_nil
176
+ [ Rack::Request::FORM_DATA_MEDIA_TYPES, Rack::Request::PARSEABLE_DATA_MEDIA_TYPES ].flatten.each do |content_type|
177
+ it "ignores #{content_type}" do
178
+ io = StringIO.new('name=Other+Test+Thing')
179
+ subject.call({
180
+ 'PATH_INFO' => '/info',
181
+ 'REQUEST_METHOD' => 'POST',
182
+ 'CONTENT_TYPE' => content_type,
183
+ 'rack.input' => io,
184
+ 'CONTENT_LENGTH' => io.length
185
+ })
186
+ subject.env['rack.request.form_hash'].should be_nil
187
+ end
184
188
  end
185
189
  end
186
190
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -98,7 +98,7 @@ dependencies:
98
98
  requirements:
99
99
  - - ! '>='
100
100
  - !ruby/object:Gem::Version
101
- version: '0'
101
+ version: 0.5.2
102
102
  type: :runtime
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
@@ -106,7 +106,7 @@ dependencies:
106
106
  requirements:
107
107
  - - ! '>='
108
108
  - !ruby/object:Gem::Version
109
- version: '0'
109
+ version: 0.5.2
110
110
  - !ruby/object:Gem::Dependency
111
111
  name: hashie
112
112
  requirement: !ruby/object:Gem::Requirement
@@ -348,7 +348,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
348
348
  version: '0'
349
349
  segments:
350
350
  - 0
351
- hash: 3430639806354577699
351
+ hash: 1249607937311024438
352
352
  required_rubygems_version: !ruby/object:Gem::Requirement
353
353
  none: false
354
354
  requirements:
@@ -357,7 +357,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
357
357
  version: '0'
358
358
  segments:
359
359
  - 0
360
- hash: 3430639806354577699
360
+ hash: 1249607937311024438
361
361
  requirements: []
362
362
  rubyforge_project: grape
363
363
  rubygems_version: 1.8.24