diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bd2c217 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +*.DS_Store diff --git a/lib/types/multipart.js b/lib/types/multipart.js index e166625..2a54786 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 var ReadableStream = require('stream').Readable || require('readable-stream'), inherits = require('util').inherits; @@ -71,7 +69,10 @@ function Multipart(boy, cfg) { : Infinity), partsLimit = (limits && typeof limits.parts === 'number' ? limits.parts - : Infinity); + : Infinity), + fieldNameSizeLimit = (limits && typeof limits.fieldNameSize === 'number' + ? limits.fieldNameSize + : 100); var nfiles = 0, nfields = 0, @@ -149,7 +150,7 @@ function Multipart(boy, cfg) { charset = defCharset; if (header['content-disposition']) { - parsed = parseParams(header['content-disposition'][0]); + parsed = parseParams(header['content-disposition'][0], fieldNameSizeLimit); if (!RE_FIELD.test(parsed[0])) return skipPart(part); for (i = 0, len = parsed.length; i < len; ++i) { diff --git a/lib/utils.js b/lib/utils.js index ed3129e..a46e4e7 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -4,7 +4,7 @@ var RE_ENCODED = /%([a-fA-F0-9]{2})/g; function encodedReplacer(match, byte) { return String.fromCharCode(parseInt(byte, 16)); } -function parseParams(str) { +function parseParams(str, fieldNameSize) { var res = [], state = 'key', charset = '', @@ -73,7 +73,9 @@ function parseParams(str) { } else if (!inquote && (str[i] === ' ' || str[i] === '\t')) continue; } - tmp += str[i]; + + if (state !== 'value' || fieldNameSize === undefined || tmp.length < fieldNameSize) + tmp += str[i]; } if (charset && tmp.length) { tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer), diff --git a/test/test-types-multipart.js b/test/test-types-multipart.js index e6bf519..64fb2c8 100644 --- a/test/test-types-multipart.js +++ b/test/test-types-multipart.js @@ -193,6 +193,40 @@ var tests = [ ], what: 'Empty content-type and empty content-disposition' }, + { source: [ + ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k', + 'Content-Disposition: form-data; name="file_name_0"', + '', + 'super alpha file', + '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k', + 'Content-Disposition: form-data; name="file_name_1"', + '', + 'super beta file', + '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k', + 'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"', + 'Content-Type: application/octet-stream', + '', + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k', + 'Content-Disposition: form-data; name="upload_file_1"; filename="1k_b.dat"', + 'Content-Type: application/octet-stream', + '', + 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', + '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--' + ].join('\r\n') + ], + boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k', + limits: { + fieldNameSize: 5 + }, + expected: [ + ['field', 'file_', 'super alpha file', false, false], + ['field', 'file_', 'super beta file', false, false], + ['file', 'uploa', 1023, 0, '1k_a.', '7bit', 'application/octet-stream'], + ['file', 'uploa', 1023, 0, '1k_b.', '7bit', 'application/octet-stream'] + ], + what: 'Fields and files (limits: 5 byte field name size)' + }, ]; function next() {