Skip to content

Commit 2a2f471

Browse files
committed
Fix internal error when inflated body exceeds limit
1 parent 9db582d commit 2a2f471

File tree

7 files changed

+68
-3
lines changed

7 files changed

+68
-3
lines changed

HISTORY.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ unreleased
22
==========
33

44
* Fix error message for json parse whitespace in `strict`
5+
* Fix internal error when inflated body exceeds limit
56
* Prevent loss of async hooks context
67
* Prevent hanging when request already read
78

lib/read.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
*/
1313

1414
var createError = require('http-errors')
15+
var destroy = require('destroy')
1516
var getBody = require('raw-body')
1617
var iconv = require('iconv-lite')
1718
var onFinished = require('on-finished')
19+
var unpipe = require('unpipe')
1820
var zlib = require('zlib')
1921

2022
/**
@@ -89,9 +91,14 @@ function read (req, res, next, parse, debug, options) {
8991
_error = createError(400, error)
9092
}
9193

94+
// unpipe from stream and destroy
95+
if (stream !== req) {
96+
unpipe(req)
97+
destroy(stream, true)
98+
}
99+
92100
// read off entire request
93-
stream.resume()
94-
onFinished(req, function onfinished () {
101+
dump(req, function onfinished () {
95102
next(createError(400, _error))
96103
})
97104
return
@@ -179,3 +186,20 @@ function contentstream (req, debug, inflate) {
179186

180187
return stream
181188
}
189+
190+
/**
191+
* Dump the contents of a request.
192+
*
193+
* @param {object} req
194+
* @param {function} callback
195+
* @api private
196+
*/
197+
198+
function dump (req, callback) {
199+
if (onFinished.isFinished(req)) {
200+
callback(null)
201+
} else {
202+
onFinished(req, callback)
203+
req.resume()
204+
}
205+
}

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
"content-type": "~1.0.4",
1414
"debug": "2.6.9",
1515
"depd": "2.0.0",
16+
"destroy": "1.2.0",
1617
"http-errors": "2.0.0",
1718
"iconv-lite": "0.4.24",
1819
"on-finished": "2.4.1",
1920
"qs": "6.9.7",
2021
"raw-body": "2.5.1",
21-
"type-is": "~1.6.18"
22+
"type-is": "~1.6.18",
23+
"unpipe": "1.0.0"
2224
},
2325
"devDependencies": {
2426
"eslint": "7.32.0",

test/json.js

+9
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,15 @@ describe('bodyParser.json()', function () {
193193
test.write(buf)
194194
test.expect(413, done)
195195
})
196+
197+
it('should not error when inflating', function (done) {
198+
var server = createServer({ limit: '1kb' })
199+
var test = request(server).post('/')
200+
test.set('Content-Encoding', 'gzip')
201+
test.set('Content-Type', 'application/json')
202+
test.write(Buffer.from('1f8b080000000000000aab562a2e2952b252d21b05a360148c58a0540b0066f7ce1e0a0400', 'hex'))
203+
test.expect(413, done)
204+
})
196205
})
197206

198207
describe('with inflate option', function () {

test/raw.js

+9
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,15 @@ describe('bodyParser.raw()', function () {
149149
test.write(buf)
150150
test.expect(413, done)
151151
})
152+
153+
it('should not error when inflating', function (done) {
154+
var server = createServer({ limit: '1kb' })
155+
var test = request(server).post('/')
156+
test.set('Content-Encoding', 'gzip')
157+
test.set('Content-Type', 'application/octet-stream')
158+
test.write(Buffer.from('1f8b080000000000000ad3d31b05a360148c64000087e5a147040400', 'hex'))
159+
test.expect(413, done)
160+
})
152161
})
153162

154163
describe('with inflate option', function () {

test/text.js

+11
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@ describe('bodyParser.text()', function () {
168168
test.write(buf)
169169
test.expect(413, done)
170170
})
171+
172+
it('should not error when inflating', function (done) {
173+
var server = createServer({ limit: '1kb' })
174+
var test = request(server).post('/')
175+
test.set('Content-Encoding', 'gzip')
176+
test.set('Content-Type', 'text/plain')
177+
test.write(Buffer.from('1f8b080000000000000ad3d31b05a360148c64000087e5a1470404', 'hex'))
178+
setTimeout(function () {
179+
test.expect(413, done)
180+
}, 100)
181+
})
171182
})
172183

173184
describe('with inflate option', function () {

test/urlencoded.js

+9
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,15 @@ describe('bodyParser.urlencoded()', function () {
314314
test.write(buf)
315315
test.expect(413, done)
316316
})
317+
318+
it('should not error when inflating', function (done) {
319+
var server = createServer({ limit: '1kb' })
320+
var test = request(server).post('/')
321+
test.set('Content-Encoding', 'gzip')
322+
test.set('Content-Type', 'application/x-www-form-urlencoded')
323+
test.write(Buffer.from('1f8b080000000000000a2b2e29b2d51b05a360148c580000a0351f92040400', 'hex'))
324+
test.expect(413, done)
325+
})
317326
})
318327

319328
describe('with parameterLimit option', function () {

0 commit comments

Comments
 (0)