Skip to content

fix(aws-lambda): copy base64 bodies out of Node's shared Buffer pool - #92

Merged
dinwwwh merged 1 commit into
mainfrom
claude/lambda-base64-buffer-leak-650f8f
Sep 15, 2026
Merged

dinwwwh merged 1 commit into
mainfrom
claude/lambda-base64-buffer-leak-650f8f

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Sep 15, 2026

Copy link
Copy Markdown
Member

Base64-decoded Lambda request bodies were streamed as a Buffer.from(string) slice of Node's shared allocation pool. Because a warm Lambda process serves many invocations, that pool still holds other requests' bytes, so any consumer that touched the chunk's .buffer (for example Buffer.from(chunk.buffer), new DataView(chunk.buffer), or a postMessage transfer) could read them or detach the pool process-wide. The adapter now copies the decoded bytes into a private Uint8Array, matching what the node adapter already does.

Fixes

  • Octet-stream and event-stream chunks own an ArrayBuffer sized exactly to the body; .buffer no longer exposes neighbouring invocations' data.
  • Transferring a chunk detaches only that chunk, not Node's shared pool.
  • The misleading as Uint8Array<ArrayBuffer> cast is gone; the type now reflects an actual plain ArrayBuffer.

Testing

  • New regression test asserts the streamed chunk starts at offset 0 and its buffer equals the body length. It fails on the previous code (offset in the tens of thousands inside a 64 KiB pool) and passes now.
  • Full aws-lambda suite, eslint, and tsc -b are green.

@pkg-pr-new

pkg-pr-new Bot commented Sep 15, 2026

Copy link
Copy Markdown
@standard-server/aws-lambda

npm i https://pkg.pr.new/@standard-server/aws-lambda@92

@standard-server/core

npm i https://pkg.pr.new/@standard-server/core@92

@standard-server/fastify

npm i https://pkg.pr.new/@standard-server/fastify@92

@standard-server/fetch

npm i https://pkg.pr.new/@standard-server/fetch@92

@standard-server/node

npm i https://pkg.pr.new/@standard-server/node@92

@standard-server/peer

npm i https://pkg.pr.new/@standard-server/peer@92

@standard-server/shared

npm i https://pkg.pr.new/@standard-server/shared@92

commit: a999007

@codecov

codecov Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed

codspeed Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 108 skipped benchmarks1


Comparing claude/lambda-base64-buffer-leak-650f8f (a999007) with main (39372f1)

Open in CodSpeed

Footnotes

  1. 108 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Base64 body copy in the aws-lambda adapter — packages/aws-lambda/src/body.ts:37 now wraps Buffer.from(event.body, 'base64') in new Uint8Array(...), so the enqueued chunk owns a private, exactly-sized ArrayBuffer instead of a slice of Node's shared 64 KiB pool. The misleading as Uint8Array<ArrayBuffer> cast is gone.
  • Regression test — packages/aws-lambda/src/body.test.ts:139 reads the first streamed chunk and asserts byteOffset === 0, buffer.byteLength === byteLength, and content. I confirmed empirically that pre-fix code yields a 65536-byte backing buffer against a 6-byte chunk, so the assertion fails on the old code rather than being theatre.

The fix is correct (new Uint8Array(typedArray) copies element-wise, unlike the ArrayBuffer constructor overload), applies uniformly to every hint that consumes bytes, and there are no other Buffer.from(..., 'base64') sites in packages/. Mergeable as-is.

Pullfrog  | View workflow run | Using DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏

@dinwwwh
dinwwwh merged commit bd25cdc into main Sep 15, 2026
11 checks passed
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.

1 participant