Skip to content

Commit 95e8293

Browse files
authored
fix(NODE-3815): update Decimal128 constructor validation (#476)
1 parent 187d1c4 commit 95e8293

File tree

4 files changed

+51
-6
lines changed

4 files changed

+51
-6
lines changed

src/decimal128.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Buffer } from 'buffer';
22
import { BSONTypeError } from './error';
33
import { Long } from './long';
4+
import { isUint8Array } from './parser/utils';
45

56
const PARSE_STRING_REGEXP = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/;
67
const PARSE_INF_REGEXP = /^(\+|-)?(Infinity|inf)$/i;
@@ -132,8 +133,13 @@ export class Decimal128 {
132133

133134
if (typeof bytes === 'string') {
134135
this.bytes = Decimal128.fromString(bytes).bytes;
135-
} else {
136+
} else if (isUint8Array(bytes)) {
137+
if (bytes.byteLength !== 16) {
138+
throw new BSONTypeError('Decimal128 must take a Buffer of 16 bytes');
139+
}
136140
this.bytes = bytes;
141+
} else {
142+
throw new BSONTypeError('Decimal128 must take a Buffer or string');
137143
}
138144
}
139145

test/.eslintrc.json

+16-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@
3131
"error",
3232
"global"
3333
],
34-
"promise/no-native": "off"
34+
"promise/no-native": "off",
35+
"no-restricted-properties": [
36+
"error",
37+
{
38+
"object": "describe",
39+
"property": "only"
40+
},
41+
{
42+
"object": "it",
43+
"property": "only"
44+
},
45+
{
46+
"object": "context",
47+
"property": "only"
48+
}
49+
]
3550
}
3651
}

test/node/decimal128_tests.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ describe('Decimal128', function () {
12051205
done();
12061206
});
12071207

1208-
it('accepts strings in the constructor', function (done) {
1208+
it('accepts strings in the constructor', () => {
12091209
expect(new Decimal128('0').toString()).to.equal('0');
12101210
expect(new Decimal128('00').toString()).to.equal('0');
12111211
expect(new Decimal128('0.5').toString()).to.equal('0.5');
@@ -1216,6 +1216,30 @@ describe('Decimal128', function () {
12161216
expect(new Decimal128('0.0011').toString()).to.equal('0.0011');
12171217
expect(new Decimal128('0.00110').toString()).to.equal('0.00110');
12181218
expect(new Decimal128('-1e400').toString()).to.equal('-1E+400');
1219-
done();
1219+
});
1220+
1221+
it('throws correct error for invalid constructor argument type', () => {
1222+
const constructorArgErrMsg = 'Decimal128 must take a Buffer or string';
1223+
1224+
expect(() => new Decimal128(-0)).to.throw(constructorArgErrMsg);
1225+
expect(() => new Decimal128(-1)).to.throw(constructorArgErrMsg);
1226+
expect(() => new Decimal128(10)).to.throw(constructorArgErrMsg);
1227+
expect(() => new Decimal128(1111111111111111)).to.throw(constructorArgErrMsg);
1228+
});
1229+
1230+
it('throws correct error for an invalid Buffer constructor argument', () => {
1231+
const byteLengthErrMsg = 'Decimal128 must take a Buffer of 16 bytes';
1232+
1233+
expect(() => new Decimal128(new Uint8Array(0))).to.throw(byteLengthErrMsg);
1234+
expect(() => new Decimal128(Buffer.alloc(0))).to.throw(byteLengthErrMsg);
1235+
expect(() => new Decimal128(new Uint8Array(3))).to.throw(byteLengthErrMsg);
1236+
expect(() => new Decimal128(Buffer.alloc(3))).to.throw(byteLengthErrMsg);
1237+
expect(() => new Decimal128(new Uint8Array(17))).to.throw(byteLengthErrMsg);
1238+
expect(() => new Decimal128(Buffer.alloc(17))).to.throw(byteLengthErrMsg);
1239+
});
1240+
1241+
it('does not throw error for an empty Buffer of correct length constructor argument', () => {
1242+
expect(() => new Decimal128(Buffer.alloc(16))).to.not.throw();
1243+
expect(() => new Decimal128(new Uint8Array(16))).to.not.throw();
12201244
});
12211245
});

test/node/extended_json_tests.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ describe('Extended JSON', function () {
227227
binary: new Binary(''),
228228
code: new Code('function() {}'),
229229
dbRef: new DBRef('tests', new Int32(1), 'test'),
230-
decimal128: new Decimal128(128),
230+
decimal128: new Decimal128('128'),
231231
double: new Double(10.1),
232232
int32: new Int32(10),
233233
long: new Long(234),
@@ -248,7 +248,7 @@ describe('Extended JSON', function () {
248248
binary: { $binary: { base64: '', subType: '00' } },
249249
code: { $code: 'function() {}' },
250250
dbRef: { $ref: 'tests', $id: { $numberInt: '1' }, $db: 'test' },
251-
decimal128: { $numberDecimal: '0E-6176' },
251+
decimal128: { $numberDecimal: '128' },
252252
double: { $numberDouble: '10.1' },
253253
int32: { $numberInt: '10' },
254254
long: { $numberLong: '234' },

0 commit comments

Comments
 (0)