bson 6.6.0 → 6.8.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/README.md +27 -0
- package/bson.d.ts +148 -7
- package/lib/bson.bundle.js +134 -74
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +134 -74
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +134 -74
- package/lib/bson.mjs.map +1 -1
- package/lib/bson.rn.cjs +136 -75
- package/lib/bson.rn.cjs.map +1 -1
- package/package.json +14 -15
- package/src/constants.ts +1 -1
- package/src/double.ts +36 -0
- package/src/int_32.ts +34 -0
- package/src/long.ts +211 -31
- package/src/parse_utf8.ts +35 -0
- package/src/parser/deserializer.ts +1 -7
- package/src/utils/node_byte_utils.ts +2 -5
- package/src/utils/string_utils.ts +44 -0
- package/src/utils/web_byte_utils.ts +2 -8
- package/src/validate_utf8.ts +0 -47
package/README.md
CHANGED
|
@@ -11,6 +11,33 @@ You can learn more about it in [the specification](http://bsonspec.org).
|
|
|
11
11
|
- [Documentation](#documentation)
|
|
12
12
|
- [FAQ](#faq)
|
|
13
13
|
|
|
14
|
+
|
|
15
|
+
### Release Integrity
|
|
16
|
+
|
|
17
|
+
Releases are created automatically and signed using the [Node team's GPG key](https://pgp.mongodb.com/node-driver.asc). This applies to the git tag as well as all release packages provided as part of a GitHub release. To verify the provided packages, download the key and import it using gpg:
|
|
18
|
+
|
|
19
|
+
```shell
|
|
20
|
+
gpg --import node-driver.asc
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The GitHub release contains a detached signature file for the NPM package (named
|
|
24
|
+
`bson-X.Y.Z.tgz.sig`).
|
|
25
|
+
|
|
26
|
+
The following command returns the link npm package.
|
|
27
|
+
```shell
|
|
28
|
+
npm view bson@vX.Y.Z dist.tarball
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Using the result of the above command, a `curl` command can return the official npm package for the release.
|
|
32
|
+
|
|
33
|
+
To verify the integrity of the downloaded package, run the following command:
|
|
34
|
+
```shell
|
|
35
|
+
gpg --verify bson-X.Y.Z.tgz.sig bson-X.Y.Z.tgz
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
>[!Note]
|
|
39
|
+
No verification is done when using npm to install the package. The contents of the Github tarball and npm's tarball are identical.
|
|
40
|
+
|
|
14
41
|
## Bugs / Feature Requests
|
|
15
42
|
|
|
16
43
|
Think you've found a bug? Want to see a new feature in `bson`? Please open a case in our issue management tool, JIRA:
|
package/bson.d.ts
CHANGED
|
@@ -601,6 +601,20 @@ export declare class Double extends BSONValue {
|
|
|
601
601
|
* @param value - the number we want to represent as a double.
|
|
602
602
|
*/
|
|
603
603
|
constructor(value: number);
|
|
604
|
+
/**
|
|
605
|
+
* Attempt to create an double type from string.
|
|
606
|
+
*
|
|
607
|
+
* This method will throw a BSONError on any string input that is not representable as a IEEE-754 64-bit double.
|
|
608
|
+
* Notably, this method will also throw on the following string formats:
|
|
609
|
+
* - Strings in non-decimal and non-exponential formats (binary, hex, or octal digits)
|
|
610
|
+
* - Strings with characters other than numeric, floating point, or leading sign characters (Note: 'Infinity', '-Infinity', and 'NaN' input strings are still allowed)
|
|
611
|
+
* - Strings with leading and/or trailing whitespace
|
|
612
|
+
*
|
|
613
|
+
* Strings with leading zeros, however, are also allowed
|
|
614
|
+
*
|
|
615
|
+
* @param value - the string we want to represent as a double.
|
|
616
|
+
*/
|
|
617
|
+
static fromString(value: string): Double;
|
|
604
618
|
/**
|
|
605
619
|
* Access the number value.
|
|
606
620
|
*
|
|
@@ -677,6 +691,20 @@ export declare class Int32 extends BSONValue {
|
|
|
677
691
|
* @param value - the number we want to represent as an int32.
|
|
678
692
|
*/
|
|
679
693
|
constructor(value: number | string);
|
|
694
|
+
/**
|
|
695
|
+
* Attempt to create an Int32 type from string.
|
|
696
|
+
*
|
|
697
|
+
* This method will throw a BSONError on any string input that is not representable as an Int32.
|
|
698
|
+
* Notably, this method will also throw on the following string formats:
|
|
699
|
+
* - Strings in non-decimal formats (exponent notation, binary, hex, or octal digits)
|
|
700
|
+
* - Strings non-numeric and non-leading sign characters (ex: '2.0', '24,000')
|
|
701
|
+
* - Strings with leading and/or trailing whitespace
|
|
702
|
+
*
|
|
703
|
+
* Strings with leading zeros, however, are allowed.
|
|
704
|
+
*
|
|
705
|
+
* @param value - the string we want to represent as an int32.
|
|
706
|
+
*/
|
|
707
|
+
static fromString(value: string): Int32;
|
|
680
708
|
/**
|
|
681
709
|
* Access the number value.
|
|
682
710
|
*
|
|
@@ -732,18 +760,26 @@ export declare class Long extends BSONValue {
|
|
|
732
760
|
unsigned: boolean;
|
|
733
761
|
/**
|
|
734
762
|
* Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
|
|
735
|
-
* See the from* functions below for more convenient ways of constructing Longs.
|
|
736
|
-
*
|
|
737
|
-
* Acceptable signatures are:
|
|
738
|
-
* - Long(low, high, unsigned?)
|
|
739
|
-
* - Long(bigint, unsigned?)
|
|
740
|
-
* - Long(string, unsigned?)
|
|
741
763
|
*
|
|
742
764
|
* @param low - The low (signed) 32 bits of the long
|
|
743
765
|
* @param high - The high (signed) 32 bits of the long
|
|
744
766
|
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
745
767
|
*/
|
|
746
|
-
constructor(low
|
|
768
|
+
constructor(low: number, high?: number, unsigned?: boolean);
|
|
769
|
+
/**
|
|
770
|
+
* Constructs a 64 bit two's-complement integer, given a bigint representation.
|
|
771
|
+
*
|
|
772
|
+
* @param value - BigInt representation of the long value
|
|
773
|
+
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
774
|
+
*/
|
|
775
|
+
constructor(value: bigint, unsigned?: boolean);
|
|
776
|
+
/**
|
|
777
|
+
* Constructs a 64 bit two's-complement integer, given a string representation.
|
|
778
|
+
*
|
|
779
|
+
* @param value - String representation of the long value
|
|
780
|
+
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
781
|
+
*/
|
|
782
|
+
constructor(value: string, unsigned?: boolean);
|
|
747
783
|
static TWO_PWR_24: Long;
|
|
748
784
|
/** Maximum unsigned value. */
|
|
749
785
|
static MAX_UNSIGNED_VALUE: Long;
|
|
@@ -791,8 +827,113 @@ export declare class Long extends BSONValue {
|
|
|
791
827
|
* @returns The corresponding Long value
|
|
792
828
|
*/
|
|
793
829
|
static fromBigInt(value: bigint, unsigned?: boolean): Long;
|
|
830
|
+
/* Excluded from this release type: _fromString */
|
|
831
|
+
/**
|
|
832
|
+
* Returns a signed Long representation of the given string, written using radix 10.
|
|
833
|
+
* Will throw an error if the given text is not exactly representable as a Long.
|
|
834
|
+
* Throws an error if any of the following conditions are true:
|
|
835
|
+
* - the string contains invalid characters for the radix 10
|
|
836
|
+
* - the string contains whitespace
|
|
837
|
+
* - the value the string represents is too large or too small to be a Long
|
|
838
|
+
* Unlike Long.fromString, this method does not coerce '+/-Infinity' and 'NaN' to Long.Zero
|
|
839
|
+
* @param str - The textual representation of the Long
|
|
840
|
+
* @returns The corresponding Long value
|
|
841
|
+
*/
|
|
842
|
+
static fromStringStrict(str: string): Long;
|
|
843
|
+
/**
|
|
844
|
+
* Returns a Long representation of the given string, written using the radix 10.
|
|
845
|
+
* Will throw an error if the given parameters are not exactly representable as a Long.
|
|
846
|
+
* Throws an error if any of the following conditions are true:
|
|
847
|
+
* - the string contains invalid characters for the given radix
|
|
848
|
+
* - the string contains whitespace
|
|
849
|
+
* - the value the string represents is too large or too small to be a Long
|
|
850
|
+
* Unlike Long.fromString, this method does not coerce '+/-Infinity' and 'NaN' to Long.Zero
|
|
851
|
+
* @param str - The textual representation of the Long
|
|
852
|
+
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
853
|
+
* @returns The corresponding Long value
|
|
854
|
+
*/
|
|
855
|
+
static fromStringStrict(str: string, unsigned?: boolean): Long;
|
|
856
|
+
/**
|
|
857
|
+
* Returns a signed Long representation of the given string, written using the specified radix.
|
|
858
|
+
* Will throw an error if the given parameters are not exactly representable as a Long.
|
|
859
|
+
* Throws an error if any of the following conditions are true:
|
|
860
|
+
* - the string contains invalid characters for the given radix
|
|
861
|
+
* - the string contains whitespace
|
|
862
|
+
* - the value the string represents is too large or too small to be a Long
|
|
863
|
+
* Unlike Long.fromString, this method does not coerce '+/-Infinity' and 'NaN' to Long.Zero
|
|
864
|
+
* @param str - The textual representation of the Long
|
|
865
|
+
* @param radix - The radix in which the text is written (2-36), defaults to 10
|
|
866
|
+
* @returns The corresponding Long value
|
|
867
|
+
*/
|
|
868
|
+
static fromStringStrict(str: string, radix?: boolean): Long;
|
|
794
869
|
/**
|
|
795
870
|
* Returns a Long representation of the given string, written using the specified radix.
|
|
871
|
+
* Will throw an error if the given parameters are not exactly representable as a Long.
|
|
872
|
+
* Throws an error if any of the following conditions are true:
|
|
873
|
+
* - the string contains invalid characters for the given radix
|
|
874
|
+
* - the string contains whitespace
|
|
875
|
+
* - the value the string represents is too large or too small to be a Long
|
|
876
|
+
* Unlike Long.fromString, this method does not coerce '+/-Infinity' and 'NaN' to Long.Zero
|
|
877
|
+
* @param str - The textual representation of the Long
|
|
878
|
+
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
879
|
+
* @param radix - The radix in which the text is written (2-36), defaults to 10
|
|
880
|
+
* @returns The corresponding Long value
|
|
881
|
+
*/
|
|
882
|
+
static fromStringStrict(str: string, unsigned?: boolean, radix?: number): Long;
|
|
883
|
+
/**
|
|
884
|
+
* Returns a signed Long representation of the given string, written using radix 10.
|
|
885
|
+
*
|
|
886
|
+
* If the input string is empty, this function will throw a BSONError.
|
|
887
|
+
*
|
|
888
|
+
* If input string does not have valid signed 64-bit Long representation, this method will return a coerced value:
|
|
889
|
+
* - inputs that overflow 64-bit signed long will be coerced to Long.MAX_VALUE and Long.MIN_VALUE respectively
|
|
890
|
+
* - 'NaN' or '+/-Infinity' are coerced to Long.ZERO
|
|
891
|
+
* - other invalid characters sequences have variable behavior
|
|
892
|
+
*
|
|
893
|
+
* @param str - The textual representation of the Long
|
|
894
|
+
* @returns The corresponding Long value
|
|
895
|
+
*/
|
|
896
|
+
static fromString(str: string): Long;
|
|
897
|
+
/**
|
|
898
|
+
* Returns a signed Long representation of the given string, written using the provided radix.
|
|
899
|
+
*
|
|
900
|
+
* If the input string is empty or a provided radix is not within (2-36), this function will throw a BSONError.
|
|
901
|
+
*
|
|
902
|
+
* If input parameters do not have valid signed 64-bit Long representation, this method will return a coerced value:
|
|
903
|
+
* - inputs that overflow 64-bit signed long will be coerced to Long.MAX_VALUE and Long.MIN_VALUE respectively
|
|
904
|
+
* - if the radix is less than 24, 'NaN' is coerced to Long.ZERO
|
|
905
|
+
* - if the radix is less than 35, '+/-Infinity' inputs are coerced to Long.ZERO
|
|
906
|
+
* - other invalid characters sequences have variable behavior
|
|
907
|
+
* @param str - The textual representation of the Long
|
|
908
|
+
* @param radix - The radix in which the text is written (2-36), defaults to 10
|
|
909
|
+
* @returns The corresponding Long value
|
|
910
|
+
*/
|
|
911
|
+
static fromString(str: string, radix?: number): Long;
|
|
912
|
+
/**
|
|
913
|
+
* Returns a Long representation of the given string, written using radix 10.
|
|
914
|
+
*
|
|
915
|
+
* If the input string is empty, this function will throw a BSONError.
|
|
916
|
+
*
|
|
917
|
+
* If input parameters do not have a valid 64-bit Long representation, this method will return a coerced value:
|
|
918
|
+
* - inputs that overflow 64-bit long will be coerced to max or min (if signed) values
|
|
919
|
+
* - if the radix is less than 24, 'NaN' is coerced to Long.ZERO
|
|
920
|
+
* - if the radix is less than 35, '+/-Infinity' inputs are coerced to Long.ZERO
|
|
921
|
+
* - other invalid characters sequences have variable behavior
|
|
922
|
+
* @param str - The textual representation of the Long
|
|
923
|
+
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
924
|
+
* @returns The corresponding Long value
|
|
925
|
+
*/
|
|
926
|
+
static fromString(str: string, unsigned?: boolean): Long;
|
|
927
|
+
/**
|
|
928
|
+
* Returns a Long representation of the given string, written using the specified radix.
|
|
929
|
+
*
|
|
930
|
+
* If the input string is empty or a provided radix is not within (2-36), this function will throw a BSONError.
|
|
931
|
+
*
|
|
932
|
+
* If input parameters do not have a valid 64-bit Long representation, this method will return a coerced value:
|
|
933
|
+
* - inputs that overflow 64-bit long will be coerced to max or min (if signed) values
|
|
934
|
+
* - if the radix is less than 24, 'NaN' is coerced to Long.ZERO
|
|
935
|
+
* - if the radix is less than 35, '+/-Infinity' inputs are coerced to Long.ZERO
|
|
936
|
+
* - other invalid characters sequences have variable behavior
|
|
796
937
|
* @param str - The textual representation of the Long
|
|
797
938
|
* @param unsigned - Whether unsigned or not, defaults to signed
|
|
798
939
|
* @param radix - The radix in which the text is written (2-36), defaults to 10
|
package/lib/bson.bundle.js
CHANGED
|
@@ -137,41 +137,20 @@ class BSONOffsetError extends BSONError {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const FOUR_BIT_CHAR = 0xf0;
|
|
148
|
-
const CONTINUING_CHAR = 0x80;
|
|
149
|
-
function validateUtf8(bytes, start, end) {
|
|
150
|
-
let continuation = 0;
|
|
151
|
-
for (let i = start; i < end; i += 1) {
|
|
152
|
-
const byte = bytes[i];
|
|
153
|
-
if (continuation) {
|
|
154
|
-
if ((byte & FIRST_TWO_BITS) !== CONTINUING_CHAR) {
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
continuation -= 1;
|
|
140
|
+
let TextDecoderFatal;
|
|
141
|
+
let TextDecoderNonFatal;
|
|
142
|
+
function parseUtf8(buffer, start, end, fatal) {
|
|
143
|
+
if (fatal) {
|
|
144
|
+
TextDecoderFatal ??= new TextDecoder('utf8', { fatal: true });
|
|
145
|
+
try {
|
|
146
|
+
return TextDecoderFatal.decode(buffer.subarray(start, end));
|
|
158
147
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
continuation = 1;
|
|
162
|
-
}
|
|
163
|
-
else if ((byte & FIRST_FOUR_BITS) === THREE_BIT_CHAR) {
|
|
164
|
-
continuation = 2;
|
|
165
|
-
}
|
|
166
|
-
else if ((byte & FIRST_FIVE_BITS) === FOUR_BIT_CHAR) {
|
|
167
|
-
continuation = 3;
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
148
|
+
catch (cause) {
|
|
149
|
+
throw new BSONError('Invalid UTF-8 string in BSON document', { cause });
|
|
172
150
|
}
|
|
173
151
|
}
|
|
174
|
-
|
|
152
|
+
TextDecoderNonFatal ??= new TextDecoder('utf8', { fatal: false });
|
|
153
|
+
return TextDecoderNonFatal.decode(buffer.subarray(start, end));
|
|
175
154
|
}
|
|
176
155
|
|
|
177
156
|
function tryReadBasicLatin(uint8array, start, end) {
|
|
@@ -292,9 +271,7 @@ const nodeJsByteUtils = {
|
|
|
292
271
|
if (fatal) {
|
|
293
272
|
for (let i = 0; i < string.length; i++) {
|
|
294
273
|
if (string.charCodeAt(i) === 0xfffd) {
|
|
295
|
-
|
|
296
|
-
throw new BSONError('Invalid UTF-8 string in BSON document');
|
|
297
|
-
}
|
|
274
|
+
parseUtf8(buffer, start, end, true);
|
|
298
275
|
break;
|
|
299
276
|
}
|
|
300
277
|
}
|
|
@@ -418,15 +395,7 @@ const webByteUtils = {
|
|
|
418
395
|
if (basicLatin != null) {
|
|
419
396
|
return basicLatin;
|
|
420
397
|
}
|
|
421
|
-
|
|
422
|
-
try {
|
|
423
|
-
return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
|
|
424
|
-
}
|
|
425
|
-
catch (cause) {
|
|
426
|
-
throw new BSONError('Invalid UTF-8 string in BSON document', { cause });
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
|
|
398
|
+
return parseUtf8(uint8array, start, end, fatal);
|
|
430
399
|
},
|
|
431
400
|
utf8ByteLength(input) {
|
|
432
401
|
return new TextEncoder().encode(input).byteLength;
|
|
@@ -839,6 +808,32 @@ class DBRef extends BSONValue {
|
|
|
839
808
|
}
|
|
840
809
|
}
|
|
841
810
|
|
|
811
|
+
function removeLeadingZerosAndExplicitPlus(str) {
|
|
812
|
+
if (str === '') {
|
|
813
|
+
return str;
|
|
814
|
+
}
|
|
815
|
+
let startIndex = 0;
|
|
816
|
+
const isNegative = str[startIndex] === '-';
|
|
817
|
+
const isExplicitlyPositive = str[startIndex] === '+';
|
|
818
|
+
if (isExplicitlyPositive || isNegative) {
|
|
819
|
+
startIndex += 1;
|
|
820
|
+
}
|
|
821
|
+
let foundInsignificantZero = false;
|
|
822
|
+
for (; startIndex < str.length && str[startIndex] === '0'; ++startIndex) {
|
|
823
|
+
foundInsignificantZero = true;
|
|
824
|
+
}
|
|
825
|
+
if (!foundInsignificantZero) {
|
|
826
|
+
return isExplicitlyPositive ? str.slice(1) : str;
|
|
827
|
+
}
|
|
828
|
+
return `${isNegative ? '-' : ''}${str.length === startIndex ? '0' : str.slice(startIndex)}`;
|
|
829
|
+
}
|
|
830
|
+
function validateStringCharacters(str, radix) {
|
|
831
|
+
radix = radix ?? 10;
|
|
832
|
+
const validCharacters = '0123456789abcdefghijklmnopqrstuvwxyz'.slice(0, radix);
|
|
833
|
+
const regex = new RegExp(`[^-+${validCharacters}]`, 'i');
|
|
834
|
+
return regex.test(str) ? false : str;
|
|
835
|
+
}
|
|
836
|
+
|
|
842
837
|
let wasm = undefined;
|
|
843
838
|
try {
|
|
844
839
|
wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11])), {}).exports;
|
|
@@ -861,19 +856,18 @@ class Long extends BSONValue {
|
|
|
861
856
|
get __isLong__() {
|
|
862
857
|
return true;
|
|
863
858
|
}
|
|
864
|
-
constructor(
|
|
859
|
+
constructor(lowOrValue = 0, highOrUnsigned, unsigned) {
|
|
865
860
|
super();
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
}
|
|
861
|
+
const unsignedBool = typeof highOrUnsigned === 'boolean' ? highOrUnsigned : Boolean(unsigned);
|
|
862
|
+
const high = typeof highOrUnsigned === 'number' ? highOrUnsigned : 0;
|
|
863
|
+
const res = typeof lowOrValue === 'string'
|
|
864
|
+
? Long.fromString(lowOrValue, unsignedBool)
|
|
865
|
+
: typeof lowOrValue === 'bigint'
|
|
866
|
+
? Long.fromBigInt(lowOrValue, unsignedBool)
|
|
867
|
+
: { low: lowOrValue | 0, high: high | 0, unsigned: unsignedBool };
|
|
868
|
+
this.low = res.low;
|
|
869
|
+
this.high = res.high;
|
|
870
|
+
this.unsigned = res.unsigned;
|
|
877
871
|
}
|
|
878
872
|
static fromBits(lowBits, highBits, unsigned) {
|
|
879
873
|
return new Long(lowBits, highBits, unsigned);
|
|
@@ -925,27 +919,20 @@ class Long extends BSONValue {
|
|
|
925
919
|
return Long.fromBits(value % TWO_PWR_32_DBL | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
|
|
926
920
|
}
|
|
927
921
|
static fromBigInt(value, unsigned) {
|
|
928
|
-
|
|
922
|
+
const FROM_BIGINT_BIT_MASK = BigInt(0xffffffff);
|
|
923
|
+
const FROM_BIGINT_BIT_SHIFT = BigInt(32);
|
|
924
|
+
return new Long(Number(value & FROM_BIGINT_BIT_MASK), Number((value >> FROM_BIGINT_BIT_SHIFT) & FROM_BIGINT_BIT_MASK), unsigned);
|
|
929
925
|
}
|
|
930
|
-
static
|
|
926
|
+
static _fromString(str, unsigned, radix) {
|
|
931
927
|
if (str.length === 0)
|
|
932
928
|
throw new BSONError('empty string');
|
|
933
|
-
if (str === 'NaN' || str === 'Infinity' || str === '+Infinity' || str === '-Infinity')
|
|
934
|
-
return Long.ZERO;
|
|
935
|
-
if (typeof unsigned === 'number') {
|
|
936
|
-
(radix = unsigned), (unsigned = false);
|
|
937
|
-
}
|
|
938
|
-
else {
|
|
939
|
-
unsigned = !!unsigned;
|
|
940
|
-
}
|
|
941
|
-
radix = radix || 10;
|
|
942
929
|
if (radix < 2 || 36 < radix)
|
|
943
930
|
throw new BSONError('radix');
|
|
944
931
|
let p;
|
|
945
932
|
if ((p = str.indexOf('-')) > 0)
|
|
946
933
|
throw new BSONError('interior hyphen');
|
|
947
934
|
else if (p === 0) {
|
|
948
|
-
return Long.
|
|
935
|
+
return Long._fromString(str.substring(1), unsigned, radix).neg();
|
|
949
936
|
}
|
|
950
937
|
const radixToPower = Long.fromNumber(Math.pow(radix, 8));
|
|
951
938
|
let result = Long.ZERO;
|
|
@@ -963,6 +950,45 @@ class Long extends BSONValue {
|
|
|
963
950
|
result.unsigned = unsigned;
|
|
964
951
|
return result;
|
|
965
952
|
}
|
|
953
|
+
static fromStringStrict(str, unsignedOrRadix, radix) {
|
|
954
|
+
let unsigned = false;
|
|
955
|
+
if (typeof unsignedOrRadix === 'number') {
|
|
956
|
+
(radix = unsignedOrRadix), (unsignedOrRadix = false);
|
|
957
|
+
}
|
|
958
|
+
else {
|
|
959
|
+
unsigned = !!unsignedOrRadix;
|
|
960
|
+
}
|
|
961
|
+
radix ??= 10;
|
|
962
|
+
if (str.trim() !== str) {
|
|
963
|
+
throw new BSONError(`Input: '${str}' contains leading and/or trailing whitespace`);
|
|
964
|
+
}
|
|
965
|
+
if (!validateStringCharacters(str, radix)) {
|
|
966
|
+
throw new BSONError(`Input: '${str}' contains invalid characters for radix: ${radix}`);
|
|
967
|
+
}
|
|
968
|
+
const cleanedStr = removeLeadingZerosAndExplicitPlus(str);
|
|
969
|
+
const result = Long._fromString(cleanedStr, unsigned, radix);
|
|
970
|
+
if (result.toString(radix).toLowerCase() !== cleanedStr.toLowerCase()) {
|
|
971
|
+
throw new BSONError(`Input: ${str} is not representable as ${result.unsigned ? 'an unsigned' : 'a signed'} 64-bit Long ${radix != null ? `with radix: ${radix}` : ''}`);
|
|
972
|
+
}
|
|
973
|
+
return result;
|
|
974
|
+
}
|
|
975
|
+
static fromString(str, unsignedOrRadix, radix) {
|
|
976
|
+
let unsigned = false;
|
|
977
|
+
if (typeof unsignedOrRadix === 'number') {
|
|
978
|
+
(radix = unsignedOrRadix), (unsignedOrRadix = false);
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
unsigned = !!unsignedOrRadix;
|
|
982
|
+
}
|
|
983
|
+
radix ??= 10;
|
|
984
|
+
if (str === 'NaN' && radix < 24) {
|
|
985
|
+
return Long.ZERO;
|
|
986
|
+
}
|
|
987
|
+
else if ((str === 'Infinity' || str === '+Infinity' || str === '-Infinity') && radix < 35) {
|
|
988
|
+
return Long.ZERO;
|
|
989
|
+
}
|
|
990
|
+
return Long._fromString(str, unsigned, radix);
|
|
991
|
+
}
|
|
966
992
|
static fromBytes(bytes, unsigned, le) {
|
|
967
993
|
return le ? Long.fromBytesLE(bytes, unsigned) : Long.fromBytesBE(bytes, unsigned);
|
|
968
994
|
}
|
|
@@ -2040,6 +2066,28 @@ class Double extends BSONValue {
|
|
|
2040
2066
|
}
|
|
2041
2067
|
this.value = +value;
|
|
2042
2068
|
}
|
|
2069
|
+
static fromString(value) {
|
|
2070
|
+
const coercedValue = Number(value);
|
|
2071
|
+
if (value === 'NaN')
|
|
2072
|
+
return new Double(NaN);
|
|
2073
|
+
if (value === 'Infinity')
|
|
2074
|
+
return new Double(Infinity);
|
|
2075
|
+
if (value === '-Infinity')
|
|
2076
|
+
return new Double(-Infinity);
|
|
2077
|
+
if (!Number.isFinite(coercedValue)) {
|
|
2078
|
+
throw new BSONError(`Input: ${value} is not representable as a Double`);
|
|
2079
|
+
}
|
|
2080
|
+
if (value.trim() !== value) {
|
|
2081
|
+
throw new BSONError(`Input: '${value}' contains whitespace`);
|
|
2082
|
+
}
|
|
2083
|
+
if (value === '') {
|
|
2084
|
+
throw new BSONError(`Input is an empty string`);
|
|
2085
|
+
}
|
|
2086
|
+
if (/[^-0-9.+eE]/.test(value)) {
|
|
2087
|
+
throw new BSONError(`Input: '${value}' is not in decimal or exponential notation`);
|
|
2088
|
+
}
|
|
2089
|
+
return new Double(coercedValue);
|
|
2090
|
+
}
|
|
2043
2091
|
valueOf() {
|
|
2044
2092
|
return this.value;
|
|
2045
2093
|
}
|
|
@@ -2081,6 +2129,23 @@ class Int32 extends BSONValue {
|
|
|
2081
2129
|
}
|
|
2082
2130
|
this.value = +value | 0;
|
|
2083
2131
|
}
|
|
2132
|
+
static fromString(value) {
|
|
2133
|
+
const cleanedValue = removeLeadingZerosAndExplicitPlus(value);
|
|
2134
|
+
const coercedValue = Number(value);
|
|
2135
|
+
if (BSON_INT32_MAX < coercedValue) {
|
|
2136
|
+
throw new BSONError(`Input: '${value}' is larger than the maximum value for Int32`);
|
|
2137
|
+
}
|
|
2138
|
+
else if (BSON_INT32_MIN > coercedValue) {
|
|
2139
|
+
throw new BSONError(`Input: '${value}' is smaller than the minimum value for Int32`);
|
|
2140
|
+
}
|
|
2141
|
+
else if (!Number.isSafeInteger(coercedValue)) {
|
|
2142
|
+
throw new BSONError(`Input: '${value}' is not a safe integer`);
|
|
2143
|
+
}
|
|
2144
|
+
else if (coercedValue.toString() !== cleanedValue) {
|
|
2145
|
+
throw new BSONError(`Input: '${value}' is not a valid Int32 string`);
|
|
2146
|
+
}
|
|
2147
|
+
return new Int32(coercedValue);
|
|
2148
|
+
}
|
|
2084
2149
|
valueOf() {
|
|
2085
2150
|
return this.value;
|
|
2086
2151
|
}
|
|
@@ -3168,12 +3233,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
|
|
|
3168
3233
|
stringSize > buffer.length - index ||
|
|
3169
3234
|
buffer[index + stringSize - 1] !== 0)
|
|
3170
3235
|
throw new BSONError('bad string length in bson');
|
|
3171
|
-
|
|
3172
|
-
if (!validateUtf8(buffer, index, index + stringSize - 1)) {
|
|
3173
|
-
throw new BSONError('Invalid UTF-8 string in BSON document');
|
|
3174
|
-
}
|
|
3175
|
-
}
|
|
3176
|
-
const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, false);
|
|
3236
|
+
const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
|
|
3177
3237
|
index = index + stringSize;
|
|
3178
3238
|
const oidBuffer = ByteUtils.allocateUnsafe(12);
|
|
3179
3239
|
for (let i = 0; i < 12; i++)
|