bson 6.3.0 → 6.4.1
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/bson.d.ts +2 -3
- package/lib/bson.bundle.js +302 -249
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +302 -249
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +302 -249
- package/lib/bson.mjs.map +1 -1
- package/lib/bson.rn.cjs +302 -249
- package/lib/bson.rn.cjs.map +1 -1
- package/package.json +18 -18
- package/src/bson.ts +3 -6
- package/src/db_ref.ts +0 -1
- package/src/decimal128.ts +1 -1
- package/src/objectid.ts +34 -15
- package/src/parser/deserializer.ts +75 -144
- package/src/parser/serializer.ts +41 -104
- package/src/utils/byte_utils.ts +2 -8
- package/src/utils/latin.ts +44 -1
- package/src/utils/node_byte_utils.ts +12 -6
- package/src/utils/number_utils.ts +174 -0
- package/src/utils/web_byte_utils.ts +10 -10
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"vendor"
|
|
15
15
|
],
|
|
16
16
|
"types": "bson.d.ts",
|
|
17
|
-
"version": "6.
|
|
17
|
+
"version": "6.4.1",
|
|
18
18
|
"author": {
|
|
19
19
|
"name": "The MongoDB NodeJS Team",
|
|
20
20
|
"email": "dbx-node@mongodb.com"
|
|
@@ -27,39 +27,39 @@
|
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
|
30
|
-
"@microsoft/api-extractor": "^7.
|
|
31
|
-
"@octokit/core": "^
|
|
30
|
+
"@microsoft/api-extractor": "^7.40.5",
|
|
31
|
+
"@octokit/core": "^5.1.0",
|
|
32
32
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
33
|
-
"@rollup/plugin-typescript": "^11.1.
|
|
33
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
|
34
34
|
"@types/chai": "^4.3.11",
|
|
35
35
|
"@types/mocha": "^10.0.6",
|
|
36
|
-
"@types/node": "^
|
|
37
|
-
"@types/sinon": "^
|
|
36
|
+
"@types/node": "^20.11.19",
|
|
37
|
+
"@types/sinon": "^17.0.3",
|
|
38
38
|
"@types/sinon-chai": "^3.2.12",
|
|
39
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
40
|
-
"@typescript-eslint/parser": "^
|
|
39
|
+
"@typescript-eslint/eslint-plugin": "^7.0.2",
|
|
40
|
+
"@typescript-eslint/parser": "^7.0.2",
|
|
41
41
|
"benchmark": "^2.1.4",
|
|
42
42
|
"chai": "^4.3.10",
|
|
43
43
|
"chalk": "^5.3.0",
|
|
44
44
|
"dbx-js-tools": "github:mongodb-js/dbx-js-tools",
|
|
45
|
-
"eslint": "^8.
|
|
46
|
-
"eslint-config-prettier": "^
|
|
45
|
+
"eslint": "^8.56.0",
|
|
46
|
+
"eslint-config-prettier": "^9.1.0",
|
|
47
47
|
"eslint-plugin-no-bigint-usage": "file:etc/eslint/no-bigint-usage",
|
|
48
|
-
"eslint-plugin-prettier": "^
|
|
48
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
49
49
|
"eslint-plugin-tsdoc": "^0.2.17",
|
|
50
|
-
"magic-string": "^0.30.
|
|
51
|
-
"mocha": "10.
|
|
50
|
+
"magic-string": "^0.30.7",
|
|
51
|
+
"mocha": "10.3.0",
|
|
52
52
|
"node-fetch": "^3.3.2",
|
|
53
53
|
"nyc": "^15.1.0",
|
|
54
|
-
"prettier": "^2.
|
|
55
|
-
"rollup": "^
|
|
56
|
-
"sinon": "^
|
|
54
|
+
"prettier": "^3.2.5",
|
|
55
|
+
"rollup": "^4.12.0",
|
|
56
|
+
"sinon": "^17.0.1",
|
|
57
57
|
"sinon-chai": "^3.7.0",
|
|
58
58
|
"source-map-support": "^0.5.21",
|
|
59
59
|
"standard-version": "^9.5.0",
|
|
60
60
|
"tar": "^6.2.0",
|
|
61
|
-
"ts-node": "^10.9.
|
|
62
|
-
"tsd": "^0.
|
|
61
|
+
"ts-node": "^10.9.2",
|
|
62
|
+
"tsd": "^0.30.5",
|
|
63
63
|
"typescript": "^5.0.4",
|
|
64
64
|
"typescript-cached-transpile": "0.0.6",
|
|
65
65
|
"uuid": "^9.0.1"
|
package/src/bson.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { BSONRegExp } from './regexp';
|
|
|
16
16
|
import { BSONSymbol } from './symbol';
|
|
17
17
|
import { Timestamp } from './timestamp';
|
|
18
18
|
import { ByteUtils } from './utils/byte_utils';
|
|
19
|
+
import { NumberUtils } from './utils/number_utils';
|
|
19
20
|
export type { UUIDExtended, BinaryExtended, BinaryExtendedLegacy, BinarySequence } from './binary';
|
|
20
21
|
export type { CodeExtended } from './code';
|
|
21
22
|
export type { DBRefLike } from './db_ref';
|
|
@@ -115,7 +116,7 @@ export function serialize(object: Document, options: SerializeOptions = {}): Uin
|
|
|
115
116
|
);
|
|
116
117
|
|
|
117
118
|
// Create the final buffer
|
|
118
|
-
const finishedBuffer = ByteUtils.
|
|
119
|
+
const finishedBuffer = ByteUtils.allocateUnsafe(serializationIndex);
|
|
119
120
|
|
|
120
121
|
// Copy into the finished buffer
|
|
121
122
|
finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);
|
|
@@ -232,11 +233,7 @@ export function deserializeStream(
|
|
|
232
233
|
// Loop over all documents
|
|
233
234
|
for (let i = 0; i < numberOfDocuments; i++) {
|
|
234
235
|
// Find size of the document
|
|
235
|
-
const size =
|
|
236
|
-
bufferData[index] |
|
|
237
|
-
(bufferData[index + 1] << 8) |
|
|
238
|
-
(bufferData[index + 2] << 16) |
|
|
239
|
-
(bufferData[index + 3] << 24);
|
|
236
|
+
const size = NumberUtils.getInt32LE(bufferData, index);
|
|
240
237
|
// Update options with index
|
|
241
238
|
internalOptions.index = index;
|
|
242
239
|
// Parse the document at this point
|
package/src/db_ref.ts
CHANGED
package/src/decimal128.ts
CHANGED
package/src/objectid.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BSONValue } from './bson_value';
|
|
2
2
|
import { BSONError } from './error';
|
|
3
3
|
import { type InspectFn, defaultInspect } from './parser/utils';
|
|
4
|
-
import {
|
|
4
|
+
import { ByteUtils } from './utils/byte_utils';
|
|
5
|
+
import { NumberUtils } from './utils/number_utils';
|
|
5
6
|
|
|
6
7
|
// Regular expression that checks for hex value
|
|
7
8
|
const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
|
|
@@ -21,8 +22,6 @@ export interface ObjectIdExtended {
|
|
|
21
22
|
$oid: string;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
const kId = Symbol('id');
|
|
25
|
-
|
|
26
25
|
/**
|
|
27
26
|
* A class representation of the BSON ObjectId type.
|
|
28
27
|
* @public
|
|
@@ -39,7 +38,7 @@ export class ObjectId extends BSONValue {
|
|
|
39
38
|
static cacheHexString: boolean;
|
|
40
39
|
|
|
41
40
|
/** ObjectId Bytes @internal */
|
|
42
|
-
private
|
|
41
|
+
private buffer!: Uint8Array;
|
|
43
42
|
/** ObjectId hexString cache @internal */
|
|
44
43
|
private __id?: string;
|
|
45
44
|
|
|
@@ -108,13 +107,13 @@ export class ObjectId extends BSONValue {
|
|
|
108
107
|
if (workingId == null || typeof workingId === 'number') {
|
|
109
108
|
// The most common use case (blank id, new objectId instance)
|
|
110
109
|
// Generate a new id
|
|
111
|
-
this
|
|
110
|
+
this.buffer = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
|
|
112
111
|
} else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {
|
|
113
112
|
// If intstanceof matches we can escape calling ensure buffer in Node.js environments
|
|
114
|
-
this
|
|
113
|
+
this.buffer = ByteUtils.toLocalBufferType(workingId);
|
|
115
114
|
} else if (typeof workingId === 'string') {
|
|
116
115
|
if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
|
|
117
|
-
this
|
|
116
|
+
this.buffer = ByteUtils.fromHex(workingId);
|
|
118
117
|
} else {
|
|
119
118
|
throw new BSONError(
|
|
120
119
|
'input must be a 24 character hex string, 12 byte Uint8Array, or an integer'
|
|
@@ -134,11 +133,11 @@ export class ObjectId extends BSONValue {
|
|
|
134
133
|
* @readonly
|
|
135
134
|
*/
|
|
136
135
|
get id(): Uint8Array {
|
|
137
|
-
return this
|
|
136
|
+
return this.buffer;
|
|
138
137
|
}
|
|
139
138
|
|
|
140
139
|
set id(value: Uint8Array) {
|
|
141
|
-
this
|
|
140
|
+
this.buffer = value;
|
|
142
141
|
if (ObjectId.cacheHexString) {
|
|
143
142
|
this.__id = ByteUtils.toHex(value);
|
|
144
143
|
}
|
|
@@ -178,10 +177,10 @@ export class ObjectId extends BSONValue {
|
|
|
178
177
|
}
|
|
179
178
|
|
|
180
179
|
const inc = ObjectId.getInc();
|
|
181
|
-
const buffer = ByteUtils.
|
|
180
|
+
const buffer = ByteUtils.allocateUnsafe(12);
|
|
182
181
|
|
|
183
182
|
// 4-byte timestamp
|
|
184
|
-
|
|
183
|
+
NumberUtils.setInt32BE(buffer, 0, time);
|
|
185
184
|
|
|
186
185
|
// set PROCESS_UNIQUE if yet not initialized
|
|
187
186
|
if (PROCESS_UNIQUE === null) {
|
|
@@ -240,7 +239,9 @@ export class ObjectId extends BSONValue {
|
|
|
240
239
|
}
|
|
241
240
|
|
|
242
241
|
if (ObjectId.is(otherId)) {
|
|
243
|
-
return
|
|
242
|
+
return (
|
|
243
|
+
this.buffer[11] === otherId.buffer[11] && ByteUtils.equals(this.buffer, otherId.buffer)
|
|
244
|
+
);
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
if (typeof otherId === 'string') {
|
|
@@ -259,7 +260,7 @@ export class ObjectId extends BSONValue {
|
|
|
259
260
|
/** Returns the generation date (accurate up to the second) that this ID was generated. */
|
|
260
261
|
getTimestamp(): Date {
|
|
261
262
|
const timestamp = new Date();
|
|
262
|
-
const time =
|
|
263
|
+
const time = NumberUtils.getUint32BE(this.buffer, 0);
|
|
263
264
|
timestamp.setTime(Math.floor(time) * 1000);
|
|
264
265
|
return timestamp;
|
|
265
266
|
}
|
|
@@ -269,15 +270,33 @@ export class ObjectId extends BSONValue {
|
|
|
269
270
|
return new ObjectId();
|
|
270
271
|
}
|
|
271
272
|
|
|
273
|
+
/** @internal */
|
|
274
|
+
serializeInto(uint8array: Uint8Array, index: number): 12 {
|
|
275
|
+
uint8array[index] = this.buffer[0];
|
|
276
|
+
uint8array[index + 1] = this.buffer[1];
|
|
277
|
+
uint8array[index + 2] = this.buffer[2];
|
|
278
|
+
uint8array[index + 3] = this.buffer[3];
|
|
279
|
+
uint8array[index + 4] = this.buffer[4];
|
|
280
|
+
uint8array[index + 5] = this.buffer[5];
|
|
281
|
+
uint8array[index + 6] = this.buffer[6];
|
|
282
|
+
uint8array[index + 7] = this.buffer[7];
|
|
283
|
+
uint8array[index + 8] = this.buffer[8];
|
|
284
|
+
uint8array[index + 9] = this.buffer[9];
|
|
285
|
+
uint8array[index + 10] = this.buffer[10];
|
|
286
|
+
uint8array[index + 11] = this.buffer[11];
|
|
287
|
+
return 12;
|
|
288
|
+
}
|
|
289
|
+
|
|
272
290
|
/**
|
|
273
291
|
* Creates an ObjectId from a second based number, with the rest of the ObjectId zeroed out. Used for comparisons or sorting the ObjectId.
|
|
274
292
|
*
|
|
275
293
|
* @param time - an integer number representing a number of seconds.
|
|
276
294
|
*/
|
|
277
295
|
static createFromTime(time: number): ObjectId {
|
|
278
|
-
const buffer = ByteUtils.
|
|
296
|
+
const buffer = ByteUtils.allocate(12);
|
|
297
|
+
for (let i = 11; i >= 4; i--) buffer[i] = 0;
|
|
279
298
|
// Encode time into first 4 bytes
|
|
280
|
-
|
|
299
|
+
NumberUtils.setInt32BE(buffer, 0, time);
|
|
281
300
|
// Return the new objectId
|
|
282
301
|
return new ObjectId(buffer);
|
|
283
302
|
}
|
|
@@ -14,7 +14,8 @@ import { ObjectId } from '../objectid';
|
|
|
14
14
|
import { BSONRegExp } from '../regexp';
|
|
15
15
|
import { BSONSymbol } from '../symbol';
|
|
16
16
|
import { Timestamp } from '../timestamp';
|
|
17
|
-
import {
|
|
17
|
+
import { ByteUtils } from '../utils/byte_utils';
|
|
18
|
+
import { NumberUtils } from '../utils/number_utils';
|
|
18
19
|
import { validateUtf8 } from '../validate_utf8';
|
|
19
20
|
|
|
20
21
|
/** @public */
|
|
@@ -91,11 +92,7 @@ export function internalDeserialize(
|
|
|
91
92
|
options = options == null ? {} : options;
|
|
92
93
|
const index = options && options.index ? options.index : 0;
|
|
93
94
|
// Read the document size
|
|
94
|
-
const size =
|
|
95
|
-
buffer[index] |
|
|
96
|
-
(buffer[index + 1] << 8) |
|
|
97
|
-
(buffer[index + 2] << 16) |
|
|
98
|
-
(buffer[index + 3] << 24);
|
|
95
|
+
const size = NumberUtils.getInt32LE(buffer, index);
|
|
99
96
|
|
|
100
97
|
if (size < 5) {
|
|
101
98
|
throw new BSONError(`bson size must be >= 5, is ${size}`);
|
|
@@ -164,7 +161,7 @@ function deserializeObject(
|
|
|
164
161
|
// Reflects utf-8 validation setting regardless of global or specific key validation
|
|
165
162
|
let validationSetting: boolean;
|
|
166
163
|
// Set of keys either to enable or disable validation on
|
|
167
|
-
|
|
164
|
+
let utf8KeysSet;
|
|
168
165
|
|
|
169
166
|
// Check for boolean uniformity and empty validation option
|
|
170
167
|
const utf8ValidatedKeys = validation.utf8;
|
|
@@ -190,6 +187,8 @@ function deserializeObject(
|
|
|
190
187
|
|
|
191
188
|
// Add keys to set that will either be validated or not based on validationSetting
|
|
192
189
|
if (!globalUTFValidation) {
|
|
190
|
+
utf8KeysSet = new Set();
|
|
191
|
+
|
|
193
192
|
for (const key of Object.keys(utf8ValidatedKeys)) {
|
|
194
193
|
utf8KeysSet.add(key);
|
|
195
194
|
}
|
|
@@ -202,8 +201,8 @@ function deserializeObject(
|
|
|
202
201
|
if (buffer.length < 5) throw new BSONError('corrupt bson message < 5 bytes long');
|
|
203
202
|
|
|
204
203
|
// Read the document size
|
|
205
|
-
const size =
|
|
206
|
-
|
|
204
|
+
const size = NumberUtils.getInt32LE(buffer, index);
|
|
205
|
+
index += 4;
|
|
207
206
|
|
|
208
207
|
// Ensure buffer is valid size
|
|
209
208
|
if (size < 5 || size > buffer.length) throw new BSONError('corrupt bson message');
|
|
@@ -217,7 +216,6 @@ function deserializeObject(
|
|
|
217
216
|
let isPossibleDBRef = isArray ? false : null;
|
|
218
217
|
|
|
219
218
|
// While we have more left data left keep parsing
|
|
220
|
-
const dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
221
219
|
while (!done) {
|
|
222
220
|
// Read the type
|
|
223
221
|
const elementType = buffer[index++];
|
|
@@ -240,7 +238,7 @@ function deserializeObject(
|
|
|
240
238
|
|
|
241
239
|
// shouldValidateKey is true if the key should be validated, false otherwise
|
|
242
240
|
let shouldValidateKey = true;
|
|
243
|
-
if (globalUTFValidation || utf8KeysSet
|
|
241
|
+
if (globalUTFValidation || utf8KeysSet?.has(name)) {
|
|
244
242
|
shouldValidateKey = validationSetting;
|
|
245
243
|
} else {
|
|
246
244
|
shouldValidateKey = !validationSetting;
|
|
@@ -254,11 +252,8 @@ function deserializeObject(
|
|
|
254
252
|
index = i + 1;
|
|
255
253
|
|
|
256
254
|
if (elementType === constants.BSON_DATA_STRING) {
|
|
257
|
-
const stringSize =
|
|
258
|
-
|
|
259
|
-
(buffer[index++] << 8) |
|
|
260
|
-
(buffer[index++] << 16) |
|
|
261
|
-
(buffer[index++] << 24);
|
|
255
|
+
const stringSize = NumberUtils.getInt32LE(buffer, index);
|
|
256
|
+
index += 4;
|
|
262
257
|
if (
|
|
263
258
|
stringSize <= 0 ||
|
|
264
259
|
stringSize > buffer.length - index ||
|
|
@@ -269,37 +264,25 @@ function deserializeObject(
|
|
|
269
264
|
value = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
|
|
270
265
|
index = index + stringSize;
|
|
271
266
|
} else if (elementType === constants.BSON_DATA_OID) {
|
|
272
|
-
const oid = ByteUtils.
|
|
273
|
-
oid
|
|
267
|
+
const oid = ByteUtils.allocateUnsafe(12);
|
|
268
|
+
for (let i = 0; i < 12; i++) oid[i] = buffer[index + i];
|
|
274
269
|
value = new ObjectId(oid);
|
|
275
270
|
index = index + 12;
|
|
276
271
|
} else if (elementType === constants.BSON_DATA_INT && promoteValues === false) {
|
|
277
|
-
value = new Int32(
|
|
278
|
-
|
|
279
|
-
);
|
|
272
|
+
value = new Int32(NumberUtils.getInt32LE(buffer, index));
|
|
273
|
+
index += 4;
|
|
280
274
|
} else if (elementType === constants.BSON_DATA_INT) {
|
|
281
|
-
value =
|
|
282
|
-
|
|
283
|
-
(buffer[index++] << 8) |
|
|
284
|
-
(buffer[index++] << 16) |
|
|
285
|
-
(buffer[index++] << 24);
|
|
286
|
-
} else if (elementType === constants.BSON_DATA_NUMBER && promoteValues === false) {
|
|
287
|
-
value = new Double(dataview.getFloat64(index, true));
|
|
288
|
-
index = index + 8;
|
|
275
|
+
value = NumberUtils.getInt32LE(buffer, index);
|
|
276
|
+
index += 4;
|
|
289
277
|
} else if (elementType === constants.BSON_DATA_NUMBER) {
|
|
290
|
-
value =
|
|
291
|
-
index
|
|
278
|
+
value = NumberUtils.getFloat64LE(buffer, index);
|
|
279
|
+
index += 8;
|
|
280
|
+
if (promoteValues === false) value = new Double(value);
|
|
292
281
|
} else if (elementType === constants.BSON_DATA_DATE) {
|
|
293
|
-
const lowBits =
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
(buffer[index++] << 24);
|
|
298
|
-
const highBits =
|
|
299
|
-
buffer[index++] |
|
|
300
|
-
(buffer[index++] << 8) |
|
|
301
|
-
(buffer[index++] << 16) |
|
|
302
|
-
(buffer[index++] << 24);
|
|
282
|
+
const lowBits = NumberUtils.getInt32LE(buffer, index);
|
|
283
|
+
const highBits = NumberUtils.getInt32LE(buffer, index + 4);
|
|
284
|
+
index += 8;
|
|
285
|
+
|
|
303
286
|
value = new Date(new Long(lowBits, highBits).toNumber());
|
|
304
287
|
} else if (elementType === constants.BSON_DATA_BOOLEAN) {
|
|
305
288
|
if (buffer[index] !== 0 && buffer[index] !== 1)
|
|
@@ -307,11 +290,8 @@ function deserializeObject(
|
|
|
307
290
|
value = buffer[index++] === 1;
|
|
308
291
|
} else if (elementType === constants.BSON_DATA_OBJECT) {
|
|
309
292
|
const _index = index;
|
|
310
|
-
const objectSize =
|
|
311
|
-
|
|
312
|
-
(buffer[index + 1] << 8) |
|
|
313
|
-
(buffer[index + 2] << 16) |
|
|
314
|
-
(buffer[index + 3] << 24);
|
|
293
|
+
const objectSize = NumberUtils.getInt32LE(buffer, index);
|
|
294
|
+
|
|
315
295
|
if (objectSize <= 0 || objectSize > buffer.length - index)
|
|
316
296
|
throw new BSONError('bad embedded document length in bson');
|
|
317
297
|
|
|
@@ -329,11 +309,7 @@ function deserializeObject(
|
|
|
329
309
|
index = index + objectSize;
|
|
330
310
|
} else if (elementType === constants.BSON_DATA_ARRAY) {
|
|
331
311
|
const _index = index;
|
|
332
|
-
const objectSize =
|
|
333
|
-
buffer[index] |
|
|
334
|
-
(buffer[index + 1] << 8) |
|
|
335
|
-
(buffer[index + 2] << 16) |
|
|
336
|
-
(buffer[index + 3] << 24);
|
|
312
|
+
const objectSize = NumberUtils.getInt32LE(buffer, index);
|
|
337
313
|
let arrayOptions: DeserializeOptions = options;
|
|
338
314
|
|
|
339
315
|
// Stop index
|
|
@@ -357,46 +333,38 @@ function deserializeObject(
|
|
|
357
333
|
} else if (elementType === constants.BSON_DATA_NULL) {
|
|
358
334
|
value = null;
|
|
359
335
|
} else if (elementType === constants.BSON_DATA_LONG) {
|
|
360
|
-
// Unpack the low and high bits
|
|
361
|
-
const dataview = BSONDataView.fromUint8Array(buffer.subarray(index, index + 8));
|
|
362
|
-
|
|
363
|
-
const lowBits =
|
|
364
|
-
buffer[index++] |
|
|
365
|
-
(buffer[index++] << 8) |
|
|
366
|
-
(buffer[index++] << 16) |
|
|
367
|
-
(buffer[index++] << 24);
|
|
368
|
-
const highBits =
|
|
369
|
-
buffer[index++] |
|
|
370
|
-
(buffer[index++] << 8) |
|
|
371
|
-
(buffer[index++] << 16) |
|
|
372
|
-
(buffer[index++] << 24);
|
|
373
|
-
const long = new Long(lowBits, highBits);
|
|
374
336
|
if (useBigInt64) {
|
|
375
|
-
value =
|
|
376
|
-
|
|
377
|
-
// Promote the long if possible
|
|
378
|
-
value =
|
|
379
|
-
long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
|
|
380
|
-
? long.toNumber()
|
|
381
|
-
: long;
|
|
337
|
+
value = NumberUtils.getBigInt64LE(buffer, index);
|
|
338
|
+
index += 8;
|
|
382
339
|
} else {
|
|
383
|
-
|
|
340
|
+
// Unpack the low and high bits
|
|
341
|
+
const lowBits = NumberUtils.getInt32LE(buffer, index);
|
|
342
|
+
const highBits = NumberUtils.getInt32LE(buffer, index + 4);
|
|
343
|
+
index += 8;
|
|
344
|
+
|
|
345
|
+
const long = new Long(lowBits, highBits);
|
|
346
|
+
// Promote the long if possible
|
|
347
|
+
if (promoteLongs && promoteValues === true) {
|
|
348
|
+
value =
|
|
349
|
+
long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
|
|
350
|
+
? long.toNumber()
|
|
351
|
+
: long;
|
|
352
|
+
} else {
|
|
353
|
+
value = long;
|
|
354
|
+
}
|
|
384
355
|
}
|
|
385
356
|
} else if (elementType === constants.BSON_DATA_DECIMAL128) {
|
|
386
357
|
// Buffer to contain the decimal bytes
|
|
387
|
-
const bytes = ByteUtils.
|
|
358
|
+
const bytes = ByteUtils.allocateUnsafe(16);
|
|
388
359
|
// Copy the next 16 bytes into the bytes buffer
|
|
389
|
-
|
|
360
|
+
for (let i = 0; i < 16; i++) bytes[i] = buffer[index + i];
|
|
390
361
|
// Update index
|
|
391
362
|
index = index + 16;
|
|
392
363
|
// Assign the new Decimal128 value
|
|
393
364
|
value = new Decimal128(bytes);
|
|
394
365
|
} else if (elementType === constants.BSON_DATA_BINARY) {
|
|
395
|
-
let binarySize =
|
|
396
|
-
|
|
397
|
-
(buffer[index++] << 8) |
|
|
398
|
-
(buffer[index++] << 16) |
|
|
399
|
-
(buffer[index++] << 24);
|
|
366
|
+
let binarySize = NumberUtils.getInt32LE(buffer, index);
|
|
367
|
+
index += 4;
|
|
400
368
|
const totalBinarySize = binarySize;
|
|
401
369
|
const subType = buffer[index++];
|
|
402
370
|
|
|
@@ -411,11 +379,8 @@ function deserializeObject(
|
|
|
411
379
|
if (buffer['slice'] != null) {
|
|
412
380
|
// If we have subtype 2 skip the 4 bytes for the size
|
|
413
381
|
if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
|
|
414
|
-
binarySize =
|
|
415
|
-
|
|
416
|
-
(buffer[index++] << 8) |
|
|
417
|
-
(buffer[index++] << 16) |
|
|
418
|
-
(buffer[index++] << 24);
|
|
382
|
+
binarySize = NumberUtils.getInt32LE(buffer, index);
|
|
383
|
+
index += 4;
|
|
419
384
|
if (binarySize < 0)
|
|
420
385
|
throw new BSONError('Negative binary type element size found for subtype 0x02');
|
|
421
386
|
if (binarySize > totalBinarySize - 4)
|
|
@@ -433,14 +398,10 @@ function deserializeObject(
|
|
|
433
398
|
}
|
|
434
399
|
}
|
|
435
400
|
} else {
|
|
436
|
-
const _buffer = ByteUtils.allocate(binarySize);
|
|
437
401
|
// If we have subtype 2 skip the 4 bytes for the size
|
|
438
402
|
if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
|
|
439
|
-
binarySize =
|
|
440
|
-
|
|
441
|
-
(buffer[index++] << 8) |
|
|
442
|
-
(buffer[index++] << 16) |
|
|
443
|
-
(buffer[index++] << 24);
|
|
403
|
+
binarySize = NumberUtils.getInt32LE(buffer, index);
|
|
404
|
+
index += 4;
|
|
444
405
|
if (binarySize < 0)
|
|
445
406
|
throw new BSONError('Negative binary type element size found for subtype 0x02');
|
|
446
407
|
if (binarySize > totalBinarySize - 4)
|
|
@@ -449,13 +410,12 @@ function deserializeObject(
|
|
|
449
410
|
throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
|
|
450
411
|
}
|
|
451
412
|
|
|
452
|
-
// Copy the data
|
|
453
|
-
for (i = 0; i < binarySize; i++) {
|
|
454
|
-
_buffer[i] = buffer[index + i];
|
|
455
|
-
}
|
|
456
|
-
|
|
457
413
|
if (promoteBuffers && promoteValues) {
|
|
458
|
-
value =
|
|
414
|
+
value = ByteUtils.allocateUnsafe(binarySize);
|
|
415
|
+
// Copy the data
|
|
416
|
+
for (i = 0; i < binarySize; i++) {
|
|
417
|
+
value[i] = buffer[index + i];
|
|
418
|
+
}
|
|
459
419
|
} else {
|
|
460
420
|
value = new Binary(buffer.slice(index, index + binarySize), subType);
|
|
461
421
|
if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
|
|
@@ -539,11 +499,8 @@ function deserializeObject(
|
|
|
539
499
|
// Set the object
|
|
540
500
|
value = new BSONRegExp(source, regExpOptions);
|
|
541
501
|
} else if (elementType === constants.BSON_DATA_SYMBOL) {
|
|
542
|
-
const stringSize =
|
|
543
|
-
|
|
544
|
-
(buffer[index++] << 8) |
|
|
545
|
-
(buffer[index++] << 16) |
|
|
546
|
-
(buffer[index++] << 24);
|
|
502
|
+
const stringSize = NumberUtils.getInt32LE(buffer, index);
|
|
503
|
+
index += 4;
|
|
547
504
|
if (
|
|
548
505
|
stringSize <= 0 ||
|
|
549
506
|
stringSize > buffer.length - index ||
|
|
@@ -555,31 +512,18 @@ function deserializeObject(
|
|
|
555
512
|
value = promoteValues ? symbol : new BSONSymbol(symbol);
|
|
556
513
|
index = index + stringSize;
|
|
557
514
|
} else if (elementType === constants.BSON_DATA_TIMESTAMP) {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
buffer[index++] * (1 << 8) +
|
|
564
|
-
buffer[index++] * (1 << 16) +
|
|
565
|
-
buffer[index++] * (1 << 24);
|
|
566
|
-
const t =
|
|
567
|
-
buffer[index++] +
|
|
568
|
-
buffer[index++] * (1 << 8) +
|
|
569
|
-
buffer[index++] * (1 << 16) +
|
|
570
|
-
buffer[index++] * (1 << 24);
|
|
571
|
-
|
|
572
|
-
value = new Timestamp({ i, t });
|
|
515
|
+
value = new Timestamp({
|
|
516
|
+
i: NumberUtils.getUint32LE(buffer, index),
|
|
517
|
+
t: NumberUtils.getUint32LE(buffer, index + 4)
|
|
518
|
+
});
|
|
519
|
+
index += 8;
|
|
573
520
|
} else if (elementType === constants.BSON_DATA_MIN_KEY) {
|
|
574
521
|
value = new MinKey();
|
|
575
522
|
} else if (elementType === constants.BSON_DATA_MAX_KEY) {
|
|
576
523
|
value = new MaxKey();
|
|
577
524
|
} else if (elementType === constants.BSON_DATA_CODE) {
|
|
578
|
-
const stringSize =
|
|
579
|
-
|
|
580
|
-
(buffer[index++] << 8) |
|
|
581
|
-
(buffer[index++] << 16) |
|
|
582
|
-
(buffer[index++] << 24);
|
|
525
|
+
const stringSize = NumberUtils.getInt32LE(buffer, index);
|
|
526
|
+
index += 4;
|
|
583
527
|
if (
|
|
584
528
|
stringSize <= 0 ||
|
|
585
529
|
stringSize > buffer.length - index ||
|
|
@@ -599,11 +543,8 @@ function deserializeObject(
|
|
|
599
543
|
// Update parse index position
|
|
600
544
|
index = index + stringSize;
|
|
601
545
|
} else if (elementType === constants.BSON_DATA_CODE_W_SCOPE) {
|
|
602
|
-
const totalSize =
|
|
603
|
-
|
|
604
|
-
(buffer[index++] << 8) |
|
|
605
|
-
(buffer[index++] << 16) |
|
|
606
|
-
(buffer[index++] << 24);
|
|
546
|
+
const totalSize = NumberUtils.getInt32LE(buffer, index);
|
|
547
|
+
index += 4;
|
|
607
548
|
|
|
608
549
|
// Element cannot be shorter than totalSize + stringSize + documentSize + terminator
|
|
609
550
|
if (totalSize < 4 + 4 + 4 + 1) {
|
|
@@ -611,11 +552,8 @@ function deserializeObject(
|
|
|
611
552
|
}
|
|
612
553
|
|
|
613
554
|
// Get the code string size
|
|
614
|
-
const stringSize =
|
|
615
|
-
|
|
616
|
-
(buffer[index++] << 8) |
|
|
617
|
-
(buffer[index++] << 16) |
|
|
618
|
-
(buffer[index++] << 24);
|
|
555
|
+
const stringSize = NumberUtils.getInt32LE(buffer, index);
|
|
556
|
+
index += 4;
|
|
619
557
|
// Check if we have a valid string
|
|
620
558
|
if (
|
|
621
559
|
stringSize <= 0 ||
|
|
@@ -637,11 +575,7 @@ function deserializeObject(
|
|
|
637
575
|
// Parse the element
|
|
638
576
|
const _index = index;
|
|
639
577
|
// Decode the size of the object document
|
|
640
|
-
const objectSize =
|
|
641
|
-
buffer[index] |
|
|
642
|
-
(buffer[index + 1] << 8) |
|
|
643
|
-
(buffer[index + 2] << 16) |
|
|
644
|
-
(buffer[index + 3] << 24);
|
|
578
|
+
const objectSize = NumberUtils.getInt32LE(buffer, index);
|
|
645
579
|
// Decode the scope object
|
|
646
580
|
const scopeObject = deserializeObject(buffer, _index, options, false);
|
|
647
581
|
// Adjust the index
|
|
@@ -660,11 +594,8 @@ function deserializeObject(
|
|
|
660
594
|
value = new Code(functionString, scopeObject);
|
|
661
595
|
} else if (elementType === constants.BSON_DATA_DBPOINTER) {
|
|
662
596
|
// Get the code string size
|
|
663
|
-
const stringSize =
|
|
664
|
-
|
|
665
|
-
(buffer[index++] << 8) |
|
|
666
|
-
(buffer[index++] << 16) |
|
|
667
|
-
(buffer[index++] << 24);
|
|
597
|
+
const stringSize = NumberUtils.getInt32LE(buffer, index);
|
|
598
|
+
index += 4;
|
|
668
599
|
// Check if we have a valid string
|
|
669
600
|
if (
|
|
670
601
|
stringSize <= 0 ||
|
|
@@ -683,8 +614,8 @@ function deserializeObject(
|
|
|
683
614
|
index = index + stringSize;
|
|
684
615
|
|
|
685
616
|
// Read the oid
|
|
686
|
-
const oidBuffer = ByteUtils.
|
|
687
|
-
|
|
617
|
+
const oidBuffer = ByteUtils.allocateUnsafe(12);
|
|
618
|
+
for (let i = 0; i < 12; i++) oidBuffer[i] = buffer[index + i];
|
|
688
619
|
const oid = new ObjectId(oidBuffer);
|
|
689
620
|
|
|
690
621
|
// Update the index
|