File tree Expand file tree Collapse file tree 2 files changed +25
-25
lines changed Expand file tree Collapse file tree 2 files changed +25
-25
lines changed Original file line number Diff line number Diff line change 55 hexToAscii ,
66 asciiToHex ,
77 xorHexStrings ,
8- strToBase64 ,
8+ base64Utf8Encode ,
99 extractApiKey ,
1010} from '../encoding' ;
1111
@@ -62,33 +62,18 @@ describe('asciiToHex', () => {
6262 } ) ;
6363} ) ;
6464
65- describe ( 'strToBase64 ' , ( ) => {
65+ describe ( 'base64Utf8Encode ' , ( ) => {
6666 test ( 'can handle an empty string' , ( ) => {
67- const obj = '' ;
67+ const text = '' ;
6868 const expected = '' ;
69-
70- const result = strToBase64 ( obj ) ;
71-
72- expect ( result ) . toBe ( expected ) ;
73- } ) ;
74-
75- test ( 'can encode any string' , ( ) => {
76- const obj = {
77- key : 'ABCabc123' ,
78- empty : null ,
79- array : [ 1 , 2 , 3 ] ,
80- } ;
81- const expected = 'W29iamVjdCBPYmplY3Rd' ;
82-
83- const result = strToBase64 ( obj ) ;
84-
69+ const result = base64Utf8Encode ( text ) ;
8570 expect ( result ) . toBe ( expected ) ;
8671 } ) ;
8772
88- test ( 'supports unicode characters' , ( ) => {
89- const obj = { key : '😇😈' } ;
90- const expected = 'W29iamVjdCBPYmplY3Rd ' ;
91- const result = strToBase64 ( obj ) ;
73+ test ( 'supports Unicode characters outside the BMP ' , ( ) => {
74+ const text = '😇😈' ;
75+ const expected = '8J+Yh/CfmIg= ' ;
76+ const result = base64Utf8Encode ( text ) ;
9277 expect ( result ) . toBe ( expected ) ;
9378 } ) ;
9479} ) ;
Original file line number Diff line number Diff line change @@ -32,11 +32,26 @@ export const base64ToHex = (bytes: string) => asciiToHex(base64.decode(bytes));
3232
3333export const hexToBase64 = ( hex : string ) => base64 . encode ( hexToAscii ( hex ) ) ;
3434
35- /** Encode a JavaScript string to a string in Base64 format. */
36- export const strToBase64 = ( text : string ) : string =>
35+ /**
36+ * Encode a string as the base64 representation of its UTF-8 bytes.
37+ *
38+ * This lets us pass an arbitrary string through a channel (like the
39+ * `postMessage` on RN's webviews on Android) that tries to do something
40+ * like percent-decode it.
41+ */
42+ export const base64Utf8Encode = ( text : string ) : string =>
3743 // References on reliably encoding strings to Base64:
3844 // https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa#Unicode_strings
3945 // https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
46+ //
47+ // In short:
48+ // * base64 encoders want bytes, not really Unicode strings, so they
49+ // insist their input consist of the characters U+0000 to U+00FF;
50+ // * `encodeURIComponent` together with `unescape` is a way of getting
51+ // that, effectively producing the UTF-8 encoding of the input.
52+ //
53+ // We use `base64.encode` because `btoa` is unavailable in the JS
54+ // environment provided by RN on iOS.
4055 base64 . encode ( unescape ( encodeURIComponent ( text ) ) ) ;
4156
4257// Extract an API key encoded as a hex string XOR'ed with a one time pad (OTP)
You can’t perform that action at this time.
0 commit comments