Skip to content

Fix bigIntToBytes: non-growable list and broken comparisons#28

Merged
Harry-Chen merged 2 commits intonfcim:masterfrom
klaasdannen:fix/bigint-to-bytes
Mar 13, 2026
Merged

Fix bigIntToBytes: non-growable list and broken comparisons#28
Harry-Chen merged 2 commits intonfcim:masterfrom
klaasdannen:fix/bigint-to-bytes

Conversation

@klaasdannen
Copy link
Contributor

Summary

  • bigIntToBytes() created a non-growable List<int?>.filled(0, null, growable: false) then cast it to Uint8List and called .add(), which crashes at runtime with a RangeError
  • Fixed overflow check: 0 as BigInt is an invalid cast, replaced with BigInt.zero
  • Fixed reversed list: .reversed returns an Iterable, not Uint8List -- now uses .reversed.toList()
  • Added missing type annotation on endianness parameter

Test plan

  • Existing tests in test/ndef_test.dart continue to pass
  • Verify BigInt round-trip encoding/decoding works for values that exercise this path (e.g., Signature records)

@Harry-Chen
Copy link
Contributor

@klaasdannen Thank you very much for all the fixes! Please rebase this PR to master and run dartfmt on all changed files, then I will merge.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes ByteUtils.bigIntToBytes() so it no longer crashes at runtime when appending bytes, and corrects BigInt overflow checking and endianness reversal behavior.

Changes:

  • Replace invalid/non-growable list initialization with a growable List<int> and convert via Uint8List.fromList.
  • Fix overflow check by using BigInt.zero and improve reversal by materializing .reversed into a List.
  • Add a concrete type annotation to the endianness parameter.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +78 to +79
var list = <int>[];
BigInt v = value!;
Comment on lines 80 to +82
for (int i = 0; i < length; i++) {
list.add((v! % (BigInt.from(256))).toInt());
v ~/= (BigInt.from(256));
list.add((v % BigInt.from(256)).toInt());
v ~/= BigInt.from(256);
Comment on lines +84 to 86
if (v != BigInt.zero) {
throw ArgumentError("Value $value is overflow from range of $length bytes");
}
Comment on lines 73 to +90
static Uint8List bigIntToBytes(
BigInt? value,
int length, {
endianness = Endianness.Big,
Endianness endianness = Endianness.Big,
}) {
Uint8List? list = List<int?>.filled(0, null, growable: false) as Uint8List;
BigInt? v = value;
var list = <int>[];
BigInt v = value!;
for (int i = 0; i < length; i++) {
list.add((v! % (BigInt.from(256))).toInt());
v ~/= (BigInt.from(256));
list.add((v % BigInt.from(256)).toInt());
v ~/= BigInt.from(256);
}

/// unrelated_type_equality_check checked!
BigInt zero = 0 as BigInt;
if (v != zero) {
throw "Value $value is overflow from range of $length bytes";
if (v != BigInt.zero) {
throw ArgumentError("Value $value is overflow from range of $length bytes");
}
if (endianness == Endianness.Big) {
list = list.reversed as Uint8List?;
list = list.reversed.toList();
}
return Uint8List.fromList(list!);
return Uint8List.fromList(list);
The method created a non-growable List<int?>.filled(0, null, growable: false)
then cast it to Uint8List and called .add() on it, which crashes at runtime.
Also fixed: invalid cast of int 0 to BigInt for overflow check, missing type
annotation on endianness parameter, and .reversed producing an Iterable
being cast directly to Uint8List instead of converting to List first.
@klaasdannen klaasdannen force-pushed the fix/bigint-to-bytes branch from 11dd1ff to 90cc241 Compare March 13, 2026 15:28
@Harry-Chen Harry-Chen merged commit ab09640 into nfcim:master Mar 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants