Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const parseParams = require('./utils').parseParams

function Busboy (opts) {
if (!(this instanceof Busboy)) { return new Busboy(opts) }
if (typeof opts !== 'object') {
throw new TypeError('Busboy expected an options-Object.')
}
if (opts.highWaterMark !== undefined) { WritableStream.call(this, { autoDestroy: false, highWaterMark: opts.highWaterMark }) } else { WritableStream.call(this, { autoDestroy: false }) }

this._done = false
Expand Down Expand Up @@ -32,7 +35,7 @@ Busboy.prototype.emit = function (ev) {
Busboy.prototype.parseHeaders = function (headers) {
this._parser = undefined
if (headers['content-type']) {
const parsed = parseParams(headers['content-type'])
const parsed = parseParams(headers['content-type'], this.opts.limits || {})
let matched; let type
for (var i = 0; i < TYPES.length; ++i) { // eslint-disable-line no-var
type = TYPES[i]
Expand Down
4 changes: 1 addition & 3 deletions lib/types/multipart.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// * support 1 nested multipart level
// (see second multipart example here:
// http://www.w3.org/TR/html401/interact/forms.html#didx-multipartform-data)
// * support limits.fieldNameSize
// -- this will require modifications to utils.parseParams

const ReadableStream = require('stream').Readable
const inherits = require('util').inherits
Expand Down Expand Up @@ -135,7 +133,7 @@ function Multipart (boy, cfg) {
if (charset === undefined) { charset = defCharset }

if (header['content-disposition']) {
parsed = parseParams(header['content-disposition'][0])
parsed = parseParams(header['content-disposition'][0], limits)
if (!RE_FIELD.test(parsed[0])) { return skipPart(part) }
for (i = 0, len = parsed.length; i < len; ++i) {
if (RE_NAME.test(parsed[i][0])) {
Expand Down
23 changes: 16 additions & 7 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ const RE_ENCODED = /%([a-fA-F0-9]{2})/g
function encodedReplacer (match, byte) {
return String.fromCharCode(parseInt(byte, 16))
}
function parseParams (str) {

const rfcSpecificFieldnames = ['name', 'encoding', 'boundary', 'charset', 'filename']

function parseParams (str, options) {
const res = []
let state = 'key'
let charset = ''
Expand All @@ -13,12 +16,12 @@ function parseParams (str) {
let p = 0
let tmp = ''

const fieldNameSize = (options && options.fieldNameSize) || Infinity

for (var i = 0, len = str.length; i < len; ++i) { // eslint-disable-line no-var
if (str[i] === '\\' && inquote) {
if (escaping) { escaping = false } else {
escaping = true
continue
}
escaping = !escaping
continue
} else if (str[i] === '"') {
if (!escaping) {
if (inquote) {
Expand All @@ -38,9 +41,15 @@ function parseParams (str) {
tmp = ''
continue
} else if (state === 'key' &&
(str[i] === '*' || str[i] === '=') &&
res.length) {
(str[i] === '*' || str[i] === '=') &&
res.length) {
if (str[i] === '*') { state = 'charset' } else { state = 'value' }
if (
str[i] === '=' &&
fieldNameSize !== Infinity &&
rfcSpecificFieldnames.indexOf(tmp) === -1) {
tmp = tmp.substring(0, fieldNameSize)
}
res[p] = [tmp, undefined]
tmp = ''
continue
Expand Down
10 changes: 9 additions & 1 deletion test/parse-params.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,18 @@ describe('parse-params', () => {
source: 'multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY',
expected: ['multipart/form-data', ['charset', 'utf-8'], ['boundary', '0xKhTmLbOuNdArY']],
what: 'Multiple non-quoted parameters'
},
{
options: {
fieldNameSize: 2
},
source: 'text/plain; encoding="utf8";\t foo=bar;test',
expected: ['text/plain', ['encoding', 'utf8'], ['fo', 'bar'], 'test'],
what: 'fieldNameSize should be respected'
}
].forEach((v) => {
it(v.what, () => {
const result = parseParams(v.source)
const result = parseParams(v.source, v.options)
const msg = 'parsed parameters mismatch.\n' +
'Saw: ' + inspect(result) + '\n' +
'Expected: ' + inspect(v.expected)
Expand Down
3 changes: 2 additions & 1 deletion test/types-multipart.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ describe('types-multipart', () => {
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
limits: {
fileSize: 13,
fieldSize: 5
fieldSize: 5,
fieldNameSize: 3
},
expected: [
['field', 'file_name_0', 'super', false, true, '7bit', 'text/plain'],
Expand Down