Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 33 additions & 16 deletions lib/records/media/bluetooth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ class _Address {

_Address.fromBytes(Uint8List? bytes) {
if (bytes != null) {
assert(bytes.length == 6, "Bytes length of address data must be 6 bytes");
if (bytes.length != 6) {
throw ArgumentError.value(
bytes.length,
"bytes.length",
"Bluetooth address must be 6 bytes",
Comment on lines +21 to +24
);
}
addr = bytes;
}
}
Expand All @@ -36,13 +42,21 @@ class _Address {
if (exp.hasMatch(address)) {
var nums = address.split(RegExp("[-:]"));
var bts = <int>[];
assert(nums.length == 6);
if (nums.length != 6) {
throw FormatException(
"Bluetooth address must have 6 octets, got ${nums.length}",
address,
);
}
for (var n in nums) {
bts.add(int.parse(n, radix: 16));
}
addr = Uint8List.fromList(bts);
} else {
throw ArgumentError("Pattern of adress string is wrong, got $address");
throw FormatException(
"Invalid Bluetooth address format",
address,
);
}
}
}
Expand Down Expand Up @@ -337,10 +351,9 @@ class DeviceClass {
}

static String getServiceClassName(int index) {
assert(
index >= 13 && index < 24,
"Index of Service Class Name must be in [13,24)",
);
if (index < 13 || index >= 24) {
throw RangeError.range(index, 13, 23, "index");
}
return serviceClassNameList[index - 13];
}

