bson 4.5.1 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/HISTORY.md +572 -0
  2. package/bower.json +1 -1
  3. package/bson.d.ts +70 -13
  4. package/dist/bson.browser.esm.js +314 -177
  5. package/dist/bson.browser.esm.js.map +1 -1
  6. package/dist/bson.browser.umd.js +317 -176
  7. package/dist/bson.browser.umd.js.map +1 -1
  8. package/dist/bson.bundle.js +317 -176
  9. package/dist/bson.bundle.js.map +1 -1
  10. package/dist/bson.esm.js +314 -177
  11. package/dist/bson.esm.js.map +1 -1
  12. package/lib/binary.js +11 -9
  13. package/lib/binary.js.map +1 -1
  14. package/lib/bson.js +11 -3
  15. package/lib/bson.js.map +1 -1
  16. package/lib/code.js +0 -1
  17. package/lib/code.js.map +1 -1
  18. package/lib/constants.js +5 -1
  19. package/lib/constants.js.map +1 -1
  20. package/lib/db_ref.js +0 -1
  21. package/lib/db_ref.js.map +1 -1
  22. package/lib/decimal128.js +6 -5
  23. package/lib/decimal128.js.map +1 -1
  24. package/lib/double.js +3 -1
  25. package/lib/double.js.map +1 -1
  26. package/lib/ensure_buffer.js +3 -2
  27. package/lib/ensure_buffer.js.map +1 -1
  28. package/lib/error.js +55 -0
  29. package/lib/error.js.map +1 -0
  30. package/lib/extended_json.js +11 -5
  31. package/lib/extended_json.js.map +1 -1
  32. package/lib/int_32.js +4 -2
  33. package/lib/int_32.js.map +1 -1
  34. package/lib/objectid.js +39 -35
  35. package/lib/objectid.js.map +1 -1
  36. package/lib/parser/deserializer.js +131 -53
  37. package/lib/parser/deserializer.js.map +1 -1
  38. package/lib/parser/serializer.js +13 -12
  39. package/lib/parser/serializer.js.map +1 -1
  40. package/lib/regexp.js +9 -2
  41. package/lib/regexp.js.map +1 -1
  42. package/lib/symbol.js +0 -2
  43. package/lib/symbol.js.map +1 -1
  44. package/lib/uuid.js +4 -4
  45. package/lib/uuid.js.map +1 -1
  46. package/lib/uuid_utils.js +2 -1
  47. package/lib/uuid_utils.js.map +1 -1
  48. package/package.json +16 -3
  49. package/src/binary.ts +12 -10
  50. package/src/bson.ts +7 -1
  51. package/src/code.ts +0 -1
  52. package/src/constants.ts +6 -0
  53. package/src/db_ref.ts +0 -1
  54. package/src/decimal128.ts +6 -5
  55. package/src/double.ts +4 -1
  56. package/src/ensure_buffer.ts +3 -2
  57. package/src/error.ts +23 -0
  58. package/src/extended_json.ts +13 -5
  59. package/src/int_32.ts +5 -2
  60. package/src/objectid.ts +40 -43
  61. package/src/parser/deserializer.ts +159 -57
  62. package/src/parser/serializer.ts +13 -12
  63. package/src/regexp.ts +14 -2
  64. package/src/symbol.ts +0 -2
  65. package/src/uuid.ts +4 -4
  66. package/src/uuid_utils.ts +2 -1
