Skip to content

Fix base64 handling and also support Buffer.#145

Merged
kentonv merged 3 commits into
mainfrom
kenton/fix-base64
Mar 9, 2026
Merged

Fix base64 handling and also support Buffer.#145
kentonv merged 3 commits into
mainfrom
kenton/fix-base64

Conversation

@kentonv

@kentonv kentonv commented Mar 8, 2026

Copy link
Copy Markdown
Member
  • base64 encoding of large arrays no longer throws on any platform.
  • When toBase64 is unavailable, but Buffer is, this uses Buffer.
  • Also, we now accept Buffer for serialization and treat it like Uint8Array.
  • Also, when decoding, if Buffer is available, we decode to it. This is convenient for Node users.
  • Also fixed the stripping of base64 padding (trailing =).

Fixes #126

Opencode+Opus: https://share.opencode.cloudflare.dev/share/VwnZjojz

* base64 encoding of large arrays no longer throws on any platform.
* When toBase64 is unavailable, but Buffer is, this uses Buffer.
* Also, we now accept Buffer for serialization and treat it like Uint8Array.
* Also, when decoding, if Buffer is available, we decode to it. This is convenient for Node users.
* Also fixed the stripping of base64 padding (trailing `=`).

Fixes #126

Opencode+Opus: https://share.opencode.cloudflare.dev/share/VwnZjojz
@kentonv kentonv requested a review from dmmulroy March 8, 2026 00:26
@changeset-bot

changeset-bot Bot commented Mar 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 23dcf0b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
capnweb Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Mar 8, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/cloudflare/capnweb@145

commit: 23dcf0b

Comment thread src/serialize.ts Dismissed
}
b64 = btoa(binary);
}
return ["bytes", b64.replace(/=+$/, "")];

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on
library input
may run slow on strings with many repetitions of '='.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is a false positive. This regex will never backtrack, and the input is in any case guaranteed never to have more than two trailing =.

@kentonv

kentonv commented Mar 8, 2026

Copy link
Copy Markdown
Member Author

@jasnell I'm curious if you have an opinion on this.

With this change, Cap'n Web will automatically deserialize byte arrays as Buffer, if it is available, otherwise it will use Uint8Array. Buffer is a subclass of Uint8Array so this seems pretty safe, and also more convenient on Node (and node_compat mode in Workers, presumably).

Any concerns?

@jasnell

jasnell commented Mar 8, 2026

Copy link
Copy Markdown

The are some quirky differences with methods like slice but otherwise should be fine

Comment thread src/serialize.ts
} else if (typeof Buffer !== "undefined") {
let buf = bytes instanceof Buffer ? bytes
: Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
b64 = buf.toString("base64");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

do you want base64 or base64url?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Plain base64 is correct. This is for encoding in JSON strings, no need to worry about + or /.

Comment thread src/serialize.ts
}
b64 = btoa(binary);
}
return ["bytes", b64.replace(/=+$/, "")];

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This stripping is redundant when we used toBase64() since we set omitPadding: true, I should skip it in that case.

Also add a test verifying padding-stripping.
@kentonv kentonv merged commit 5667226 into main Mar 9, 2026
7 checks passed
@kentonv kentonv deleted the kenton/fix-base64 branch March 9, 2026 19:19
@github-actions github-actions Bot mentioned this pull request Mar 9, 2026
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.

Call stack size exceeded error when sending large UInt8Array

3 participants