diff --git a/.gitignore b/.gitignore index 6e49526..1ea7dd3 100644 --- a/.gitignore +++ b/.gitignore @@ -148,5 +148,8 @@ yarn.lock .vscode .idea +#tap files +.tap/ + /benchmarks/node_modules/ /benchmarks/package-lock.json diff --git a/README.md b/README.md index c74e618..ece3cc8 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@
-[![Build Status](https://github.com/fastify/busboy/workflows/ci/badge.svg)](https://github.com/fastify/busboy/actions) +[![Build Status](https://github.com/fastify/busboy/actions/workflows/ci.yml/badge.svg)](https://github.com/fastify/busboy/actions) [![Coverage Status](https://coveralls.io/repos/fastify/busboy/badge.svg?branch=master)](https://coveralls.io/r/fastify/busboy?branch=master) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/) -[![Security Responsible Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](https://github.com/nodejs/security-wg/blob/HEAD/processes/responsible_disclosure_template.md) +[![Security Responsible Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](https://github.com/fastify/.github/blob/main/SECURITY.md)
diff --git a/deps/dicer/lib/Dicer.js b/deps/dicer/lib/Dicer.js index 79da160..3c8c081 100644 --- a/deps/dicer/lib/Dicer.js +++ b/deps/dicer/lib/Dicer.js @@ -78,7 +78,7 @@ Dicer.prototype._write = function (data, encoding, cb) { if (this._headerFirst && this._isPreamble) { if (!this._part) { this._part = new PartStream(this._partOpts) - if (this._events.preamble) { this.emit('preamble', this._part) } else { this._ignore() } + if (this.listenerCount('preamble') !== 0) { this.emit('preamble', this._part) } else { this._ignore() } } const r = this._hparser.push(data) if (!this._inHeader && r !== undefined && r < data.length) { data = data.slice(r) } else { return cb() } @@ -135,7 +135,7 @@ Dicer.prototype._oninfo = function (isMatch, data, start, end) { } } if (this._dashes === 2) { - if ((start + i) < end && this._events.trailer) { this.emit('trailer', data.slice(start + i, end)) } + if ((start + i) < end && this.listenerCount('trailer') !== 0) { this.emit('trailer', data.slice(start + i, end)) } this.reset() this._finished = true // no more parts will be added @@ -153,7 +153,13 @@ Dicer.prototype._oninfo = function (isMatch, data, start, end) { this._part._read = function (n) { self._unpause() } - if (this._isPreamble && this._events.preamble) { this.emit('preamble', this._part) } else if (this._isPreamble !== true && this._events.part) { this.emit('part', this._part) } else { this._ignore() } + if (this._isPreamble && this.listenerCount('preamble') !== 0) { + this.emit('preamble', this._part) + } else if (this._isPreamble !== true && this.listenerCount('part') !== 0) { + this.emit('part', this._part) + } else { + this._ignore() + } if (!this._isPreamble) { this._inHeader = true } } if (data && start < end && !this._ignoreData) { diff --git a/lib/types/multipart.js b/lib/types/multipart.js index ad242db..d691eca 100644 --- a/lib/types/multipart.js +++ b/lib/types/multipart.js @@ -163,7 +163,7 @@ function Multipart (boy, cfg) { ++nfiles - if (!boy._events.file) { + if (boy.listenerCount('file') === 0) { self.parser._ignore() return } diff --git a/lib/utils/decodeText.js b/lib/utils/decodeText.js index be35d6b..eac7d35 100644 --- a/lib/utils/decodeText.js +++ b/lib/utils/decodeText.js @@ -96,7 +96,7 @@ const decoders = { if (textDecoders.has(this.toString())) { try { return textDecoders.get(this).decode(data) - } catch (e) { } + } catch {} } return typeof data === 'string' ? data diff --git a/package.json b/package.json index 4be895c..83693ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fastify/busboy", - "version": "2.1.0", + "version": "2.1.1", "private": false, "author": "Brian White ", "contributors": [ @@ -43,7 +43,7 @@ "standard": "^17.0.0", "tap": "^16.3.8", "tinybench": "^2.5.1", - "tsd": "^0.29.0", + "tsd": "^0.30.0", "typescript": "^5.0.2" }, "keywords": [ @@ -55,7 +55,7 @@ "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/fastify/busboy.git" + "url": "git+https://github.com/fastify/busboy.git" }, "tsd": { "directory": "test/types", diff --git a/test/decode-text.test.js b/test/decode-text.test.js new file mode 100644 index 0000000..5723fe9 --- /dev/null +++ b/test/decode-text.test.js @@ -0,0 +1,33 @@ +'use strict' + +const { test } = require('tap') +const decodeText = require('../lib/utils/decodeText') + +test('decodeText', t => { + const testCases = [ + { description: 'UTF-8 encoding', text: Buffer.from('Hello, World!', 'utf8'), initialCharset: 'utf8', outputCharset: 'utf8', expected: 'Hello, World!' }, + { description: 'UTF-8 encoding empty', text: Buffer.from('', 'utf8'), initialCharset: 'utf8', outputCharset: 'utf8', expected: '' }, + { description: 'Latin1 encoding', text: Buffer.from('Hello, World!', 'latin1'), initialCharset: 'latin1', outputCharset: 'latin1', expected: 'Hello, World!' }, + { description: 'Latin1 encoding empty', text: Buffer.from('', 'latin1'), initialCharset: 'latin1', outputCharset: 'latin1', expected: '' }, + { description: 'UTF-16LE encoding', text: Buffer.from('Hello, World!', 'utf16le'), initialCharset: 'utf16le', outputCharset: 'utf16le', expected: 'Hello, World!' }, + { description: 'UTF-16LE encoding with special char', text: Buffer.from('Hello, World! 🌍🚀', 'utf16le'), initialCharset: 'utf16le', outputCharset: 'utf16le', expected: 'Hello, World! 🌍🚀' }, + { description: 'UTF-8 to UTF-16LE encoding', text: 'Hello, World!', initialCharset: 'utf16le', outputCharset: 'utf16le', expected: 'Hello, World!' }, + { description: 'UTF-16LE encoding empty', text: Buffer.from('', 'utf16le'), initialCharset: 'utf16le', outputCharset: 'utf16le', expected: '' }, + { description: 'Base64 encoding', text: Buffer.from('Hello, World!').toString('base64'), initialCharset: 'base64', outputCharset: 'base64', expected: 'SGVsbG8sIFdvcmxkIQ==' }, + { description: 'UTF-8 to Base64 encoding', text: 'Hello, World!', initialCharset: 'utf8', outputCharset: 'base64', expected: 'SGVsbG8sIFdvcmxkIQ==' }, + { description: 'Base64 encoding empty', text: Buffer.from('', 'utf8'), initialCharset: 'utf8', outputCharset: 'base64', expected: '' }, + { description: 'UTF8 to base64', text: Buffer.from('Hello, World!', 'utf-8'), initialCharset: 'utf8', outputCharset: 'base64', expected: 'SGVsbG8sIFdvcmxkIQ==' }, + { description: 'Unknown', text: 'Hello, World!', initialCharset: 'utf8', outputCharset: 'other', expected: 'Hello, World!' }, + { description: 'Unknown empty', text: Buffer.from('', 'utf8'), initialCharset: 'utf8', outputCharset: 'other', expected: '' }, + { description: 'Unknown', text: 'Hello, World!', initialCharset: 'utf8', outputCharset: 'utf-8', expected: 'Hello, World!' } + ] + + t.plan(testCases.length) + + testCases.forEach((c, index) => { + t.test(c.description, t => { + t.plan(1) + t.equal(decodeText(c.text, c.initialCharset, c.outputCharset), c.expected, `Test case ${index + 1}`) + }) + }) +})