Expand Down Expand Up @@ -1020,10 +1033,12 @@ class BluetoothLowEnergyRecord extends BluetoothRecord {

String? get roleCapabilities {
if (attributes.containsKey(EIRType.LERole)) {
assert(
attributes[EIRType.LERole]!.length == 1,
"Bytes length of LE Role must be 1",
);
if (attributes[EIRType.LERole]!.length != 1) {
throw FormatException(
"LE Role attribute must be 1 byte, "
"got ${attributes[EIRType.LERole]!.length}",
);
}
var index = attributes[EIRType.LERole]![0];
if (index < leRoleList.length) {
return leRoleList[index];
Expand Down Expand Up @@ -1100,10 +1115,12 @@ class BluetoothLowEnergyRecord extends BluetoothRecord {

String? get appearance {
if (attributes.containsKey(EIRType.Appearance)) {
assert(
attributes[EIRType.Appearance]!.length == 4,
"Bytes length of appearance must be 4",
);
if (attributes[EIRType.Appearance]!.length != 4) {
throw FormatException(
"Appearance attribute must be 4 bytes, "
"got ${attributes[EIRType.Appearance]!.length}",
);
}
int? value = ByteUtils.bytesToInt(
attributes[EIRType.Appearance],
endianness: Endianness.Little,
Expand All @@ -1127,7 +1144,7 @@ class BluetoothLowEnergyRecord extends BluetoothRecord {
}
}
if (index == null) {
throw ArgumentError.notNull("Appearance $appearance is not correct");
throw ArgumentError.value(appearance, "appearance", "Unknown appearance");
}
attributes[EIRType.Appearance] = ByteUtils.intToBytes(
index,
Expand Down
38 changes: 25 additions & 13 deletions lib/records/well_known/handover.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,15 @@ class AlternativeCarrierRecord extends WellKnownRecord {

/// Sets the carrier power state from an index.
set carrierPowerStateIndex(int carrierPowerStateIndex) {
assert(
carrierPowerStateIndex >= 0 &&
carrierPowerStateIndex < CarrierPowerState.values.length,
);
if (carrierPowerStateIndex < 0 ||
carrierPowerStateIndex >= CarrierPowerState.values.length) {
throw RangeError.range(
carrierPowerStateIndex,
0,
Comment on lines +84 to +88
CarrierPowerState.values.length - 1,
"carrierPowerStateIndex",
);
}
carrierPowerState = CarrierPowerState.values[carrierPowerStateIndex];
}

Expand All @@ -97,10 +102,14 @@ class AlternativeCarrierRecord extends WellKnownRecord {
payload.add(carrierDataReference.length);
payload.addAll(carrierDataReference);

assert(
auxDataReferenceList.length < 255,
"Number of auxDataReference must be in [0,256)",
);
if (auxDataReferenceList.length >= 255) {
throw RangeError.range(
auxDataReferenceList.length,
0,
254,
"auxDataReferenceList.length",
);
}

payload.add(auxDataReferenceList.length);
for (int i = 0; i < auxDataReferenceList.length; i++) {
Expand All @@ -125,10 +134,11 @@ class AlternativeCarrierRecord extends WellKnownRecord {
auxDataReferenceList.add(stream.readBytes(auxDataReferenceLength));
}

assert(
stream.isEnd() == true,
"payload has ${stream.unreadLength} bytes after decode",
);
if (!stream.isEnd()) {
throw FormatException(
"Payload has ${stream.unreadLength} unexpected trailing bytes",
);
}
Comment on lines +137 to +141
}
}

Expand Down Expand Up @@ -195,7 +205,9 @@ class CollisionResolutionRecord extends WellKnownRecord {
"RandomNumber expects int or Uint8List, got ${randomNumber.runtimeType}",
);
}
assert(value >= 0 && value <= 0xffff);
if (value < 0 || value > 0xffff) {
throw RangeError.range(value, 0, 0xffff, "randomNumber");
}
_randomNumber = value;
}

Expand Down
4 changes: 3 additions & 1 deletion lib/records/well_known/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ class TextRecord extends WellKnownRecord {
int flag = stream.readByte();
int languagePayloadLength = flag & 0x3F;

assert(languagePayloadLength != 0, "language code length can not be zero");
if (languagePayloadLength == 0) {
throw FormatException("Language code length must not be zero");
}
Comment on lines +109 to +111

if (flag >> 7 == 1) {
encoding = TextEncoding.UTF16;
Expand Down
43 changes: 43 additions & 0 deletions test/helpers.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'dart:typed_data';

import 'package:test/test.dart';

import 'package:ndef/ndef.dart';
import 'package:ndef/utilities.dart';

/// Decode hex strings and verify they match the expected records.
void testParse(List<String> hexStrings, List<List<NDEFRecord>> messages) {
for (int i = 0; i < hexStrings.length; i++) {
var decoded = decodeRawNdefMessage(hexStrings[i].toBytes());
expect(decoded.length, messages[i].length,
reason: 'Message $i record count mismatch');
Comment on lines +9 to +13
for (int j = 0; j < decoded.length; j++) {
expect(decoded[j].isEqual(messages[i][j]), isTrue,
reason: 'Message $i record $j mismatch');
}
}
}

/// Encode records and verify they produce the expected hex strings.
void testGenerate(List<String> hexStrings, List<List<NDEFRecord>> messages) {
for (int i = 0; i < hexStrings.length; i++) {
expect(encodeNdefMessage(messages[i]).toHexString(), hexStrings[i],
reason: 'Message $i encoding mismatch');
}
}

/// Encode then decode records, verifying round-trip fidelity.
void testRoundTrip(List<List<NDEFRecord>> messages) {
for (int i = 0; i < messages.length; i++) {
var decoded = decodeRawNdefMessage(encodeNdefMessage(messages[i]));
expect(decoded.length, messages[i].length,
reason: 'Round-trip message $i record count mismatch');
for (int j = 0; j < decoded.length; j++) {
expect(decoded[j].isEqual(messages[i][j]), isTrue,
reason: 'Round-trip message $i record $j mismatch');
}
}
}

/// Shorthand to convert a hex string to [Uint8List].
Uint8List hexToBytes(String hex) => ByteUtils.hexStringToBytes(hex);
Loading
Loading