Skip to content

Commit

Permalink
feat(NODE-4892)!: error on bson types not from this version
Browse files Browse the repository at this point in the history
  • Loading branch information
nbbeeken committed Dec 15, 2022
1 parent 95d5edf commit 1be51f5
Show file tree
Hide file tree
Showing 24 changed files with 292 additions and 606 deletions.
9 changes: 9 additions & 0 deletions src/binary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export class Binary {
get _bsontype(): 'Binary' {
return 'Binary';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

/**
* Binary default subtype
Expand Down Expand Up @@ -305,6 +309,11 @@ const UUID_BYTE_LENGTH = 16;
* @public
*/
export class UUID extends Binary {
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

static cacheHexString: boolean;

/** UUID hexString cache @internal */
Expand Down
4 changes: 4 additions & 0 deletions src/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export class Code {
get _bsontype(): 'Code' {
return 'Code';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

code: string;

Expand Down
4 changes: 4 additions & 0 deletions src/db_ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export class DBRef {
get _bsontype(): 'DBRef' {
return 'DBRef';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

collection!: string;
oid!: ObjectId;
Expand Down
4 changes: 4 additions & 0 deletions src/decimal128.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ export class Decimal128 {
get _bsontype(): 'Decimal128' {
return 'Decimal128';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

readonly bytes!: Uint8Array;

Expand Down
4 changes: 4 additions & 0 deletions src/double.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export class Double {
get _bsontype(): 'Double' {
return 'Double';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

value!: number;
/**
Expand Down
13 changes: 8 additions & 5 deletions src/extended_json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,9 @@ const BSON_TYPE_MAPPINGS = {
),
MaxKey: () => new MaxKey(),
MinKey: () => new MinKey(),
ObjectID: (o: ObjectId) => new ObjectId(o),
// The _bsontype for ObjectId is spelled with a capital "D", to the mapping above will be used (most of the time)
// specifically BSON versions 4.0.0 and 4.0.1 the _bsontype was changed to "ObjectId" so we keep this mapping to support
// those version of BSON
ObjectId: (o: ObjectId) => new ObjectId(o),
BSONRegExp: (o: BSONRegExp) => new BSONRegExp(o.pattern, o.options),
Symbol: (o: BSONSymbol) => new BSONSymbol(o.value),
BSONSymbol: (o: BSONSymbol) => new BSONSymbol(o.value),
Timestamp: (o: Timestamp) => Timestamp.fromBits(o.low, o.high)
} as const;

Expand Down Expand Up @@ -312,6 +308,13 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) {
}
}
return _doc;
} else if (
doc != null &&
typeof doc === 'object' &&
typeof doc._bsontype === 'string' &&
doc[Symbol.for('@@mdb.bson.version')] == null
) {
throw new BSONError('Unsupported BSON version, bson types must be from bson 5.0 or later');
} else if (isBSONType(doc)) {
// the "document" is really just a BSON type object
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
4 changes: 4 additions & 0 deletions src/int_32.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export class Int32 {
get _bsontype(): 'Int32' {
return 'Int32';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

value!: number;
/**
Expand Down
4 changes: 4 additions & 0 deletions src/long.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ export class Long {
get _bsontype(): 'Long' {
return 'Long';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

/** An indicator used to reliably determine if an object is a Long or not. */
get __isLong__(): boolean {
Expand Down
4 changes: 4 additions & 0 deletions src/max_key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export class MaxKey {
get _bsontype(): 'MaxKey' {
return 'MaxKey';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

/** @internal */
toExtendedJSON(): MaxKeyExtended {
Expand Down
4 changes: 4 additions & 0 deletions src/min_key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export class MinKey {
get _bsontype(): 'MinKey' {
return 'MinKey';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

/** @internal */
toExtendedJSON(): MinKeyExtended {
Expand Down
8 changes: 6 additions & 2 deletions src/objectid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ const kId = Symbol('id');
* @category BSONType
*/
export class ObjectId {
get _bsontype(): 'ObjectID' {
return 'ObjectID';
get _bsontype(): 'ObjectId' {
return 'ObjectId';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

/** @internal */
Expand Down
2 changes: 1 addition & 1 deletion src/parser/calculate_size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function calculateElement(
case 'object':
if (value == null || value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1;
} else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
} else if (value['_bsontype'] === 'ObjectId') {
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (12 + 1);
} else if (value instanceof Date || isDate(value)) {
return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1);
Expand Down
94 changes: 50 additions & 44 deletions src/parser/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -685,13 +685,11 @@ export function serializeInto(
index = serializeNull(buffer, key, value, index);
} else if (value === null) {
index = serializeNull(buffer, key, value, index);
} else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
index = serializeObjectId(buffer, key, value, index);
} else if (isUint8Array(value)) {
index = serializeBuffer(buffer, key, value, index);
} else if (value instanceof RegExp || isRegExp(value)) {
index = serializeRegExp(buffer, key, value, index);
} else if (typeof value === 'object' && value['_bsontype'] == null) {
} else if (typeof value === 'object' && value._bsontype == null) {
index = serializeObject(
buffer,
key,
Expand All @@ -703,19 +701,23 @@ export function serializeInto(
ignoreUndefined,
path
);
} else if (typeof value === 'object' && value[Symbol.for('@@mdb.bson.version')] == null) {
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);
} else if (
typeof value === 'object' &&
isBSONType(value) &&
value._bsontype === 'Decimal128'
) {
index = serializeDecimal128(buffer, key, value, index);
} else if (value['_bsontype'] === 'Long' || value['_bsontype'] === 'Timestamp') {
} else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
index = serializeLong(buffer, key, value, index);
} else if (value['_bsontype'] === 'Double') {
} else if (value._bsontype === 'Double') {
index = serializeDouble(buffer, key, value, index);
} else if (typeof value === 'function' && serializeFunctions) {
index = serializeFunction(buffer, key, value, index);
} else if (value['_bsontype'] === 'Code') {
} else if (value._bsontype === 'Code') {
index = serializeCode(
buffer,
key,
Expand All @@ -727,20 +729,20 @@ export function serializeInto(
ignoreUndefined,
path
);
} else if (value['_bsontype'] === 'Binary') {
} else if (value._bsontype === 'Binary') {
index = serializeBinary(buffer, key, value, index);
} else if (value['_bsontype'] === 'Symbol') {
} else if (value._bsontype === 'Symbol') {
index = serializeSymbol(buffer, key, value, index);
} else if (value['_bsontype'] === 'DBRef') {
} else if (value._bsontype === 'DBRef') {
index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
} else if (value['_bsontype'] === 'BSONRegExp') {
} else if (value._bsontype === 'BSONRegExp') {
index = serializeBSONRegExp(buffer, key, value, index);
} else if (value['_bsontype'] === 'Int32') {
} else if (value._bsontype === 'Int32') {
index = serializeInt32(buffer, key, value, index);
} else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
} else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
index = serializeMinMax(buffer, key, value, index);
} else if (typeof value['_bsontype'] !== 'undefined') {
throw new BSONTypeError(`Unrecognized or invalid _bsontype: ${String(value['_bsontype'])}`);
} else if (typeof value._bsontype !== 'undefined') {
throw new BSONTypeError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
}
}
} else if (object instanceof Map || isMap(object)) {
Expand Down Expand Up @@ -790,13 +792,11 @@ export function serializeInto(
index = serializeDate(buffer, key, value, index);
} else if (value === null || (value === undefined && ignoreUndefined === false)) {
index = serializeNull(buffer, key, value, index);
} else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
index = serializeObjectId(buffer, key, value, index);
} else if (isUint8Array(value)) {
index = serializeBuffer(buffer, key, value, index);
} else if (value instanceof RegExp || isRegExp(value)) {
index = serializeRegExp(buffer, key, value, index);
} else if (type === 'object' && value['_bsontype'] == null) {
} else if (type === 'object' && value._bsontype == null) {
index = serializeObject(
buffer,
key,
Expand All @@ -808,13 +808,17 @@ export function serializeInto(
ignoreUndefined,
path
);
} else if (type === 'object' && value['_bsontype'] === 'Decimal128') {
} else if (typeof value === 'object' && value[Symbol.for('@@mdb.bson.version')] == null) {
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);
} else if (type === 'object' && value._bsontype === 'Decimal128') {
index = serializeDecimal128(buffer, key, value, index);
} else if (value['_bsontype'] === 'Long' || value['_bsontype'] === 'Timestamp') {
} else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
index = serializeLong(buffer, key, value, index);
} else if (value['_bsontype'] === 'Double') {
} else if (value._bsontype === 'Double') {
index = serializeDouble(buffer, key, value, index);
} else if (value['_bsontype'] === 'Code') {
} else if (value._bsontype === 'Code') {
index = serializeCode(
buffer,
key,
Expand All @@ -828,20 +832,20 @@ export function serializeInto(
);
} else if (typeof value === 'function' && serializeFunctions) {
index = serializeFunction(buffer, key, value, index);
} else if (value['_bsontype'] === 'Binary') {
} else if (value._bsontype === 'Binary') {
index = serializeBinary(buffer, key, value, index);
} else if (value['_bsontype'] === 'Symbol') {
} else if (value._bsontype === 'Symbol') {
index = serializeSymbol(buffer, key, value, index);
} else if (value['_bsontype'] === 'DBRef') {
} else if (value._bsontype === 'DBRef') {
index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
} else if (value['_bsontype'] === 'BSONRegExp') {
} else if (value._bsontype === 'BSONRegExp') {
index = serializeBSONRegExp(buffer, key, value, index);
} else if (value['_bsontype'] === 'Int32') {
} else if (value._bsontype === 'Int32') {
index = serializeInt32(buffer, key, value, index);
} else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
} else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
index = serializeMinMax(buffer, key, value, index);
} else if (typeof value['_bsontype'] !== 'undefined') {
throw new BSONTypeError(`Unrecognized or invalid _bsontype: ${String(value['_bsontype'])}`);
} else if (typeof value._bsontype !== 'undefined') {
throw new BSONTypeError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
}
}
} else {
Expand Down Expand Up @@ -895,13 +899,11 @@ export function serializeInto(
if (ignoreUndefined === false) index = serializeNull(buffer, key, value, index);
} else if (value === null) {
index = serializeNull(buffer, key, value, index);
} else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
index = serializeObjectId(buffer, key, value, index);
} else if (isUint8Array(value)) {
index = serializeBuffer(buffer, key, value, index);
} else if (value instanceof RegExp || isRegExp(value)) {
index = serializeRegExp(buffer, key, value, index);
} else if (type === 'object' && value['_bsontype'] == null) {
} else if (type === 'object' && value._bsontype == null) {
index = serializeObject(
buffer,
key,
Expand All @@ -913,13 +915,17 @@ export function serializeInto(
ignoreUndefined,
path
);
} else if (type === 'object' && value['_bsontype'] === 'Decimal128') {
} else if (typeof value === 'object' && value[Symbol.for('@@mdb.bson.version')] == null) {
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);
} else if (type === 'object' && value._bsontype === 'Decimal128') {
index = serializeDecimal128(buffer, key, value, index);
} else if (value['_bsontype'] === 'Long' || value['_bsontype'] === 'Timestamp') {
} else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
index = serializeLong(buffer, key, value, index);
} else if (value['_bsontype'] === 'Double') {
} else if (value._bsontype === 'Double') {
index = serializeDouble(buffer, key, value, index);
} else if (value['_bsontype'] === 'Code') {
} else if (value._bsontype === 'Code') {
index = serializeCode(
buffer,
key,
Expand All @@ -933,20 +939,20 @@ export function serializeInto(
);
} else if (typeof value === 'function' && serializeFunctions) {
index = serializeFunction(buffer, key, value, index);
} else if (value['_bsontype'] === 'Binary') {
} else if (value._bsontype === 'Binary') {
index = serializeBinary(buffer, key, value, index);
} else if (value['_bsontype'] === 'Symbol') {
} else if (value._bsontype === 'Symbol') {
index = serializeSymbol(buffer, key, value, index);
} else if (value['_bsontype'] === 'DBRef') {
} else if (value._bsontype === 'DBRef') {
index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
} else if (value['_bsontype'] === 'BSONRegExp') {
} else if (value._bsontype === 'BSONRegExp') {
index = serializeBSONRegExp(buffer, key, value, index);
} else if (value['_bsontype'] === 'Int32') {
} else if (value._bsontype === 'Int32') {
index = serializeInt32(buffer, key, value, index);
} else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
} else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
index = serializeMinMax(buffer, key, value, index);
} else if (typeof value['_bsontype'] !== 'undefined') {
throw new BSONTypeError(`Unrecognized or invalid _bsontype: ${String(value['_bsontype'])}`);
} else if (typeof value._bsontype !== 'undefined') {
throw new BSONTypeError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/regexp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export class BSONRegExp {
get _bsontype(): 'BSONRegExp' {
return 'BSONRegExp';
}
/** @internal */
get [Symbol.for('@@mdb.bson.version')](): 5 {
return 5;
}

pattern!: string;
options!: string;
Expand Down Expand Up @@ -100,4 +104,13 @@ export class BSONRegExp {
}
throw new BSONTypeError(`Unexpected BSONRegExp EJSON object form: ${JSON.stringify(doc)}`);
}

/** @internal */
[Symbol.for('nodejs.util.inspect.custom')](): string {
return this.inspect();
}

inspect(): string {
return `new BSONRegExp(${JSON.stringify(this.pattern)}, ${JSON.stringify(this.options)})`;
}
}
Loading

0 comments on commit 1be51f5

Please sign in to comment.