Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

multiparty

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

multiparty - npm Package Compare versions

Comparing version 2.1.9 to 2.2.0

test/standalone/test-issue-19.js

10

CHANGELOG.md

@@ -0,1 +1,11 @@

### 2.2.0
* additional callback API to support multiple files with same field name
* fix assertion crash when max field count is exceeded
* fix assertion crash when client aborts an invalid request
* (>=v0.10 only) unpipe the request when an error occurs to save resources.
* update readable-stream to ~1.1.9
* fix assertion crash when EMFILE occurrs
* (no more assertions - only 'error' events)
### 2.1.9

@@ -2,0 +12,0 @@

2

examples/azureblobstorage.js

@@ -37,3 +37,3 @@ var http = require('http')

res.send('File uploaded successfully');
}
});

@@ -40,0 +40,0 @@ server.listen(PORT, function() {

@@ -9,3 +9,2 @@ exports.Form = Form;

, os = require('os')
, assert = require('assert')
, StringDecoder = require('string_decoder').StringDecoder

@@ -89,15 +88,11 @@ , StreamCounter = require('stream-counter')

req.on('error', function(err) {
error(self, err);
});
req.on('aborted', function() {
self.emit('aborted');
error(self, new Error("Request aborted"));
});
self.handleError = handleError;
self.bytesExpected = getBytesExpected(req.headers);
req.on('error', handleError);
req.on('aborted', onReqAborted);
var contentType = req.headers['content-type'];
if (!contentType) {
error(self, new Error('missing content-type header'));
handleError(new Error('missing content-type header'));
return;

@@ -108,3 +103,3 @@ }

if (!m) {
error(self, new Error('unrecognized content-type: ' + contentType));
handleError(new Error('unrecognized content-type: ' + contentType));
return;

@@ -117,4 +112,6 @@ }

if (cb) {
var fields = {}
, files = {};
var fieldsTable = {};
var filesTable = {};
var fieldsList = [];
var filesList = [];
self.on('error', function(err) {

@@ -124,11 +121,45 @@ cb(err);

self.on('field', function(name, value) {
fields[name] = value;
fieldsTable[name] = value;
fieldsList.push({name: name, value: value});
});
self.on('file', function(name, file) {
files[name] = file;
filesTable[name] = file;
filesList.push(file);
});
self.on('close', function() {
cb(null, fields, files);
cb(null, fieldsTable, filesTable, fieldsList, filesList);
});
}
function onReqAborted() {
self.emit('aborted');
handleError(new Error("Request aborted"));
}
function handleError(err) {
var first = !self.error;
if (first) {
self.error = err;
req.removeListener('aborted', onReqAborted);
// welp. 0.8 doesn't support unpipe, too bad so sad.
// let's drop support for 0.8 soon.
if (req.unpipe) {
req.unpipe(self);
}
}
self.openedFiles.forEach(function(file) {
file.ws.destroy();
fs.unlink(file.path, function(err) {
// this is already an error condition, ignore 2nd error
});
});
self.openedFiles = [];
if (first) {
self.emit('error', err);
}
}
};

@@ -161,7 +192,7 @@

if (index === boundaryLength - 2) {
if (c !== CR) return error(self, new Error("Expected CR Received " + c));
if (c !== CR) return self.handleError(new Error("Expected CR Received " + c));
index++;
break;
} else if (index === boundaryLength - 1) {
if (c !== LF) return error(self, new Error("Expected LF Received " + c));
if (c !== LF) return self.handleError(new Error("Expected LF Received " + c));
index = 0;

@@ -194,3 +225,3 @@ self.onParsePartBegin();

// empty header field
error(self, new Error("Empty header field"));
self.handleError(new Error("Empty header field"));
return;

@@ -206,3 +237,3 @@ }

if (cl < A || cl > Z) {
error(self, new Error("Expected alphabetic character, received " + c));
self.handleError(new Error("Expected alphabetic character, received " + c));
return;

@@ -226,9 +257,9 @@ }

case HEADER_VALUE_ALMOST_DONE:
if (c !== LF) return error(self, new Error("Expected LF Received " + c));
if (c !== LF) return self.handleError(new Error("Expected LF Received " + c));
state = HEADER_FIELD_START;
break;
case HEADERS_ALMOST_DONE:
if (c !== LF) return error(self, new Error("Expected LF Received " + c));
if (c !== LF) return self.handleError(new Error("Expected LF Received " + c));
var err = self.onParseHeadersEnd(i + 1);
if (err) return error(self, err);
if (err) return self.handleError(err);
state = PART_DATA_START;

@@ -317,3 +348,3 @@ break;

default:
error(self, new Error("Parser has invalid state."));
self.handleError(new Error("Parser has invalid state."));
return;

@@ -414,2 +445,7 @@ }

self.totalFieldCount += 1;
if (self.totalFieldCount >= self.maxFields) {
return new Error("maxFields " + self.maxFields + " exceeded.");
}
self.destStream = new stream.PassThrough();

@@ -428,7 +464,2 @@ self.destStream.on('drain', function() {

self.boundary.length - LAST_BOUNDARY_SUFFIX_LEN);
self.totalFieldCount += 1;
if (self.totalFieldCount >= self.maxFields) {
error(self, new Error("maxFields " + self.maxFields + " exceeded."));
return;
}

@@ -462,14 +493,2 @@ self.emit('part', self.destStream);

function error(self, err) {
assert.ok(!self.error, err.stack);
self.error = err;
self.emit('error', err);
self.openedFiles.forEach(function(file) {
file.ws.destroy();
fs.unlink(file.path, function(err) {
// this is already an error condition, ignore 2nd error
});
});
}
function beginFlush(self) {

@@ -493,2 +512,3 @@ self.flushing += 1;

var file = {
fieldName: fileStream.name,
originalFilename: fileStream.filename,

@@ -516,3 +536,3 @@ path: uploadPath(self.uploadDir, fileStream.filename),

file.ws.on('error', function(err) {
error(self, err);
if (!self.error) self.handleError(err);
});

@@ -528,4 +548,4 @@ file.ws.on('close', function() {

function handleField(self, fieldStream) {
var value = ''
, decoder = new StringDecoder(self.encoding);
var value = '';
var decoder = new StringDecoder(self.encoding);

@@ -535,5 +555,7 @@ beginFlush(self);

var buffer = fieldStream.read();
if (!buffer) return;
self.totalFieldSize += buffer.length;
if (self.totalFieldSize > self.maxFieldsSize) {
error(self, new Error("maxFieldsSize " + self.maxFieldsSize + " exceeded"));
self.handleError(new Error("maxFieldsSize " + self.maxFieldsSize + " exceeded"));
return;

@@ -584,3 +606,3 @@ }

} else if (self.state !== END) {
error(self, new Error('stream ended unexpectedly'));
self.handleError(new Error('stream ended unexpectedly'));
}

@@ -587,0 +609,0 @@ self.finished = true;

{
"name": "multiparty",
"version": "2.1.9",
"version": "2.2.0",
"description": "multipart/form-data parser which supports streaming",

@@ -25,3 +25,3 @@ "repository": {

"scripts": {
"test": "mocha --reporter spec --recursive test/test.js"
"test": "ulimit -n 500 && mocha --timeout 4000 --reporter spec --recursive test/test.js"
},

@@ -33,5 +33,5 @@ "engines": {

"dependencies": {
"readable-stream": "~1.0.2",
"stream-counter": "~0.1.0"
"readable-stream": "~1.1.9",
"stream-counter": "~0.2.0"
}
}

@@ -6,2 +6,6 @@ [![Build Status](https://travis-ci.org/superjoe30/node-multiparty.png?branch=master)](https://travis-ci.org/superjoe30/node-multiparty)

See also [busboy](https://github.com/mscdex/busboy) - a
[faster](https://github.com/mscdex/dicer/wiki/Benchmarks) alternative
which may be worth looking into.
### Why the fork?

@@ -28,3 +32,2 @@

* See [examples](examples).
* Using express or connect? See [connect-multiparty](https://github.com/superjoe30/connect-multiparty)

@@ -97,3 +100,3 @@ Parse an incoming `multipart/form-data` request.

```js
form.parse(req, function(err, fields, files) {
form.parse(req, function(err, fieldsObject, filesObject, fieldsList, filesList) {
// ...

@@ -103,2 +106,12 @@ });

It is often convenient to access a field or file by name. In this situation,
use `fieldsObject` or `filesObject`. However sometimes, as in the case of a
`<input type="file" multiple="multiple">` the multipart stream will contain
multiple files of the same input name, and you are interested in all of them.
In this case, use `filesList`.
Another example is when you do not care what the field name of a file is; you
are merely interested in a single upload. In this case, set `maxFields` to 1
(assuming no other fields expected besides the file) and use `filesList[0]`.
#### form.bytesReceived

@@ -155,2 +168,3 @@

* `file` - an object with these properties:
- `fieldName` - same as `name` - the field name for this file
- `originalFilename` - the filename that the user reports for the file

@@ -157,0 +171,0 @@ - `path` - the absolute path of the uploaded file on disk

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc