Skip to content

Commit b1701ff

Browse files
authoredJun 18, 2024··
Correctly transform base64 with multiple instances of + or / (#4252)
String.replace only replaces a single instance of the search pattern by default; we need a regex in g mode if we want to replace them all.
1 parent c55289e commit b1701ff

File tree

2 files changed

+7
-6
lines changed

2 files changed

+7
-6
lines changed
 

‎spec/unit/base64.spec.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,18 @@ describe.each(["browser", "node"])("Base64 encoding (%s)", (env) => {
5050
});
5151

5252
it("Should encode unpadded URL-safe base64", () => {
53-
const toEncode = "?????";
53+
// Chosen to have padding and multiple instances of / and + in the base64
54+
const toEncode = "???????⊕⊗⊗";
5455
const data = new TextEncoder().encode(toEncode);
5556

5657
const encoded = encodeUnpaddedBase64Url(data);
57-
expect(encoded).toEqual("Pz8_Pz8");
58+
expect(encoded).toEqual("Pz8_Pz8_P-KKleKKl-KKlw");
5859
});
5960

6061
it("Should decode URL-safe base64", () => {
61-
const decoded = new TextDecoder().decode(decodeBase64("Pz8_Pz8="));
62+
const decoded = new TextDecoder().decode(decodeBase64("Pz8_Pz8_P-KKleKKl-KKlw=="));
6263

63-
expect(decoded).toStrictEqual("?????");
64+
expect(decoded).toStrictEqual("???????⊕⊗⊗");
6465
});
6566

6667
it("Encode unpadded should not have padding", () => {

‎src/base64.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export function encodeUnpaddedBase64(uint8Array: ArrayBuffer | Uint8Array): stri
5959
* @returns The unpadded base64.
6060
*/
6161
export function encodeUnpaddedBase64Url(uint8Array: ArrayBuffer | Uint8Array): string {
62-
return encodeUnpaddedBase64(uint8Array).replace("+", "-").replace("/", "_");
62+
return encodeUnpaddedBase64(uint8Array).replace(/\+/g, "-").replace(/\//g, "_");
6363
}
6464

6565
/**
@@ -75,7 +75,7 @@ export function decodeBase64(base64: string): Uint8Array {
7575
const itFunc = function* (): Generator<number> {
7676
const decoded = atob(
7777
// built-in atob doesn't support base64url: convert so we support either
78-
base64.replace("-", "+").replace("_", "/"),
78+
base64.replace(/-/g, "+").replace(/_/g, "/"),
7979
);
8080
for (let i = 0; i < decoded.length; ++i) {
8181
yield decoded.charCodeAt(i);

0 commit comments

Comments
 (0)
Please sign in to comment.