From 5fff29fb84e0d8de900414cb15354cca7cf5f51b Mon Sep 17 00:00:00 2001 From: Nicolas Morel Date: Wed, 21 Oct 2026 10:35:11 +0200 Subject: [PATCH] fix: don't rely on payload own hasOwnProperty --- lib/index.js | 2 +- test/index.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 41fa1b3..3fcf65b 100755 --- a/lib/index.js +++ b/lib/index.js @@ -252,7 +252,7 @@ internals.multipart = function (req, options, source, contentType) { const set = (name, value) => { - if (!data.hasOwnProperty(name)) { + if (!Object.prototype.hasOwnProperty.call(data, name)) { data[name] = value; } else if (Array.isArray(data[name])) { diff --git a/test/index.js b/test/index.js index 505d964..253c496 100755 --- a/test/index.js +++ b/test/index.js @@ -1445,6 +1445,36 @@ describe('parse()', () => { await expect(Subtext.parse(request, null, { parse: true, output: 'data' })).to.reject('Invalid multipart payload format'); }); + + it('handles hasOwnProperty in multipart name', async () => { + + const body = + '--X\r\n' + + 'Content-Disposition: form-data; name="hasOwnProperty"\r\n' + + '\r\n' + + 'v\r\n' + + '--X\r\n' + + 'Content-Disposition: form-data; name="f"; filename="a.txt"\r\n' + + 'Content-Type: text/plain\r\n' + + '\r\n' + + 'hello\r\n' + + '--X--\r\n'; + + for (const output of ['data', 'stream', 'annotated', 'file']) { + const request = Wreck.toReadableStream(body); + request.headers = { + 'content-type': 'multipart/form-data; boundary=X' + }; + + const { payload } = await Subtext.parse(request, null, { parse: true, output: 'data', multipart: { output } }); + expect(payload.hasOwnProperty).to.equal('v'); + expect(payload.f).to.exist(); + + if (output === 'file') { + await Fs.promises.unlink(payload.f.path); + } + } + }); });