Skip to content

Commit

Permalink
fix: invalid character error in cookie serialize
Browse files Browse the repository at this point in the history
  • Loading branch information
aiji42 committed Mar 8, 2022
1 parent 193cdec commit 465ef9b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
1 change: 1 addition & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- abotsi
- ahbruns
- ahmedeldessouki
- aiji42
- airjp73
- airondumael
- Alarid
Expand Down
8 changes: 8 additions & 0 deletions packages/remix-server-runtime/__tests__/cookies-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ describe("cookies", () => {
expect(value).toMatchInlineSnapshot(`"hello michael"`);
});

it("parses/serializes string values containing non-ascii characters", async () => {
let cookie = createCookie("my-cookie");
let setCookie = await cookie.serialize("日本語");
let value = await cookie.parse(getCookieFromSetCookie(setCookie));

expect(value).toBe("日本語");
});

it("fails to parses signed string values with invalid signature", async () => {
let cookie = createCookie("my-cookie", {
secrets: ["secret1"],
Expand Down
20 changes: 18 additions & 2 deletions packages/remix-server-runtime/cookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,29 @@ async function decodeCookieValue(
}

function encodeData(value: any): string {
return btoa(JSON.stringify(value));
return btoa(toBinary(JSON.stringify(value)));
}

function decodeData(value: string): any {
try {
return JSON.parse(atob(value));
return JSON.parse(fromBinary(atob(value)));
} catch (error) {
return {};
}
}

function toBinary(value: string): string {
const codeUnits = new Uint16Array(value.length);
for (let i = 0; i < codeUnits.length; i++) {
codeUnits[i] = value.charCodeAt(i);
}
return String.fromCharCode(...new Uint8Array(codeUnits.buffer));
}

function fromBinary(value: string): string {
const bytes = new Uint8Array(value.length);
for (let i = 0; i < bytes.length; i++) {
bytes[i] = value.charCodeAt(i);
}
return String.fromCharCode(...new Uint16Array(bytes.buffer));
}

0 comments on commit 465ef9b

Please sign in to comment.