@@ -2034,6 +2034,97 @@ var BSON = (function (exports) {
2034
2034
  buffer$1.INSPECT_MAX_BYTES;
2035
2035
  buffer$1.kMaxLength;
2036
2036
 
2037
+ /*! *****************************************************************************
2038
+ Copyright (c) Microsoft Corporation.
2039
+
2040
+ Permission to use, copy, modify, and/or distribute this software for any
2041
+ purpose with or without fee is hereby granted.
2042
+
2043
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
2044
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2045
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
2046
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2047
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
2048
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2049
+ PERFORMANCE OF THIS SOFTWARE.
2050
+ ***************************************************************************** */
2051
+
2052
+ /* global Reflect, Promise */
2053
+ var _extendStatics = function extendStatics(d, b) {
2054
+ _extendStatics = Object.setPrototypeOf || {
2055
+ __proto__: []
2056
+ } instanceof Array && function (d, b) {
2057
+ d.__proto__ = b;
2058
+ } || function (d, b) {
2059
+ for (var p in b) {
2060
+ if (b.hasOwnProperty(p)) d[p] = b[p];
2061
+ }
2062
+ };
2063
+
2064
+ return _extendStatics(d, b);
2065
+ };
2066
+
2067
+ function __extends(d, b) {
2068
+ _extendStatics(d, b);
2069
+
2070
+ function __() {
2071
+ this.constructor = d;
2072
+ }
2073
+
2074
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
2075
+ }
2076
+
2077
+ var _assign = function __assign() {
2078
+ _assign = Object.assign || function __assign(t) {
2079
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
2080
+ s = arguments[i];
2081
+
2082
+ for (var p in s) {
2083
+ if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
2084
+ }
2085
+ }
2086
+
2087
+ return t;
2088
+ };
2089
+
2090
+ return _assign.apply(this, arguments);
2091
+ };
2092
+
2093
+ /** @public */
2094
+ var BSONError = /** @class */ (function (_super) {
2095
+ __extends(BSONError, _super);
2096
+ function BSONError(message) {
2097
+ var _this = _super.call(this, message) || this;
2098
+ Object.setPrototypeOf(_this, BSONError.prototype);
2099
+ return _this;
2100
+ }
2101
+ Object.defineProperty(BSONError.prototype, "name", {
2102
+ get: function () {
2103
+ return 'BSONError';
2104
+ },
2105
+ enumerable: false,
2106
+ configurable: true
2107
+ });
2108
+ return BSONError;
2109
+ }(Error));
2110
+ /** @public */
2111
+ var BSONTypeError = /** @class */ (function (_super) {
2112
+ __extends(BSONTypeError, _super);
2113
+ function BSONTypeError(message) {
2114
+ var _this = _super.call(this, message) || this;
2115
+ Object.setPrototypeOf(_this, BSONTypeError.prototype);
2116
+ return _this;
2117
+ }
2118
+ Object.defineProperty(BSONTypeError.prototype, "name", {
2119
+ get: function () {
2120
+ return 'BSONTypeError';
2121
+ },
2122
+ enumerable: false,
2123
+ configurable: true
2124
+ });
2125
+ return BSONTypeError;
2126
+ }(TypeError));
2127
+
2037
2128
  function checkForMath(potentialGlobal) {
2038
2129
  // eslint-disable-next-line eqeqeq
2039
2130
  return potentialGlobal && potentialGlobal.Math == Math && potentialGlobal;
@@ -2145,7 +2236,7 @@ var BSON = (function (exports) {
2145
2236
  * @param potentialBuffer - The potential buffer
2146
2237
  * @returns Buffer the input if potentialBuffer is a buffer, or a buffer that
2147
2238
  * wraps a passed in Uint8Array
2148
- * @throws TypeError If anything other than a Buffer or Uint8Array is passed in
2239
+ * @throws BSONTypeError If anything other than a Buffer or Uint8Array is passed in
2149
2240
  */
2150
2241
  function ensureBuffer(potentialBuffer) {
2151
2242
  if (ArrayBuffer.isView(potentialBuffer)) {
@@ -2154,7 +2245,7 @@ var BSON = (function (exports) {
2154
2245
  if (isAnyArrayBuffer(potentialBuffer)) {
2155
2246
  return buffer_1.from(potentialBuffer);
2156
2247
  }
2157
- throw new TypeError('Must use either Buffer or TypedArray');
2248
+ throw new BSONTypeError('Must use either Buffer or TypedArray');
2158
2249
  }
2159
2250
 
2160
2251
  // Validation regex for v4 uuid (validates with or without dashes)
@@ -2164,7 +2255,7 @@ var BSON = (function (exports) {
2164
2255
  };
2165
2256
  var uuidHexStringToBuffer = function (hexString) {
2166
2257
  if (!uuidValidateString(hexString)) {
2167
- throw new TypeError('UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".');
2258
+ throw new BSONTypeError('UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".');
2168
2259
  }
2169
2260
  var sanitizedHexString = hexString.replace(/-/g, '');
2170
2261
  return buffer_1.from(sanitizedHexString, 'hex');
@@ -2212,7 +2303,7 @@ var BSON = (function (exports) {
2212
2303
  this.id = uuidHexStringToBuffer(input);
2213
2304
  }
2214
2305
  else {
2215
- throw new TypeError('Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).');
2306
+ throw new BSONTypeError('Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).');
2216
2307
  }
2217
2308
  }
2218
2309
  Object.defineProperty(UUID.prototype, "id", {
@@ -2252,14 +2343,13 @@ var BSON = (function (exports) {
2252
2343
  };
2253
2344
  /**
2254
2345
  * Converts the id into a 36 character (dashes included) hex string, unless a encoding is specified.
2255
- * @internal
2256
2346
  */
2257
2347
  UUID.prototype.toString = function (encoding) {
2258
2348
  return encoding ? this.id.toString(encoding) : this.toHexString();
2259
2349
  };
2260
2350
  /**
2261
- * Converts the id into its JSON string representation. A 36 character (dashes included) hex string in the format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
2262
- * @internal
2351
+ * Converts the id into its JSON string representation.
2352
+ * A 36 character (dashes included) hex string in the format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
2263
2353
  */
2264
2354
  UUID.prototype.toJSON = function () {
2265
2355
  return this.toHexString();
@@ -2371,7 +2461,7 @@ var BSON = (function (exports) {
2371
2461
  !ArrayBuffer.isView(buffer) &&
2372
2462
  !(buffer instanceof ArrayBuffer) &&
2373
2463
  !Array.isArray(buffer)) {
2374
- throw new TypeError('Binary can only be constructed from string, Buffer, TypedArray, or Array<number>');
2464
+ throw new BSONTypeError('Binary can only be constructed from string, Buffer, TypedArray, or Array<number>');
2375
2465
  }
2376
2466
  this.sub_type = subType !== null && subType !== void 0 ? subType : Binary.BSON_BINARY_SUBTYPE_DEFAULT;
2377
2467
  if (buffer == null) {
@@ -2403,10 +2493,10 @@ var BSON = (function (exports) {
2403
2493
  Binary.prototype.put = function (byteValue) {
2404
2494
  // If it's a string and a has more than one character throw an error
2405
2495
  if (typeof byteValue === 'string' && byteValue.length !== 1) {
2406
- throw new TypeError('only accepts single character String');
2496
+ throw new BSONTypeError('only accepts single character String');
2407
2497
  }
2408
2498
  else if (typeof byteValue !== 'number' && byteValue.length !== 1)
2409
- throw new TypeError('only accepts single character Uint8Array or Array');
2499
+ throw new BSONTypeError('only accepts single character Uint8Array or Array');
2410
2500
  // Decode the byte value once
2411
2501
  var decodedByte;
2412
2502
  if (typeof byteValue === 'string') {
@@ -2419,7 +2509,7 @@ var BSON = (function (exports) {
2419
2509
  decodedByte = byteValue[0];
2420
2510
  }
2421
2511
  if (decodedByte < 0 || decodedByte > 255) {
2422
- throw new TypeError('only accepts number in a valid unsigned byte range 0-255');
2512
+ throw new BSONTypeError('only accepts number in a valid unsigned byte range 0-255');
2423
2513
  }
2424
2514
  if (this.buffer.length > this.position) {
2425
2515
  this.buffer[this.position++] = decodedByte;
@@ -2491,11 +2581,9 @@ var BSON = (function (exports) {
2491
2581
  Binary.prototype.length = function () {
2492
2582
  return this.position;
2493
2583
  };
2494
- /** @internal */
2495
2584
  Binary.prototype.toJSON = function () {
2496
2585
  return this.buffer.toString('base64');
2497
2586
  };
2498
- /** @internal */
2499
2587
  Binary.prototype.toString = function (format) {
2500
2588
  return this.buffer.toString(format);
2501
2589
  };
@@ -2517,12 +2605,11 @@ var BSON = (function (exports) {
2517
2605
  }
2518
2606
  };
2519
2607
  };
2520
- /** @internal */
2521
2608
  Binary.prototype.toUUID = function () {
2522
2609
  if (this.sub_type === Binary.SUBTYPE_UUID) {
2523
2610
  return new UUID(this.buffer.slice(0, this.position));
2524
2611
  }
2525
- throw new Error("Binary sub_type \"" + this.sub_type + "\" is not supported for converting to UUID. Only \"" + Binary.SUBTYPE_UUID + "\" is currently supported.");
2612
+ throw new BSONError("Binary sub_type \"" + this.sub_type + "\" is not supported for converting to UUID. Only \"" + Binary.SUBTYPE_UUID + "\" is currently supported.");
2526
2613
  };
2527
2614
  /** @internal */
2528
2615
  Binary.fromExtendedJSON = function (doc, options) {
@@ -2546,7 +2633,7 @@ var BSON = (function (exports) {
2546
2633
  data = uuidHexStringToBuffer(doc.$uuid);
2547
2634
  }
2548
2635
  if (!data) {
2549
- throw new TypeError("Unexpected Binary Extended JSON format " + JSON.stringify(doc));
2636
+ throw new BSONTypeError("Unexpected Binary Extended JSON format " + JSON.stringify(doc));
2550
2637
  }
2551
2638
  return new Binary(data, type);
2552
2639
  };
@@ -2577,6 +2664,10 @@ var BSON = (function (exports) {
2577
2664
  Binary.SUBTYPE_UUID = 4;
2578
2665
  /** MD5 BSON type */
2579
2666
  Binary.SUBTYPE_MD5 = 5;
2667
+ /** Encrypted BSON type */
2668
+ Binary.SUBTYPE_ENCRYPTED = 6;
2669
+ /** Column BSON type */
2670
+ Binary.SUBTYPE_COLUMN = 7;
2580
2671
  /** User BSON type */
2581
2672
  Binary.SUBTYPE_USER_DEFINED = 128;
2582
2673
  return Binary;
@@ -2598,7 +2689,6 @@ var BSON = (function (exports) {
2598
2689
  this.code = code;
2599
2690
  this.scope = scope;
2600
2691
  }
2601
- /** @internal */
2602
2692
  Code.prototype.toJSON = function () {
2603
2693
  return { code: this.code, scope: this.scope };
2604
2694
  };
@@ -2670,7 +2760,6 @@ var BSON = (function (exports) {
2670
2760
  enumerable: false,
2671
2761
  configurable: true
2672
2762
  });
2673
- /** @internal */
2674
2763
  DBRef.prototype.toJSON = function () {
2675
2764
  var o = Object.assign({
2676
2765
  $ref: this.collection,
@@ -3697,7 +3786,7 @@ var BSON = (function (exports) {
3697
3786
  return false;
3698
3787
  }
3699
3788
  function invalidErr(string, message) {
3700
- throw new TypeError("\"" + string + "\" is not a valid Decimal128 string - " + message);
3789
+ throw new BSONTypeError("\"" + string + "\" is not a valid Decimal128 string - " + message);
3701
3790
  }
3702
3791
  /**
3703
3792
  * A class representation of the BSON Decimal128 type.
@@ -3764,7 +3853,7 @@ var BSON = (function (exports) {
3764
3853
  // TODO: implementing a custom parsing for this, or refactoring the regex would yield
3765
3854
  // further gains.
3766
3855
  if (representation.length >= 7000) {
3767
- throw new TypeError('' + representation + ' not a valid Decimal128 string');
3856
+ throw new BSONTypeError('' + representation + ' not a valid Decimal128 string');
3768
3857
  }
3769
3858
  // Results
3770
3859
  var stringMatch = representation.match(PARSE_STRING_REGEXP);
@@ -3772,7 +3861,7 @@ var BSON = (function (exports) {
3772
3861
  var nanMatch = representation.match(PARSE_NAN_REGEXP);
3773
3862
  // Validate the string
3774
3863
  if ((!stringMatch && !infMatch && !nanMatch) || representation.length === 0) {
3775
- throw new TypeError('' + representation + ' not a valid Decimal128 string');
3864
+ throw new BSONTypeError('' + representation + ' not a valid Decimal128 string');
3776
3865
  }
3777
3866
  if (stringMatch) {
3778
3867
  // full_match = stringMatch[0]
@@ -3834,7 +3923,7 @@ var BSON = (function (exports) {
3834
3923
  index = index + 1;
3835
3924
  }
3836
3925
  if (sawRadix && !nDigitsRead)
3837
- throw new TypeError('' + representation + ' not a valid Decimal128 string');
3926
+ throw new BSONTypeError('' + representation + ' not a valid Decimal128 string');
3838
3927
  // Read exponent if exists
3839
3928
  if (representation[index] === 'e' || representation[index] === 'E') {
3840
3929
  // Read exponent digits
@@ -3865,7 +3954,7 @@ var BSON = (function (exports) {
3865
3954
  lastDigit = nDigitsStored - 1;
3866
3955
  significantDigits = nDigits;
3867
3956
  if (significantDigits !== 1) {
3868
- while (representation[firstNonZero + significantDigits - 1] === '0') {
3957
+ while (digits[firstNonZero + significantDigits - 1] === 0) {
3869
3958
  significantDigits = significantDigits - 1;
3870
3959
  }
3871
3960
  }
@@ -4290,10 +4379,12 @@ var BSON = (function (exports) {
4290
4379
  Double.prototype.valueOf = function () {
4291
4380
  return this.value;
4292
4381
  };
4293
- /** @internal */
4294
4382
  Double.prototype.toJSON = function () {
4295
4383
  return this.value;
4296
4384
  };
4385
+ Double.prototype.toString = function (radix) {
4386
+ return this.value.toString(radix);
4387
+ };
4297
4388
  /** @internal */
4298
4389
  Double.prototype.toExtendedJSON = function (options) {
4299
4390
  if (options && (options.legacy || (options.relaxed && isFinite(this.value)))) {
@@ -4349,7 +4440,7 @@ var BSON = (function (exports) {
4349
4440
  if (value instanceof Number) {
4350
4441
  value = value.valueOf();
4351
4442
  }
4352
- this.value = +value;
4443
+ this.value = +value | 0;
4353
4444
  }
4354
4445
  /**
4355
4446
  * Access the number value.
@@ -4359,7 +4450,9 @@ var BSON = (function (exports) {
4359
4450
  Int32.prototype.valueOf = function () {
4360
4451
  return this.value;
4361
4452
  };
4362
- /** @internal */
4453
+ Int32.prototype.toString = function (radix) {
4454
+ return this.value.toString(radix);
4455
+ };
4363
4456
  Int32.prototype.toJSON = function () {
4364
4457
  return this.value;
4365
4458
  };
@@ -4453,50 +4546,57 @@ var BSON = (function (exports) {
4453
4546
  /**
4454
4547
  * Create an ObjectId type
4455
4548
  *
4456
- * @param id - Can be a 24 character hex string, 12 byte binary Buffer, or a number.
4549
+ * @param inputId - Can be a 24 character hex string, 12 byte binary Buffer, or a number.
4457
4550
  */
4458
- function ObjectId(id) {
4551
+ function ObjectId(inputId) {
4459
4552
  if (!(this instanceof ObjectId))
4460
- return new ObjectId(id);
4461
- // Duck-typing to support ObjectId from different npm packages
4462
- if (id instanceof ObjectId) {
4463
- this[kId] = id.id;
4464
- this.__id = id.__id;
4465
- }
4466
- if (typeof id === 'object' && id && 'id' in id) {
4467
- if ('toHexString' in id && typeof id.toHexString === 'function') {
4468
- this[kId] = buffer_1.from(id.toHexString(), 'hex');
4553
+ return new ObjectId(inputId);
4554
+ // workingId is set based on type of input and whether valid id exists for the input
4555
+ var workingId;
4556
+ if (typeof inputId === 'object' && inputId && 'id' in inputId) {
4557
+ if (typeof inputId.id !== 'string' && !ArrayBuffer.isView(inputId.id)) {
4558
+ throw new BSONTypeError('Argument passed in must have an id that is of type string or Buffer');
4559
+ }
4560
+ if ('toHexString' in inputId && typeof inputId.toHexString === 'function') {
4561
+ workingId = buffer_1.from(inputId.toHexString(), 'hex');
4469
4562
  }
4470
4563
  else {
4471
- this[kId] = typeof id.id === 'string' ? buffer_1.from(id.id) : id.id;
4564
+ workingId = inputId.id;
4472
4565
  }
4473
4566
  }
4474
- // The most common use case (blank id, new objectId instance)
4475
- if (id == null || typeof id === 'number') {
4567
+ else {
4568
+ workingId = inputId;
4569
+ }
4570
+ // the following cases use workingId to construct an ObjectId
4571
+ if (workingId == null || typeof workingId === 'number') {
4572
+ // The most common use case (blank id, new objectId instance)
4476
4573
  // Generate a new id
4477
- this[kId] = ObjectId.generate(typeof id === 'number' ? id : undefined);
4478
- // If we are caching the hex string
4479
- if (ObjectId.cacheHexString) {
4480
- this.__id = this.id.toString('hex');
4481
- }
4574
+ this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
4482
4575
  }
4483
- if (ArrayBuffer.isView(id) && id.byteLength === 12) {
4484
- this[kId] = ensureBuffer(id);
4576
+ else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {
4577
+ this[kId] = ensureBuffer(workingId);
4485
4578
  }
4486
- if (typeof id === 'string') {
4487
- if (id.length === 12) {
4488
- var bytes = buffer_1.from(id);
4579
+ else if (typeof workingId === 'string') {
4580
+ if (workingId.length === 12) {
4581
+ var bytes = buffer_1.from(workingId);
4489
4582
  if (bytes.byteLength === 12) {
4490
4583
  this[kId] = bytes;
4491
4584
  }
4585
+ else {
4586
+ throw new BSONTypeError('Argument passed in must be a string of 12 bytes');
4587
+ }
4492
4588
  }
4493
- else if (id.length === 24 && checkForHexRegExp.test(id)) {
4494
- this[kId] = buffer_1.from(id, 'hex');
4589
+ else if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
4590
+ this[kId] = buffer_1.from(workingId, 'hex');
4495
4591
  }
4496
4592
  else {
4497
- throw new TypeError('Argument passed in must be a Buffer or string of 12 bytes or a string of 24 hex characters');
4593
+ throw new BSONTypeError('Argument passed in must be a string of 12 bytes or a string of 24 hex characters');
4498
4594
  }
4499
4595
  }
4596
+ else {
4597
+ throw new BSONTypeError('Argument passed in does not match the accepted types');
4598
+ }
4599
+ // If we are caching the hex string
4500
4600
  if (ObjectId.cacheHexString) {
4501
4601
  this.__id = this.id.toString('hex');
4502
4602
  }
@@ -4560,7 +4660,7 @@ var BSON = (function (exports) {
4560
4660
  */
4561
4661
  ObjectId.generate = function (time) {
4562
4662
  if ('number' !== typeof time) {
4563
- time = ~~(Date.now() / 1000);
4663
+ time = Math.floor(Date.now() / 1000);
4564
4664
  }
4565
4665
  var inc = ObjectId.getInc();
4566
4666
  var buffer = buffer_1.alloc(12);
@@ -4586,7 +4686,6 @@ var BSON = (function (exports) {
4586
4686
  * Converts the id into a 24 character hex string for printing
4587
4687
  *
4588
4688
  * @param format - The Buffer toString format parameter.
4589
- * @internal
4590
4689
  */
4591
4690
  ObjectId.prototype.toString = function (format) {
4592
4691
  // Is the id a buffer then use the buffer toString method to return the format
@@ -4594,10 +4693,7 @@ var BSON = (function (exports) {
4594
4693
  return this.id.toString(format);
4595
4694
  return this.toHexString();
4596
4695
  };
4597
- /**
4598
- * Converts to its JSON the 24 character hex string representation.
4599
- * @internal
4600
- */
4696
+ /** Converts to its JSON the 24 character hex string representation. */
4601
4697
  ObjectId.prototype.toJSON = function () {
4602
4698
  return this.toHexString();
4603
4699
  };
@@ -4663,7 +4759,7 @@ var BSON = (function (exports) {
4663
4759
  ObjectId.createFromHexString = function (hexString) {
4664
4760
  // Throw an error if it's not a valid setup
4665
4761
  if (typeof hexString === 'undefined' || (hexString != null && hexString.length !== 24)) {
4666
- throw new TypeError('Argument passed in must be a single String of 12 bytes or a string of 24 hex characters');
4762
+ throw new BSONTypeError('Argument passed in must be a single String of 12 bytes or a string of 24 hex characters');
4667
4763
  }
4668
4764
  return new ObjectId(buffer_1.from(hexString, 'hex'));
4669
4765
  };
@@ -4719,7 +4815,7 @@ var BSON = (function (exports) {
4719
4815
  return "new ObjectId(\"" + this.toHexString() + "\")";
4720
4816
  };
4721
4817
  /** @internal */
4722
- ObjectId.index = ~~(Math.random() * 0xffffff);
4818
+ ObjectId.index = Math.floor(Math.random() * 0xffffff);
4723
4819
  return ObjectId;
4724
4820
  }());
4725
4821
  // Deprecated methods
@@ -4754,6 +4850,12 @@ var BSON = (function (exports) {
4754
4850
  return new BSONRegExp(pattern, options);
4755
4851
  this.pattern = pattern;
4756
4852
  this.options = alphabetize(options !== null && options !== void 0 ? options : '');
4853
+ if (this.pattern.indexOf('\x00') !== -1) {
4854
+ throw new BSONError("BSON Regex patterns cannot contain null bytes, found: " + JSON.stringify(this.pattern));
4855
+ }
4856
+ if (this.options.indexOf('\x00') !== -1) {
4857
+ throw new BSONError("BSON Regex options cannot contain null bytes, found: " + JSON.stringify(this.options));
4858
+ }
4757
4859
  // Validate options
4758
4860
  for (var i = 0; i < this.options.length; i++) {
4759
4861
  if (!(this.options[i] === 'i' ||
@@ -4762,7 +4864,7 @@ var BSON = (function (exports) {
4762
4864
  this.options[i] === 'l' ||
4763
4865
  this.options[i] === 's' ||
4764
4866
  this.options[i] === 'u')) {
4765
- throw new Error("The regular expression option [" + this.options[i] + "] is not supported");
4867
+ throw new BSONError("The regular expression option [" + this.options[i] + "] is not supported");
4766
4868
  }
4767
4869
  }
4768
4870
  }
@@ -4793,7 +4895,7 @@ var BSON = (function (exports) {
4793
4895
  if ('$regularExpression' in doc) {
4794
4896
  return new BSONRegExp(doc.$regularExpression.pattern, BSONRegExp.parseOptions(doc.$regularExpression.options));
4795
4897
  }
4796
- throw new TypeError("Unexpected BSONRegExp EJSON object form: " + JSON.stringify(doc));
4898
+ throw new BSONTypeError("Unexpected BSONRegExp EJSON object form: " + JSON.stringify(doc));
4797
4899
  };
4798
4900
  return BSONRegExp;
4799
4901
  }());
@@ -4816,7 +4918,6 @@ var BSON = (function (exports) {
4816
4918
  BSONSymbol.prototype.valueOf = function () {
4817
4919
  return this.value;
4818
4920
  };
4819
- /** @internal */
4820
4921
  BSONSymbol.prototype.toString = function () {
4821
4922
  return this.value;
4822
4923
  };
@@ -4824,7 +4925,6 @@ var BSON = (function (exports) {
4824
4925
  BSONSymbol.prototype.inspect = function () {
4825
4926
  return "new BSONSymbol(\"" + this.value + "\")";
4826
4927
  };
4827
- /** @internal */
4828
4928
  BSONSymbol.prototype.toJSON = function () {
4829
4929
  return this.value;
4830
4930
  };
@@ -4844,46 +4944,6 @@ var BSON = (function (exports) {
4844
4944
  }());
4845
4945
  Object.defineProperty(BSONSymbol.prototype, '_bsontype', { value: 'Symbol' });
4846
4946
 
4847
- /*! *****************************************************************************
4848
- Copyright (c) Microsoft Corporation.
4849
-
4850
- Permission to use, copy, modify, and/or distribute this software for any
4851
- purpose with or without fee is hereby granted.
4852
-
4853
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
4854
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
4855
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
4856
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
4857
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
4858
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
4859
- PERFORMANCE OF THIS SOFTWARE.
4860
- ***************************************************************************** */
4861
-
4862
- /* global Reflect, Promise */
4863
- var _extendStatics = function extendStatics(d, b) {
4864
- _extendStatics = Object.setPrototypeOf || {
4865
- __proto__: []
4866
- } instanceof Array && function (d, b) {
4867
- d.__proto__ = b;
4868
- } || function (d, b) {
4869
- for (var p in b) {
4870
- if (b.hasOwnProperty(p)) d[p] = b[p];
4871
- }
4872
- };
4873
-
4874
- return _extendStatics(d, b);
4875
- };
4876
-
4877
- function __extends(d, b) {
4878
- _extendStatics(d, b);
4879
-
4880
- function __() {
4881
- this.constructor = d;
4882
- }
4883
-
4884
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
4885
- }
4886
-
4887
4947
  /** @public */
4888
4948
  var LongWithoutOverridesClass = Long;
4889
4949
  /** @public */
@@ -5098,7 +5158,7 @@ var BSON = (function (exports) {
5098
5158
  var current = props[props.length - 1];
5099
5159
  var leadingSpace = ' '.repeat(leadingPart.length + alreadySeen.length / 2);
5100
5160
  var dashes = '-'.repeat(circularPart.length + (alreadySeen.length + current.length) / 2 - 1);
5101
- throw new TypeError('Converting circular structure to EJSON:\n' +
5161
+ throw new BSONTypeError('Converting circular structure to EJSON:\n' +
5102
5162
  (" " + leadingPart + alreadySeen + circularPart + current + "\n") +
5103
5163
  (" " + leadingSpace + "\\" + dashes + "/"));
5104
5164
  }
@@ -5171,7 +5231,7 @@ var BSON = (function (exports) {
5171
5231
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5172
5232
  function serializeDocument(doc, options) {
5173
5233
  if (doc == null || typeof doc !== 'object')
5174
- throw new Error('not an object instance');
5234
+ throw new BSONError('not an object instance');
5175
5235
  var bsontype = doc._bsontype;
5176
5236
  if (typeof bsontype === 'undefined') {
5177
5237
  // It's a regular object. Recursively serialize its property values.
@@ -5198,7 +5258,7 @@ var BSON = (function (exports) {
5198
5258
  // Copy the object into this library's version of that type.
5199
5259
  var mapper = BSON_TYPE_MAPPINGS[doc._bsontype];
5200
5260
  if (!mapper) {
5201
- throw new TypeError('Unrecognized or invalid _bsontype: ' + doc._bsontype);
5261
+ throw new BSONTypeError('Unrecognized or invalid _bsontype: ' + doc._bsontype);
5202
5262
  }
5203
5263
  outDoc = mapper(outDoc);
5204
5264
  }
@@ -5212,7 +5272,7 @@ var BSON = (function (exports) {
5212
5272
  return outDoc.toExtendedJSON(options);
5213
5273
  }
5214
5274
  else {
5215
- throw new Error('_bsontype must be a string, but was: ' + typeof bsontype);
5275
+ throw new BSONError('_bsontype must be a string, but was: ' + typeof bsontype);
5216
5276
  }
5217
5277
  }
5218
5278
  /**
@@ -5247,7 +5307,12 @@ var BSON = (function (exports) {
5247
5307
  finalOptions.strict = !finalOptions.relaxed;
5248
5308
  if (typeof finalOptions.strict === 'boolean')
5249
5309
  finalOptions.relaxed = !finalOptions.strict;
5250
- return JSON.parse(text, function (_key, value) { return deserializeValue(value, finalOptions); });
5310
+ return JSON.parse(text, function (key, value) {
5311
+ if (key.indexOf('\x00') !== -1) {
5312
+ throw new BSONError("BSON Document field names cannot contain null bytes, found: " + JSON.stringify(key));
5313
+ }
5314
+ return deserializeValue(value, finalOptions);
5315
+ });
5251
5316
  }
5252
5317
  EJSON.parse = parse;
5253
5318
  /**
@@ -5505,6 +5570,10 @@ var BSON = (function (exports) {
5505
5570
  var BSON_BINARY_SUBTYPE_UUID_NEW = 4;
5506
5571
  /** Binary MD5 Type @internal */
5507
5572
  var BSON_BINARY_SUBTYPE_MD5 = 5;
5573
+ /** Encrypted BSON type @internal */
5574
+ var BSON_BINARY_SUBTYPE_ENCRYPTED = 6;
5575
+ /** Column BSON type @internal */
5576
+ var BSON_BINARY_SUBTYPE_COLUMN = 7;
5508
5577
  /** Binary User Defined Type @internal */
5509
5578
  var BSON_BINARY_SUBTYPE_USER_DEFINED = 128;
5510
5579
 
@@ -5749,20 +5818,20 @@ var BSON = (function (exports) {
5749
5818
  (buffer[index + 2] << 16) |
5750
5819
  (buffer[index + 3] << 24);
5751
5820
  if (size < 5) {
5752
- throw new Error("bson size must be >= 5, is " + size);
5821
+ throw new BSONError("bson size must be >= 5, is " + size);
5753
5822
  }
5754
5823
  if (options.allowObjectSmallerThanBufferSize && buffer.length < size) {
5755
- throw new Error("buffer length " + buffer.length + " must be >= bson size " + size);
5824
+ throw new BSONError("buffer length " + buffer.length + " must be >= bson size " + size);
5756
5825
  }
5757
5826
  if (!options.allowObjectSmallerThanBufferSize && buffer.length !== size) {
5758
- throw new Error("buffer length " + buffer.length + " must === bson size " + size);
5827
+ throw new BSONError("buffer length " + buffer.length + " must === bson size " + size);
5759
5828
  }
5760
5829
  if (size + index > buffer.byteLength) {
5761
- throw new Error("(bson size " + size + " + options.index " + index + " must be <= buffer length " + buffer.byteLength + ")");
5830
+ throw new BSONError("(bson size " + size + " + options.index " + index + " must be <= buffer length " + buffer.byteLength + ")");
5762
5831
  }
5763
5832
  // Illegal end value
5764
5833
  if (buffer[index + size - 1] !== 0) {
5765
- throw new Error("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");
5834
+ throw new BSONError("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");
5766
5835
  }
5767
5836
  // Start deserializtion
5768
5837
  return deserializeObject(buffer, index, options, isArray);
@@ -5781,16 +5850,53 @@ var BSON = (function (exports) {
5781
5850
  var promoteBuffers = options['promoteBuffers'] == null ? false : options['promoteBuffers'];
5782
5851
  var promoteLongs = options['promoteLongs'] == null ? true : options['promoteLongs'];
5783
5852
  var promoteValues = options['promoteValues'] == null ? true : options['promoteValues'];
5853
+ // Ensures default validation option if none given
5854
+ var validation = options.validation == null ? { utf8: true } : options.validation;
5855
+ // Shows if global utf-8 validation is enabled or disabled
5856
+ var globalUTFValidation = true;
5857
+ // Reflects utf-8 validation setting regardless of global or specific key validation
5858
+ var validationSetting;
5859
+ // Set of keys either to enable or disable validation on
5860
+ var utf8KeysSet = new Set();
5861
+ // Check for boolean uniformity and empty validation option
5862
+ var utf8ValidatedKeys = validation.utf8;
5863
+ if (typeof utf8ValidatedKeys === 'boolean') {
5864
+ validationSetting = utf8ValidatedKeys;
5865
+ }
5866
+ else {
5867
+ globalUTFValidation = false;
5868
+ var utf8ValidationValues = Object.keys(utf8ValidatedKeys).map(function (key) {
5869
+ return utf8ValidatedKeys[key];
5870
+ });
5871
+ if (utf8ValidationValues.length === 0) {
5872
+ throw new BSONError('UTF-8 validation setting cannot be empty');
5873
+ }
5874
+ if (typeof utf8ValidationValues[0] !== 'boolean') {
5875
+ throw new BSONError('Invalid UTF-8 validation option, must specify boolean values');
5876
+ }
5877
+ validationSetting = utf8ValidationValues[0];
5878
+ // Ensures boolean uniformity in utf-8 validation (all true or all false)
5879
+ if (!utf8ValidationValues.every(function (item) { return item === validationSetting; })) {
5880
+ throw new BSONError('Invalid UTF-8 validation option - keys must be all true or all false');
5881
+ }
5882
+ }
5883
+ // Add keys to set that will either be validated or not based on validationSetting
5884
+ if (!globalUTFValidation) {
5885
+ for (var _i = 0, _a = Object.keys(utf8ValidatedKeys); _i < _a.length; _i++) {
5886
+ var key = _a[_i];
5887
+ utf8KeysSet.add(key);
5888
+ }
5889
+ }
5784
5890
  // Set the start index
5785
5891
  var startIndex = index;
5786
5892
  // Validate that we have at least 4 bytes of buffer
5787
5893
  if (buffer.length < 5)
5788
- throw new Error('corrupt bson message < 5 bytes long');
5894
+ throw new BSONError('corrupt bson message < 5 bytes long');
5789
5895
  // Read the document size
5790
5896
  var size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
5791
5897
  // Ensure buffer is valid size
5792
5898
  if (size < 5 || size > buffer.length)
5793
- throw new Error('corrupt bson message');
5899
+ throw new BSONError('corrupt bson message');
5794
5900
  // Create holding object
5795
5901
  var object = isArray ? [] : {};
5796
5902
  // Used for arrays to skip having to perform utf8 decoding
@@ -5812,8 +5918,17 @@ var BSON = (function (exports) {
5812
5918
  }
5813
5919
  // If are at the end of the buffer there is a problem with the document
5814
5920
  if (i >= buffer.byteLength)
5815
- throw new Error('Bad BSON Document: illegal CString');
5921
+ throw new BSONError('Bad BSON Document: illegal CString');
5922
+ // Represents the key
5816
5923
  var name = isArray ? arrayIndex++ : buffer.toString('utf8', index, i);
5924
+ // shouldValidateKey is true if the key should be validated, false otherwise
5925
+ var shouldValidateKey = true;
5926
+ if (globalUTFValidation || utf8KeysSet.has(name)) {
5927
+ shouldValidateKey = validationSetting;
5928
+ }
5929
+ else {
5930
+ shouldValidateKey = !validationSetting;
5931
+ }
5817
5932
  if (isPossibleDBRef !== false && name[0] === '$') {
5818
5933
  isPossibleDBRef = allowedDBRefKeys.test(name);
5819
5934
  }
@@ -5826,17 +5941,10 @@ var BSON = (function (exports) {
5826
5941
  (buffer[index++] << 24);
5827
5942
  if (stringSize <= 0 ||
5828
5943
  stringSize > buffer.length - index ||
5829
- buffer[index + stringSize - 1] !== 0)
5830
- throw new Error('bad string length in bson');
5831
- value = buffer.toString('utf8', index, index + stringSize - 1);
5832
- for (var i_1 = 0; i_1 < value.length; i_1++) {
5833
- if (value.charCodeAt(i_1) === 0xfffd) {
5834
- if (!validateUtf8(buffer, index, index + stringSize - 1)) {
5835
- throw new Error('Invalid UTF-8 string in BSON document');
5836
- }
5837
- break;
5838
- }
5944
+ buffer[index + stringSize - 1] !== 0) {
5945
+ throw new BSONError('bad string length in bson');
5839
5946
  }
5947
+ value = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
5840
5948
  index = index + stringSize;
5841
5949
  }
5842
5950
  else if (elementType === BSON_DATA_OID) {
@@ -5876,7 +5984,7 @@ var BSON = (function (exports) {
5876
5984
  }
5877
5985
  else if (elementType === BSON_DATA_BOOLEAN) {
5878
5986
  if (buffer[index] !== 0 && buffer[index] !== 1)
5879
- throw new Error('illegal boolean type value');
5987
+ throw new BSONError('illegal boolean type value');
5880
5988
  value = buffer[index++] === 1;
5881
5989
  }
5882
5990
  else if (elementType === BSON_DATA_OBJECT) {
@@ -5886,13 +5994,17 @@ var BSON = (function (exports) {
5886
5994
  (buffer[index + 2] << 16) |
5887
5995
  (buffer[index + 3] << 24);
5888
5996
  if (objectSize <= 0 || objectSize > buffer.length - index)
5889
- throw new Error('bad embedded document length in bson');
5997
+ throw new BSONError('bad embedded document length in bson');
5890
5998
  // We have a raw value
5891
5999
  if (raw) {
5892
6000
  value = buffer.slice(index, index + objectSize);
5893
6001
  }
5894
6002
  else {
5895
- value = deserializeObject(buffer, _index, options, false);
6003
+ var objectOptions = options;
6004
+ if (!globalUTFValidation) {
6005
+ objectOptions = _assign(_assign({}, options), { validation: { utf8: shouldValidateKey } });
6006
+ }
6007
+ value = deserializeObject(buffer, _index, objectOptions, false);
5896
6008
  }
5897
6009
  index = index + objectSize;
5898
6010
  }
@@ -5913,12 +6025,15 @@ var BSON = (function (exports) {
5913
6025
  }
5914
6026
  arrayOptions['raw'] = true;
5915
6027
  }
6028
+ if (!globalUTFValidation) {
6029
+ arrayOptions = _assign(_assign({}, arrayOptions), { validation: { utf8: shouldValidateKey } });
6030
+ }
5916
6031
  value = deserializeObject(buffer, _index, arrayOptions, true);
5917
6032
  index = index + objectSize;
5918
6033
  if (buffer[index - 1] !== 0)
5919
- throw new Error('invalid array terminator byte');
6034
+ throw new BSONError('invalid array terminator byte');
5920
6035
  if (index !== stopIndex)
5921
- throw new Error('corrupted array bson');
6036
+ throw new BSONError('corrupted array bson');
5922
6037
  }
5923
6038
  else if (elementType === BSON_DATA_UNDEFINED) {
5924
6039
  value = undefined;
@@ -5974,10 +6089,10 @@ var BSON = (function (exports) {
5974
6089
  var subType = buffer[index++];
5975
6090
  // Did we have a negative binary size, throw
5976
6091
  if (binarySize < 0)
5977
- throw new Error('Negative binary type element size found');
6092
+ throw new BSONError('Negative binary type element size found');
5978
6093
  // Is the length longer than the document
5979
6094
  if (binarySize > buffer.byteLength)
5980
- throw new Error('Binary type size larger than document size');
6095
+ throw new BSONError('Binary type size larger than document size');
5981
6096
  // Decode as raw Buffer object if options specifies it
5982
6097
  if (buffer['slice'] != null) {
5983
6098
  // If we have subtype 2 skip the 4 bytes for the size
@@ -5988,11 +6103,11 @@ var BSON = (function (exports) {
5988
6103
  (buffer[index++] << 16) |
5989
6104
  (buffer[index++] << 24);
5990
6105
  if (binarySize < 0)
5991
- throw new Error('Negative binary type element size found for subtype 0x02');
6106
+ throw new BSONError('Negative binary type element size found for subtype 0x02');
5992
6107
  if (binarySize > totalBinarySize - 4)
5993
- throw new Error('Binary type with subtype 0x02 contains too long binary size');
6108
+ throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
5994
6109
  if (binarySize < totalBinarySize - 4)
5995
- throw new Error('Binary type with subtype 0x02 contains too short binary size');
6110
+ throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
5996
6111
  }
5997
6112
  if (promoteBuffers && promoteValues) {
5998
6113
  value = buffer.slice(index, index + binarySize);
@@ -6011,11 +6126,11 @@ var BSON = (function (exports) {
6011
6126
  (buffer[index++] << 16) |
6012
6127
  (buffer[index++] << 24);
6013
6128
  if (binarySize < 0)
6014
- throw new Error('Negative binary type element size found for subtype 0x02');
6129
+ throw new BSONError('Negative binary type element size found for subtype 0x02');
6015
6130
  if (binarySize > totalBinarySize - 4)
6016
- throw new Error('Binary type with subtype 0x02 contains too long binary size');
6131
+ throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
6017
6132
  if (binarySize < totalBinarySize - 4)
6018
- throw new Error('Binary type with subtype 0x02 contains too short binary size');
6133
+ throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
6019
6134
  }
6020
6135
  // Copy the data
6021
6136
  for (i = 0; i < binarySize; i++) {
@@ -6040,7 +6155,7 @@ var BSON = (function (exports) {
6040
6155
  }
6041
6156
  // If are at the end of the buffer there is a problem with the document
6042
6157
  if (i >= buffer.length)
6043
- throw new Error('Bad BSON Document: illegal CString');
6158
+ throw new BSONError('Bad BSON Document: illegal CString');
6044
6159
  // Return the C string
6045
6160
  var source = buffer.toString('utf8', index, i);
6046
6161
  // Create the regexp
@@ -6053,7 +6168,7 @@ var BSON = (function (exports) {
6053
6168
  }
6054
6169
  // If are at the end of the buffer there is a problem with the document
6055
6170
  if (i >= buffer.length)
6056
- throw new Error('Bad BSON Document: illegal CString');
6171
+ throw new BSONError('Bad BSON Document: illegal CString');
6057
6172
  // Return the C string
6058
6173
  var regExpOptions = buffer.toString('utf8', index, i);
6059
6174
  index = i + 1;
@@ -6084,7 +6199,7 @@ var BSON = (function (exports) {
6084
6199
  }
6085
6200
  // If are at the end of the buffer there is a problem with the document
6086
6201
  if (i >= buffer.length)
6087
- throw new Error('Bad BSON Document: illegal CString');
6202
+ throw new BSONError('Bad BSON Document: illegal CString');
6088
6203
  // Return the C string
6089
6204
  var source = buffer.toString('utf8', index, i);
6090
6205
  index = i + 1;
@@ -6096,7 +6211,7 @@ var BSON = (function (exports) {
6096
6211
  }
6097
6212
  // If are at the end of the buffer there is a problem with the document
6098
6213
  if (i >= buffer.length)
6099
- throw new Error('Bad BSON Document: illegal CString');
6214
+ throw new BSONError('Bad BSON Document: illegal CString');
6100
6215
  // Return the C string
6101
6216
  var regExpOptions = buffer.toString('utf8', index, i);
6102
6217
  index = i + 1;
@@ -6110,9 +6225,10 @@ var BSON = (function (exports) {
6110
6225
  (buffer[index++] << 24);
6111
6226
  if (stringSize <= 0 ||
6112
6227
  stringSize > buffer.length - index ||
6113
- buffer[index + stringSize - 1] !== 0)
6114
- throw new Error('bad string length in bson');
6115
- var symbol = buffer.toString('utf8', index, index + stringSize - 1);
6228
+ buffer[index + stringSize - 1] !== 0) {
6229
+ throw new BSONError('bad string length in bson');
6230
+ }
6231
+ var symbol = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
6116
6232
  value = promoteValues ? symbol : new BSONSymbol(symbol);
6117
6233
  index = index + stringSize;
6118
6234
  }
@@ -6140,9 +6256,10 @@ var BSON = (function (exports) {
6140
6256
  (buffer[index++] << 24);
6141
6257
  if (stringSize <= 0 ||
6142
6258
  stringSize > buffer.length - index ||
6143
- buffer[index + stringSize - 1] !== 0)
6144
- throw new Error('bad string length in bson');
6145
- var functionString = buffer.toString('utf8', index, index + stringSize - 1);
6259
+ buffer[index + stringSize - 1] !== 0) {
6260
+ throw new BSONError('bad string length in bson');
6261
+ }
6262
+ var functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
6146
6263
  // If we are evaluating the functions
6147
6264
  if (evalFunctions) {
6148
6265
  // If we have cache enabled let's look for the md5 of the function in the cache
@@ -6167,7 +6284,7 @@ var BSON = (function (exports) {
6167
6284
  (buffer[index++] << 24);
6168
6285
  // Element cannot be shorter than totalSize + stringSize + documentSize + terminator
6169
6286
  if (totalSize < 4 + 4 + 4 + 1) {
6170
- throw new Error('code_w_scope total size shorter minimum expected length');
6287
+ throw new BSONError('code_w_scope total size shorter minimum expected length');
6171
6288
  }
6172
6289
  // Get the code string size
6173
6290
  var stringSize = buffer[index++] |
@@ -6177,10 +6294,11 @@ var BSON = (function (exports) {
6177
6294
  // Check if we have a valid string
6178
6295
  if (stringSize <= 0 ||
6179
6296
  stringSize > buffer.length - index ||
6180
- buffer[index + stringSize - 1] !== 0)
6181
- throw new Error('bad string length in bson');
6297
+ buffer[index + stringSize - 1] !== 0) {
6298
+ throw new BSONError('bad string length in bson');
6299
+ }
6182
6300
  // Javascript function
6183
- var functionString = buffer.toString('utf8', index, index + stringSize - 1);
6301
+ var functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
6184
6302
  // Update parse index position
6185
6303
  index = index + stringSize;
6186
6304
  // Parse the element
@@ -6196,11 +6314,11 @@ var BSON = (function (exports) {
6196
6314
  index = index + objectSize;
6197
6315
  // Check if field length is too short
6198
6316
  if (totalSize < 4 + 4 + objectSize + stringSize) {
6199
- throw new Error('code_w_scope total size is too short, truncating scope');
6317
+ throw new BSONError('code_w_scope total size is too short, truncating scope');
6200
6318
  }
6201
6319
  // Check if totalSize field is too long
6202
6320
  if (totalSize > 4 + 4 + objectSize + stringSize) {
6203
- throw new Error('code_w_scope total size is too long, clips outer document');
6321
+ throw new BSONError('code_w_scope total size is too long, clips outer document');
6204
6322
  }
6205
6323
  // If we are evaluating the functions
6206
6324
  if (evalFunctions) {
@@ -6228,10 +6346,12 @@ var BSON = (function (exports) {
6228
6346
  if (stringSize <= 0 ||
6229
6347
  stringSize > buffer.length - index ||
6230
6348
  buffer[index + stringSize - 1] !== 0)
6231
- throw new Error('bad string length in bson');
6349
+ throw new BSONError('bad string length in bson');
6232
6350
  // Namespace
6233
- if (!validateUtf8(buffer, index, index + stringSize - 1)) {
6234
- throw new Error('Invalid UTF-8 string in BSON document');
6351
+ if (validation != null && validation.utf8) {
6352
+ if (!validateUtf8(buffer, index, index + stringSize - 1)) {
6353
+ throw new BSONError('Invalid UTF-8 string in BSON document');
6354
+ }
6235
6355
  }
6236
6356
  var namespace = buffer.toString('utf8', index, index + stringSize - 1);
6237
6357
  // Update parse index position
@@ -6246,7 +6366,7 @@ var BSON = (function (exports) {
6246
6366
  value = new DBRef(namespace, oid);
6247
6367
  }
6248
6368
  else {
6249
- throw new Error('Detected unknown BSON type ' + elementType.toString(16) + ' for fieldname "' + name + '"');
6369
+ throw new BSONError('Detected unknown BSON type ' + elementType.toString(16) + ' for fieldname "' + name + '"');
6250
6370
  }
6251
6371
  if (name === '__proto__') {
6252
6372
  Object.defineProperty(object, name, {
@@ -6263,8 +6383,8 @@ var BSON = (function (exports) {
6263
6383
  // Check if the deserialization was against a valid array/object
6264
6384
  if (size !== index - startIndex) {
6265
6385
  if (isArray)
6266
- throw new Error('corrupt array bson');
6267
- throw new Error('corrupt object bson');
6386
+ throw new BSONError('corrupt array bson');
6387
+ throw new BSONError('corrupt object bson');
6268
6388
  }
6269
6389
  // if we did not find "$ref", "$id", "$db", or found an extraneous $key, don't make a DBRef
6270
6390
  if (!isPossibleDBRef)
@@ -6293,6 +6413,21 @@ var BSON = (function (exports) {
6293
6413
  // Set the object
6294
6414
  return functionCache[functionString].bind(object);
6295
6415
  }
6416
+ function getValidatedString(buffer, start, end, shouldValidateUtf8) {
6417
+ var value = buffer.toString('utf8', start, end);
6418
+ // if utf8 validation is on, do the check
6419
+ if (shouldValidateUtf8) {
6420
+ for (var i = 0; i < value.length; i++) {
6421
+ if (value.charCodeAt(i) === 0xfffd) {
6422
+ if (!validateUtf8(buffer, start, end)) {
6423
+ throw new BSONError('Invalid UTF-8 string in BSON document');
6424
+ }
6425
+ break;
6426
+ }
6427
+ }
6428
+ }
6429
+ return value;
6430
+ }
6296
6431
 
6297
6432
  // Copyright (c) 2008, Fair Oaks Labs, Inc.
6298
6433
  function writeIEEE754(buffer, value, offset, endian, mLen, nBytes) {
@@ -6577,7 +6712,7 @@ var BSON = (function (exports) {
6577
6712
  buffer.set(value.id.subarray(0, 12), index);
6578
6713
  }
6579
6714
  else {
6580
- throw new TypeError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
6715
+ throw new BSONTypeError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
6581
6716
  }
6582
6717
  // Adjust index
6583
6718
  return index + 12;
@@ -6616,7 +6751,7 @@ var BSON = (function (exports) {
6616
6751
  if (path === void 0) { path = []; }
6617
6752
  for (var i = 0; i < path.length; i++) {
6618
6753
  if (path[i] === value)
6619
- throw new Error('cyclic dependency detected');
6754
+ throw new BSONError('cyclic dependency detected');
6620
6755
  }
6621
6756
  // Push value to stack
6622
6757
  path.push(value);
@@ -6919,7 +7054,7 @@ var BSON = (function (exports) {
6919
7054
  // Is there an override value
6920
7055
  if (value && value.toBSON) {
6921
7056
  if (typeof value.toBSON !== 'function')
6922
- throw new TypeError('toBSON is not a function');
7057
+ throw new BSONTypeError('toBSON is not a function');
6923
7058
  value = value.toBSON();
6924
7059
  }
6925
7060
  if (typeof value === 'string') {
@@ -6929,7 +7064,7 @@ var BSON = (function (exports) {
6929
7064
  index = serializeNumber(buffer, key, value, index, true);
6930
7065
  }
6931
7066
  else if (typeof value === 'bigint') {
6932
- throw new TypeError('Unsupported type BigInt, please use Decimal128');
7067
+ throw new BSONTypeError('Unsupported type BigInt, please use Decimal128');
6933
7068
  }
6934
7069
  else if (typeof value === 'boolean') {
6935
7070
  index = serializeBoolean(buffer, key, value, index, true);
@@ -6991,7 +7126,7 @@ var BSON = (function (exports) {
6991
7126
  index = serializeMinMax(buffer, key, value, index, true);
6992
7127
  }
6993
7128
  else if (typeof value['_bsontype'] !== 'undefined') {
6994
- throw new TypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
7129
+ throw new BSONTypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
6995
7130
  }
6996
7131
  }
6997
7132
  }
@@ -7033,7 +7168,7 @@ var BSON = (function (exports) {
7033
7168
  index = serializeNumber(buffer, key, value, index);
7034
7169
  }
7035
7170
  else if (type === 'bigint' || isBigInt64Array(value) || isBigUInt64Array(value)) {
7036
- throw new TypeError('Unsupported type BigInt, please use Decimal128');
7171
+ throw new BSONTypeError('Unsupported type BigInt, please use Decimal128');
7037
7172
  }
7038
7173
  else if (type === 'boolean') {
7039
7174
  index = serializeBoolean(buffer, key, value, index);
@@ -7090,7 +7225,7 @@ var BSON = (function (exports) {
7090
7225
  index = serializeMinMax(buffer, key, value, index);
7091
7226
  }
7092
7227
  else if (typeof value['_bsontype'] !== 'undefined') {
7093
- throw new TypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
7228
+ throw new BSONTypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
7094
7229
  }
7095
7230
  }
7096
7231
  }
@@ -7098,10 +7233,10 @@ var BSON = (function (exports) {
7098
7233
  // Did we provide a custom serialization method
7099
7234
  if (object.toBSON) {
7100
7235
  if (typeof object.toBSON !== 'function')
7101
- throw new TypeError('toBSON is not a function');
7236
+ throw new BSONTypeError('toBSON is not a function');
7102
7237
  object = object.toBSON();
7103
7238
  if (object != null && typeof object !== 'object')
7104
- throw new TypeError('toBSON function did not return an object');
7239
+ throw new BSONTypeError('toBSON function did not return an object');
7105
7240
  }
7106
7241
  // Iterate over all the keys
7107
7242
  for (var key in object) {
@@ -7109,7 +7244,7 @@ var BSON = (function (exports) {
7109
7244
  // Is there an override value
7110
7245
  if (value && value.toBSON) {
7111
7246
  if (typeof value.toBSON !== 'function')
7112
- throw new TypeError('toBSON is not a function');
7247
+ throw new BSONTypeError('toBSON is not a function');
7113
7248
  value = value.toBSON();
7114
7249
  }
7115
7250
  // Check the type of the value
@@ -7137,7 +7272,7 @@ var BSON = (function (exports) {
7137
7272
  index = serializeNumber(buffer, key, value, index);
7138
7273
  }
7139
7274
  else if (type === 'bigint') {
7140
- throw new TypeError('Unsupported type BigInt, please use Decimal128');
7275
+ throw new BSONTypeError('Unsupported type BigInt, please use Decimal128');
7141
7276
  }
7142
7277
  else if (type === 'boolean') {
7143
7278
  index = serializeBoolean(buffer, key, value, index);
@@ -7198,7 +7333,7 @@ var BSON = (function (exports) {
7198
7333
  index = serializeMinMax(buffer, key, value, index);
7199
7334
  }
7200
7335
  else if (typeof value['_bsontype'] !== 'undefined') {
7201
- throw new TypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
7336
+ throw new BSONTypeError('Unrecognized or invalid _bsontype: ' + value['_bsontype']);
7202
7337
  }
7203
7338
  }
7204
7339
  }
@@ -7371,13 +7506,19 @@ var BSON = (function (exports) {
7371
7506
  serializeWithBufferAndIndex: serializeWithBufferAndIndex,
7372
7507
  deserialize: deserialize,
7373
7508
  calculateObjectSize: calculateObjectSize,
7374
- deserializeStream: deserializeStream
7509
+ deserializeStream: deserializeStream,
7510
+ BSONError: BSONError,
7511
+ BSONTypeError: BSONTypeError
7375
7512
  };
7376
7513
 
7514
+ exports.BSONError = BSONError;
7377
7515
  exports.BSONRegExp = BSONRegExp;
7378
7516
  exports.BSONSymbol = BSONSymbol;
7517
+ exports.BSONTypeError = BSONTypeError;
7379
7518
  exports.BSON_BINARY_SUBTYPE_BYTE_ARRAY = BSON_BINARY_SUBTYPE_BYTE_ARRAY;
7519
+ exports.BSON_BINARY_SUBTYPE_COLUMN = BSON_BINARY_SUBTYPE_COLUMN;
7380
7520
  exports.BSON_BINARY_SUBTYPE_DEFAULT = BSON_BINARY_SUBTYPE_DEFAULT;
7521
+ exports.BSON_BINARY_SUBTYPE_ENCRYPTED = BSON_BINARY_SUBTYPE_ENCRYPTED;
7381
7522
  exports.BSON_BINARY_SUBTYPE_FUNCTION = BSON_BINARY_SUBTYPE_FUNCTION;
7382
7523
  exports.BSON_BINARY_SUBTYPE_MD5 = BSON_BINARY_SUBTYPE_MD5;
7383
7524
  exports.BSON_BINARY_SUBTYPE_USER_DEFINED = BSON_BINARY_SUBTYPE_USER_DEFINED;