🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

multer

Package Overview
Dependencies
Maintainers
5
Versions
55
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

multer - npm Package Compare versions

Comparing version
3.0.0-alpha.1
to
3.0.0-alpha.2
+1
-0
index.js

@@ -31,2 +31,3 @@ import bytes from 'bytes'

fields: parseLimit(options.limits || {}, 'fields', 1000),
fieldNestingDepth: (options.limits || {}).fieldNestingDepth ?? Infinity,
fileSize: parseLimit(options.limits || {}, 'fileSize', '8MB'),

@@ -33,0 +34,0 @@ files: parseLimit(options.limits || {}, 'files', 10),

@@ -8,2 +8,3 @@ const errorMessages = new Map([

['LIMIT_FIELD_COUNT', 'Too many fields'],
['LIMIT_FIELD_NESTING', 'Field name nesting too deep'],
['LIMIT_UNEXPECTED_FILE', 'Unexpected file field']

@@ -10,0 +11,0 @@ ])

@@ -0,1 +1,2 @@

import { unlink } from 'node:fs'
import { extname } from 'node:path'

@@ -7,3 +8,2 @@ import { pipeline as _pipeline } from 'node:stream'

import { createWriteStream } from 'fs-temp'
import hasOwnProperty from 'has-own-property'
import _onFinished from 'on-finished'

@@ -18,3 +18,5 @@ import FileType from 'stream-file-type'

function drainStream (stream) {
stream.on('readable', stream.read.bind(stream))
stream.on('readable', () => {
while (stream.read() !== null) { /* drain */ }
})
}

@@ -34,6 +36,12 @@

// Work around bug in Busboy (https://github.com/mscdex/busboy/issues/6)
if (limits && hasOwnProperty(limits, 'fieldNameSize') && fieldname.length > limits.fieldNameSize) {
if (limits && Object.hasOwn(limits, 'fieldNameSize') && fieldname.length > limits.fieldNameSize) {
return reject(new MulterError('LIMIT_FIELD_KEY'))
}
if (limits && Object.hasOwn(limits, 'fieldNestingDepth')) {
if (fieldname.split('[').length - 1 > limits.fieldNestingDepth) {
return reject(new MulterError('LIMIT_FIELD_NESTING', fieldname))
}
}
result.push({ key: fieldname, value: value })

@@ -46,3 +54,3 @@ })

function collectFiles (busboy, limits, fileFilter) {
function collectFiles (busboy, limits, fileFilter, pendingTargets, settledPaths) {
return new Promise((resolve, reject) => {

@@ -61,3 +69,3 @@ const result = []

// Work around bug in Busboy (https://github.com/mscdex/busboy/issues/6)
if (limits && hasOwnProperty(limits, 'fieldNameSize') && fieldname.length > limits.fieldNameSize) {
if (limits && Object.hasOwn(limits, 'fieldNameSize') && fieldname.length > limits.fieldNameSize) {
return reject(new MulterError('LIMIT_FIELD_KEY'))

@@ -80,2 +88,3 @@ }

const target = createWriteStream()
pendingTargets.add(target)
const detector = new FileType()

@@ -87,2 +96,6 @@ const fileClosed = new Promise((resolve) => target.on('close', resolve))

await fileClosed
pendingTargets.delete(target)
// Track the finished file so an abort/error on a *later* file can
// still remove it; once readBody resolves it is consumed downstream.
settledPaths.add(target.path)
file.path = target.path

@@ -97,3 +110,6 @@ file.size = target.bytesWritten

})
.catch(reject)
.catch((err) => {
pendingTargets.delete(target)
reject(err)
})

@@ -109,5 +125,7 @@ result.push(promise)

const busboy = new Busboy({ headers: req.headers, limits: limits })
const pendingTargets = new Set()
const settledPaths = new Set()
const fields = collectFields(busboy, limits)
const files = collectFiles(busboy, limits, fileFilter)
const files = collectFiles(busboy, limits, fileFilter, pendingTargets, settledPaths)
const guard = new Promise((resolve, reject) => {

@@ -122,2 +140,5 @@ req.on('error', (err) => reject(err))

busboy.on('finish', resolve)
// Fallback when busboy stays silent on a malformed body.
req.on('close', () => setImmediate(() => reject(new MulterError('CLIENT_ABORTED'))))
})

@@ -133,4 +154,19 @@

drainStream(req)
req.resume()
busboy.removeAllListeners()
// Clean up any in-flight fs-temp files left behind by aborted/erroring uploads.
for (const target of pendingTargets) {
target.destroy()
if (target.path) unlink(target.path, () => {})
}
pendingTargets.clear()
// Also remove files that already finished writing: they are no longer in
// pendingTargets and, since readBody is throwing, will never be consumed.
for (const settledPath of settledPaths) {
unlink(settledPath, () => {})
}
settledPaths.clear()
// Wait for request to close, finish, or error

@@ -137,0 +173,0 @@ await onFinished(req).catch(/* c8 ignore next: Already handled by req.on('error', _) */ () => {})

+6
-4
{
"name": "multer",
"description": "Middleware for handling `multipart/form-data`.",
"version": "3.0.0-alpha.1",
"version": "3.0.0-alpha.2",
"contributors": [

@@ -28,3 +28,2 @@ "Hage Yaapa <captain@hacksparrow.com> (http://www.hacksparrow.com)",

"fs-temp": "^2.0.1",
"has-own-property": "^2.0.0",
"on-finished": "^2.3.0",

@@ -46,3 +45,3 @@ "stream-file-type": "^0.6.1",

"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
"node": ">= 18"
},

@@ -55,4 +54,7 @@ "files": [

"scripts": {
"test": "standard && c8 --check-coverage --statements 100 mocha"
"lint": "standard",
"test": "mocha",
"test:ci": "c8 --reporter=lcovonly --reporter=text --check-coverage --statements 100 npm test",
"test:cov": "c8 --reporter=html --reporter=text npm test"
}
}

@@ -143,2 +143,3 @@ # Multer [![Build Status](https://travis-ci.org/expressjs/multer.svg?branch=master)](https://travis-ci.org/expressjs/multer) [![NPM version](https://badge.fury.io/js/multer.svg)](https://badge.fury.io/js/multer) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard)

`fields` | Max number of fields per request | `1000`
`fieldNestingDepth` | Max number of nesting levels for field names (e.g. `a[b][c]` has 2 levels) | Infinity
`fileSize` | Max number of bytes per file | `'8MB'`

@@ -145,0 +146,0 @@ `files` | Max number of files per request | `10`