Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(NODE-3815): update Decimal128 constructor validation #476

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/decimal128.ts
@@ -1,6 +1,7 @@
import { Buffer } from 'buffer';
import { BSONTypeError } from './error';
import { Long } from './long';
import { isUint8Array } from './parser/utils';

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

if (typeof bytes === 'string') {
this.bytes = Decimal128.fromString(bytes).bytes;
} else {
} else if (isUint8Array(bytes)) {
if (bytes.byteLength !== 16) {
throw new BSONTypeError('Decimal128 must take a Buffer of 16 bytes');
}
this.bytes = bytes;
} else {
throw new BSONTypeError('Decimal128 must take a Buffer or string');
}
}

Expand Down
17 changes: 16 additions & 1 deletion test/.eslintrc.json
Expand Up @@ -31,6 +31,21 @@
"error",
"global"
],
"promise/no-native": "off"
"promise/no-native": "off",
"no-restricted-properties": [
"error",
{
"object": "describe",
"property": "only"
},
{
"object": "it",
"property": "only"
},
{
"object": "context",
"property": "only"
}
]
}
}
28 changes: 26 additions & 2 deletions test/node/decimal128_tests.js
Expand Up @@ -1205,7 +1205,7 @@ describe('Decimal128', function () {
done();
});

it('accepts strings in the constructor', function (done) {
it('accepts strings in the constructor', () => {
expect(new Decimal128('0').toString()).to.equal('0');
expect(new Decimal128('00').toString()).to.equal('0');
expect(new Decimal128('0.5').toString()).to.equal('0.5');
Expand All @@ -1216,6 +1216,30 @@ describe('Decimal128', function () {
expect(new Decimal128('0.0011').toString()).to.equal('0.0011');
expect(new Decimal128('0.00110').toString()).to.equal('0.00110');
expect(new Decimal128('-1e400').toString()).to.equal('-1E+400');
done();
});

it('throws correct error for invalid constructor argument type', () => {
const constructorArgErrMsg = 'Decimal128 must take a Buffer or string';

expect(() => new Decimal128(-0)).to.throw(constructorArgErrMsg);
expect(() => new Decimal128(-1)).to.throw(constructorArgErrMsg);
expect(() => new Decimal128(10)).to.throw(constructorArgErrMsg);
expect(() => new Decimal128(1111111111111111)).to.throw(constructorArgErrMsg);
});

it('throws correct error for an invalid Buffer constructor argument', () => {
const byteLengthErrMsg = 'Decimal128 must take a Buffer of 16 bytes';

syz99 marked this conversation as resolved.
Show resolved Hide resolved
expect(() => new Decimal128(new Uint8Array(0))).to.throw(byteLengthErrMsg);
expect(() => new Decimal128(Buffer.alloc(0))).to.throw(byteLengthErrMsg);
expect(() => new Decimal128(new Uint8Array(3))).to.throw(byteLengthErrMsg);
expect(() => new Decimal128(Buffer.alloc(3))).to.throw(byteLengthErrMsg);
expect(() => new Decimal128(new Uint8Array(17))).to.throw(byteLengthErrMsg);
expect(() => new Decimal128(Buffer.alloc(17))).to.throw(byteLengthErrMsg);
});

it('does not throw error for an empty Buffer of correct length constructor argument', () => {
expect(() => new Decimal128(Buffer.alloc(16))).to.not.throw();
expect(() => new Decimal128(new Uint8Array(16))).to.not.throw();
});
});
4 changes: 2 additions & 2 deletions test/node/extended_json_tests.js
Expand Up @@ -227,7 +227,7 @@ describe('Extended JSON', function () {
binary: new Binary(''),
code: new Code('function() {}'),
dbRef: new DBRef('tests', new Int32(1), 'test'),
decimal128: new Decimal128(128),
decimal128: new Decimal128('128'),
double: new Double(10.1),
int32: new Int32(10),
long: new Long(234),
Expand All @@ -248,7 +248,7 @@ describe('Extended JSON', function () {
binary: { $binary: { base64: '', subType: '00' } },
code: { $code: 'function() {}' },
dbRef: { $ref: 'tests', $id: { $numberInt: '1' }, $db: 'test' },
decimal128: { $numberDecimal: '0E-6176' },
decimal128: { $numberDecimal: '128' },
double: { $numberDouble: '10.1' },
int32: { $numberInt: '10' },
long: { $numberLong: '234' },
Expand Down