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