Skip to content

Commit b272a6c

Browse files
authored
feat: RN 70.x compatibility (#108)
* Replace `throwJSError` with `throwOrDie` * Implement randomUUID function (untested) * Replace instances of `jsi::detail::throwOrDie` ... with `throw jsi::JSError` * Fix generic on JSError (oops) * Clean up duplicate JSErrors * Remove superfluous returns after throwing JSErrors
1 parent d9c4c08 commit b272a6c

File tree

6 files changed

+55
-43
lines changed

6 files changed

+55
-43
lines changed

cpp/Cipher/MGLCipherHostObject.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -451,9 +451,6 @@ void MGLCipherHostObject::installMethods() {
451451
"setAuthTag", JSIF([=]) {
452452
if (count != 1 || !arguments[0].isObject() ||
453453
!arguments[0].asObject(runtime).isArrayBuffer(runtime)) {
454-
jsi::detail::throwJSError(
455-
runtime,
456-
"cipher.setAuthTag requires an ArrayBuffer tag argument");
457454
throw jsi::JSError(
458455
runtime,
459456
"cipher.setAuthTag requires an ArrayBuffer tag argument");
@@ -467,9 +464,6 @@ void MGLCipherHostObject::installMethods() {
467464
auto authTagArrayBuffer =
468465
arguments[0].asObject(runtime).getArrayBuffer(runtime);
469466
if (!CheckSizeInt32(runtime, authTagArrayBuffer)) {
470-
jsi::detail::throwJSError(
471-
runtime,
472-
"cipher.setAuthTag requires an ArrayBuffer tag argument");
473467
throw jsi::JSError(
474468
runtime,
475469
"cipher.setAuthTag requires an ArrayBuffer tag argument");
@@ -502,8 +496,6 @@ void MGLCipherHostObject::installMethods() {
502496
}
503497

504498
if (!is_valid) {
505-
jsi::detail::throwJSError(runtime,
506-
"Invalid authentication tag length");
507499
throw jsi::JSError(runtime, "Invalid authentication tag length");
508500
}
509501

cpp/Cipher/MGLPublicCipherInstaller.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,17 @@ FieldDefinition getPublicCipherFieldDefinition(
5757
runtime, arguments, &offset);
5858

5959
if (!pkey) {
60-
jsi::detail::throwJSError(runtime, "Could not generate key");
6160
throw new jsi::JSError(runtime, "Could not generate key");
6261
}
6362

6463
auto buf = arguments[offset].asObject(runtime).getArrayBuffer(runtime);
6564
if (!CheckSizeInt32(runtime, buf)) {
66-
jsi::detail::throwJSError(runtime, "Data buffer is too long");
6765
throw new jsi::JSError(runtime, "Data buffer is too long");
6866
}
6967

7068
uint32_t padding =
7169
static_cast<uint32_t>(arguments[offset + 1].getNumber());
7270
if (!padding) {
73-
jsi::detail::throwJSError(runtime, "Invalid padding");
7471
throw new jsi::JSError(runtime, "Invalid padding");
7572
}
7673

@@ -81,7 +78,6 @@ FieldDefinition getPublicCipherFieldDefinition(
8178

8279
digest = EVP_get_digestbyname(oaep_str.c_str());
8380
if (digest == nullptr) {
84-
jsi::detail::throwJSError(runtime, "Invalid digest (oaep_str)");
8581
throw new jsi::JSError(runtime, "Invalid digest (oaep_str)");
8682
}
8783
}
@@ -90,7 +86,6 @@ FieldDefinition getPublicCipherFieldDefinition(
9086
auto oaep_label_buffer =
9187
arguments[offset + 3].getObject(runtime).getArrayBuffer(runtime);
9288
if (!CheckSizeInt32(runtime, oaep_label_buffer)) {
93-
jsi::detail::throwJSError(runtime, "oaep_label buffer is too long");
9489
throw new jsi::JSError(runtime, "oaep_label buffer is too long");
9590
}
9691
}
@@ -101,7 +96,6 @@ FieldDefinition getPublicCipherFieldDefinition(
10196
runtime, pkey, padding, digest, arguments[offset + 3], buf);
10297

10398
if (!out.has_value()) {
104-
jsi::detail::throwJSError(runtime, "Failed to decrypt");
10599
throw new jsi::JSError(runtime, "Failed to decrypt");
106100
}
107101

cpp/Cipher/MGLRsa.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ RsaKeyPairGenConfig prepareRsaKeyGenConfig(jsi::Runtime& runtime,
108108
arguments[offset].asString(runtime).utf8(runtime).c_str());
109109

110110
if (config.md == nullptr) {
111-
jsi::detail::throwJSError(runtime, "invalid digest");
112111
throw new jsi::JSError(runtime, "invalid digest");
113112
}
114113
}
@@ -119,7 +118,6 @@ RsaKeyPairGenConfig prepareRsaKeyGenConfig(jsi::Runtime& runtime,
119118
arguments[offset + 1].asString(runtime).utf8(runtime).c_str());
120119

121120
if (config.mgf1_md == nullptr) {
122-
jsi::detail::throwJSError(runtime, "invalid digest");
123121
throw new jsi::JSError(runtime, "invalid digest");
124122
}
125123
}
@@ -129,7 +127,6 @@ RsaKeyPairGenConfig prepareRsaKeyGenConfig(jsi::Runtime& runtime,
129127
config.saltlen = static_cast<int>(arguments[offset + 2].asNumber());
130128

131129
if (config.saltlen < 0) {
132-
jsi::detail::throwJSError(runtime, "salt length is out of range");
133130
throw new jsi::JSError(runtime, "salt length is out of range");
134131
}
135132
}
@@ -157,14 +154,12 @@ std::pair<StringOrBuffer, StringOrBuffer> generateRSAKeyPair(
157154
EVPKeyCtxPointer ctx = setup(config);
158155

159156
if (!ctx) {
160-
jsi::detail::throwJSError(runtime, "Error on key generation job");
161157
throw new jsi::JSError(runtime, "Error on key generation job");
162158
}
163159

164160
// Generate the key
165161
EVP_PKEY* pkey = nullptr;
166162
if (!EVP_PKEY_keygen(ctx.get(), &pkey)) {
167-
jsi::detail::throwJSError(runtime, "Error generating key");
168163
throw new jsi::JSError(runtime, "Error generating key");
169164
}
170165

@@ -178,7 +173,7 @@ std::pair<StringOrBuffer, StringOrBuffer> generateRSAKeyPair(
178173
config->private_key_encoding);
179174

180175
if (!publicBuffer.has_value() || !privateBuffer.has_value()) {
181-
jsi::detail::throwJSError(runtime,
176+
throw jsi::JSError(runtime,
182177
"Failed to encode public and/or private key");
183178
}
184179

cpp/MGLKeys.cpp

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,7 @@ std::optional<StringOrBuffer> WritePrivateKey(
348348
}
349349

350350
if (err) {
351-
jsi::detail::throwJSError(runtime, "Failed to encode private key");
352-
return {};
351+
throw jsi::JSError(runtime, "Failed to encode private key");
353352
}
354353

355354
return BIOToStringOrBuffer(bio.get(), config.format_);
@@ -389,8 +388,7 @@ std::optional<StringOrBuffer> WritePublicKey(
389388
// CHECK(bio);
390389

391390
if (!WritePublicKeyInner(pkey, bio, config)) {
392-
jsi::detail::throwJSError(runtime, "Failed to encode public key");
393-
return std::nullopt;
391+
throw jsi::JSError(runtime, "Failed to encode public key");
394392
}
395393

396394
return BIOToStringOrBuffer(bio.get(), config.format_);
@@ -648,8 +646,7 @@ ManagedEVPPKey::GetPrivateKeyEncodingFromJs(jsi::Runtime& runtime,
648646
auto cipher_name = arguments[*offset].getString(runtime).utf8(runtime);
649647
result.cipher_ = EVP_get_cipherbyname(cipher_name.c_str());
650648
if (result.cipher_ == nullptr) {
651-
jsi::detail::throwJSError(runtime, "Unknown cipher");
652-
return NonCopyableMaybe<PrivateKeyEncodingConfig>();
649+
throw jsi::JSError(runtime, "Unknown cipher");
653650
}
654651
needs_passphrase = true;
655652
} else {
@@ -666,15 +663,15 @@ ManagedEVPPKey::GetPrivateKeyEncodingFromJs(jsi::Runtime& runtime,
666663
jsi::ArrayBuffer passphrase =
667664
arguments[*offset].asObject(runtime).getArrayBuffer(runtime);
668665
if (!CheckSizeInt32(runtime, passphrase)) {
669-
jsi::detail::throwJSError(runtime, "passphrase is too long");
666+
throw jsi::JSError(runtime, "passphrase is too long");
670667
}
671668

672669
result.passphrase_ = NonCopyableMaybe<ByteSource>(
673670
ToNullTerminatedByteSource(runtime, passphrase));
674671
} else {
675672
if (needs_passphrase &&
676673
(arguments[*offset].isNull() || arguments[*offset].isUndefined())) {
677-
jsi::detail::throwJSError(
674+
throw jsi::JSError(
678675
runtime, "passphrase is null or unfedined but it is required");
679676
}
680677
}
@@ -728,7 +725,7 @@ ManagedEVPPKey ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(
728725
args[(*offset)++].asObject(runtime).getArrayBuffer(runtime);
729726

730727
if (!CheckSizeInt32(runtime, dataArrayBuffer)) {
731-
jsi::detail::throwJSError(runtime, "data is too big");
728+
throw jsi::JSError(runtime, "data is too big");
732729
}
733730

734731
NonCopyableMaybe<PrivateKeyEncodingConfig> config_ =
@@ -766,7 +763,6 @@ ManagedEVPPKey ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(
766763
is_public = false;
767764
break;
768765
default:
769-
jsi::detail::throwJSError(runtime, "Invalid key encoding type");
770766
throw new jsi::JSError(runtime, "Invalid key encoding type");
771767
}
772768

@@ -784,9 +780,6 @@ ManagedEVPPKey ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(
784780
return ManagedEVPPKey::GetParsedKey(runtime, std::move(pkey), ret,
785781
"Failed to read asymmetric key");
786782
} else {
787-
jsi::detail::throwJSError(runtime,
788-
"publicEncrypt api only supports ArrayBuffer keys"
789-
"for now");
790783
throw new jsi::JSError(
791784
runtime, "public encrypt only supports ArrayBuffer at the moment");
792785
// CHECK(args[*offset]->IsObject());
@@ -808,11 +801,10 @@ ManagedEVPPKey ManagedEVPPKey::GetParsedKey(jsi::Runtime& runtime,
808801
// CHECK(pkey);
809802
break;
810803
case ParseKeyResult::kParseKeyNeedPassphrase:
811-
jsi::detail::throwJSError(runtime,
804+
throw jsi::JSError(runtime,
812805
"Passphrase required for encrypted key");
813806
break;
814807
default:
815-
jsi::detail::throwJSError(runtime, default_msg);
816808
throw new jsi::JSError(runtime, default_msg);
817809
}
818810

cpp/Sig/MGLSignHostObjects.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ void SignBase::InstallMethods(mode mode) {
350350
this->fields.push_back(buildPair(
351351
"init", JSIF([=]) {
352352
if (count != 1 || !arguments[0].isString()) {
353-
jsi::detail::throwJSError(runtime, "init requires algorithm param");
353+
throw jsi::JSError(runtime, "init requires algorithm param");
354354
return {};
355355
}
356356

@@ -378,19 +378,19 @@ void SignBase::InstallMethods(mode mode) {
378378
this->fields.push_back(buildPair(
379379
"update", JSIF([=]) {
380380
if (count != 1) {
381-
jsi::detail::throwJSError(runtime, "update requires 2 arguments");
381+
throw jsi::JSError(runtime, "update requires 2 arguments");
382382
}
383383

384384
if (!arguments[0].isObject() ||
385385
!arguments[0].asObject(runtime).isArrayBuffer(runtime)) {
386-
jsi::detail::throwJSError(
386+
throw jsi::JSError(
387387
runtime, "First argument (data) needs to be an array buffer");
388388
}
389389

390390
auto data = arguments[0].asObject(runtime).getArrayBuffer(runtime);
391391

392392
if (!CheckSizeInt32(runtime, data)) {
393-
jsi::detail::throwJSError(runtime, "data is too large");
393+
throw jsi::JSError(runtime, "data is too large");
394394
}
395395

396396
if (mdctx_ == nullptr) return (int)kSignNotInitialised;
@@ -433,7 +433,6 @@ void SignBase::InstallMethods(mode mode) {
433433
this->SignFinal(runtime, key, padding, salt_len, dsa_sig_enc);
434434

435435
if (ret.error != kSignOk) {
436-
jsi::detail::throwJSError(runtime, "Error signing");
437436
throw new jsi::JSError(runtime, "Error signing");
438437
}
439438

@@ -455,7 +454,6 @@ void SignBase::InstallMethods(mode mode) {
455454
jsi::ArrayBuffer hbuf =
456455
arguments[offset].asObject(runtime).getArrayBuffer(runtime);
457456
if (!CheckSizeInt32(runtime, hbuf)) {
458-
jsi::detail::throwJSError(runtime, "buffer is too big");
459457
throw jsi::JSError(runtime, "buffer is too big");
460458
}
461459

@@ -482,7 +480,7 @@ void SignBase::InstallMethods(mode mode) {
482480
signature = ConvertSignatureToDER(
483481
pkey, ArrayBufferToByteSource(runtime, hbuf));
484482
if (signature.data() == nullptr) {
485-
jsi::detail::throwJSError(runtime, "kSignMalformedSignature");
483+
throw jsi::JSError(runtime, "kSignMalformedSignature");
486484
}
487485
// return crypto::CheckThrow(env,
488486
// Error::kSignMalformedSignature);
@@ -492,7 +490,7 @@ void SignBase::InstallMethods(mode mode) {
492490
Error err = this->VerifyFinal(pkey, signature, padding, salt_len,
493491
&verify_result);
494492
if (err != kSignOk) {
495-
jsi::detail::throwJSError(runtime, "Error on verify");
493+
throw jsi::JSError(runtime, "Error on verify");
496494
}
497495

498496
return verify_result;

src/random.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,44 @@ export function getRandomValues(data: DataType) {
274274
randomFillSync(data, 0);
275275
return data;
276276
}
277+
278+
const byteToHex: string[] = [];
279+
280+
for (let i = 0; i < 256; ++i) {
281+
byteToHex.push((i + 0x100).toString(16).slice(1));
282+
}
283+
284+
// Based on https://github.com/uuidjs/uuid/blob/main/src/v4.js
285+
export function randomUUID() {
286+
const size = 16;
287+
const buffer = new Buffer(size)
288+
randomFillSync(buffer, 0, size);
289+
290+
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
291+
buffer[6] = (buffer[6] & 0x0f) | 0x40;
292+
buffer[8] = (buffer[8] & 0x3f) | 0x80;
293+
294+
return (
295+
byteToHex[buffer[0]] +
296+
byteToHex[buffer[1]] +
297+
byteToHex[buffer[2]] +
298+
byteToHex[buffer[3]] +
299+
'-' +
300+
byteToHex[buffer[4]] +
301+
byteToHex[buffer[5]] +
302+
'-' +
303+
byteToHex[buffer[6]] +
304+
byteToHex[buffer[7]] +
305+
'-' +
306+
byteToHex[buffer[8]] +
307+
byteToHex[buffer[9]] +
308+
'-' +
309+
byteToHex[buffer[10]] +
310+
byteToHex[buffer[11]] +
311+
byteToHex[buffer[12]] +
312+
byteToHex[buffer[13]] +
313+
byteToHex[buffer[14]] +
314+
byteToHex[buffer[15]]
315+
).toLowerCase();
316+
}
317+

0 commit comments

Comments
 (0)