Skip to content

Commit 8a408fc

Browse files
committed
a much more thorough fix for 64 bit number encoding
1 parent b0e43ca commit 8a408fc

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

lib/encode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ encode.bytes = function( buffers, data ) {
4343
}
4444

4545
encode.number = function( buffers, data ) {
46-
var maxLo = 4294967295
46+
var maxLo = 0x80000000
4747
var hi = ( data / maxLo ) << 0
4848
var lo = ( data % maxLo ) << 0
4949
var val = hi * maxLo + lo

test/encode.test.js

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,42 @@ describe("bencode", function() {
3636
it('should be able to encode a negative float (as int)', function() {
3737
assert.equal(bencode.encode(-123.5), 'i-123e');
3838
})
39-
it('should be able to encode a positive 64 bit int', function() {
40-
assert.equal(bencode.encode(4777722361), 'i4777722361e');
39+
it('should be able to safely encode numbers between -/+ 2 ^ 53 (as ints)', function() {
40+
assert.equal(bencode.encode(0), 'i' + 0 + 'e');
41+
42+
var JAVASCRIPT_INT_BITS = 53;
43+
var MAX_JAVASCRIPT_INT = Math.pow(2, JAVASCRIPT_INT_BITS);
44+
45+
for (var exp = 1; exp < JAVASCRIPT_INT_BITS; ++exp) {
46+
var val = Math.pow(2, exp);
47+
// try the positive and negative
48+
assert.equal(bencode.encode(val), 'i' + val + 'e');
49+
assert.equal(bencode.encode(-val), 'i-' + val + 'e');
50+
51+
// try the value, one above and one below, both positive and negative
52+
var above = val + 1;
53+
var below = val - 1;
54+
55+
assert.equal(bencode.encode(above), 'i' + above + 'e');
56+
assert.equal(bencode.encode(-above), 'i-' + above + 'e');
57+
58+
assert.equal(bencode.encode(below), 'i' + below + 'e');
59+
assert.equal(bencode.encode(-below), 'i-' + below + 'e');
60+
}
61+
assert.equal(bencode.encode(MAX_JAVASCRIPT_INT), 'i' + MAX_JAVASCRIPT_INT + 'e');
62+
assert.equal(bencode.encode(-MAX_JAVASCRIPT_INT), 'i-' + MAX_JAVASCRIPT_INT + 'e');
63+
});
64+
it('should be able to encode a previously problematice 64 bit int', function() {
65+
assert.equal(bencode.encode(2433088826), 'i' + 2433088826 + 'e');
4166
})
4267
it('should be able to encode a negative 64 bit int', function() {
43-
assert.equal(bencode.encode(-4777722361), 'i-4777722361e');
68+
assert.equal(bencode.encode(-0xffffffff), 'i-' + 0xffffffff + 'e');
4469
})
4570
it('should be able to encode a positive 64 bit float (as int)', function() {
46-
assert.equal(bencode.encode(4777722361.5), 'i4777722361e');
71+
assert.equal(bencode.encode(0xffffffff + 0.5), 'i' + 0xffffffff + 'e');
4772
})
4873
it('should be able to encode a negative 64 bit float (as int)', function() {
49-
assert.equal(bencode.encode(-4777722361.5), 'i-4777722361e');
74+
assert.equal(bencode.encode(-0xffffffff - 0.5), 'i-' + 0xffffffff + 'e');
5075
})
5176
it('should be able to encode a string', function() {
5277
assert.equal(bencode.encode("asdf"), '4:asdf');

0 commit comments

Comments
 (0)