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