Replace right shift with truncating divide (#128)
Closes #125
In JavaScript the shift operators cause numbers to be truncated to 32
bits, so the `>> 32` operation will always result in 0 on the web. This
causes a problem once the length of the file hits 512MB.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3b63c8..d6ec9e4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
## 3.0.2-dev
-- Require Dart 2.14.0.
+* Require Dart 2.14.0.
+* Fix bug calculating hashes for content larger than 512MB when compiled to JS.
## 3.0.1
diff --git a/lib/src/hash_sink.dart b/lib/src/hash_sink.dart
index adebf22..cd23823 100644
--- a/lib/src/hash_sink.dart
+++ b/lib/src/hash_sink.dart
@@ -161,7 +161,7 @@
// We're essentially doing byteData.setUint64(offset, lengthInBits, _endian)
// here, but that method isn't supported on dart2js so we implement it
// manually instead.
- var highBits = lengthInBits >> 32;
+ var highBits = lengthInBits ~/ 0x100000000; // >> 32
var lowBits = lengthInBits & mask32;
if (_endian == Endian.big) {
byteData.setUint32(offset, highBits, _endian);
diff --git a/pubspec.yaml b/pubspec.yaml
index 7d413b7..44c3207 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -10,5 +10,6 @@
typed_data: ^1.3.0
dev_dependencies:
+ convert: ^3.0.0
lints: ^1.0.0
test: ^1.16.0
diff --git a/test/sha1_test.dart b/test/sha1_test.dart
index 9c1749e..4630d04 100644
--- a/test/sha1_test.dart
+++ b/test/sha1_test.dart
@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:convert';
+import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:test/test.dart';
@@ -44,6 +45,19 @@
});
}
});
+ group('large file', () {
+ final chunk = List.filled(1024, 0);
+ test('produces correct hash', () async {
+ final sink = AccumulatorSink<Digest>();
+ final hash = sha1.startChunkedConversion(sink);
+ for (var i = 0; i < 512 * 1024; i++) {
+ hash.add(chunk);
+ }
+ hash.close();
+ expect(sink.events.single.toString(),
+ '5b088492c9f4778f409b7ae61477dec124c99033');
+ });
+ });
}
// Standard test vectors from: