bson 4.7.0 → 5.0.0-alpha.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/bson.d.ts +207 -259
- package/lib/bson.bundle.js +4033 -0
- package/lib/bson.bundle.js.map +1 -0
- package/lib/bson.cjs +4028 -0
- package/lib/bson.cjs.map +1 -0
- package/lib/bson.mjs +4002 -0
- package/lib/bson.mjs.map +1 -0
- package/package.json +49 -62
- package/src/binary.ts +63 -52
- package/src/bson.ts +27 -108
- package/src/code.ts +24 -14
- package/src/constants.ts +28 -0
- package/src/db_ref.ts +13 -8
- package/src/decimal128.ts +31 -25
- package/src/double.ts +7 -5
- package/src/error.ts +0 -2
- package/src/extended_json.ts +148 -148
- package/src/index.ts +19 -0
- package/src/int_32.ts +7 -5
- package/src/long.ts +16 -16
- package/src/max_key.ts +6 -6
- package/src/min_key.ts +6 -6
- package/src/objectid.ts +41 -74
- package/src/parser/calculate_size.ts +39 -63
- package/src/parser/deserializer.ts +41 -112
- package/src/parser/serializer.ts +234 -341
- package/src/parser/utils.ts +1 -99
- package/src/regexp.ts +16 -5
- package/src/symbol.ts +7 -5
- package/src/timestamp.ts +62 -27
- package/src/utils/byte_utils.ts +61 -0
- package/src/utils/node_byte_utils.ts +141 -0
- package/src/utils/web_byte_utils.ts +190 -0
- package/src/uuid_utils.ts +15 -15
- package/bower.json +0 -26
- package/dist/bson.browser.esm.js +0 -7470
- package/dist/bson.browser.esm.js.map +0 -1
- package/dist/bson.browser.umd.js +0 -7537
- package/dist/bson.browser.umd.js.map +0 -1
- package/dist/bson.bundle.js +0 -7536
- package/dist/bson.bundle.js.map +0 -1
- package/dist/bson.esm.js +0 -5436
- package/dist/bson.esm.js.map +0 -1
- package/lib/binary.js +0 -426
- package/lib/binary.js.map +0 -1
- package/lib/bson.js +0 -251
- package/lib/bson.js.map +0 -1
- package/lib/code.js +0 -46
- package/lib/code.js.map +0 -1
- package/lib/constants.js +0 -82
- package/lib/constants.js.map +0 -1
- package/lib/db_ref.js +0 -97
- package/lib/db_ref.js.map +0 -1
- package/lib/decimal128.js +0 -669
- package/lib/decimal128.js.map +0 -1
- package/lib/double.js +0 -76
- package/lib/double.js.map +0 -1
- package/lib/ensure_buffer.js +0 -25
- package/lib/ensure_buffer.js.map +0 -1
- package/lib/error.js +0 -55
- package/lib/error.js.map +0 -1
- package/lib/extended_json.js +0 -390
- package/lib/extended_json.js.map +0 -1
- package/lib/int_32.js +0 -58
- package/lib/int_32.js.map +0 -1
- package/lib/long.js +0 -900
- package/lib/long.js.map +0 -1
- package/lib/map.js +0 -123
- package/lib/map.js.map +0 -1
- package/lib/max_key.js +0 -33
- package/lib/max_key.js.map +0 -1
- package/lib/min_key.js +0 -33
- package/lib/min_key.js.map +0 -1
- package/lib/objectid.js +0 -299
- package/lib/objectid.js.map +0 -1
- package/lib/parser/calculate_size.js +0 -194
- package/lib/parser/calculate_size.js.map +0 -1
- package/lib/parser/deserializer.js +0 -665
- package/lib/parser/deserializer.js.map +0 -1
- package/lib/parser/serializer.js +0 -867
- package/lib/parser/serializer.js.map +0 -1
- package/lib/parser/utils.js +0 -115
- package/lib/parser/utils.js.map +0 -1
- package/lib/regexp.js +0 -74
- package/lib/regexp.js.map +0 -1
- package/lib/symbol.js +0 -48
- package/lib/symbol.js.map +0 -1
- package/lib/timestamp.js +0 -102
- package/lib/timestamp.js.map +0 -1
- package/lib/utils/global.js +0 -18
- package/lib/utils/global.js.map +0 -1
- package/lib/uuid_utils.js +0 -35
- package/lib/uuid_utils.js.map +0 -1
- package/lib/validate_utf8.js +0 -47
- package/lib/validate_utf8.js.map +0 -1
- package/src/ensure_buffer.ts +0 -27
- package/src/map.ts +0 -119
- package/src/utils/global.ts +0 -22
|
@@ -1,665 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.deserialize = void 0;
|
|
15
|
-
var buffer_1 = require("buffer");
|
|
16
|
-
var binary_1 = require("../binary");
|
|
17
|
-
var code_1 = require("../code");
|
|
18
|
-
var constants = require("../constants");
|
|
19
|
-
var db_ref_1 = require("../db_ref");
|
|
20
|
-
var decimal128_1 = require("../decimal128");
|
|
21
|
-
var double_1 = require("../double");
|
|
22
|
-
var error_1 = require("../error");
|
|
23
|
-
var int_32_1 = require("../int_32");
|
|
24
|
-
var long_1 = require("../long");
|
|
25
|
-
var max_key_1 = require("../max_key");
|
|
26
|
-
var min_key_1 = require("../min_key");
|
|
27
|
-
var objectid_1 = require("../objectid");
|
|
28
|
-
var regexp_1 = require("../regexp");
|
|
29
|
-
var symbol_1 = require("../symbol");
|
|
30
|
-
var timestamp_1 = require("../timestamp");
|
|
31
|
-
var validate_utf8_1 = require("../validate_utf8");
|
|
32
|
-
// Internal long versions
|
|
33
|
-
var JS_INT_MAX_LONG = long_1.Long.fromNumber(constants.JS_INT_MAX);
|
|
34
|
-
var JS_INT_MIN_LONG = long_1.Long.fromNumber(constants.JS_INT_MIN);
|
|
35
|
-
var functionCache = {};
|
|
36
|
-
function deserialize(buffer, options, isArray) {
|
|
37
|
-
options = options == null ? {} : options;
|
|
38
|
-
var index = options && options.index ? options.index : 0;
|
|
39
|
-
// Read the document size
|
|
40
|
-
var size = buffer[index] |
|
|
41
|
-
(buffer[index + 1] << 8) |
|
|
42
|
-
(buffer[index + 2] << 16) |
|
|
43
|
-
(buffer[index + 3] << 24);
|
|
44
|
-
if (size < 5) {
|
|
45
|
-
throw new error_1.BSONError("bson size must be >= 5, is ".concat(size));
|
|
46
|
-
}
|
|
47
|
-
if (options.allowObjectSmallerThanBufferSize && buffer.length < size) {
|
|
48
|
-
throw new error_1.BSONError("buffer length ".concat(buffer.length, " must be >= bson size ").concat(size));
|
|
49
|
-
}
|
|
50
|
-
if (!options.allowObjectSmallerThanBufferSize && buffer.length !== size) {
|
|
51
|
-
throw new error_1.BSONError("buffer length ".concat(buffer.length, " must === bson size ").concat(size));
|
|
52
|
-
}
|
|
53
|
-
if (size + index > buffer.byteLength) {
|
|
54
|
-
throw new error_1.BSONError("(bson size ".concat(size, " + options.index ").concat(index, " must be <= buffer length ").concat(buffer.byteLength, ")"));
|
|
55
|
-
}
|
|
56
|
-
// Illegal end value
|
|
57
|
-
if (buffer[index + size - 1] !== 0) {
|
|
58
|
-
throw new error_1.BSONError("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");
|
|
59
|
-
}
|
|
60
|
-
// Start deserializtion
|
|
61
|
-
return deserializeObject(buffer, index, options, isArray);
|
|
62
|
-
}
|
|
63
|
-
exports.deserialize = deserialize;
|
|
64
|
-
var allowedDBRefKeys = /^\$ref$|^\$id$|^\$db$/;
|
|
65
|
-
function deserializeObject(buffer, index, options, isArray) {
|
|
66
|
-
if (isArray === void 0) { isArray = false; }
|
|
67
|
-
var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions'];
|
|
68
|
-
var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions'];
|
|
69
|
-
var fieldsAsRaw = options['fieldsAsRaw'] == null ? null : options['fieldsAsRaw'];
|
|
70
|
-
// Return raw bson buffer instead of parsing it
|
|
71
|
-
var raw = options['raw'] == null ? false : options['raw'];
|
|
72
|
-
// Return BSONRegExp objects instead of native regular expressions
|
|
73
|
-
var bsonRegExp = typeof options['bsonRegExp'] === 'boolean' ? options['bsonRegExp'] : false;
|
|
74
|
-
// Controls the promotion of values vs wrapper classes
|
|
75
|
-
var promoteBuffers = options['promoteBuffers'] == null ? false : options['promoteBuffers'];
|
|
76
|
-
var promoteLongs = options['promoteLongs'] == null ? true : options['promoteLongs'];
|
|
77
|
-
var promoteValues = options['promoteValues'] == null ? true : options['promoteValues'];
|
|
78
|
-
// Ensures default validation option if none given
|
|
79
|
-
var validation = options.validation == null ? { utf8: true } : options.validation;
|
|
80
|
-
// Shows if global utf-8 validation is enabled or disabled
|
|
81
|
-
var globalUTFValidation = true;
|
|
82
|
-
// Reflects utf-8 validation setting regardless of global or specific key validation
|
|
83
|
-
var validationSetting;
|
|
84
|
-
// Set of keys either to enable or disable validation on
|
|
85
|
-
var utf8KeysSet = new Set();
|
|
86
|
-
// Check for boolean uniformity and empty validation option
|
|
87
|
-
var utf8ValidatedKeys = validation.utf8;
|
|
88
|
-
if (typeof utf8ValidatedKeys === 'boolean') {
|
|
89
|
-
validationSetting = utf8ValidatedKeys;
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
globalUTFValidation = false;
|
|
93
|
-
var utf8ValidationValues = Object.keys(utf8ValidatedKeys).map(function (key) {
|
|
94
|
-
return utf8ValidatedKeys[key];
|
|
95
|
-
});
|
|
96
|
-
if (utf8ValidationValues.length === 0) {
|
|
97
|
-
throw new error_1.BSONError('UTF-8 validation setting cannot be empty');
|
|
98
|
-
}
|
|
99
|
-
if (typeof utf8ValidationValues[0] !== 'boolean') {
|
|
100
|
-
throw new error_1.BSONError('Invalid UTF-8 validation option, must specify boolean values');
|
|
101
|
-
}
|
|
102
|
-
validationSetting = utf8ValidationValues[0];
|
|
103
|
-
// Ensures boolean uniformity in utf-8 validation (all true or all false)
|
|
104
|
-
if (!utf8ValidationValues.every(function (item) { return item === validationSetting; })) {
|
|
105
|
-
throw new error_1.BSONError('Invalid UTF-8 validation option - keys must be all true or all false');
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// Add keys to set that will either be validated or not based on validationSetting
|
|
109
|
-
if (!globalUTFValidation) {
|
|
110
|
-
for (var _i = 0, _a = Object.keys(utf8ValidatedKeys); _i < _a.length; _i++) {
|
|
111
|
-
var key = _a[_i];
|
|
112
|
-
utf8KeysSet.add(key);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// Set the start index
|
|
116
|
-
var startIndex = index;
|
|
117
|
-
// Validate that we have at least 4 bytes of buffer
|
|
118
|
-
if (buffer.length < 5)
|
|
119
|
-
throw new error_1.BSONError('corrupt bson message < 5 bytes long');
|
|
120
|
-
// Read the document size
|
|
121
|
-
var size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
|
|
122
|
-
// Ensure buffer is valid size
|
|
123
|
-
if (size < 5 || size > buffer.length)
|
|
124
|
-
throw new error_1.BSONError('corrupt bson message');
|
|
125
|
-
// Create holding object
|
|
126
|
-
var object = isArray ? [] : {};
|
|
127
|
-
// Used for arrays to skip having to perform utf8 decoding
|
|
128
|
-
var arrayIndex = 0;
|
|
129
|
-
var done = false;
|
|
130
|
-
var isPossibleDBRef = isArray ? false : null;
|
|
131
|
-
// While we have more left data left keep parsing
|
|
132
|
-
var dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
133
|
-
while (!done) {
|
|
134
|
-
// Read the type
|
|
135
|
-
var elementType = buffer[index++];
|
|
136
|
-
// If we get a zero it's the last byte, exit
|
|
137
|
-
if (elementType === 0)
|
|
138
|
-
break;
|
|
139
|
-
// Get the start search index
|
|
140
|
-
var i = index;
|
|
141
|
-
// Locate the end of the c string
|
|
142
|
-
while (buffer[i] !== 0x00 && i < buffer.length) {
|
|
143
|
-
i++;
|
|
144
|
-
}
|
|
145
|
-
// If are at the end of the buffer there is a problem with the document
|
|
146
|
-
if (i >= buffer.byteLength)
|
|
147
|
-
throw new error_1.BSONError('Bad BSON Document: illegal CString');
|
|
148
|
-
// Represents the key
|
|
149
|
-
var name = isArray ? arrayIndex++ : buffer.toString('utf8', index, i);
|
|
150
|
-
// shouldValidateKey is true if the key should be validated, false otherwise
|
|
151
|
-
var shouldValidateKey = true;
|
|
152
|
-
if (globalUTFValidation || utf8KeysSet.has(name)) {
|
|
153
|
-
shouldValidateKey = validationSetting;
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
shouldValidateKey = !validationSetting;
|
|
157
|
-
}
|
|
158
|
-
if (isPossibleDBRef !== false && name[0] === '$') {
|
|
159
|
-
isPossibleDBRef = allowedDBRefKeys.test(name);
|
|
160
|
-
}
|
|
161
|
-
var value = void 0;
|
|
162
|
-
index = i + 1;
|
|
163
|
-
if (elementType === constants.BSON_DATA_STRING) {
|
|
164
|
-
var stringSize = buffer[index++] |
|
|
165
|
-
(buffer[index++] << 8) |
|
|
166
|
-
(buffer[index++] << 16) |
|
|
167
|
-
(buffer[index++] << 24);
|
|
168
|
-
if (stringSize <= 0 ||
|
|
169
|
-
stringSize > buffer.length - index ||
|
|
170
|
-
buffer[index + stringSize - 1] !== 0) {
|
|
171
|
-
throw new error_1.BSONError('bad string length in bson');
|
|
172
|
-
}
|
|
173
|
-
value = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
|
|
174
|
-
index = index + stringSize;
|
|
175
|
-
}
|
|
176
|
-
else if (elementType === constants.BSON_DATA_OID) {
|
|
177
|
-
var oid = buffer_1.Buffer.alloc(12);
|
|
178
|
-
buffer.copy(oid, 0, index, index + 12);
|
|
179
|
-
value = new objectid_1.ObjectId(oid);
|
|
180
|
-
index = index + 12;
|
|
181
|
-
}
|
|
182
|
-
else if (elementType === constants.BSON_DATA_INT && promoteValues === false) {
|
|
183
|
-
value = new int_32_1.Int32(buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24));
|
|
184
|
-
}
|
|
185
|
-
else if (elementType === constants.BSON_DATA_INT) {
|
|
186
|
-
value =
|
|
187
|
-
buffer[index++] |
|
|
188
|
-
(buffer[index++] << 8) |
|
|
189
|
-
(buffer[index++] << 16) |
|
|
190
|
-
(buffer[index++] << 24);
|
|
191
|
-
}
|
|
192
|
-
else if (elementType === constants.BSON_DATA_NUMBER && promoteValues === false) {
|
|
193
|
-
value = new double_1.Double(dataview.getFloat64(index, true));
|
|
194
|
-
index = index + 8;
|
|
195
|
-
}
|
|
196
|
-
else if (elementType === constants.BSON_DATA_NUMBER) {
|
|
197
|
-
value = dataview.getFloat64(index, true);
|
|
198
|
-
index = index + 8;
|
|
199
|
-
}
|
|
200
|
-
else if (elementType === constants.BSON_DATA_DATE) {
|
|
201
|
-
var lowBits = buffer[index++] |
|
|
202
|
-
(buffer[index++] << 8) |
|
|
203
|
-
(buffer[index++] << 16) |
|
|
204
|
-
(buffer[index++] << 24);
|
|
205
|
-
var highBits = buffer[index++] |
|
|
206
|
-
(buffer[index++] << 8) |
|
|
207
|
-
(buffer[index++] << 16) |
|
|
208
|
-
(buffer[index++] << 24);
|
|
209
|
-
value = new Date(new long_1.Long(lowBits, highBits).toNumber());
|
|
210
|
-
}
|
|
211
|
-
else if (elementType === constants.BSON_DATA_BOOLEAN) {
|
|
212
|
-
if (buffer[index] !== 0 && buffer[index] !== 1)
|
|
213
|
-
throw new error_1.BSONError('illegal boolean type value');
|
|
214
|
-
value = buffer[index++] === 1;
|
|
215
|
-
}
|
|
216
|
-
else if (elementType === constants.BSON_DATA_OBJECT) {
|
|
217
|
-
var _index = index;
|
|
218
|
-
var objectSize = buffer[index] |
|
|
219
|
-
(buffer[index + 1] << 8) |
|
|
220
|
-
(buffer[index + 2] << 16) |
|
|
221
|
-
(buffer[index + 3] << 24);
|
|
222
|
-
if (objectSize <= 0 || objectSize > buffer.length - index)
|
|
223
|
-
throw new error_1.BSONError('bad embedded document length in bson');
|
|
224
|
-
// We have a raw value
|
|
225
|
-
if (raw) {
|
|
226
|
-
value = buffer.slice(index, index + objectSize);
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
var objectOptions = options;
|
|
230
|
-
if (!globalUTFValidation) {
|
|
231
|
-
objectOptions = __assign(__assign({}, options), { validation: { utf8: shouldValidateKey } });
|
|
232
|
-
}
|
|
233
|
-
value = deserializeObject(buffer, _index, objectOptions, false);
|
|
234
|
-
}
|
|
235
|
-
index = index + objectSize;
|
|
236
|
-
}
|
|
237
|
-
else if (elementType === constants.BSON_DATA_ARRAY) {
|
|
238
|
-
var _index = index;
|
|
239
|
-
var objectSize = buffer[index] |
|
|
240
|
-
(buffer[index + 1] << 8) |
|
|
241
|
-
(buffer[index + 2] << 16) |
|
|
242
|
-
(buffer[index + 3] << 24);
|
|
243
|
-
var arrayOptions = options;
|
|
244
|
-
// Stop index
|
|
245
|
-
var stopIndex = index + objectSize;
|
|
246
|
-
// All elements of array to be returned as raw bson
|
|
247
|
-
if (fieldsAsRaw && fieldsAsRaw[name]) {
|
|
248
|
-
arrayOptions = {};
|
|
249
|
-
for (var n in options) {
|
|
250
|
-
arrayOptions[n] = options[n];
|
|
251
|
-
}
|
|
252
|
-
arrayOptions['raw'] = true;
|
|
253
|
-
}
|
|
254
|
-
if (!globalUTFValidation) {
|
|
255
|
-
arrayOptions = __assign(__assign({}, arrayOptions), { validation: { utf8: shouldValidateKey } });
|
|
256
|
-
}
|
|
257
|
-
value = deserializeObject(buffer, _index, arrayOptions, true);
|
|
258
|
-
index = index + objectSize;
|
|
259
|
-
if (buffer[index - 1] !== 0)
|
|
260
|
-
throw new error_1.BSONError('invalid array terminator byte');
|
|
261
|
-
if (index !== stopIndex)
|
|
262
|
-
throw new error_1.BSONError('corrupted array bson');
|
|
263
|
-
}
|
|
264
|
-
else if (elementType === constants.BSON_DATA_UNDEFINED) {
|
|
265
|
-
value = undefined;
|
|
266
|
-
}
|
|
267
|
-
else if (elementType === constants.BSON_DATA_NULL) {
|
|
268
|
-
value = null;
|
|
269
|
-
}
|
|
270
|
-
else if (elementType === constants.BSON_DATA_LONG) {
|
|
271
|
-
// Unpack the low and high bits
|
|
272
|
-
var lowBits = buffer[index++] |
|
|
273
|
-
(buffer[index++] << 8) |
|
|
274
|
-
(buffer[index++] << 16) |
|
|
275
|
-
(buffer[index++] << 24);
|
|
276
|
-
var highBits = buffer[index++] |
|
|
277
|
-
(buffer[index++] << 8) |
|
|
278
|
-
(buffer[index++] << 16) |
|
|
279
|
-
(buffer[index++] << 24);
|
|
280
|
-
var long = new long_1.Long(lowBits, highBits);
|
|
281
|
-
// Promote the long if possible
|
|
282
|
-
if (promoteLongs && promoteValues === true) {
|
|
283
|
-
value =
|
|
284
|
-
long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
|
|
285
|
-
? long.toNumber()
|
|
286
|
-
: long;
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
value = long;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
else if (elementType === constants.BSON_DATA_DECIMAL128) {
|
|
293
|
-
// Buffer to contain the decimal bytes
|
|
294
|
-
var bytes = buffer_1.Buffer.alloc(16);
|
|
295
|
-
// Copy the next 16 bytes into the bytes buffer
|
|
296
|
-
buffer.copy(bytes, 0, index, index + 16);
|
|
297
|
-
// Update index
|
|
298
|
-
index = index + 16;
|
|
299
|
-
// Assign the new Decimal128 value
|
|
300
|
-
var decimal128 = new decimal128_1.Decimal128(bytes);
|
|
301
|
-
// If we have an alternative mapper use that
|
|
302
|
-
if ('toObject' in decimal128 && typeof decimal128.toObject === 'function') {
|
|
303
|
-
value = decimal128.toObject();
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
value = decimal128;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
else if (elementType === constants.BSON_DATA_BINARY) {
|
|
310
|
-
var binarySize = buffer[index++] |
|
|
311
|
-
(buffer[index++] << 8) |
|
|
312
|
-
(buffer[index++] << 16) |
|
|
313
|
-
(buffer[index++] << 24);
|
|
314
|
-
var totalBinarySize = binarySize;
|
|
315
|
-
var subType = buffer[index++];
|
|
316
|
-
// Did we have a negative binary size, throw
|
|
317
|
-
if (binarySize < 0)
|
|
318
|
-
throw new error_1.BSONError('Negative binary type element size found');
|
|
319
|
-
// Is the length longer than the document
|
|
320
|
-
if (binarySize > buffer.byteLength)
|
|
321
|
-
throw new error_1.BSONError('Binary type size larger than document size');
|
|
322
|
-
// Decode as raw Buffer object if options specifies it
|
|
323
|
-
if (buffer['slice'] != null) {
|
|
324
|
-
// If we have subtype 2 skip the 4 bytes for the size
|
|
325
|
-
if (subType === binary_1.Binary.SUBTYPE_BYTE_ARRAY) {
|
|
326
|
-
binarySize =
|
|
327
|
-
buffer[index++] |
|
|
328
|
-
(buffer[index++] << 8) |
|
|
329
|
-
(buffer[index++] << 16) |
|
|
330
|
-
(buffer[index++] << 24);
|
|
331
|
-
if (binarySize < 0)
|
|
332
|
-
throw new error_1.BSONError('Negative binary type element size found for subtype 0x02');
|
|
333
|
-
if (binarySize > totalBinarySize - 4)
|
|
334
|
-
throw new error_1.BSONError('Binary type with subtype 0x02 contains too long binary size');
|
|
335
|
-
if (binarySize < totalBinarySize - 4)
|
|
336
|
-
throw new error_1.BSONError('Binary type with subtype 0x02 contains too short binary size');
|
|
337
|
-
}
|
|
338
|
-
if (promoteBuffers && promoteValues) {
|
|
339
|
-
value = buffer.slice(index, index + binarySize);
|
|
340
|
-
}
|
|
341
|
-
else {
|
|
342
|
-
value = new binary_1.Binary(buffer.slice(index, index + binarySize), subType);
|
|
343
|
-
if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW) {
|
|
344
|
-
value = value.toUUID();
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
var _buffer = buffer_1.Buffer.alloc(binarySize);
|
|
350
|
-
// If we have subtype 2 skip the 4 bytes for the size
|
|
351
|
-
if (subType === binary_1.Binary.SUBTYPE_BYTE_ARRAY) {
|
|
352
|
-
binarySize =
|
|
353
|
-
buffer[index++] |
|
|
354
|
-
(buffer[index++] << 8) |
|
|
355
|
-
(buffer[index++] << 16) |
|
|
356
|
-
(buffer[index++] << 24);
|
|
357
|
-
if (binarySize < 0)
|
|
358
|
-
throw new error_1.BSONError('Negative binary type element size found for subtype 0x02');
|
|
359
|
-
if (binarySize > totalBinarySize - 4)
|
|
360
|
-
throw new error_1.BSONError('Binary type with subtype 0x02 contains too long binary size');
|
|
361
|
-
if (binarySize < totalBinarySize - 4)
|
|
362
|
-
throw new error_1.BSONError('Binary type with subtype 0x02 contains too short binary size');
|
|
363
|
-
}
|
|
364
|
-
// Copy the data
|
|
365
|
-
for (i = 0; i < binarySize; i++) {
|
|
366
|
-
_buffer[i] = buffer[index + i];
|
|
367
|
-
}
|
|
368
|
-
if (promoteBuffers && promoteValues) {
|
|
369
|
-
value = _buffer;
|
|
370
|
-
}
|
|
371
|
-
else if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW) {
|
|
372
|
-
value = new binary_1.Binary(buffer.slice(index, index + binarySize), subType).toUUID();
|
|
373
|
-
}
|
|
374
|
-
else {
|
|
375
|
-
value = new binary_1.Binary(buffer.slice(index, index + binarySize), subType);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
// Update the index
|
|
379
|
-
index = index + binarySize;
|
|
380
|
-
}
|
|
381
|
-
else if (elementType === constants.BSON_DATA_REGEXP && bsonRegExp === false) {
|
|
382
|
-
// Get the start search index
|
|
383
|
-
i = index;
|
|
384
|
-
// Locate the end of the c string
|
|
385
|
-
while (buffer[i] !== 0x00 && i < buffer.length) {
|
|
386
|
-
i++;
|
|
387
|
-
}
|
|
388
|
-
// If are at the end of the buffer there is a problem with the document
|
|
389
|
-
if (i >= buffer.length)
|
|
390
|
-
throw new error_1.BSONError('Bad BSON Document: illegal CString');
|
|
391
|
-
// Return the C string
|
|
392
|
-
var source = buffer.toString('utf8', index, i);
|
|
393
|
-
// Create the regexp
|
|
394
|
-
index = i + 1;
|
|
395
|
-
// Get the start search index
|
|
396
|
-
i = index;
|
|
397
|
-
// Locate the end of the c string
|
|
398
|
-
while (buffer[i] !== 0x00 && i < buffer.length) {
|
|
399
|
-
i++;
|
|
400
|
-
}
|
|
401
|
-
// If are at the end of the buffer there is a problem with the document
|
|
402
|
-
if (i >= buffer.length)
|
|
403
|
-
throw new error_1.BSONError('Bad BSON Document: illegal CString');
|
|
404
|
-
// Return the C string
|
|
405
|
-
var regExpOptions = buffer.toString('utf8', index, i);
|
|
406
|
-
index = i + 1;
|
|
407
|
-
// For each option add the corresponding one for javascript
|
|
408
|
-
var optionsArray = new Array(regExpOptions.length);
|
|
409
|
-
// Parse options
|
|
410
|
-
for (i = 0; i < regExpOptions.length; i++) {
|
|
411
|
-
switch (regExpOptions[i]) {
|
|
412
|
-
case 'm':
|
|
413
|
-
optionsArray[i] = 'm';
|
|
414
|
-
break;
|
|
415
|
-
case 's':
|
|
416
|
-
optionsArray[i] = 'g';
|
|
417
|
-
break;
|
|
418
|
-
case 'i':
|
|
419
|
-
optionsArray[i] = 'i';
|
|
420
|
-
break;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
value = new RegExp(source, optionsArray.join(''));
|
|
424
|
-
}
|
|
425
|
-
else if (elementType === constants.BSON_DATA_REGEXP && bsonRegExp === true) {
|
|
426
|
-
// Get the start search index
|
|
427
|
-
i = index;
|
|
428
|
-
// Locate the end of the c string
|
|
429
|
-
while (buffer[i] !== 0x00 && i < buffer.length) {
|
|
430
|
-
i++;
|
|
431
|
-
}
|
|
432
|
-
// If are at the end of the buffer there is a problem with the document
|
|
433
|
-
if (i >= buffer.length)
|
|
434
|
-
throw new error_1.BSONError('Bad BSON Document: illegal CString');
|
|
435
|
-
// Return the C string
|
|
436
|
-
var source = buffer.toString('utf8', index, i);
|
|
437
|
-
index = i + 1;
|
|
438
|
-
// Get the start search index
|
|
439
|
-
i = index;
|
|
440
|
-
// Locate the end of the c string
|
|
441
|
-
while (buffer[i] !== 0x00 && i < buffer.length) {
|
|
442
|
-
i++;
|
|
443
|
-
}
|
|
444
|
-
// If are at the end of the buffer there is a problem with the document
|
|
445
|
-
if (i >= buffer.length)
|
|
446
|
-
throw new error_1.BSONError('Bad BSON Document: illegal CString');
|
|
447
|
-
// Return the C string
|
|
448
|
-
var regExpOptions = buffer.toString('utf8', index, i);
|
|
449
|
-
index = i + 1;
|
|
450
|
-
// Set the object
|
|
451
|
-
value = new regexp_1.BSONRegExp(source, regExpOptions);
|
|
452
|
-
}
|
|
453
|
-
else if (elementType === constants.BSON_DATA_SYMBOL) {
|
|
454
|
-
var stringSize = buffer[index++] |
|
|
455
|
-
(buffer[index++] << 8) |
|
|
456
|
-
(buffer[index++] << 16) |
|
|
457
|
-
(buffer[index++] << 24);
|
|
458
|
-
if (stringSize <= 0 ||
|
|
459
|
-
stringSize > buffer.length - index ||
|
|
460
|
-
buffer[index + stringSize - 1] !== 0) {
|
|
461
|
-
throw new error_1.BSONError('bad string length in bson');
|
|
462
|
-
}
|
|
463
|
-
var symbol = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
|
|
464
|
-
value = promoteValues ? symbol : new symbol_1.BSONSymbol(symbol);
|
|
465
|
-
index = index + stringSize;
|
|
466
|
-
}
|
|
467
|
-
else if (elementType === constants.BSON_DATA_TIMESTAMP) {
|
|
468
|
-
var lowBits = buffer[index++] |
|
|
469
|
-
(buffer[index++] << 8) |
|
|
470
|
-
(buffer[index++] << 16) |
|
|
471
|
-
(buffer[index++] << 24);
|
|
472
|
-
var highBits = buffer[index++] |
|
|
473
|
-
(buffer[index++] << 8) |
|
|
474
|
-
(buffer[index++] << 16) |
|
|
475
|
-
(buffer[index++] << 24);
|
|
476
|
-
value = new timestamp_1.Timestamp(lowBits, highBits);
|
|
477
|
-
}
|
|
478
|
-
else if (elementType === constants.BSON_DATA_MIN_KEY) {
|
|
479
|
-
value = new min_key_1.MinKey();
|
|
480
|
-
}
|
|
481
|
-
else if (elementType === constants.BSON_DATA_MAX_KEY) {
|
|
482
|
-
value = new max_key_1.MaxKey();
|
|
483
|
-
}
|
|
484
|
-
else if (elementType === constants.BSON_DATA_CODE) {
|
|
485
|
-
var stringSize = buffer[index++] |
|
|
486
|
-
(buffer[index++] << 8) |
|
|
487
|
-
(buffer[index++] << 16) |
|
|
488
|
-
(buffer[index++] << 24);
|
|
489
|
-
if (stringSize <= 0 ||
|
|
490
|
-
stringSize > buffer.length - index ||
|
|
491
|
-
buffer[index + stringSize - 1] !== 0) {
|
|
492
|
-
throw new error_1.BSONError('bad string length in bson');
|
|
493
|
-
}
|
|
494
|
-
var functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
|
|
495
|
-
// If we are evaluating the functions
|
|
496
|
-
if (evalFunctions) {
|
|
497
|
-
// If we have cache enabled let's look for the md5 of the function in the cache
|
|
498
|
-
if (cacheFunctions) {
|
|
499
|
-
// Got to do this to avoid V8 deoptimizing the call due to finding eval
|
|
500
|
-
value = isolateEval(functionString, functionCache, object);
|
|
501
|
-
}
|
|
502
|
-
else {
|
|
503
|
-
value = isolateEval(functionString);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
else {
|
|
507
|
-
value = new code_1.Code(functionString);
|
|
508
|
-
}
|
|
509
|
-
// Update parse index position
|
|
510
|
-
index = index + stringSize;
|
|
511
|
-
}
|
|
512
|
-
else if (elementType === constants.BSON_DATA_CODE_W_SCOPE) {
|
|
513
|
-
var totalSize = buffer[index++] |
|
|
514
|
-
(buffer[index++] << 8) |
|
|
515
|
-
(buffer[index++] << 16) |
|
|
516
|
-
(buffer[index++] << 24);
|
|
517
|
-
// Element cannot be shorter than totalSize + stringSize + documentSize + terminator
|
|
518
|
-
if (totalSize < 4 + 4 + 4 + 1) {
|
|
519
|
-
throw new error_1.BSONError('code_w_scope total size shorter minimum expected length');
|
|
520
|
-
}
|
|
521
|
-
// Get the code string size
|
|
522
|
-
var stringSize = buffer[index++] |
|
|
523
|
-
(buffer[index++] << 8) |
|
|
524
|
-
(buffer[index++] << 16) |
|
|
525
|
-
(buffer[index++] << 24);
|
|
526
|
-
// Check if we have a valid string
|
|
527
|
-
if (stringSize <= 0 ||
|
|
528
|
-
stringSize > buffer.length - index ||
|
|
529
|
-
buffer[index + stringSize - 1] !== 0) {
|
|
530
|
-
throw new error_1.BSONError('bad string length in bson');
|
|
531
|
-
}
|
|
532
|
-
// Javascript function
|
|
533
|
-
var functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
|
|
534
|
-
// Update parse index position
|
|
535
|
-
index = index + stringSize;
|
|
536
|
-
// Parse the element
|
|
537
|
-
var _index = index;
|
|
538
|
-
// Decode the size of the object document
|
|
539
|
-
var objectSize = buffer[index] |
|
|
540
|
-
(buffer[index + 1] << 8) |
|
|
541
|
-
(buffer[index + 2] << 16) |
|
|
542
|
-
(buffer[index + 3] << 24);
|
|
543
|
-
// Decode the scope object
|
|
544
|
-
var scopeObject = deserializeObject(buffer, _index, options, false);
|
|
545
|
-
// Adjust the index
|
|
546
|
-
index = index + objectSize;
|
|
547
|
-
// Check if field length is too short
|
|
548
|
-
if (totalSize < 4 + 4 + objectSize + stringSize) {
|
|
549
|
-
throw new error_1.BSONError('code_w_scope total size is too short, truncating scope');
|
|
550
|
-
}
|
|
551
|
-
// Check if totalSize field is too long
|
|
552
|
-
if (totalSize > 4 + 4 + objectSize + stringSize) {
|
|
553
|
-
throw new error_1.BSONError('code_w_scope total size is too long, clips outer document');
|
|
554
|
-
}
|
|
555
|
-
// If we are evaluating the functions
|
|
556
|
-
if (evalFunctions) {
|
|
557
|
-
// If we have cache enabled let's look for the md5 of the function in the cache
|
|
558
|
-
if (cacheFunctions) {
|
|
559
|
-
// Got to do this to avoid V8 deoptimizing the call due to finding eval
|
|
560
|
-
value = isolateEval(functionString, functionCache, object);
|
|
561
|
-
}
|
|
562
|
-
else {
|
|
563
|
-
value = isolateEval(functionString);
|
|
564
|
-
}
|
|
565
|
-
value.scope = scopeObject;
|
|
566
|
-
}
|
|
567
|
-
else {
|
|
568
|
-
value = new code_1.Code(functionString, scopeObject);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
else if (elementType === constants.BSON_DATA_DBPOINTER) {
|
|
572
|
-
// Get the code string size
|
|
573
|
-
var stringSize = buffer[index++] |
|
|
574
|
-
(buffer[index++] << 8) |
|
|
575
|
-
(buffer[index++] << 16) |
|
|
576
|
-
(buffer[index++] << 24);
|
|
577
|
-
// Check if we have a valid string
|
|
578
|
-
if (stringSize <= 0 ||
|
|
579
|
-
stringSize > buffer.length - index ||
|
|
580
|
-
buffer[index + stringSize - 1] !== 0)
|
|
581
|
-
throw new error_1.BSONError('bad string length in bson');
|
|
582
|
-
// Namespace
|
|
583
|
-
if (validation != null && validation.utf8) {
|
|
584
|
-
if (!(0, validate_utf8_1.validateUtf8)(buffer, index, index + stringSize - 1)) {
|
|
585
|
-
throw new error_1.BSONError('Invalid UTF-8 string in BSON document');
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
var namespace = buffer.toString('utf8', index, index + stringSize - 1);
|
|
589
|
-
// Update parse index position
|
|
590
|
-
index = index + stringSize;
|
|
591
|
-
// Read the oid
|
|
592
|
-
var oidBuffer = buffer_1.Buffer.alloc(12);
|
|
593
|
-
buffer.copy(oidBuffer, 0, index, index + 12);
|
|
594
|
-
var oid = new objectid_1.ObjectId(oidBuffer);
|
|
595
|
-
// Update the index
|
|
596
|
-
index = index + 12;
|
|
597
|
-
// Upgrade to DBRef type
|
|
598
|
-
value = new db_ref_1.DBRef(namespace, oid);
|
|
599
|
-
}
|
|
600
|
-
else {
|
|
601
|
-
throw new error_1.BSONError("Detected unknown BSON type ".concat(elementType.toString(16), " for fieldname \"").concat(name, "\""));
|
|
602
|
-
}
|
|
603
|
-
if (name === '__proto__') {
|
|
604
|
-
Object.defineProperty(object, name, {
|
|
605
|
-
value: value,
|
|
606
|
-
writable: true,
|
|
607
|
-
enumerable: true,
|
|
608
|
-
configurable: true
|
|
609
|
-
});
|
|
610
|
-
}
|
|
611
|
-
else {
|
|
612
|
-
object[name] = value;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
// Check if the deserialization was against a valid array/object
|
|
616
|
-
if (size !== index - startIndex) {
|
|
617
|
-
if (isArray)
|
|
618
|
-
throw new error_1.BSONError('corrupt array bson');
|
|
619
|
-
throw new error_1.BSONError('corrupt object bson');
|
|
620
|
-
}
|
|
621
|
-
// if we did not find "$ref", "$id", "$db", or found an extraneous $key, don't make a DBRef
|
|
622
|
-
if (!isPossibleDBRef)
|
|
623
|
-
return object;
|
|
624
|
-
if ((0, db_ref_1.isDBRefLike)(object)) {
|
|
625
|
-
var copy = Object.assign({}, object);
|
|
626
|
-
delete copy.$ref;
|
|
627
|
-
delete copy.$id;
|
|
628
|
-
delete copy.$db;
|
|
629
|
-
return new db_ref_1.DBRef(object.$ref, object.$id, object.$db, copy);
|
|
630
|
-
}
|
|
631
|
-
return object;
|
|
632
|
-
}
|
|
633
|
-
/**
|
|
634
|
-
* Ensure eval is isolated, store the result in functionCache.
|
|
635
|
-
*
|
|
636
|
-
* @internal
|
|
637
|
-
*/
|
|
638
|
-
function isolateEval(functionString, functionCache, object) {
|
|
639
|
-
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
640
|
-
if (!functionCache)
|
|
641
|
-
return new Function(functionString);
|
|
642
|
-
// Check for cache hit, eval if missing and return cached function
|
|
643
|
-
if (functionCache[functionString] == null) {
|
|
644
|
-
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
645
|
-
functionCache[functionString] = new Function(functionString);
|
|
646
|
-
}
|
|
647
|
-
// Set the object
|
|
648
|
-
return functionCache[functionString].bind(object);
|
|
649
|
-
}
|
|
650
|
-
function getValidatedString(buffer, start, end, shouldValidateUtf8) {
|
|
651
|
-
var value = buffer.toString('utf8', start, end);
|
|
652
|
-
// if utf8 validation is on, do the check
|
|
653
|
-
if (shouldValidateUtf8) {
|
|
654
|
-
for (var i = 0; i < value.length; i++) {
|
|
655
|
-
if (value.charCodeAt(i) === 0xfffd) {
|
|
656
|
-
if (!(0, validate_utf8_1.validateUtf8)(buffer, start, end)) {
|
|
657
|
-
throw new error_1.BSONError('Invalid UTF-8 string in BSON document');
|
|
658
|
-
}
|
|
659
|
-
break;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
return value;
|
|
664
|
-
}
|
|
665
|
-
//# sourceMappingURL=deserializer.js.map
|