bson 6.1.0 → 6.3.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.
package/lib/bson.mjs CHANGED
@@ -13,6 +13,26 @@ function isMap(d) {
13
13
  function isDate(d) {
14
14
  return Object.prototype.toString.call(d) === '[object Date]';
15
15
  }
16
+ function defaultInspect(x, _options) {
17
+ return JSON.stringify(x, (k, v) => {
18
+ if (typeof v === 'bigint') {
19
+ return { $numberLong: `${v}` };
20
+ }
21
+ else if (isMap(v)) {
22
+ return Object.fromEntries(v);
23
+ }
24
+ return v;
25
+ });
26
+ }
27
+ function getStylizeFunction(options) {
28
+ const stylizeExists = options != null &&
29
+ typeof options === 'object' &&
30
+ 'stylize' in options &&
31
+ typeof options.stylize === 'function';
32
+ if (stylizeExists) {
33
+ return options.stylize;
34
+ }
35
+ }
16
36
 
17
37
  const BSON_MAJOR_VERSION = 6;
18
38
  const BSON_INT32_MAX = 0x7fffffff;
@@ -75,8 +95,8 @@ class BSONError extends Error {
75
95
  get name() {
76
96
  return 'BSONError';
77
97
  }
78
- constructor(message) {
79
- super(message);
98
+ constructor(message, options) {
99
+ super(message, options);
80
100
  }
81
101
  static isBSONError(value) {
82
102
  return (value != null &&
@@ -93,7 +113,7 @@ class BSONVersionError extends BSONError {
93
113
  return 'BSONVersionError';
94
114
  }
95
115
  constructor() {
96
- super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.0 or later`);
116
+ super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.x.x`);
97
117
  }
98
118
  }
99
119
  class BSONRuntimeError extends BSONError {
@@ -105,6 +125,79 @@ class BSONRuntimeError extends BSONError {
105
125
  }
106
126
  }
107
127
 
128
+ const FIRST_BIT = 0x80;
129
+ const FIRST_TWO_BITS = 0xc0;
130
+ const FIRST_THREE_BITS = 0xe0;
131
+ const FIRST_FOUR_BITS = 0xf0;
132
+ const FIRST_FIVE_BITS = 0xf8;
133
+ const TWO_BIT_CHAR = 0xc0;
134
+ const THREE_BIT_CHAR = 0xe0;
135
+ const FOUR_BIT_CHAR = 0xf0;
136
+ const CONTINUING_CHAR = 0x80;
137
+ function validateUtf8(bytes, start, end) {
138
+ let continuation = 0;
139
+ for (let i = start; i < end; i += 1) {
140
+ const byte = bytes[i];
141
+ if (continuation) {
142
+ if ((byte & FIRST_TWO_BITS) !== CONTINUING_CHAR) {
143
+ return false;
144
+ }
145
+ continuation -= 1;
146
+ }
147
+ else if (byte & FIRST_BIT) {
148
+ if ((byte & FIRST_THREE_BITS) === TWO_BIT_CHAR) {
149
+ continuation = 1;
150
+ }
151
+ else if ((byte & FIRST_FOUR_BITS) === THREE_BIT_CHAR) {
152
+ continuation = 2;
153
+ }
154
+ else if ((byte & FIRST_FIVE_BITS) === FOUR_BIT_CHAR) {
155
+ continuation = 3;
156
+ }
157
+ else {
158
+ return false;
159
+ }
160
+ }
161
+ }
162
+ return !continuation;
163
+ }
164
+
165
+ function tryLatin(uint8array, start, end) {
166
+ if (uint8array.length === 0) {
167
+ return '';
168
+ }
169
+ const stringByteLength = end - start;
170
+ if (stringByteLength === 0) {
171
+ return '';
172
+ }
173
+ if (stringByteLength > 20) {
174
+ return null;
175
+ }
176
+ if (stringByteLength === 1 && uint8array[start] < 128) {
177
+ return String.fromCharCode(uint8array[start]);
178
+ }
179
+ if (stringByteLength === 2 && uint8array[start] < 128 && uint8array[start + 1] < 128) {
180
+ return String.fromCharCode(uint8array[start]) + String.fromCharCode(uint8array[start + 1]);
181
+ }
182
+ if (stringByteLength === 3 &&
183
+ uint8array[start] < 128 &&
184
+ uint8array[start + 1] < 128 &&
185
+ uint8array[start + 2] < 128) {
186
+ return (String.fromCharCode(uint8array[start]) +
187
+ String.fromCharCode(uint8array[start + 1]) +
188
+ String.fromCharCode(uint8array[start + 2]));
189
+ }
190
+ const latinBytes = [];
191
+ for (let i = start; i < end; i++) {
192
+ const byte = uint8array[i];
193
+ if (byte > 127) {
194
+ return null;
195
+ }
196
+ latinBytes.push(byte);
197
+ }
198
+ return String.fromCharCode(...latinBytes);
199
+ }
200
+
108
201
  function nodejsMathRandomBytes(byteLength) {
109
202
  return nodeJsByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256)));
110
203
  }
