Repository: intel/rohd (dart)

Issue:
`LogicValue.ofString` fails if representation exceeds maximum positive `int` value
### Describe the bug

Dart's `int.parse` function reads strings without a `-` as positive.  If a number is parsed as positive but exceeds the maximum positive value representable by a signed integer, then it will throw an exception.  The `LogicValue.ofString` function does not handle this scenario.

### To Reproduce

This test fails:
```dart
    test('big unsigned int string', () {
      expect(LogicValue.ofString('1' * 64),
          equals(LogicValue.ofInt(0xffffffff, 64)));
    });
```

Error:
```
FormatException: Positive input exceeds the limit of integer
1111111111111111111111111111111111111111111111111111111111111111
```

### Expected behavior

Correctly parses large numbers as unsigned.

### Actual behavior

Exception thrown

### Additional: Dart SDK info

_No response_

### Additional: pubspec.yaml

_No response_

### Additional: Context

_No response_

Pull request:
<!-- Please make sure you check out the contribution guidelines before submitting a pull request! -->

## Description & Motivation

Fixes a bug in parsing large unsigned binary integers (#183)

## Related Issue(s)

Fix #183 

## Testing

Added a new test.  Existing tests pass.

## Backwards-compatibility

> Is this a breaking change that will not be backwards-compatible?  If yes, how so?

No

## Documentation

> Does the change require any updates to documentation?  If so, where?  Are they included?

No

Patch:
diff --git a/lib/src/values/logic_value.dart b/lib/src/values/logic_value.dart
index 8d8c22629..b589800ea 100644
--- a/lib/src/values/logic_value.dart
+++ b/lib/src/values/logic_value.dart
@@ -180,8 +180,8 @@ abstract class LogicValue {
     final width = stringRepresentation.length;
 
     if (width <= _INT_BITS) {
-      final value = int.parse(valueString, radix: 2);
-      final invalid = int.parse(invalidString, radix: 2);
+      final value = _unsignedBinaryParse(valueString);
+      final invalid = _unsignedBinaryParse(invalidString);
       return _SmallLogicValue(value, invalid, width);
     } else {
       final value = BigInt.parse(valueString, radix: 2);
@@ -791,7 +791,24 @@ enum _ShiftType { left, right, arithmeticRight }
 /// Converts a binary [String] representation to a binary [int].
 ///
 /// Ignores all '_' in the provided binary.
-int bin(String s) => int.parse(s.replaceAll('_', ''), radix: 2);
+int bin(String s) => _unsignedBinaryParse(s.replaceAll('_', ''));
+
+/// Parses [source] as a binary integer, similarly to [int.parse].
+///
+/// If [source] interpreted as a positive signed integer would be larger than
+/// the maximum allowed by [int], then [int.parse] will throw an exception. This
+/// function will instead properly interpret it as an unsigned integer.
+int _unsignedBinaryParse(String source) {
+  final val = int.tryParse(source, radix: 2);
+  if (val != null) {
+    return val;
+  } else {
+    final hex = BigInt.parse(source, radix: 2).toRadixString(16);
+
+    // With `0x` in front of a hex literal, it will be interpreted as unsigned.
+    return int.parse('0x$hex');
+  }
+}
 
 /// Enum for a [LogicValue]'s value.
 enum _LogicValueEnum { zero, one, x, z }


Test patch:
diff --git a/test/logic_value_test.dart b/test/logic_value_test.dart
index 36d2a44c7..67f2f3a96 100644
--- a/test/logic_value_test.dart
+++ b/test/logic_value_test.dart
@@ -91,6 +91,9 @@ void main() {
       expect(
           <LogicValue>[].swizzle(), equals(LogicValue.ofBigInt(BigInt.two, 0)));
     });
+    test('big unsigned int string', () {
+      expect(LogicValue.ofString('1' * 64), equals(LogicValue.ofInt(-1, 64)));
+    });
     test('unary', () {
       expect(LogicValue.one.isValid, equals(true));
       expect(LogicValue.zero.isValid, equals(true));