react-native-ble-manager 12.4.3 → 12.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -460,6 +460,15 @@ public class BleManager extends NativeBleManagerSpec {
460
460
  callback.invoke("ServiceUUID and characteristicUUID required.");
461
461
  return;
462
462
  }
463
+ // Validate UUID formats to prevent crash
464
+ if (!UUIDHelper.isValidBLEUUID(serviceUUID)) {
465
+ callback.invoke("Invalid service UUID format: " + serviceUUID);
466
+ return;
467
+ }
468
+ if (!UUIDHelper.isValidBLEUUID(characteristicUUID)) {
469
+ callback.invoke("Invalid characteristic UUID format: " + characteristicUUID);
470
+ return;
471
+ }
463
472
  Peripheral peripheral = peripherals.get(deviceUUID);
464
473
  if (peripheral != null) {
465
474
  peripheral.registerNotify(UUIDHelper.uuidFromString(serviceUUID),
@@ -475,6 +484,15 @@ public class BleManager extends NativeBleManagerSpec {
475
484
  callback.invoke("ServiceUUID and characteristicUUID required.");
476
485
  return;
477
486
  }
487
+ // Validate UUID formats to prevent crash
488
+ if (!UUIDHelper.isValidBLEUUID(serviceUUID)) {
489
+ callback.invoke("Invalid service UUID format: " + serviceUUID);
490
+ return;
491
+ }
492
+ if (!UUIDHelper.isValidBLEUUID(characteristicUUID)) {
493
+ callback.invoke("Invalid characteristic UUID format: " + characteristicUUID);
494
+ return;
495
+ }
478
496
  Peripheral peripheral = peripherals.get(deviceUUID);
479
497
  if (peripheral != null) {
480
498
  if (peripheral.isConnected()) {
@@ -494,6 +512,15 @@ public class BleManager extends NativeBleManagerSpec {
494
512
  callback.invoke("ServiceUUID and characteristicUUID required.");
495
513
  return;
496
514
  }
515
+ // Validate UUID formats to prevent crash
516
+ if (!UUIDHelper.isValidBLEUUID(serviceUUID)) {
517
+ callback.invoke("Invalid service UUID format: " + serviceUUID);
518
+ return;
519
+ }
520
+ if (!UUIDHelper.isValidBLEUUID(characteristicUUID)) {
521
+ callback.invoke("Invalid characteristic UUID format: " + characteristicUUID);
522
+ return;
523
+ }
497
524
  Peripheral peripheral = peripherals.get(deviceUUID);
498
525
  if (peripheral != null) {
499
526
  if (peripheral.isConnected()) {
@@ -514,6 +541,15 @@ public class BleManager extends NativeBleManagerSpec {
514
541
  callback.invoke("ServiceUUID and characteristicUUID required.");
515
542
  return;
516
543
  }
544
+ // Validate UUID formats to prevent crash
545
+ if (!UUIDHelper.isValidBLEUUID(serviceUUID)) {
546
+ callback.invoke("Invalid service UUID format: " + serviceUUID);
547
+ return;
548
+ }
549
+ if (!UUIDHelper.isValidBLEUUID(characteristicUUID)) {
550
+ callback.invoke("Invalid characteristic UUID format: " + characteristicUUID);
551
+ return;
552
+ }
517
553
  Peripheral peripheral = peripherals.get(deviceUUID);
518
554
  if (peripheral != null) {
519
555
  if (peripheral.isConnected()) {
@@ -539,6 +575,15 @@ public class BleManager extends NativeBleManagerSpec {
539
575
  callback.invoke("ServiceUUID and characteristicUUID required.");
540
576
  return;
541
577
  }
578
+ // Validate UUID formats to prevent crash
579
+ if (!UUIDHelper.isValidBLEUUID(serviceUUID)) {
580
+ callback.invoke("Invalid service UUID format: " + serviceUUID);
581
+ return;
582
+ }
583
+ if (!UUIDHelper.isValidBLEUUID(characteristicUUID)) {
584
+ callback.invoke("Invalid characteristic UUID format: " + characteristicUUID);
585
+ return;
586
+ }
542
587
  Peripheral peripheral = peripherals.get(deviceUUID);
543
588
  if (peripheral != null) {
544
589
  if (peripheral.isConnected()) {
@@ -563,6 +608,15 @@ public class BleManager extends NativeBleManagerSpec {
563
608
  callback.invoke("ServiceUUID and characteristicUUID required.");
564
609
  return;
565
610
  }
611
+ // Validate UUID formats to prevent crash
612
+ if (!UUIDHelper.isValidBLEUUID(serviceUUID)) {
613
+ callback.invoke("Invalid service UUID format: " + serviceUUID);
614
+ return;
615
+ }
616
+ if (!UUIDHelper.isValidBLEUUID(characteristicUUID)) {
617
+ callback.invoke("Invalid characteristic UUID format: " + characteristicUUID);
618
+ return;
619
+ }
566
620
  Peripheral peripheral = peripherals.get(deviceUUID);
567
621
  if (peripheral != null) {
568
622
  if (peripheral.isConnected()) {
@@ -582,6 +636,19 @@ public class BleManager extends NativeBleManagerSpec {
582
636
  callback.invoke("ServiceUUID, CharacteristicUUID and descriptorUUID required.", null);
583
637
  return;
584
638
  }
639
+ // Validate UUID formats to prevent crash
640
+ if (!UUIDHelper.isValidBLEUUID(serviceUUID)) {
641
+ callback.invoke("Invalid service UUID format: " + serviceUUID, null);
642
+ return;
643
+ }
644
+ if (!UUIDHelper.isValidBLEUUID(characteristicUUID)) {
645
+ callback.invoke("Invalid characteristic UUID format: " + characteristicUUID, null);
646
+ return;
647
+ }
648
+ if (!UUIDHelper.isValidBLEUUID(descriptorUUID)) {
649
+ callback.invoke("Invalid descriptor UUID format: " + descriptorUUID, null);
650
+ return;
651
+ }
585
652
 
586
653
  Peripheral peripheral = peripherals.get(deviceUUID);
587
654
  if (peripheral == null) {
@@ -604,6 +671,19 @@ public class BleManager extends NativeBleManagerSpec {
604
671
  callback.invoke("ServiceUUID, CharacteristicUUID and descriptorUUID required.", null);
605
672
  return;
606
673
  }
674
+ // Validate UUID formats to prevent crash
675
+ if (!UUIDHelper.isValidBLEUUID(serviceUUID)) {
676
+ callback.invoke("Invalid service UUID format: " + serviceUUID, null);
677
+ return;
678
+ }
679
+ if (!UUIDHelper.isValidBLEUUID(characteristicUUID)) {
680
+ callback.invoke("Invalid characteristic UUID format: " + characteristicUUID, null);
681
+ return;
682
+ }
683
+ if (!UUIDHelper.isValidBLEUUID(descriptorUUID)) {
684
+ callback.invoke("Invalid descriptor UUID format: " + descriptorUUID, null);
685
+ return;
686
+ }
607
687
 
608
688
  Peripheral peripheral = peripherals.get(deviceUUID);
609
689
  if (peripheral == null) {
@@ -109,9 +109,17 @@ public class CompanionScanner {
109
109
  AssociationRequest.Builder builder = new AssociationRequest.Builder()
110
110
  .setSingleDevice(options.hasKey("single") && options.getBoolean("single")) ;
111
111
 
112
+ int validUUIDCount = 0;
112
113
  for (int i = 0; i < serviceUUIDs.size(); i++) {
113
- final ParcelUuid uuid = new ParcelUuid(UUIDHelper.uuidFromString(serviceUUIDs.getString(i)));
114
+ String uuidString = serviceUUIDs.getString(i);
115
+ // Validate UUID format to prevent crash
116
+ if (!UUIDHelper.isValidBLEUUID(uuidString)) {
117
+ Log.w(LOG_TAG, "Warning: Invalid UUID format in scan options: " + uuidString + ", skipping");
118
+ continue;
119
+ }
120
+ final ParcelUuid uuid = new ParcelUuid(UUIDHelper.uuidFromString(uuidString));
114
121
  Log.d(LOG_TAG, "Filter service: " + uuid);
122
+ validUUIDCount++;
115
123
 
116
124
  builder = builder
117
125
  // Add LE filter.
@@ -119,6 +127,12 @@ public class CompanionScanner {
119
127
  .setScanFilter(new ScanFilter.Builder().setServiceUuid(uuid).build())
120
128
  .build());
121
129
  }
130
+
131
+ // If serviceUUIDs were provided but none were valid, return error
132
+ if (serviceUUIDs.size() > 0 && validUUIDCount == 0) {
133
+ callback.invoke("Invalid UUID format in serviceUUIDs: all UUIDs are invalid");
134
+ return;
135
+ }
122
136
 
123
137
  AssociationRequest pairingRequest = builder.build();
124
138
  if (scanCallback != null) {
@@ -104,10 +104,23 @@ public class DefaultScanManager extends ScanManager {
104
104
 
105
105
  ReadableArray serviceUUIDs = options.getArray("serviceUUIDs");
106
106
  if (serviceUUIDs != null && serviceUUIDs.size() > 0) {
107
+ int validUUIDCount = 0;
107
108
  for (int i = 0; i < serviceUUIDs.size(); i++) {
108
- ScanFilter filter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(UUIDHelper.uuidFromString(Objects.requireNonNull(serviceUUIDs.getString(i))))).build();
109
+ String uuidString = Objects.requireNonNull(serviceUUIDs.getString(i));
110
+ // Validate UUID format to prevent crash
111
+ if (!UUIDHelper.isValidBLEUUID(uuidString)) {
112
+ Log.w(BleManager.LOG_TAG, "Warning: Invalid UUID format in scan options: " + uuidString + ", skipping");
113
+ continue;
114
+ }
115
+ ScanFilter filter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(UUIDHelper.uuidFromString(uuidString))).build();
109
116
  filters.add(filter);
110
- Log.d(BleManager.LOG_TAG, "Filter service: " + serviceUUIDs.getString(i));
117
+ validUUIDCount++;
118
+ Log.d(BleManager.LOG_TAG, "Filter service: " + uuidString);
119
+ }
120
+ // If serviceUUIDs were provided but none were valid, return error
121
+ if (validUUIDCount == 0) {
122
+ callback.invoke("Invalid UUID format in serviceUUIDs: all UUIDs are invalid");
123
+ return;
111
124
  }
112
125
  }
113
126
 
@@ -1099,15 +1099,34 @@ public class Peripheral extends BluetoothGattCallback {
1099
1099
  writeCallbacks.addLast(callback);
1100
1100
  }
1101
1101
  return enqueue(() -> {
1102
- if (!isConnected() || gatt == null) {
1103
- if (withResponse && callback != null) {
1104
- writeCallbacks.removeLastOccurrence(callback);
1105
- callback.invoke("Device is not connected", null);
1106
- }
1107
- completedCommand();
1108
- return;
1109
- }
1110
- doWrite(characteristic, copyOfData);
1102
+ try {
1103
+ if (!isConnected() || gatt == null) {
1104
+ if (withResponse && callback != null) {
1105
+ if (writeCallbacks.removeLastOccurrence(callback)) {
1106
+ try {
1107
+ callback.invoke("Device is not connected", null);
1108
+ } catch (Exception callbackException) {
1109
+ Log.e(BleManager.LOG_TAG, "Error invoking write callback for disconnected device", callbackException);
1110
+ }
1111
+ }
1112
+ }
1113
+ completedCommand();
1114
+ return;
1115
+ }
1116
+ doWrite(characteristic, copyOfData);
1117
+ } catch (Exception e) {
1118
+ Log.e(BleManager.LOG_TAG, "Error in enqueueWrite lambda", e);
1119
+ if (withResponse && callback != null) {
1120
+ if (writeCallbacks.removeLastOccurrence(callback)) {
1121
+ try {
1122
+ callback.invoke("Write failed: " + e.getMessage(), null);
1123
+ } catch (Exception callbackException) {
1124
+ Log.e(BleManager.LOG_TAG, "Error invoking write callback", callbackException);
1125
+ }
1126
+ }
1127
+ }
1128
+ completedCommand();
1129
+ }
1111
1130
  });
1112
1131
  }
1113
1132
 
@@ -9,6 +9,27 @@ public class UUIDHelper {
9
9
  // base UUID used to build 128 bit Bluetooth UUIDs
10
10
  public static final String UUID_BASE = "0000XXXX-0000-1000-8000-00805f9b34fb";
11
11
 
12
+ // Validate BLE UUID format (16-bit or 128-bit)
13
+ // Returns true if the string is a valid BLE UUID format
14
+ public static boolean isValidBLEUUID(String uuidString) {
15
+ if (uuidString == null || uuidString.isEmpty()) {
16
+ return false;
17
+ }
18
+
19
+ // Validate 16-bit UUID (4 hex characters)
20
+ if (uuidString.length() == 4) {
21
+ return uuidString.matches("[0-9A-Fa-f]{4}");
22
+ }
23
+
24
+ // Validate 128-bit UUID (standard UUID format)
25
+ try {
26
+ UUID.fromString(uuidString);
27
+ return true;
28
+ } catch (IllegalArgumentException e) {
29
+ return false;
30
+ }
31
+ }
32
+
12
33
  // handle 16 and 128 bit UUIDs
13
34
  public static UUID uuidFromString(String uuid) {
14
35