Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

merged @pwmckenna's fix for 53bit numbers

  • Loading branch information...
commit 35228a25c757ff077e8e187f29a0d8f27f5cc4d8 2 parents 0f11f05 + 8a408fc
@themasch authored
Showing with 39 additions and 11 deletions.
  1. +5 −6 lib/encode.js
  2. +34 −5 test/encode.test.js
View
11 lib/encode.js
@@ -33,7 +33,7 @@ encode._encode = function( buffers, data ) {
: encode.dict( buffers, data )
break
}
-
+
}
var buff_e = new Buffer('e')
@@ -46,14 +46,13 @@ encode.bytes = function( buffers, data ) {
}
encode.number = function( buffers, data ) {
-
- var maxLo = 4294967295
+ var maxLo = 0x80000000
var hi = ( data / maxLo ) << 0
var lo = ( data % maxLo ) << 0
var val = hi * maxLo + lo
-
+
buffers.push( new Buffer( 'i' + val + 'e' ))
-
+
if( val !== data && !encode._floatConversionDetected ) {
encode._floatConversionDetected = true
console.warn(
@@ -62,7 +61,7 @@ encode.number = function( buffers, data ) {
)
console.trace()
}
-
+
}
encode.dict = function( buffers, data ) {
View
39 test/encode.test.js
@@ -2,6 +2,10 @@ var assert = require("assert");
var bencode = require('./lib.js');
describe("bencode", function() {
+
+ // prevent the warning showing up in the test
+ bencode.encode._floatConversionDetected = true
+
describe("#encode()", function() {
it('should always return a Buffer', function() {
assert.ok(Buffer.isBuffer(bencode.encode({})), "its not a buffer for empty dicts");
@@ -36,17 +40,42 @@ describe("bencode", function() {
it('should be able to encode a negative float (as int)', function() {
assert.equal(bencode.encode(-123.5), 'i-123e');
})
- it('should be able to encode a positive 64 bit int', function() {
- assert.equal(bencode.encode(4777722361), 'i4777722361e');
+ it('should be able to safely encode numbers between -/+ 2 ^ 53 (as ints)', function() {
+ assert.equal(bencode.encode(0), 'i' + 0 + 'e');
+
+ var JAVASCRIPT_INT_BITS = 53;
+ var MAX_JAVASCRIPT_INT = Math.pow(2, JAVASCRIPT_INT_BITS);
+
+ for (var exp = 1; exp < JAVASCRIPT_INT_BITS; ++exp) {
+ var val = Math.pow(2, exp);
+ // try the positive and negative
+ assert.equal(bencode.encode(val), 'i' + val + 'e');
+ assert.equal(bencode.encode(-val), 'i-' + val + 'e');
+
+ // try the value, one above and one below, both positive and negative
+ var above = val + 1;
+ var below = val - 1;
+
+ assert.equal(bencode.encode(above), 'i' + above + 'e');
+ assert.equal(bencode.encode(-above), 'i-' + above + 'e');
+
+ assert.equal(bencode.encode(below), 'i' + below + 'e');
+ assert.equal(bencode.encode(-below), 'i-' + below + 'e');
+ }
+ assert.equal(bencode.encode(MAX_JAVASCRIPT_INT), 'i' + MAX_JAVASCRIPT_INT + 'e');
+ assert.equal(bencode.encode(-MAX_JAVASCRIPT_INT), 'i-' + MAX_JAVASCRIPT_INT + 'e');
+ });
+ it('should be able to encode a previously problematice 64 bit int', function() {
+ assert.equal(bencode.encode(2433088826), 'i' + 2433088826 + 'e');
})
it('should be able to encode a negative 64 bit int', function() {
- assert.equal(bencode.encode(-4777722361), 'i-4777722361e');
+ assert.equal(bencode.encode(-0xffffffff), 'i-' + 0xffffffff + 'e');
})
it('should be able to encode a positive 64 bit float (as int)', function() {
- assert.equal(bencode.encode(4777722361.5), 'i4777722361e');
+ assert.equal(bencode.encode(0xffffffff + 0.5), 'i' + 0xffffffff + 'e');
})
it('should be able to encode a negative 64 bit float (as int)', function() {
- assert.equal(bencode.encode(-4777722361.5), 'i-4777722361e');
+ assert.equal(bencode.encode(-0xffffffff - 0.5), 'i-' + 0xffffffff + 'e');
})
it('should be able to encode a string', function() {
assert.equal(bencode.encode("asdf"), '4:asdf');
Please sign in to comment.
Something went wrong with that request. Please try again.