Skip to content

Commit

Permalink
fix: calculate object size and test for error case
Browse files Browse the repository at this point in the history
  • Loading branch information
nbbeeken committed Jan 5, 2023
1 parent 90d2467 commit 02f26dd
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 6 deletions.
10 changes: 8 additions & 2 deletions src/extended_json.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { Binary } from './binary';
import type { Document } from './bson';
import { Code } from './code';
import { BSON_INT32_MAX, BSON_INT32_MIN, BSON_INT64_MAX, BSON_INT64_MIN } from './constants';
import {
BSON_INT32_MAX,
BSON_INT32_MIN,
BSON_INT64_MAX,
BSON_INT64_MIN,
BSON_MAJOR_VERSION
} from './constants';
import { DBRef, isDBRefLike } from './db_ref';
import { Decimal128 } from './decimal128';
import { Double } from './double';
Expand Down Expand Up @@ -310,7 +316,7 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) {
doc != null &&
typeof doc === 'object' &&
typeof doc._bsontype === 'string' &&
doc[Symbol.for('@@mdb.bson.version')] == null
doc[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION
) {
throw new BSONError('Unsupported BSON version, bson types must be from bson 5.0 or later');
} else if (isBSONType(doc)) {
Expand Down
13 changes: 12 additions & 1 deletion src/parser/calculate_size.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Binary } from '../binary';
import type { Document } from '../bson';
import { BSONError } from '../error';
import * as constants from '../constants';
import { ByteUtils } from '../utils/byte_utils';
import { isAnyArrayBuffer, isDate, isRegExp } from './utils';
Expand Down Expand Up @@ -77,7 +78,17 @@ function calculateElement(
case 'boolean':
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 1);
case 'object':
if (value == null || value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
if (
value != null &&
typeof value._bsontype === 'string' &&
value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION
) {
throw new BSONError('Unsupported BSON version, bson types must be from bson 5.0 or later');
} else if (
value == null ||
value['_bsontype'] === 'MinKey' ||
value['_bsontype'] === 'MaxKey'
) {
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1;
} else if (value['_bsontype'] === 'ObjectId') {
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (12 + 1);
Expand Down
15 changes: 12 additions & 3 deletions src/parser/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,10 @@ export function serializeInto(
ignoreUndefined,
path
);
} else if (typeof value === 'object' && value[Symbol.for('@@mdb.bson.version')] == null) {
} else if (
typeof value === 'object' &&
value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION
) {
throw new BSONError('Unsupported BSON version, bson types must be from bson 5.0 or later');
} else if (value._bsontype === 'ObjectId') {
index = serializeObjectId(buffer, key, value, index);
Expand Down Expand Up @@ -809,7 +812,10 @@ export function serializeInto(
ignoreUndefined,
path
);
} else if (typeof value === 'object' && value[Symbol.for('@@mdb.bson.version')] == null) {
} else if (
typeof value === 'object' &&
value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION
) {
throw new BSONError('Unsupported BSON version, bson types must be from bson 5.0 or later');
} else if (value._bsontype === 'ObjectId') {
index = serializeObjectId(buffer, key, value, index);
Expand Down Expand Up @@ -916,7 +922,10 @@ export function serializeInto(
ignoreUndefined,
path
);
} else if (typeof value === 'object' && value[Symbol.for('@@mdb.bson.version')] == null) {
} else if (
typeof value === 'object' &&
value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION
) {
throw new BSONError('Unsupported BSON version, bson types must be from bson 5.0 or later');
} else if (value._bsontype === 'ObjectId') {
index = serializeObjectId(buffer, key, value, index);
Expand Down
8 changes: 8 additions & 0 deletions test/node/extended_json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,4 +550,12 @@ describe('Extended JSON', function () {
const result = JSON.parse(string);
expect(result).to.deep.equal({ a: 1 });
});

it(`throws if Symbol.for('@@mdb.bson.version') is the wrong version in EJSON.stringify`, () => {
expect(() =>
EJSON.stringify({
a: { _bsontype: 'Int32', value: 2, [Symbol.for('@@mdb.bson.version')]: 1 }
})
).to.throw(BSONError, /Unsupported BSON version/i);
});
});
9 changes: 9 additions & 0 deletions test/node/parser/calculate_size.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import * as BSON from '../../register-bson';
import { expect } from 'chai';
import { BSONError } from '../../register-bson';

describe('calculateSize()', () => {
it('should only enumerate own property keys from input objects', () => {
const input = { a: 1 };
Object.setPrototypeOf(input, { b: 2 });
expect(BSON.calculateObjectSize(input)).to.equal(12);
});

it(`throws if Symbol.for('@@mdb.bson.version') is the wrong version`, () => {
expect(() =>
BSON.calculateObjectSize({
a: { _bsontype: 'Int32', value: 2, [Symbol.for('@@mdb.bson.version')]: 1 }
})
).to.throw(BSONError, /Unsupported BSON version/i);
});
});
9 changes: 9 additions & 0 deletions test/node/parser/serializer.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as BSON from '../../register-bson';
import { bufferFromHexArray } from '../tools/utils';
import { expect } from 'chai';
import { BSONError } from '../../register-bson';

describe('serialize()', () => {
it('should only enumerate own property keys from input objects', () => {
Expand Down Expand Up @@ -90,5 +91,13 @@ describe('serialize()', () => {
expect(() => BSON.serialize(Buffer.alloc(2))).to.throw(/cannot be BSON documents/);
expect(() => BSON.serialize(new Uint8Array(3))).to.throw(/cannot be BSON documents/);
});

it(`throws if Symbol.for('@@mdb.bson.version') is the wrong version`, () => {
expect(() =>
BSON.serialize({
a: { _bsontype: 'Int32', value: 2, [Symbol.for('@@mdb.bson.version')]: 1 }
})
).to.throw(BSONError, /Unsupported BSON version/i);
});
});
});

0 comments on commit 02f26dd

Please sign in to comment.