Skip to content

Commit

Permalink
fix: Fix base64 encoding of unicode characters. (#613)
Browse files Browse the repository at this point in the history
  • Loading branch information
kinyoklion authored Oct 9, 2024
1 parent 35fa033 commit 35ec8d1
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import PlatformEncoding from '../../src/platform/PlatformEncoding';

it('can base64 a basic ASCII string', () => {
const encoding = new PlatformEncoding();
expect(encoding.btoa('toaster')).toEqual('dG9hc3Rlcg==');
});

it('can base64 a unicode string containing multi-byte character', () => {
const encoding = new PlatformEncoding();
expect(encoding.btoa('✇⽊❽⾵⊚▴ⶊ↺➹≈⋟⚥⤅⊈ⲏⷨ⾭Ⲗ⑲▯ⶋₐℛ⬎⿌🦄')).toEqual(
'4pyH4r2K4p294r614oqa4pa04raK4oa64p654omI4ouf4pql4qSF4oqI4rKP4reo4r6t4rKW4pGy4pav4raL4oKQ4oSb4qyO4r+M8J+mhA==',
);
});
11 changes: 3 additions & 8 deletions packages/sdk/react-native/src/polyfills/btoa.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
/* eslint-disable no-bitwise */
import { fromByteArray } from 'base64-js';

function convertToByteArray(s: string) {
const b = [];
for (let i = 0; i < s.length; i += 1) {
b.push(s.charCodeAt(i));
}
return Uint8Array.from(b);
}
import toUtf8Array from './toUtf8Array';

export function btoa(s: string) {
return fromByteArray(convertToByteArray(s));
return fromByteArray(toUtf8Array(s));
}

export function base64FromByteArray(a: Uint8Array) {
Expand Down
50 changes: 50 additions & 0 deletions packages/sdk/react-native/src/polyfills/toUtf8Array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-disable no-plusplus */
/* eslint-disable no-bitwise */

// Originally from: https://github.com/google/closure-library/blob/a1f5a029c1b32eb4793a2d920aa52abc085e1bf7/closure/goog/crypt/crypt.js

// Once React Native versions uniformly support TextEncoder this code can be removed.

// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

export default function toUtf8Array(str: string): Uint8Array {
const out: number[] = [];
let p = 0;
for (let i = 0; i < str.length; i += 1) {
let c = str.charCodeAt(i);
if (c < 128) {
out[p++] = c;
} else if (c < 2048) {
out[p++] = (c >> 6) | 192;
out[p++] = (c & 63) | 128;
} else if (
(c & 0xfc00) === 0xd800 &&
i + 1 < str.length &&
(str.charCodeAt(i + 1) & 0xfc00) === 0xdc00
) {
// Surrogate Pair
c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);
out[p++] = (c >> 18) | 240;
out[p++] = ((c >> 12) & 63) | 128;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
} else {
out[p++] = (c >> 12) | 224;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
}
}
return Uint8Array.from(out);
}

0 comments on commit 35ec8d1

Please sign in to comment.