Fix overflow bug in BigInt implementations.

Fixes #36105

Bug: http://dartbug.com/36105
Change-Id: I9adf70d11474f844d2a4fbf5fcc3754562b1cf65
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/95644
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
index 9027893..368d5e7 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
@@ -2634,7 +2634,9 @@
     var resultBits = Uint8List(8);
 
     var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
-    if (length - 53 > maxDoubleExponent) return double.infinity;
+    if (length > maxDoubleExponent + 53) {
+      return _isNegative ? double.negativeInfinity : double.infinity;
+    }
 
     // The most significant bit is for the sign.
     if (_isNegative) resultBits[7] = 0x80;
diff --git a/runtime/lib/bigint_patch.dart b/runtime/lib/bigint_patch.dart
index be23866..2046284 100644
--- a/runtime/lib/bigint_patch.dart
+++ b/runtime/lib/bigint_patch.dart
@@ -2312,7 +2312,9 @@
     var resultBits = new Uint8List(8);
 
     var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
-    if (length - 53 > maxDoubleExponent) return double.infinity;
+    if (length > maxDoubleExponent + 53) {
+      return _isNegative ? double.negativeInfinity : double.infinity;
+    }
 
     // The most significant bit is for the sign.
     if (_isNegative) resultBits[7] = 0x80;
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 045a2f1..e31fe29 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -2662,7 +2662,9 @@
     var resultBits = new Uint8List(8);
 
     var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
-    if (length - 53 > maxDoubleExponent) return double.infinity;
+    if (length > maxDoubleExponent + 53) {
+      return _isNegative ? double.negativeInfinity : double.infinity;
+    }
 
     // The most significant bit is for the sign.
     if (_isNegative) resultBits[7] = 0x80;
diff --git a/tests/corelib_2/bigint_test.dart b/tests/corelib_2/bigint_test.dart
index 46b69e1..01dea1f 100644
--- a/tests/corelib_2/bigint_test.dart
+++ b/tests/corelib_2/bigint_test.dart
@@ -1065,5 +1065,9 @@
     var b = BigInt.parse("10000000000000000001"); /// 27: ok
     Expect.equals(false, a.hashCode == b.hashCode); /// 27: ok
     Expect.equals(true, a.hashCode == (b - BigInt.one).hashCode); /// 27: ok
+
+    // Regression test for http://dartbug.com/36105
+    var overbig = -BigInt.from(10).pow(309);
+    Expect.equals(overbig.toDouble(), double.negativeInfinity);
   }
 }