Skip to content

Commit

Permalink
Fixed parse to allow buffers larger than 16 bytes to be used.
Browse files Browse the repository at this point in the history
  • Loading branch information
hoylen authored and daegalus committed Nov 13, 2022
1 parent d7bc930 commit 832f38a
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v3.0.7

* Fixed parse to allow buffers larger than 16 bytes to be used.

v3.0.6

* Enable `avoid_dynamic_calls` linting and fix appropriately. (Thanks @devoncarew)
Expand Down
41 changes: 34 additions & 7 deletions lib/uuid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,22 @@ class Uuid {
}
}

///Parses the provided [uuid] into a list of byte values as a List<int>.
/// Parses the provided [uuid] into a list of byte values as a List<int>.
///
/// Can optionally be provided a [buffer] to write into and
/// a positional [offset] for where to start inputting into the buffer.
/// a positional [offset] for where to start inputting into the buffer.
///
/// Returns the buffer containing the bytes. If no buffer was provided,
/// a new buffer is created and returned. If a _buffer_ was provided, it
/// is returned (even if the uuid bytes are not placed at the beginning of
/// that buffer).
///
/// Throws FormatException if the UUID is invalid. Optionally you can set
/// [validate] to false to disable validation of the UUID before parsing.
///
/// Throws _RangeError_ if a _buffer_ is provided and it is too small.
/// It is also thrown if a non-zero _offset_ is provided without providing
/// a _buffer_.
static List<int> parse(
String uuid, {
List<int>? buffer,
Expand All @@ -129,8 +140,20 @@ class Uuid {
}
var i = offset, ii = 0;

// Create a 16 item buffer if one hasn't been provided.
buffer = (buffer != null) ? buffer : Uint8List(16);
// Get buffer to store the result
if (buffer == null) {
// Buffer not provided: create a 16 item buffer
if (offset != 0) {
throw RangeError('non-zero offset without providing a buffer');
}
buffer = Uint8List(16);
} else {
// Buffer provided: check it is large enough
if (buffer.length - offset < 16) {
throw RangeError('buffer too small: need 16: length=${buffer.length}'
'${offset != 0 ? ', offset=$offset' : ''}');
}
}

// Convert to lowercase and replace all hex with bytes then
// string.replaceAll() does a lot of work that I don't need, and a manual
Expand Down Expand Up @@ -171,10 +194,14 @@ class Uuid {
/// Unparses a [buffer] of bytes and outputs a proper UUID string.
/// An optional [offset] is allowed if you want to start at a different point
/// in the buffer.
/// Throws an exception if the buffer does not have a length of 16
///
/// Throws a [RangeError] exception if the _buffer_ is not large enough to
/// hold the bytes. That is, if the length of the _buffer_ after the _offset_
/// is less than 16.
static String unparse(List<int> buffer, {int offset = 0}) {
if (buffer.length != 16) {
throw Exception('The provided buffer needs to have a length of 16.');
if (buffer.length - offset < 16) {
throw RangeError('buffer too small: need 16: length=${buffer.length}'
'${offset != 0 ? ', offset=$offset' : ''}');
}
var i = offset;
return '${_byteToHex[buffer[i++]]}${_byteToHex[buffer[i++]]}'
Expand Down
38 changes: 38 additions & 0 deletions test/uuid_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,44 @@ void main() {
expect(() => Uuid.unparse(Uuid.parse('(this is the uuid -> $id$id')),
throwsA(isA<FormatException>()));
});

group('buffer:', () {
const size = 64;
final buffer = Uint8List(size);

group('offset good:', () {
for (final testCase in {
'offset=0': 0,
'offset=1': 1,
'offset in the middle': 32,
'offset 16 bytes before the end': size - 16,
}.entries) {
test(testCase.key, () {
final v = Uuid.parse(Uuid.NAMESPACE_OID,
buffer: buffer, offset: testCase.value);

expect(Uuid.unparse(v, offset: testCase.value),
equals(Uuid.NAMESPACE_OID));
});
}
});

group('offset bad:', () {
for (final testCase in {
'offset 15 bytes before end': size - 15,
'offset at end of buffer': size,
'offset after end of buffer': size + 1,
'offset is negative': -1
}.entries) {
test(testCase.key, () {
expect(
() => Uuid.parse(Uuid.NAMESPACE_OID,
buffer: buffer, offset: testCase.value),
throwsA(isA<RangeError>()));
});
}
});
});
});

group('[UuidValue]', () {
Expand Down

0 comments on commit 832f38a

Please sign in to comment.