Skip to content

Fix base64 multipart uploads with line breaks - #1122

Open
justadityaraj wants to merge 2 commits into
node-formidable:masterfrom
justadityaraj:fix/base64-crlf-chunks
Open

Fix base64 multipart uploads with line breaks#1122
justadityaraj wants to merge 2 commits into
node-formidable:masterfrom
justadityaraj:fix/base64-crlf-chunks

Conversation

@justadityaraj

@justadityaraj justadityaraj commented Aug 28, 2026

Copy link
Copy Markdown

Fixes #1120.

Problem

Base64 multipart bodies may contain CRLF line wrapping. Formidable counted those characters when choosing four-character decode chunks, so decoded file data could be truncated or corrupted.

Fix

Remove CRLF from base64 data before calculating the next quartet boundary. The multipart integration regression covers a line-wrapped base64 upload and verifies its decoded bytes.

User impact

Line-wrapped base64 uploads now preserve their original file contents.

Verification

  • node --experimental-vm-modules ./node_modules/jest/bin/jest.js --runInBand test/standalone/content-transfer-encoding.test.js — 2 tests passed, including the new regression.
  • node --test ./test-node/**/*.test.js — 11 tests passed.
  • node ./node_modules/eslint/bin/eslint.js --quiet src/plugins/multipart.js — passed.
  • node ./node_modules/prettier/bin-prettier.js --check src/plugins/multipart.js test/standalone/content-transfer-encoding.test.js — passed.
  • pnpm run build-package — Rollup build passed.
  • Full Jest suite — 82 passed; 10 failures are limited to existing Windows path expectations and an ECONNRESET assertion outside the changed files.

Greptile Summary

The PR updates multipart base64 decoding to remove embedded CR and LF characters before calculating complete decode quartets, preserving line-wrapped upload contents.

  • Normalizes line breaks as multipart part-data chunks arrive.
  • Adds an integration regression that parses a line-wrapped base64 upload and verifies the decoded bytes.

Confidence Score: 5/5

The PR appears safe to merge because no eligible blocking failure remains.

No blocking failure remains.

Important Files Changed

Filename Overview
src/plugins/multipart.js Removes CR and LF from streamed base64 part data before calculating quartet boundaries.
test/standalone/content-transfer-encoding.test.js Adds an end-to-end multipart regression covering line-wrapped base64 file contents.

Sequence Diagram

sequenceDiagram
  participant Client
  participant Parser as Multipart parser
  participant Decoder as Base64 part decoder
  participant Sink as File write stream
  Client->>Parser: Line-wrapped base64 multipart body
  Parser->>Decoder: partData chunks
  Decoder->>Decoder: Remove CR/LF and buffer complete quartets
  Decoder->>Sink: Decoded binary chunks
  Parser->>Decoder: partEnd
  Decoder->>Sink: Decode final buffered characters
Loading

Reviews (2): Last reviewed commit: "refactor: use replaceAll for base64 line..." | Re-trigger Greptile

Context used:

@GrosSacASac

Copy link
Copy Markdown
Contributor

Why are you using a regex instead of a string ?

@justadityaraj

Copy link
Copy Markdown
Author

Because this is streaming input: \r and \n can arrive in separate parser chunks, and the body may contain multiple line breaks. A string replacement would remove only the first complete \r\n pair; replaceAll() is also unavailable on the supported Node 14.0.0. /[\r\n]/g removes every line-break byte independently while preserving that compatibility.

@GrosSacASac

Copy link
Copy Markdown
Contributor

But formidable project only supports node lts

@justadityaraj

Copy link
Copy Markdown
Author

But formidable project only supports node lts

right, updated in fc38c60 to use separate string replacements for \r and \n preserving split chunk handling

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multipart parsing does not ignore CRLF in base64 properly

2 participants