From de943c429271aa6f1fdefd81be0cea8d1f787ac9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 11:10:08 +0200 Subject: [PATCH] ignore leading and trailing crlfs in formdata body (#3677) (#3681) (cherry picked from commit 773ba01efb8ecc1b21ee9ffe9cb3c0f83b499c6e) Co-authored-by: Khafra --- lib/web/fetch/formdata-parser.js | 14 ++++++++++++-- test/busboy/issue-3676.js | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 test/busboy/issue-3676.js diff --git a/lib/web/fetch/formdata-parser.js b/lib/web/fetch/formdata-parser.js index 7e567e9ec65..315a4626da5 100644 --- a/lib/web/fetch/formdata-parser.js +++ b/lib/web/fetch/formdata-parser.js @@ -87,11 +87,21 @@ function multipartFormDataParser (input, mimeType) { // the first byte. const position = { position: 0 } - // Note: undici addition, allow \r\n before the body. - if (input[0] === 0x0d && input[1] === 0x0a) { + // Note: undici addition, allows leading and trailing CRLFs. + while (input[position.position] === 0x0d && input[position.position + 1] === 0x0a) { position.position += 2 } + let trailing = input.length + + while (input[trailing - 1] === 0x0a && input[trailing - 2] === 0x0d) { + trailing -= 2 + } + + if (trailing !== input.length) { + input = input.subarray(0, trailing) + } + // 5. While true: while (true) { // 5.1. If position points to a sequence of bytes starting with 0x2D 0x2D diff --git a/test/busboy/issue-3676.js b/test/busboy/issue-3676.js new file mode 100644 index 00000000000..4b74af88767 --- /dev/null +++ b/test/busboy/issue-3676.js @@ -0,0 +1,24 @@ +'use strict' + +const { test } = require('node:test') +const assert = require('node:assert') +const { Response } = require('../..') + +// https://github.com/nodejs/undici/issues/3676 +test('Leading and trailing CRLFs are ignored', async (t) => { + const response = new Response([ + '--axios-1.7.7-boundary-bPgZ9x77LfApGVUN839vui4V7\r\n' + + 'Content-Disposition: form-data; name="file"; filename="doc.txt"\r\n' + + 'Content-Type: text/plain\r\n' + + '\r\n' + + 'Helloworld\r\n' + + '--axios-1.7.7-boundary-bPgZ9x77LfApGVUN839vui4V7--\r\n' + + '\r\n' + ].join(''), { + headers: { + 'content-type': 'multipart/form-data; boundary=axios-1.7.7-boundary-bPgZ9x77LfApGVUN839vui4V7' + } + }) + + await assert.doesNotReject(response.formData()) +})