diff --git a/lib/main.js b/lib/main.js index 5702223..a9c95a4 100644 --- a/lib/main.js +++ b/lib/main.js @@ -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 @@ -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] diff --git a/lib/types/multipart.js b/lib/types/multipart.js index ac8b022..cfbe41b 100644 --- a/lib/types/multipart.js +++ b/lib/types/multipart.js @@ -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 @@ -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])) { diff --git a/lib/utils.js b/lib/utils.js index 7b45211..5948f49 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -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 = '' @@ -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) { @@ -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 diff --git a/test/parse-params.spec.js b/test/parse-params.spec.js index a4a9e4f..67e1ef9 100644 --- a/test/parse-params.spec.js +++ b/test/parse-params.spec.js @@ -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) diff --git a/test/types-multipart.spec.js b/test/types-multipart.spec.js index b3dc23d..d6e8220 100644 --- a/test/types-multipart.spec.js +++ b/test/types-multipart.spec.js @@ -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'],