@@ -163,8 +256,23 @@ const nodeJsByteUtils = {
163
256
  fromUTF8(text) {
164
257
  return Buffer.from(text, 'utf8');
165
258
  },
166
- toUTF8(buffer, start, end) {
167
- return nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8', start, end);
259
+ toUTF8(buffer, start, end, fatal) {
260
+ const basicLatin = end - start <= 20 ? tryLatin(buffer, start, end) : null;
261
+ if (basicLatin != null) {
262
+ return basicLatin;
263
+ }
264
+ const string = nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8', start, end);
265
+ if (fatal) {
266
+ for (let i = 0; i < string.length; i++) {
267
+ if (string.charCodeAt(i) === 0xfffd) {
268
+ if (!validateUtf8(buffer, start, end)) {
269
+ throw new BSONError('Invalid UTF-8 string in BSON document');
270
+ }
271
+ break;
272
+ }
273
+ }
274
+ }
275
+ return string;
168
276
  },
169
277
  utf8ByteLength(input) {
170
278
  return Buffer.byteLength(input, 'utf8');
@@ -274,8 +382,20 @@ const webByteUtils = {
274
382
  fromUTF8(text) {
275
383
  return new TextEncoder().encode(text);
276
384
  },
277
- toUTF8(uint8array, start, end) {
278
- return new TextDecoder('utf8', { fatal: false }).decode(uint8array.slice(start, end));
385
+ toUTF8(uint8array, start, end, fatal) {
386
+ const basicLatin = end - start <= 20 ? tryLatin(uint8array, start, end) : null;
387
+ if (basicLatin != null) {
388
+ return basicLatin;
389
+ }
390
+ if (fatal) {
391
+ try {
392
+ return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
393
+ }
394
+ catch (cause) {
395
+ throw new BSONError('Invalid UTF-8 string in BSON document', { cause });
396
+ }
397
+ }
398
+ return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
279
399
  },
280
400
  utf8ByteLength(input) {
281
401
  return webByteUtils.fromUTF8(input).byteLength;
@@ -300,6 +420,9 @@ class BSONValue {
300
420
  get [Symbol.for('@@mdb.bson.version')]() {
301
421
  return BSON_MAJOR_VERSION;
302
422
  }
423
+ [Symbol.for('nodejs.util.inspect.custom')](depth, options, inspect) {
424
+ return this.inspect(depth, options, inspect);
425
+ }
303
426
  }
304
427
 
305
428
  class Binary extends BSONValue {
@@ -393,8 +516,8 @@ class Binary extends BSONValue {
393
516
  if (encoding === 'base64')
394
517
  return ByteUtils.toBase64(this.buffer);
395
518
  if (encoding === 'utf8' || encoding === 'utf-8')
396
- return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength);
397
- return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength);
519
+ return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength, false);
520
+ return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength, false);
398
521
  }
399
522
  toExtendedJSON(options) {
400
523
  options = options || {};
@@ -450,12 +573,12 @@ class Binary extends BSONValue {
450
573
  }
451
574
  return type === BSON_BINARY_SUBTYPE_UUID_NEW ? new UUID(data) : new Binary(data, type);
452
575
  }
453
- [Symbol.for('nodejs.util.inspect.custom')]() {
454
- return this.inspect();
455
- }
456
- inspect() {
576
+ inspect(depth, options, inspect) {
577
+ inspect ??= defaultInspect;
457
578
  const base64 = ByteUtils.toBase64(this.buffer.subarray(0, this.position));
458
- return `Binary.createFromBase64("${base64}", ${this.sub_type})`;
579
+ const base64Arg = inspect(base64, options);
580
+ const subTypeArg = inspect(this.sub_type, options);
581
+ return `Binary.createFromBase64(${base64Arg}, ${subTypeArg})`;
459
582
  }
460
583
  }
461
584
  Binary.BSON_BINARY_SUBTYPE_DEFAULT = 0;
@@ -573,11 +696,9 @@ class UUID extends Binary {
573
696
  static isValidUUIDString(representation) {
574
697
  return UUID_WITHOUT_DASHES.test(representation) || UUID_WITH_DASHES.test(representation);
575
698
  }
576
- [Symbol.for('nodejs.util.inspect.custom')]() {
577
- return this.inspect();
578
- }
579
- inspect() {
580
- return `new UUID("${this.toHexString()}")`;
699
+ inspect(depth, options, inspect) {
700
+ inspect ??= defaultInspect;
701
+ return `new UUID(${inspect(this.toHexString(), options)})`;
581
702
  }
582
703
  }
583
704
 
@@ -605,12 +726,15 @@ class Code extends BSONValue {
605
726
  static fromExtendedJSON(doc) {
606
727
  return new Code(doc.$code, doc.$scope);
607
728
  }
608
- [Symbol.for('nodejs.util.inspect.custom')]() {
609
- return this.inspect();
610
- }
611
- inspect() {
612
- const codeJson = this.toJSON();
613
- return `new Code(${JSON.stringify(String(codeJson.code))}${codeJson.scope != null ? `, ${JSON.stringify(codeJson.scope)}` : ''})`;
729
+ inspect(depth, options, inspect) {
730
+ inspect ??= defaultInspect;
731
+ let parametersString = inspect(this.code, options);
732
+ const multiLineFn = parametersString.includes('\n');
733
+ if (this.scope != null) {
734
+ parametersString += `,${multiLineFn ? '\n' : ' '}${inspect(this.scope, options)}`;
735
+ }
736
+ const endingNewline = multiLineFn && this.scope === null;
737
+ return `new Code(${multiLineFn ? '\n' : ''}${parametersString}${endingNewline ? '\n' : ''})`;
614
738
  }
615
739
  }
616
740
 
@@ -675,12 +799,16 @@ class DBRef extends BSONValue {
675
799
  delete copy.$db;
676
800
  return new DBRef(doc.$ref, doc.$id, doc.$db, copy);
677
801
  }
678
- [Symbol.for('nodejs.util.inspect.custom')]() {
679
- return this.inspect();
680
- }
681
- inspect() {
682
- const oid = this.oid === undefined || this.oid.toString === undefined ? this.oid : this.oid.toString();
683
- return `new DBRef("${this.namespace}", new ObjectId("${String(oid)}")${this.db ? `, "${this.db}"` : ''})`;
802
+ inspect(depth, options, inspect) {
803
+ inspect ??= defaultInspect;
804
+ const args = [
805
+ inspect(this.namespace, options),
806
+ inspect(this.oid, options),
807
+ ...(this.db ? [inspect(this.db, options)] : []),
808
+ ...(Object.keys(this.fields).length > 0 ? [inspect(this.fields, options)] : [])
809
+ ];
810
+ args[1] = inspect === defaultInspect ? `new ObjectId(${args[1]})` : args[1];
811
+ return `new DBRef(${args.join(', ')})`;
684
812
  }
685
813
  }
686
814
 
@@ -1307,11 +1435,11 @@ class Long extends BSONValue {
1307
1435
  }
1308
1436
  return longResult;
1309
1437
  }
1310
- [Symbol.for('nodejs.util.inspect.custom')]() {
1311
- return this.inspect();
1312
- }
1313
- inspect() {
1314
- return `new Long("${this.toString()}"${this.unsigned ? ', true' : ''})`;
1438
+ inspect(depth, options, inspect) {
1439
+ inspect ??= defaultInspect;
1440
+ const longVal = inspect(this.toString(), options);
1441
+ const unsignedVal = this.unsigned ? `, ${inspect(this.unsigned, options)}` : '';
1442
+ return `new Long(${longVal}${unsignedVal})`;
1315
1443
  }
1316
1444
  }
1317
1445
  Long.TWO_PWR_24 = Long.fromInt(TWO_PWR_24_DBL);
@@ -1867,11 +1995,10 @@ class Decimal128 extends BSONValue {
1867
1995
  static fromExtendedJSON(doc) {
1868
1996
  return Decimal128.fromString(doc.$numberDecimal);
1869
1997
  }
1870
- [Symbol.for('nodejs.util.inspect.custom')]() {
1871
- return this.inspect();
1872
- }
1873
- inspect() {
1874
- return `new Decimal128("${this.toString()}")`;
1998
+ inspect(depth, options, inspect) {
1999
+ inspect ??= defaultInspect;
2000
+ const d128string = inspect(this.toString(), options);
2001
+ return `new Decimal128(${d128string})`;
1875
2002
  }
1876
2003
  }
1877
2004
 
@@ -1910,12 +2037,9 @@ class Double extends BSONValue {
1910
2037
  const doubleValue = parseFloat(doc.$numberDouble);
1911
2038
  return options && options.relaxed ? doubleValue : new Double(doubleValue);
1912
2039
  }
1913
- [Symbol.for('nodejs.util.inspect.custom')]() {
1914
- return this.inspect();
1915
- }
1916
- inspect() {
1917
- const eJSON = this.toExtendedJSON();
1918
- return `new Double(${eJSON.$numberDouble})`;
2040
+ inspect(depth, options, inspect) {
2041
+ inspect ??= defaultInspect;
2042
+ return `new Double(${inspect(this.value, options)})`;
1919
2043
  }
1920
2044
  }
1921
2045
 
@@ -1947,11 +2071,9 @@ class Int32 extends BSONValue {
1947
2071
  static fromExtendedJSON(doc, options) {
1948
2072
  return options && options.relaxed ? parseInt(doc.$numberInt, 10) : new Int32(doc.$numberInt);
1949
2073
  }
1950
- [Symbol.for('nodejs.util.inspect.custom')]() {
1951
- return this.inspect();
1952
- }
1953
- inspect() {
1954
- return `new Int32(${this.valueOf()})`;
2074
+ inspect(depth, options, inspect) {
2075
+ inspect ??= defaultInspect;
2076
+ return `new Int32(${inspect(this.value, options)})`;
1955
2077
  }
1956
2078
  }
1957
2079
 
@@ -1965,9 +2087,6 @@ class MaxKey extends BSONValue {
1965
2087
  static fromExtendedJSON() {
1966
2088
  return new MaxKey();
1967
2089
  }
1968
- [Symbol.for('nodejs.util.inspect.custom')]() {
1969
- return this.inspect();
1970
- }
1971
2090
  inspect() {
1972
2091
  return 'new MaxKey()';
1973
2092
  }
@@ -1983,9 +2102,6 @@ class MinKey extends BSONValue {
1983
2102
  static fromExtendedJSON() {
1984
2103
  return new MinKey();
1985
2104
  }
1986
- [Symbol.for('nodejs.util.inspect.custom')]() {
1987
- return this.inspect();
1988
- }
1989
2105
  inspect() {
1990
2106
  return 'new MinKey()';
1991
2107
  }
@@ -2156,11 +2272,9 @@ class ObjectId extends BSONValue {
2156
2272
  static fromExtendedJSON(doc) {
2157
2273
  return new ObjectId(doc.$oid);
2158
2274
  }
2159
- [Symbol.for('nodejs.util.inspect.custom')]() {
2160
- return this.inspect();
2161
- }
2162
- inspect() {
2163
- return `new ObjectId("${this.toHexString()}")`;
2275
+ inspect(depth, options, inspect) {
2276
+ inspect ??= defaultInspect;
2277
+ return `new ObjectId(${inspect(this.toHexString(), options)})`;
2164
2278
  }
2165
2279
  }
2166
2280
  ObjectId.index = Math.floor(Math.random() * 0xffffff);
@@ -2373,11 +2487,12 @@ class BSONRegExp extends BSONValue {
2373
2487
  }
2374
2488
  throw new BSONError(`Unexpected BSONRegExp EJSON object form: ${JSON.stringify(doc)}`);
2375
2489
  }
2376
- [Symbol.for('nodejs.util.inspect.custom')]() {
2377
- return this.inspect();
2378
- }
2379
- inspect() {
2380
- return `new BSONRegExp(${JSON.stringify(this.pattern)}, ${JSON.stringify(this.options)})`;
2490
+ inspect(depth, options, inspect) {
2491
+ const stylize = getStylizeFunction(options) ?? (v => v);
2492
+ inspect ??= defaultInspect;
2493
+ const pattern = stylize(inspect(this.pattern), 'regexp');
2494
+ const flags = stylize(inspect(this.options), 'regexp');
2495
+ return `new BSONRegExp(${pattern}, ${flags})`;
2381
2496
  }
2382
2497
  }
2383
2498
 
@@ -2395,9 +2510,6 @@ class BSONSymbol extends BSONValue {
2395
2510
  toString() {
2396
2511
  return this.value;
2397
2512
  }
2398
- inspect() {
2399
- return `new BSONSymbol(${JSON.stringify(this.value)})`;
2400
- }
2401
2513
  toJSON() {
2402
2514
  return this.value;
2403
2515
  }
@@ -2407,8 +2519,9 @@ class BSONSymbol extends BSONValue {
2407
2519
  static fromExtendedJSON(doc) {
2408
2520
  return new BSONSymbol(doc.$symbol);
2409
2521
  }
2410
- [Symbol.for('nodejs.util.inspect.custom')]() {
2411
- return this.inspect();
2522
+ inspect(depth, options, inspect) {
2523
+ inspect ??= defaultInspect;
2524
+ return `new BSONSymbol(${inspect(this.value, options)})`;
2412
2525
  }
2413
2526
  }
2414
2527
 
@@ -2483,52 +2596,15 @@ class Timestamp extends LongWithoutOverridesClass {
2483
2596
  : doc.$timestamp.t;
2484
2597
  return new Timestamp({ t, i });
2485
2598
  }
2486
- [Symbol.for('nodejs.util.inspect.custom')]() {
2487
- return this.inspect();
2488
- }
2489
- inspect() {
2490
- return `new Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`;
2599
+ inspect(depth, options, inspect) {
2600
+ inspect ??= defaultInspect;
2601
+ const t = inspect(this.high >>> 0, options);
2602
+ const i = inspect(this.low >>> 0, options);
2603
+ return `new Timestamp({ t: ${t}, i: ${i} })`;
2491
2604
  }
2492
2605
  }
2493
2606
  Timestamp.MAX_VALUE = Long.MAX_UNSIGNED_VALUE;
2494
2607
 
2495
- const FIRST_BIT = 0x80;
2496
- const FIRST_TWO_BITS = 0xc0;
2497
- const FIRST_THREE_BITS = 0xe0;
2498
- const FIRST_FOUR_BITS = 0xf0;
2499
- const FIRST_FIVE_BITS = 0xf8;
2500
- const TWO_BIT_CHAR = 0xc0;
2501
- const THREE_BIT_CHAR = 0xe0;
2502
- const FOUR_BIT_CHAR = 0xf0;
2503
- const CONTINUING_CHAR = 0x80;
2504
- function validateUtf8(bytes, start, end) {
2505
- let continuation = 0;
2506
- for (let i = start; i < end; i += 1) {
2507
- const byte = bytes[i];
2508
- if (continuation) {
2509
- if ((byte & FIRST_TWO_BITS) !== CONTINUING_CHAR) {
2510
- return false;
2511
- }
2512
- continuation -= 1;
2513
- }
2514
- else if (byte & FIRST_BIT) {
2515
- if ((byte & FIRST_THREE_BITS) === TWO_BIT_CHAR) {
2516
- continuation = 1;
2517
- }
2518
- else if ((byte & FIRST_FOUR_BITS) === THREE_BIT_CHAR) {
2519
- continuation = 2;
2520
- }
2521
- else if ((byte & FIRST_FIVE_BITS) === FOUR_BIT_CHAR) {
2522
- continuation = 3;
2523
- }
2524
- else {
2525
- return false;
2526
- }
2527
- }
2528
- }
2529
- return !continuation;
2530
- }
2531
-
2532
2608
  const JS_INT_MAX_LONG = Long.fromNumber(JS_INT_MAX);
2533
2609
  const JS_INT_MIN_LONG = Long.fromNumber(JS_INT_MIN);
2534
2610
  function internalDeserialize(buffer, options, isArray) {
@@ -2620,7 +2696,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2620
2696
  }
2621
2697
  if (i >= buffer.byteLength)
2622
2698
  throw new BSONError('Bad BSON Document: illegal CString');
2623
- const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i);
2699
+ const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i, false);
2624
2700
  let shouldValidateKey = true;
2625
2701
  if (globalUTFValidation || utf8KeysSet.has(name)) {
2626
2702
  shouldValidateKey = validationSetting;
@@ -2643,7 +2719,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2643
2719
  buffer[index + stringSize - 1] !== 0) {
2644
2720
  throw new BSONError('bad string length in bson');
2645
2721
  }
2646
- value = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
2722
+ value = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
2647
2723
  index = index + stringSize;
2648
2724
  }
2649
2725
  else if (elementType === BSON_DATA_OID) {
@@ -2835,7 +2911,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2835
2911
  }
2836
2912
  if (i >= buffer.length)
2837
2913
  throw new BSONError('Bad BSON Document: illegal CString');
2838
- const source = ByteUtils.toUTF8(buffer, index, i);
2914
+ const source = ByteUtils.toUTF8(buffer, index, i, false);
2839
2915
  index = i + 1;
2840
2916
  i = index;
2841
2917
  while (buffer[i] !== 0x00 && i < buffer.length) {
@@ -2843,7 +2919,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2843
2919
  }
2844
2920
  if (i >= buffer.length)
2845
2921
  throw new BSONError('Bad BSON Document: illegal CString');
2846
- const regExpOptions = ByteUtils.toUTF8(buffer, index, i);
2922
+ const regExpOptions = ByteUtils.toUTF8(buffer, index, i, false);
2847
2923
  index = i + 1;
2848
2924
  const optionsArray = new Array(regExpOptions.length);
2849
2925
  for (i = 0; i < regExpOptions.length; i++) {
@@ -2868,7 +2944,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2868
2944
  }
2869
2945
  if (i >= buffer.length)
2870
2946
  throw new BSONError('Bad BSON Document: illegal CString');
2871
- const source = ByteUtils.toUTF8(buffer, index, i);
2947
+ const source = ByteUtils.toUTF8(buffer, index, i, false);
2872
2948
  index = i + 1;
2873
2949
  i = index;
2874
2950
  while (buffer[i] !== 0x00 && i < buffer.length) {
@@ -2876,7 +2952,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2876
2952
  }
2877
2953
  if (i >= buffer.length)
2878
2954
  throw new BSONError('Bad BSON Document: illegal CString');
2879
- const regExpOptions = ByteUtils.toUTF8(buffer, index, i);
2955
+ const regExpOptions = ByteUtils.toUTF8(buffer, index, i, false);
2880
2956
  index = i + 1;
2881
2957
  value = new BSONRegExp(source, regExpOptions);
2882
2958
  }
@@ -2890,7 +2966,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2890
2966
  buffer[index + stringSize - 1] !== 0) {
2891
2967
  throw new BSONError('bad string length in bson');
2892
2968
  }
2893
- const symbol = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
2969
+ const symbol = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
2894
2970
  value = promoteValues ? symbol : new BSONSymbol(symbol);
2895
2971
  index = index + stringSize;
2896
2972
  }
@@ -2921,7 +2997,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2921
2997
  buffer[index + stringSize - 1] !== 0) {
2922
2998
  throw new BSONError('bad string length in bson');
2923
2999
  }
2924
- const functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
3000
+ const functionString = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
2925
3001
  value = new Code(functionString);
2926
3002
  index = index + stringSize;
2927
3003
  }
@@ -2942,7 +3018,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2942
3018
  buffer[index + stringSize - 1] !== 0) {
2943
3019
  throw new BSONError('bad string length in bson');
2944
3020
  }
2945
- const functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
3021
+ const functionString = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
2946
3022
  index = index + stringSize;
2947
3023
  const _index = index;
2948
3024
  const objectSize = buffer[index] |
@@ -2973,7 +3049,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2973
3049
  throw new BSONError('Invalid UTF-8 string in BSON document');
2974
3050
  }
2975
3051
  }
2976
- const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1);
3052
+ const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, false);
2977
3053
  index = index + stringSize;
2978
3054
  const oidBuffer = ByteUtils.allocate(12);
2979
3055
  oidBuffer.set(buffer.subarray(index, index + 12), 0);
@@ -3012,20 +3088,6 @@ function deserializeObject(buffer, index, options, isArray = false) {
3012
3088
  }
3013
3089
  return object;
3014
3090
  }
3015
- function getValidatedString(buffer, start, end, shouldValidateUtf8) {
3016
- const value = ByteUtils.toUTF8(buffer, start, end);
3017
- if (shouldValidateUtf8) {
3018
- for (let i = 0; i < value.length; i++) {
3019
- if (value.charCodeAt(i) === 0xfffd) {
3020
- if (!validateUtf8(buffer, start, end)) {
3021
- throw new BSONError('Invalid UTF-8 string in BSON document');
3022
- }
3023
- break;
3024
- }
3025
- }
3026
- }
3027
- return value;
3028
- }
3029
3091
 
3030
3092
  const regexp = /\x00/;
3031
3093
  const ignoreKeys = new Set(['$db', '$ref', '$id', '$clusterTime']);