HomePhabricator
Diffusion Comm 8e638ac7119a

[client-backup] implement C++ functions for encoding/decoding string in `utf-8`

Description

[client-backup] implement C++ functions for encoding/decoding string in utf-8

Summary:
ENG-4503.

To encrypt/decrypt UserData we need to have it in bytes (Uint8Array in JS or uint8_t[] in C++). From JS level it's not that easy because standard TextEncoder from JS is not available in react-native, so we're using JSI capabilities to convert this.

Encoding can be done always - any UTF-8 string can be represented as ArrayBuffer.

Decoding can be done only if ArrayBuffer has valid code points, to make this check we use this fact: link.

Depends on D8887

Test Plan:

const str = '!ABC+** /==🤬';
const bytes = commUtilsModule.encodeStringToUTF8ArrayBuffer(str);
const str2 = commUtilsModule.decodeUTF8ArrayBufferToString(
  new Uint8Array(bytes).buffer,
);
console.log(str === str2);

try {
  console.log(
    commUtilsModule.decodeUTF8ArrayBufferToString(
      new Uint8Array([72, 101, 108, 108, 111, 0x80]).buffer,
    ),
  );
} catch (e) {
  // should fail
  console.log(e);
}
try {
  console.log(
    commUtilsModule.decodeUTF8ArrayBufferToString(
      new Uint8Array([72, 101, 108, 0x80, 111, 111]).buffer,
    ),
  );
} catch (e) {
  // should fail
  console.log(e);
}
try {
  console.log(
    commUtilsModule.decodeUTF8ArrayBufferToString(
      new Uint8Array([0x80, 101, 108, 108, 111]).buffer,
    ),
  );
} catch (e) {
  // should fail
  console.log(e);
}

try {
  console.log(
    commUtilsModule.decodeUTF8ArrayBufferToString(
      new Uint8Array([72, 101, 108, 108, 111]).buffer,
    ),
  );
} catch (e) {
  // should work
  console.log(e);
}

Reviewers: michal, marcin, bartek

Reviewed By: michal, marcin, bartek

Subscribers: ashoat, tomek

Differential Revision: https://phab.comm.dev/D8888