Skip to content

Commit 36b2d43

Browse files
committed
fix(Timestamp): make sure timestamp is always unsigned
Fixes NODE-1939
1 parent 51862d8 commit 36b2d43

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

Diff for: lib/timestamp.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ const Long = require('./long');
1111
class Timestamp extends Long {
1212
constructor(low, high) {
1313
if (Long.isLong(low)) {
14-
super(low.low, low.high);
14+
super(low.low, low.high, true);
1515
} else {
16-
super(low, high);
16+
super(low, high, true);
1717
}
1818
}
1919

@@ -37,7 +37,7 @@ class Timestamp extends Long {
3737
* @return {Timestamp} the timestamp.
3838
*/
3939
static fromInt(value) {
40-
return new Timestamp(Long.fromInt(value));
40+
return new Timestamp(Long.fromInt(value, true));
4141
}
4242

4343
/**
@@ -48,7 +48,7 @@ class Timestamp extends Long {
4848
* @return {Timestamp} the timestamp.
4949
*/
5050
static fromNumber(value) {
51-
return new Timestamp(Long.fromNumber(value));
51+
return new Timestamp(Long.fromNumber(value, true));
5252
}
5353

5454
/**
@@ -72,14 +72,14 @@ class Timestamp extends Long {
7272
* @return {Timestamp} the timestamp.
7373
*/
7474
static fromString(str, opt_radix) {
75-
return new Timestamp(Long.fromString(str, opt_radix));
75+
return new Timestamp(Long.fromString(str, opt_radix, true));
7676
}
7777

7878
/**
7979
* @ignore
8080
*/
8181
toExtendedJSON() {
82-
return { $timestamp: { t: this.high, i: this.low } };
82+
return { $timestamp: { t: this.high >>> 0, i: this.low >>> 0 } };
8383
}
8484

8585
/**
@@ -91,4 +91,7 @@ class Timestamp extends Long {
9191
}
9292

9393
Object.defineProperty(Timestamp.prototype, '_bsontype', { value: 'Timestamp' });
94+
95+
Timestamp.MAX_VALUE = Timestamp.MAX_UNSIGNED_VALUE;
96+
9497
module.exports = Timestamp;

Diff for: test/node/timestamp_tests.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
3+
const BSON = require('../../lib/bson');
4+
const expect = require('chai').expect;
5+
6+
describe('Timestamp', function() {
7+
it('should have a MAX_VALUE equal to Long.MAX_UNSIGNED_VALUE', function() {
8+
expect(BSON.Timestamp.MAX_VALUE).to.equal(BSON.Long.MAX_UNSIGNED_VALUE);
9+
});
10+
11+
it('should always be an unsigned value', function() {
12+
[
13+
new BSON.Timestamp(),
14+
new BSON.Timestamp(0xff, 0xffffffff),
15+
new BSON.Timestamp(0xffffffff, 0xffffffff),
16+
new BSON.Timestamp(-1, -1),
17+
new BSON.Timestamp(new BSON.Timestamp(0xffffffff, 0xffffffff)),
18+
new BSON.Timestamp(new BSON.Long(0xffffffff, 0xfffffffff, false)),
19+
new BSON.Timestamp(new BSON.Long(0xffffffff, 0xfffffffff, true))
20+
].forEach(timestamp => {
21+
expect(timestamp).to.have.property('unsigned', true);
22+
});
23+
});
24+
25+
it('should print out an unsigned number', function() {
26+
const timestamp = new BSON.Timestamp(0xffffffff, 0xffffffff);
27+
expect(timestamp.toString()).to.equal('18446744073709551615');
28+
expect(timestamp.toJSON()).to.deep.equal({ $timestamp: '18446744073709551615' });
29+
expect(timestamp.toExtendedJSON()).to.deep.equal({
30+
$timestamp: { t: 4294967295, i: 4294967295 }
31+
});
32+
});
33+
});

0 commit comments

Comments
 (0)