something is working

This commit is contained in:
quoije
2022-09-15 01:55:36 -04:00
parent a0aa251c27
commit f38e69883c
1123 changed files with 251731 additions and 11 deletions
+194
View File
@@ -0,0 +1,194 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateObjectSize = void 0;
var buffer_1 = require("buffer");
var binary_1 = require("../binary");
var constants = require("../constants");
var utils_1 = require("./utils");
function calculateObjectSize(object, serializeFunctions, ignoreUndefined) {
var totalLength = 4 + 1;
if (Array.isArray(object)) {
for (var i = 0; i < object.length; i++) {
totalLength += calculateElement(i.toString(), object[i], serializeFunctions, true, ignoreUndefined);
}
}
else {
// If we have toBSON defined, override the current object
if (typeof (object === null || object === void 0 ? void 0 : object.toBSON) === 'function') {
object = object.toBSON();
}
// Calculate size
for (var key in object) {
totalLength += calculateElement(key, object[key], serializeFunctions, false, ignoreUndefined);
}
}
return totalLength;
}
exports.calculateObjectSize = calculateObjectSize;
/** @internal */
function calculateElement(name,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value, serializeFunctions, isArray, ignoreUndefined) {
if (serializeFunctions === void 0) { serializeFunctions = false; }
if (isArray === void 0) { isArray = false; }
if (ignoreUndefined === void 0) { ignoreUndefined = false; }
// If we have toBSON defined, override the current object
if (typeof (value === null || value === void 0 ? void 0 : value.toBSON) === 'function') {
value = value.toBSON();
}
switch (typeof value) {
case 'string':
return 1 + buffer_1.Buffer.byteLength(name, 'utf8') + 1 + 4 + buffer_1.Buffer.byteLength(value, 'utf8') + 1;
case 'number':
if (Math.floor(value) === value &&
value >= constants.JS_INT_MIN &&
value <= constants.JS_INT_MAX) {
if (value >= constants.BSON_INT32_MIN && value <= constants.BSON_INT32_MAX) {
// 32 bit
return (name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + (4 + 1);
}
else {
return (name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + (8 + 1);
}
}
else {
// 64 bit
return (name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + (8 + 1);
}
case 'undefined':
if (isArray || !ignoreUndefined)
return (name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + 1;
return 0;
case 'boolean':
return (name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + (1 + 1);
case 'object':
if (value == null || value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
return (name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + 1;
}
else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
return (name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + (12 + 1);
}
else if (value instanceof Date || (0, utils_1.isDate)(value)) {
return (name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + (8 + 1);
}
else if (ArrayBuffer.isView(value) ||
value instanceof ArrayBuffer ||
(0, utils_1.isAnyArrayBuffer)(value)) {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + (1 + 4 + 1) + value.byteLength);
}
else if (value['_bsontype'] === 'Long' ||
value['_bsontype'] === 'Double' ||
value['_bsontype'] === 'Timestamp') {
return (name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + (8 + 1);
}
else if (value['_bsontype'] === 'Decimal128') {
return (name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + (16 + 1);
}
else if (value['_bsontype'] === 'Code') {
// Calculate size depending on the availability of a scope
if (value.scope != null && Object.keys(value.scope).length > 0) {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
1 +
4 +
4 +
buffer_1.Buffer.byteLength(value.code.toString(), 'utf8') +
1 +
calculateObjectSize(value.scope, serializeFunctions, ignoreUndefined));
}
else {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
1 +
4 +
buffer_1.Buffer.byteLength(value.code.toString(), 'utf8') +
1);
}
}
else if (value['_bsontype'] === 'Binary') {
var binary = value;
// Check what kind of subtype we have
if (binary.sub_type === binary_1.Binary.SUBTYPE_BYTE_ARRAY) {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
(binary.position + 1 + 4 + 1 + 4));
}
else {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) + (binary.position + 1 + 4 + 1));
}
}
else if (value['_bsontype'] === 'Symbol') {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
buffer_1.Buffer.byteLength(value.value, 'utf8') +
4 +
1 +
1);
}
else if (value['_bsontype'] === 'DBRef') {
// Set up correct object for serialization
var ordered_values = Object.assign({
$ref: value.collection,
$id: value.oid
}, value.fields);
// Add db reference if it exists
if (value.db != null) {
ordered_values['$db'] = value.db;
}
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
1 +
calculateObjectSize(ordered_values, serializeFunctions, ignoreUndefined));
}
else if (value instanceof RegExp || (0, utils_1.isRegExp)(value)) {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
1 +
buffer_1.Buffer.byteLength(value.source, 'utf8') +
1 +
(value.global ? 1 : 0) +
(value.ignoreCase ? 1 : 0) +
(value.multiline ? 1 : 0) +
1);
}
else if (value['_bsontype'] === 'BSONRegExp') {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
1 +
buffer_1.Buffer.byteLength(value.pattern, 'utf8') +
1 +
buffer_1.Buffer.byteLength(value.options, 'utf8') +
1);
}
else {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
calculateObjectSize(value, serializeFunctions, ignoreUndefined) +
1);
}
case 'function':
// WTF for 0.4.X where typeof /someregexp/ === 'function'
if (value instanceof RegExp || (0, utils_1.isRegExp)(value) || String.call(value) === '[object RegExp]') {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
1 +
buffer_1.Buffer.byteLength(value.source, 'utf8') +
1 +
(value.global ? 1 : 0) +
(value.ignoreCase ? 1 : 0) +
(value.multiline ? 1 : 0) +
1);
}
else {
if (serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
1 +
4 +
4 +
buffer_1.Buffer.byteLength((0, utils_1.normalizedFunctionString)(value), 'utf8') +
1 +
calculateObjectSize(value.scope, serializeFunctions, ignoreUndefined));
}
else if (serializeFunctions) {
return ((name != null ? buffer_1.Buffer.byteLength(name, 'utf8') + 1 : 0) +
1 +
4 +
buffer_1.Buffer.byteLength((0, utils_1.normalizedFunctionString)(value), 'utf8') +
1);
}
}
}
return 0;
}
//# sourceMappingURL=calculate_size.js.map
File diff suppressed because one or more lines are too long
+665
View File
@@ -0,0 +1,665 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.deserialize = void 0;
var buffer_1 = require("buffer");
var binary_1 = require("../binary");
var code_1 = require("../code");
var constants = require("../constants");
var db_ref_1 = require("../db_ref");
var decimal128_1 = require("../decimal128");
var double_1 = require("../double");
var error_1 = require("../error");
var int_32_1 = require("../int_32");
var long_1 = require("../long");
var max_key_1 = require("../max_key");
var min_key_1 = require("../min_key");
var objectid_1 = require("../objectid");
var regexp_1 = require("../regexp");
var symbol_1 = require("../symbol");
var timestamp_1 = require("../timestamp");
var validate_utf8_1 = require("../validate_utf8");
// Internal long versions
var JS_INT_MAX_LONG = long_1.Long.fromNumber(constants.JS_INT_MAX);
var JS_INT_MIN_LONG = long_1.Long.fromNumber(constants.JS_INT_MIN);
var functionCache = {};
function deserialize(buffer, options, isArray) {
options = options == null ? {} : options;
var index = options && options.index ? options.index : 0;
// Read the document size
var size = buffer[index] |
(buffer[index + 1] << 8) |
(buffer[index + 2] << 16) |
(buffer[index + 3] << 24);
if (size < 5) {
throw new error_1.BSONError("bson size must be >= 5, is ".concat(size));
}
if (options.allowObjectSmallerThanBufferSize && buffer.length < size) {
throw new error_1.BSONError("buffer length ".concat(buffer.length, " must be >= bson size ").concat(size));
}
if (!options.allowObjectSmallerThanBufferSize && buffer.length !== size) {
throw new error_1.BSONError("buffer length ".concat(buffer.length, " must === bson size ").concat(size));
}
if (size + index > buffer.byteLength) {
throw new error_1.BSONError("(bson size ".concat(size, " + options.index ").concat(index, " must be <= buffer length ").concat(buffer.byteLength, ")"));
}
// Illegal end value
if (buffer[index + size - 1] !== 0) {
throw new error_1.BSONError("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");
}
// Start deserializtion
return deserializeObject(buffer, index, options, isArray);
}
exports.deserialize = deserialize;
var allowedDBRefKeys = /^\$ref$|^\$id$|^\$db$/;
function deserializeObject(buffer, index, options, isArray) {
if (isArray === void 0) { isArray = false; }
var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions'];
var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions'];
var fieldsAsRaw = options['fieldsAsRaw'] == null ? null : options['fieldsAsRaw'];
// Return raw bson buffer instead of parsing it
var raw = options['raw'] == null ? false : options['raw'];
// Return BSONRegExp objects instead of native regular expressions
var bsonRegExp = typeof options['bsonRegExp'] === 'boolean' ? options['bsonRegExp'] : false;
// Controls the promotion of values vs wrapper classes
var promoteBuffers = options['promoteBuffers'] == null ? false : options['promoteBuffers'];
var promoteLongs = options['promoteLongs'] == null ? true : options['promoteLongs'];
var promoteValues = options['promoteValues'] == null ? true : options['promoteValues'];
// Ensures default validation option if none given
var validation = options.validation == null ? { utf8: true } : options.validation;
// Shows if global utf-8 validation is enabled or disabled
var globalUTFValidation = true;
// Reflects utf-8 validation setting regardless of global or specific key validation
var validationSetting;
// Set of keys either to enable or disable validation on
var utf8KeysSet = new Set();
// Check for boolean uniformity and empty validation option
var utf8ValidatedKeys = validation.utf8;
if (typeof utf8ValidatedKeys === 'boolean') {
validationSetting = utf8ValidatedKeys;
}
else {
globalUTFValidation = false;
var utf8ValidationValues = Object.keys(utf8ValidatedKeys).map(function (key) {
return utf8ValidatedKeys[key];
});
if (utf8ValidationValues.length === 0) {
throw new error_1.BSONError('UTF-8 validation setting cannot be empty');
}
if (typeof utf8ValidationValues[0] !== 'boolean') {
throw new error_1.BSONError('Invalid UTF-8 validation option, must specify boolean values');
}
validationSetting = utf8ValidationValues[0];
// Ensures boolean uniformity in utf-8 validation (all true or all false)
if (!utf8ValidationValues.every(function (item) { return item === validationSetting; })) {
throw new error_1.BSONError('Invalid UTF-8 validation option - keys must be all true or all false');
}
}
// Add keys to set that will either be validated or not based on validationSetting
if (!globalUTFValidation) {
for (var _i = 0, _a = Object.keys(utf8ValidatedKeys); _i < _a.length; _i++) {
var key = _a[_i];
utf8KeysSet.add(key);
}
}
// Set the start index
var startIndex = index;
// Validate that we have at least 4 bytes of buffer
if (buffer.length < 5)
throw new error_1.BSONError('corrupt bson message < 5 bytes long');
// Read the document size
var size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
// Ensure buffer is valid size
if (size < 5 || size > buffer.length)
throw new error_1.BSONError('corrupt bson message');
// Create holding object
var object = isArray ? [] : {};
// Used for arrays to skip having to perform utf8 decoding
var arrayIndex = 0;
var done = false;
var isPossibleDBRef = isArray ? false : null;
// While we have more left data left keep parsing
var dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
while (!done) {
// Read the type
var elementType = buffer[index++];
// If we get a zero it's the last byte, exit
if (elementType === 0)
break;
// Get the start search index
var i = index;
// Locate the end of the c string
while (buffer[i] !== 0x00 && i < buffer.length) {
i++;
}
// If are at the end of the buffer there is a problem with the document
if (i >= buffer.byteLength)
throw new error_1.BSONError('Bad BSON Document: illegal CString');
// Represents the key
var name = isArray ? arrayIndex++ : buffer.toString('utf8', index, i);
// shouldValidateKey is true if the key should be validated, false otherwise
var shouldValidateKey = true;
if (globalUTFValidation || utf8KeysSet.has(name)) {
shouldValidateKey = validationSetting;
}
else {
shouldValidateKey = !validationSetting;
}
if (isPossibleDBRef !== false && name[0] === '$') {
isPossibleDBRef = allowedDBRefKeys.test(name);
}
var value = void 0;
index = i + 1;
if (elementType === constants.BSON_DATA_STRING) {
var stringSize = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
if (stringSize <= 0 ||
stringSize > buffer.length - index ||
buffer[index + stringSize - 1] !== 0) {
throw new error_1.BSONError('bad string length in bson');
}
value = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
index = index + stringSize;
}
else if (elementType === constants.BSON_DATA_OID) {
var oid = buffer_1.Buffer.alloc(12);
buffer.copy(oid, 0, index, index + 12);
value = new objectid_1.ObjectId(oid);
index = index + 12;
}
else if (elementType === constants.BSON_DATA_INT && promoteValues === false) {
value = new int_32_1.Int32(buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24));
}
else if (elementType === constants.BSON_DATA_INT) {
value =
buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
}
else if (elementType === constants.BSON_DATA_NUMBER && promoteValues === false) {
value = new double_1.Double(dataview.getFloat64(index, true));
index = index + 8;
}
else if (elementType === constants.BSON_DATA_NUMBER) {
value = dataview.getFloat64(index, true);
index = index + 8;
}
else if (elementType === constants.BSON_DATA_DATE) {
var lowBits = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
var highBits = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
value = new Date(new long_1.Long(lowBits, highBits).toNumber());
}
else if (elementType === constants.BSON_DATA_BOOLEAN) {
if (buffer[index] !== 0 && buffer[index] !== 1)
throw new error_1.BSONError('illegal boolean type value');
value = buffer[index++] === 1;
}
else if (elementType === constants.BSON_DATA_OBJECT) {
var _index = index;
var objectSize = buffer[index] |
(buffer[index + 1] << 8) |
(buffer[index + 2] << 16) |
(buffer[index + 3] << 24);
if (objectSize <= 0 || objectSize > buffer.length - index)
throw new error_1.BSONError('bad embedded document length in bson');
// We have a raw value
if (raw) {
value = buffer.slice(index, index + objectSize);
}
else {
var objectOptions = options;
if (!globalUTFValidation) {
objectOptions = __assign(__assign({}, options), { validation: { utf8: shouldValidateKey } });
}
value = deserializeObject(buffer, _index, objectOptions, false);
}
index = index + objectSize;
}
else if (elementType === constants.BSON_DATA_ARRAY) {
var _index = index;
var objectSize = buffer[index] |
(buffer[index + 1] << 8) |
(buffer[index + 2] << 16) |
(buffer[index + 3] << 24);
var arrayOptions = options;
// Stop index
var stopIndex = index + objectSize;
// All elements of array to be returned as raw bson
if (fieldsAsRaw && fieldsAsRaw[name]) {
arrayOptions = {};
for (var n in options) {
arrayOptions[n] = options[n];
}
arrayOptions['raw'] = true;
}
if (!globalUTFValidation) {
arrayOptions = __assign(__assign({}, arrayOptions), { validation: { utf8: shouldValidateKey } });
}
value = deserializeObject(buffer, _index, arrayOptions, true);
index = index + objectSize;
if (buffer[index - 1] !== 0)
throw new error_1.BSONError('invalid array terminator byte');
if (index !== stopIndex)
throw new error_1.BSONError('corrupted array bson');
}
else if (elementType === constants.BSON_DATA_UNDEFINED) {
value = undefined;
}
else if (elementType === constants.BSON_DATA_NULL) {
value = null;
}
else if (elementType === constants.BSON_DATA_LONG) {
// Unpack the low and high bits
var lowBits = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
var highBits = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
var long = new long_1.Long(lowBits, highBits);
// Promote the long if possible
if (promoteLongs && promoteValues === true) {
value =
long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
? long.toNumber()
: long;
}
else {
value = long;
}
}
else if (elementType === constants.BSON_DATA_DECIMAL128) {
// Buffer to contain the decimal bytes
var bytes = buffer_1.Buffer.alloc(16);
// Copy the next 16 bytes into the bytes buffer
buffer.copy(bytes, 0, index, index + 16);
// Update index
index = index + 16;
// Assign the new Decimal128 value
var decimal128 = new decimal128_1.Decimal128(bytes);
// If we have an alternative mapper use that
if ('toObject' in decimal128 && typeof decimal128.toObject === 'function') {
value = decimal128.toObject();
}
else {
value = decimal128;
}
}
else if (elementType === constants.BSON_DATA_BINARY) {
var binarySize = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
var totalBinarySize = binarySize;
var subType = buffer[index++];
// Did we have a negative binary size, throw
if (binarySize < 0)
throw new error_1.BSONError('Negative binary type element size found');
// Is the length longer than the document
if (binarySize > buffer.byteLength)
throw new error_1.BSONError('Binary type size larger than document size');
// Decode as raw Buffer object if options specifies it
if (buffer['slice'] != null) {
// If we have subtype 2 skip the 4 bytes for the size
if (subType === binary_1.Binary.SUBTYPE_BYTE_ARRAY) {
binarySize =
buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
if (binarySize < 0)
throw new error_1.BSONError('Negative binary type element size found for subtype 0x02');
if (binarySize > totalBinarySize - 4)
throw new error_1.BSONError('Binary type with subtype 0x02 contains too long binary size');
if (binarySize < totalBinarySize - 4)
throw new error_1.BSONError('Binary type with subtype 0x02 contains too short binary size');
}
if (promoteBuffers && promoteValues) {
value = buffer.slice(index, index + binarySize);
}
else {
value = new binary_1.Binary(buffer.slice(index, index + binarySize), subType);
if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW) {
value = value.toUUID();
}
}
}
else {
var _buffer = buffer_1.Buffer.alloc(binarySize);
// If we have subtype 2 skip the 4 bytes for the size
if (subType === binary_1.Binary.SUBTYPE_BYTE_ARRAY) {
binarySize =
buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
if (binarySize < 0)
throw new error_1.BSONError('Negative binary type element size found for subtype 0x02');
if (binarySize > totalBinarySize - 4)
throw new error_1.BSONError('Binary type with subtype 0x02 contains too long binary size');
if (binarySize < totalBinarySize - 4)
throw new error_1.BSONError('Binary type with subtype 0x02 contains too short binary size');
}
// Copy the data
for (i = 0; i < binarySize; i++) {
_buffer[i] = buffer[index + i];
}
if (promoteBuffers && promoteValues) {
value = _buffer;
}
else if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW) {
value = new binary_1.Binary(buffer.slice(index, index + binarySize), subType).toUUID();
}
else {
value = new binary_1.Binary(buffer.slice(index, index + binarySize), subType);
}
}
// Update the index
index = index + binarySize;
}
else if (elementType === constants.BSON_DATA_REGEXP && bsonRegExp === false) {
// Get the start search index
i = index;
// Locate the end of the c string
while (buffer[i] !== 0x00 && i < buffer.length) {
i++;
}
// If are at the end of the buffer there is a problem with the document
if (i >= buffer.length)
throw new error_1.BSONError('Bad BSON Document: illegal CString');
// Return the C string
var source = buffer.toString('utf8', index, i);
// Create the regexp
index = i + 1;
// Get the start search index
i = index;
// Locate the end of the c string
while (buffer[i] !== 0x00 && i < buffer.length) {
i++;
}
// If are at the end of the buffer there is a problem with the document
if (i >= buffer.length)
throw new error_1.BSONError('Bad BSON Document: illegal CString');
// Return the C string
var regExpOptions = buffer.toString('utf8', index, i);
index = i + 1;
// For each option add the corresponding one for javascript
var optionsArray = new Array(regExpOptions.length);
// Parse options
for (i = 0; i < regExpOptions.length; i++) {
switch (regExpOptions[i]) {
case 'm':
optionsArray[i] = 'm';
break;
case 's':
optionsArray[i] = 'g';
break;
case 'i':
optionsArray[i] = 'i';
break;
}
}
value = new RegExp(source, optionsArray.join(''));
}
else if (elementType === constants.BSON_DATA_REGEXP && bsonRegExp === true) {
// Get the start search index
i = index;
// Locate the end of the c string
while (buffer[i] !== 0x00 && i < buffer.length) {
i++;
}
// If are at the end of the buffer there is a problem with the document
if (i >= buffer.length)
throw new error_1.BSONError('Bad BSON Document: illegal CString');
// Return the C string
var source = buffer.toString('utf8', index, i);
index = i + 1;
// Get the start search index
i = index;
// Locate the end of the c string
while (buffer[i] !== 0x00 && i < buffer.length) {
i++;
}
// If are at the end of the buffer there is a problem with the document
if (i >= buffer.length)
throw new error_1.BSONError('Bad BSON Document: illegal CString');
// Return the C string
var regExpOptions = buffer.toString('utf8', index, i);
index = i + 1;
// Set the object
value = new regexp_1.BSONRegExp(source, regExpOptions);
}
else if (elementType === constants.BSON_DATA_SYMBOL) {
var stringSize = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
if (stringSize <= 0 ||
stringSize > buffer.length - index ||
buffer[index + stringSize - 1] !== 0) {
throw new error_1.BSONError('bad string length in bson');
}
var symbol = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
value = promoteValues ? symbol : new symbol_1.BSONSymbol(symbol);
index = index + stringSize;
}
else if (elementType === constants.BSON_DATA_TIMESTAMP) {
var lowBits = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
var highBits = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
value = new timestamp_1.Timestamp(lowBits, highBits);
}
else if (elementType === constants.BSON_DATA_MIN_KEY) {
value = new min_key_1.MinKey();
}
else if (elementType === constants.BSON_DATA_MAX_KEY) {
value = new max_key_1.MaxKey();
}
else if (elementType === constants.BSON_DATA_CODE) {
var stringSize = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
if (stringSize <= 0 ||
stringSize > buffer.length - index ||
buffer[index + stringSize - 1] !== 0) {
throw new error_1.BSONError('bad string length in bson');
}
var functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
// If we are evaluating the functions
if (evalFunctions) {
// If we have cache enabled let's look for the md5 of the function in the cache
if (cacheFunctions) {
// Got to do this to avoid V8 deoptimizing the call due to finding eval
value = isolateEval(functionString, functionCache, object);
}
else {
value = isolateEval(functionString);
}
}
else {
value = new code_1.Code(functionString);
}
// Update parse index position
index = index + stringSize;
}
else if (elementType === constants.BSON_DATA_CODE_W_SCOPE) {
var totalSize = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
// Element cannot be shorter than totalSize + stringSize + documentSize + terminator
if (totalSize < 4 + 4 + 4 + 1) {
throw new error_1.BSONError('code_w_scope total size shorter minimum expected length');
}
// Get the code string size
var stringSize = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
// Check if we have a valid string
if (stringSize <= 0 ||
stringSize > buffer.length - index ||
buffer[index + stringSize - 1] !== 0) {
throw new error_1.BSONError('bad string length in bson');
}
// Javascript function
var functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey);
// Update parse index position
index = index + stringSize;
// Parse the element
var _index = index;
// Decode the size of the object document
var objectSize = buffer[index] |
(buffer[index + 1] << 8) |
(buffer[index + 2] << 16) |
(buffer[index + 3] << 24);
// Decode the scope object
var scopeObject = deserializeObject(buffer, _index, options, false);
// Adjust the index
index = index + objectSize;
// Check if field length is too short
if (totalSize < 4 + 4 + objectSize + stringSize) {
throw new error_1.BSONError('code_w_scope total size is too short, truncating scope');
}
// Check if totalSize field is too long
if (totalSize > 4 + 4 + objectSize + stringSize) {
throw new error_1.BSONError('code_w_scope total size is too long, clips outer document');
}
// If we are evaluating the functions
if (evalFunctions) {
// If we have cache enabled let's look for the md5 of the function in the cache
if (cacheFunctions) {
// Got to do this to avoid V8 deoptimizing the call due to finding eval
value = isolateEval(functionString, functionCache, object);
}
else {
value = isolateEval(functionString);
}
value.scope = scopeObject;
}
else {
value = new code_1.Code(functionString, scopeObject);
}
}
else if (elementType === constants.BSON_DATA_DBPOINTER) {
// Get the code string size
var stringSize = buffer[index++] |
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);
// Check if we have a valid string
if (stringSize <= 0 ||
stringSize > buffer.length - index ||
buffer[index + stringSize - 1] !== 0)
throw new error_1.BSONError('bad string length in bson');
// Namespace
if (validation != null && validation.utf8) {
if (!(0, validate_utf8_1.validateUtf8)(buffer, index, index + stringSize - 1)) {
throw new error_1.BSONError('Invalid UTF-8 string in BSON document');
}
}
var namespace = buffer.toString('utf8', index, index + stringSize - 1);
// Update parse index position
index = index + stringSize;
// Read the oid
var oidBuffer = buffer_1.Buffer.alloc(12);
buffer.copy(oidBuffer, 0, index, index + 12);
var oid = new objectid_1.ObjectId(oidBuffer);
// Update the index
index = index + 12;
// Upgrade to DBRef type
value = new db_ref_1.DBRef(namespace, oid);
}
else {
throw new error_1.BSONError("Detected unknown BSON type ".concat(elementType.toString(16), " for fieldname \"").concat(name, "\""));
}
if (name === '__proto__') {
Object.defineProperty(object, name, {
value: value,
writable: true,
enumerable: true,
configurable: true
});
}
else {
object[name] = value;
}
}
// Check if the deserialization was against a valid array/object
if (size !== index - startIndex) {
if (isArray)
throw new error_1.BSONError('corrupt array bson');
throw new error_1.BSONError('corrupt object bson');
}
// if we did not find "$ref", "$id", "$db", or found an extraneous $key, don't make a DBRef
if (!isPossibleDBRef)
return object;
if ((0, db_ref_1.isDBRefLike)(object)) {
var copy = Object.assign({}, object);
delete copy.$ref;
delete copy.$id;
delete copy.$db;
return new db_ref_1.DBRef(object.$ref, object.$id, object.$db, copy);
}
return object;
}
/**
* Ensure eval is isolated, store the result in functionCache.
*
* @internal
*/
function isolateEval(functionString, functionCache, object) {
// eslint-disable-next-line @typescript-eslint/no-implied-eval
if (!functionCache)
return new Function(functionString);
// Check for cache hit, eval if missing and return cached function
if (functionCache[functionString] == null) {
// eslint-disable-next-line @typescript-eslint/no-implied-eval
functionCache[functionString] = new Function(functionString);
}
// Set the object
return functionCache[functionString].bind(object);
}
function getValidatedString(buffer, start, end, shouldValidateUtf8) {
var value = buffer.toString('utf8', start, end);
// if utf8 validation is on, do the check
if (shouldValidateUtf8) {
for (var i = 0; i < value.length; i++) {
if (value.charCodeAt(i) === 0xfffd) {
if (!(0, validate_utf8_1.validateUtf8)(buffer, start, end)) {
throw new error_1.BSONError('Invalid UTF-8 string in BSON document');
}
break;
}
}
}
return value;
}
//# sourceMappingURL=deserializer.js.map
File diff suppressed because one or more lines are too long
+867
View File
@@ -0,0 +1,867 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.serializeInto = void 0;
var binary_1 = require("../binary");
var constants = require("../constants");
var ensure_buffer_1 = require("../ensure_buffer");
var error_1 = require("../error");
var extended_json_1 = require("../extended_json");
var long_1 = require("../long");
var map_1 = require("../map");
var utils_1 = require("./utils");
var regexp = /\x00/; // eslint-disable-line no-control-regex
var ignoreKeys = new Set(['$db', '$ref', '$id', '$clusterTime']);
/*
* isArray indicates if we are writing to a BSON array (type 0x04)
* which forces the "key" which really an array index as a string to be written as ascii
* This will catch any errors in index as a string generation
*/
function serializeString(buffer, key, value, index, isArray) {
// Encode String type
buffer[index++] = constants.BSON_DATA_STRING;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes + 1;
buffer[index - 1] = 0;
// Write the string
var size = buffer.write(value, index + 4, undefined, 'utf8');
// Write the size of the string to buffer
buffer[index + 3] = ((size + 1) >> 24) & 0xff;
buffer[index + 2] = ((size + 1) >> 16) & 0xff;
buffer[index + 1] = ((size + 1) >> 8) & 0xff;
buffer[index] = (size + 1) & 0xff;
// Update index
index = index + 4 + size;
// Write zero
buffer[index++] = 0;
return index;
}
var SPACE_FOR_FLOAT64 = new Uint8Array(8);
var DV_FOR_FLOAT64 = new DataView(SPACE_FOR_FLOAT64.buffer, SPACE_FOR_FLOAT64.byteOffset, SPACE_FOR_FLOAT64.byteLength);
function serializeNumber(buffer, key, value, index, isArray) {
// We have an integer value
// TODO(NODE-2529): Add support for big int
if (Number.isInteger(value) &&
value >= constants.BSON_INT32_MIN &&
value <= constants.BSON_INT32_MAX) {
// If the value fits in 32 bits encode as int32
// Set int type 32 bits or less
buffer[index++] = constants.BSON_DATA_INT;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the int value
buffer[index++] = value & 0xff;
buffer[index++] = (value >> 8) & 0xff;
buffer[index++] = (value >> 16) & 0xff;
buffer[index++] = (value >> 24) & 0xff;
}
else {
// Encode as double
buffer[index++] = constants.BSON_DATA_NUMBER;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write float
DV_FOR_FLOAT64.setFloat64(0, value, true);
buffer.set(SPACE_FOR_FLOAT64, index);
// Adjust index
index = index + 8;
}
return index;
}
function serializeNull(buffer, key, _, index, isArray) {
// Set long type
buffer[index++] = constants.BSON_DATA_NULL;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
return index;
}
function serializeBoolean(buffer, key, value, index, isArray) {
// Write the type
buffer[index++] = constants.BSON_DATA_BOOLEAN;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Encode the boolean value
buffer[index++] = value ? 1 : 0;
return index;
}
function serializeDate(buffer, key, value, index, isArray) {
// Write the type
buffer[index++] = constants.BSON_DATA_DATE;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the date
var dateInMilis = long_1.Long.fromNumber(value.getTime());
var lowBits = dateInMilis.getLowBits();
var highBits = dateInMilis.getHighBits();
// Encode low bits
buffer[index++] = lowBits & 0xff;
buffer[index++] = (lowBits >> 8) & 0xff;
buffer[index++] = (lowBits >> 16) & 0xff;
buffer[index++] = (lowBits >> 24) & 0xff;
// Encode high bits
buffer[index++] = highBits & 0xff;
buffer[index++] = (highBits >> 8) & 0xff;
buffer[index++] = (highBits >> 16) & 0xff;
buffer[index++] = (highBits >> 24) & 0xff;
return index;
}
function serializeRegExp(buffer, key, value, index, isArray) {
// Write the type
buffer[index++] = constants.BSON_DATA_REGEXP;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
if (value.source && value.source.match(regexp) != null) {
throw Error('value ' + value.source + ' must not contain null bytes');
}
// Adjust the index
index = index + buffer.write(value.source, index, undefined, 'utf8');
// Write zero
buffer[index++] = 0x00;
// Write the parameters
if (value.ignoreCase)
buffer[index++] = 0x69; // i
if (value.global)
buffer[index++] = 0x73; // s
if (value.multiline)
buffer[index++] = 0x6d; // m
// Add ending zero
buffer[index++] = 0x00;
return index;
}
function serializeBSONRegExp(buffer, key, value, index, isArray) {
// Write the type
buffer[index++] = constants.BSON_DATA_REGEXP;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Check the pattern for 0 bytes
if (value.pattern.match(regexp) != null) {
// The BSON spec doesn't allow keys with null bytes because keys are
// null-terminated.
throw Error('pattern ' + value.pattern + ' must not contain null bytes');
}
// Adjust the index
index = index + buffer.write(value.pattern, index, undefined, 'utf8');
// Write zero
buffer[index++] = 0x00;
// Write the options
index = index + buffer.write(value.options.split('').sort().join(''), index, undefined, 'utf8');
// Add ending zero
buffer[index++] = 0x00;
return index;
}
function serializeMinMax(buffer, key, value, index, isArray) {
// Write the type of either min or max key
if (value === null) {
buffer[index++] = constants.BSON_DATA_NULL;
}
else if (value._bsontype === 'MinKey') {
buffer[index++] = constants.BSON_DATA_MIN_KEY;
}
else {
buffer[index++] = constants.BSON_DATA_MAX_KEY;
}
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
return index;
}
function serializeObjectId(buffer, key, value, index, isArray) {
// Write the type
buffer[index++] = constants.BSON_DATA_OID;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the objectId into the shared buffer
if (typeof value.id === 'string') {
buffer.write(value.id, index, undefined, 'binary');
}
else if ((0, utils_1.isUint8Array)(value.id)) {
// Use the standard JS methods here because buffer.copy() is buggy with the
// browser polyfill
buffer.set(value.id.subarray(0, 12), index);
}
else {
throw new error_1.BSONTypeError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
}
// Adjust index
return index + 12;
}
function serializeBuffer(buffer, key, value, index, isArray) {
// Write the type
buffer[index++] = constants.BSON_DATA_BINARY;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Get size of the buffer (current write point)
var size = value.length;
// Write the size of the string to buffer
buffer[index++] = size & 0xff;
buffer[index++] = (size >> 8) & 0xff;
buffer[index++] = (size >> 16) & 0xff;
buffer[index++] = (size >> 24) & 0xff;
// Write the default subtype
buffer[index++] = constants.BSON_BINARY_SUBTYPE_DEFAULT;
// Copy the content form the binary field to the buffer
buffer.set((0, ensure_buffer_1.ensureBuffer)(value), index);
// Adjust the index
index = index + size;
return index;
}
function serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, isArray, path) {
if (checkKeys === void 0) { checkKeys = false; }
if (depth === void 0) { depth = 0; }
if (serializeFunctions === void 0) { serializeFunctions = false; }
if (ignoreUndefined === void 0) { ignoreUndefined = true; }
if (isArray === void 0) { isArray = false; }
if (path === void 0) { path = []; }
for (var i = 0; i < path.length; i++) {
if (path[i] === value)
throw new error_1.BSONError('cyclic dependency detected');
}
// Push value to stack
path.push(value);
// Write the type
buffer[index++] = Array.isArray(value) ? constants.BSON_DATA_ARRAY : constants.BSON_DATA_OBJECT;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
var endIndex = serializeInto(buffer, value, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path);
// Pop stack
path.pop();
return endIndex;
}
function serializeDecimal128(buffer, key, value, index, isArray) {
buffer[index++] = constants.BSON_DATA_DECIMAL128;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the data from the value
// Prefer the standard JS methods because their typechecking is not buggy,
// unlike the `buffer` polyfill's.
buffer.set(value.bytes.subarray(0, 16), index);
return index + 16;
}
function serializeLong(buffer, key, value, index, isArray) {
// Write the type
buffer[index++] =
value._bsontype === 'Long' ? constants.BSON_DATA_LONG : constants.BSON_DATA_TIMESTAMP;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the date
var lowBits = value.getLowBits();
var highBits = value.getHighBits();
// Encode low bits
buffer[index++] = lowBits & 0xff;
buffer[index++] = (lowBits >> 8) & 0xff;
buffer[index++] = (lowBits >> 16) & 0xff;
buffer[index++] = (lowBits >> 24) & 0xff;
// Encode high bits
buffer[index++] = highBits & 0xff;
buffer[index++] = (highBits >> 8) & 0xff;
buffer[index++] = (highBits >> 16) & 0xff;
buffer[index++] = (highBits >> 24) & 0xff;
return index;
}
function serializeInt32(buffer, key, value, index, isArray) {
value = value.valueOf();
// Set int type 32 bits or less
buffer[index++] = constants.BSON_DATA_INT;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the int value
buffer[index++] = value & 0xff;
buffer[index++] = (value >> 8) & 0xff;
buffer[index++] = (value >> 16) & 0xff;
buffer[index++] = (value >> 24) & 0xff;
return index;
}
function serializeDouble(buffer, key, value, index, isArray) {
// Encode as double
buffer[index++] = constants.BSON_DATA_NUMBER;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write float
DV_FOR_FLOAT64.setFloat64(0, value.value, true);
buffer.set(SPACE_FOR_FLOAT64, index);
// Adjust index
index = index + 8;
return index;
}
function serializeFunction(buffer, key, value, index, _checkKeys, _depth, isArray) {
if (_checkKeys === void 0) { _checkKeys = false; }
if (_depth === void 0) { _depth = 0; }
buffer[index++] = constants.BSON_DATA_CODE;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Function string
var functionString = (0, utils_1.normalizedFunctionString)(value);
// Write the string
var size = buffer.write(functionString, index + 4, undefined, 'utf8') + 1;
// Write the size of the string to buffer
buffer[index] = size & 0xff;
buffer[index + 1] = (size >> 8) & 0xff;
buffer[index + 2] = (size >> 16) & 0xff;
buffer[index + 3] = (size >> 24) & 0xff;
// Update index
index = index + 4 + size - 1;
// Write zero
buffer[index++] = 0;
return index;
}
function serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, isArray) {
if (checkKeys === void 0) { checkKeys = false; }
if (depth === void 0) { depth = 0; }
if (serializeFunctions === void 0) { serializeFunctions = false; }
if (ignoreUndefined === void 0) { ignoreUndefined = true; }
if (isArray === void 0) { isArray = false; }
if (value.scope && typeof value.scope === 'object') {
// Write the type
buffer[index++] = constants.BSON_DATA_CODE_W_SCOPE;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Starting index
var startIndex = index;
// Serialize the function
// Get the function string
var functionString = typeof value.code === 'string' ? value.code : value.code.toString();
// Index adjustment
index = index + 4;
// Write string into buffer
var codeSize = buffer.write(functionString, index + 4, undefined, 'utf8') + 1;
// Write the size of the string to buffer
buffer[index] = codeSize & 0xff;
buffer[index + 1] = (codeSize >> 8) & 0xff;
buffer[index + 2] = (codeSize >> 16) & 0xff;
buffer[index + 3] = (codeSize >> 24) & 0xff;
// Write end 0
buffer[index + 4 + codeSize - 1] = 0;
// Write the
index = index + codeSize + 4;
//
// Serialize the scope value
var endIndex = serializeInto(buffer, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined);
index = endIndex - 1;
// Writ the total
var totalSize = endIndex - startIndex;
// Write the total size of the object
buffer[startIndex++] = totalSize & 0xff;
buffer[startIndex++] = (totalSize >> 8) & 0xff;
buffer[startIndex++] = (totalSize >> 16) & 0xff;
buffer[startIndex++] = (totalSize >> 24) & 0xff;
// Write trailing zero
buffer[index++] = 0;
}
else {
buffer[index++] = constants.BSON_DATA_CODE;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Function string
var functionString = value.code.toString();
// Write the string
var size = buffer.write(functionString, index + 4, undefined, 'utf8') + 1;
// Write the size of the string to buffer
buffer[index] = size & 0xff;
buffer[index + 1] = (size >> 8) & 0xff;
buffer[index + 2] = (size >> 16) & 0xff;
buffer[index + 3] = (size >> 24) & 0xff;
// Update index
index = index + 4 + size - 1;
// Write zero
buffer[index++] = 0;
}
return index;
}
function serializeBinary(buffer, key, value, index, isArray) {
// Write the type
buffer[index++] = constants.BSON_DATA_BINARY;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Extract the buffer
var data = value.value(true);
// Calculate size
var size = value.position;
// Add the deprecated 02 type 4 bytes of size to total
if (value.sub_type === binary_1.Binary.SUBTYPE_BYTE_ARRAY)
size = size + 4;
// Write the size of the string to buffer
buffer[index++] = size & 0xff;
buffer[index++] = (size >> 8) & 0xff;
buffer[index++] = (size >> 16) & 0xff;
buffer[index++] = (size >> 24) & 0xff;
// Write the subtype to the buffer
buffer[index++] = value.sub_type;
// If we have binary type 2 the 4 first bytes are the size
if (value.sub_type === binary_1.Binary.SUBTYPE_BYTE_ARRAY) {
size = size - 4;
buffer[index++] = size & 0xff;
buffer[index++] = (size >> 8) & 0xff;
buffer[index++] = (size >> 16) & 0xff;
buffer[index++] = (size >> 24) & 0xff;
}
// Write the data to the object
buffer.set(data, index);
// Adjust the index
index = index + value.position;
return index;
}
function serializeSymbol(buffer, key, value, index, isArray) {
// Write the type
buffer[index++] = constants.BSON_DATA_SYMBOL;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
// Write the string
var size = buffer.write(value.value, index + 4, undefined, 'utf8') + 1;
// Write the size of the string to buffer
buffer[index] = size & 0xff;
buffer[index + 1] = (size >> 8) & 0xff;
buffer[index + 2] = (size >> 16) & 0xff;
buffer[index + 3] = (size >> 24) & 0xff;
// Update index
index = index + 4 + size - 1;
// Write zero
buffer[index++] = 0x00;
return index;
}
function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, isArray) {
// Write the type
buffer[index++] = constants.BSON_DATA_OBJECT;
// Number of written bytes
var numberOfWrittenBytes = !isArray
? buffer.write(key, index, undefined, 'utf8')
: buffer.write(key, index, undefined, 'ascii');
// Encode the name
index = index + numberOfWrittenBytes;
buffer[index++] = 0;
var startIndex = index;
var output = {
$ref: value.collection || value.namespace,
$id: value.oid
};
if (value.db != null) {
output.$db = value.db;
}
output = Object.assign(output, value.fields);
var endIndex = serializeInto(buffer, output, false, index, depth + 1, serializeFunctions);
// Calculate object size
var size = endIndex - startIndex;
// Write the size
buffer[startIndex++] = size & 0xff;
buffer[startIndex++] = (size >> 8) & 0xff;
buffer[startIndex++] = (size >> 16) & 0xff;
buffer[startIndex++] = (size >> 24) & 0xff;
// Set index
return endIndex;
}
function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) {
if (checkKeys === void 0) { checkKeys = false; }
if (startingIndex === void 0) { startingIndex = 0; }
if (depth === void 0) { depth = 0; }
if (serializeFunctions === void 0) { serializeFunctions = false; }
if (ignoreUndefined === void 0) { ignoreUndefined = true; }
if (path === void 0) { path = []; }
startingIndex = startingIndex || 0;
path = path || [];
// Push the object to the path
path.push(object);
// Start place to serialize into
var index = startingIndex + 4;
// Special case isArray
if (Array.isArray(object)) {
// Get object keys
for (var i = 0; i < object.length; i++) {
var key = "".concat(i);
var value = object[i];
// Is there an override value
if (typeof (value === null || value === void 0 ? void 0 : value.toBSON) === 'function') {
value = value.toBSON();
}
if (typeof value === 'string') {
index = serializeString(buffer, key, value, index, true);
}
else if (typeof value === 'number') {
index = serializeNumber(buffer, key, value, index, true);
}
else if (typeof value === 'bigint') {
throw new error_1.BSONTypeError('Unsupported type BigInt, please use Decimal128');
}
else if (typeof value === 'boolean') {
index = serializeBoolean(buffer, key, value, index, true);
}
else if (value instanceof Date || (0, utils_1.isDate)(value)) {
index = serializeDate(buffer, key, value, index, true);
}
else if (value === undefined) {
index = serializeNull(buffer, key, value, index, true);
}
else if (value === null) {
index = serializeNull(buffer, key, value, index, true);
}
else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
index = serializeObjectId(buffer, key, value, index, true);
}
else if ((0, utils_1.isUint8Array)(value)) {
index = serializeBuffer(buffer, key, value, index, true);
}
else if (value instanceof RegExp || (0, utils_1.isRegExp)(value)) {
index = serializeRegExp(buffer, key, value, index, true);
}
else if (typeof value === 'object' && value['_bsontype'] == null) {
index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, true, path);
}
else if (typeof value === 'object' &&
(0, extended_json_1.isBSONType)(value) &&
value._bsontype === 'Decimal128') {
index = serializeDecimal128(buffer, key, value, index, true);
}
else if (value['_bsontype'] === 'Long' || value['_bsontype'] === 'Timestamp') {
index = serializeLong(buffer, key, value, index, true);
}
else if (value['_bsontype'] === 'Double') {
index = serializeDouble(buffer, key, value, index, true);
}
else if (typeof value === 'function' && serializeFunctions) {
index = serializeFunction(buffer, key, value, index, checkKeys, depth, true);
}
else if (value['_bsontype'] === 'Code') {
index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, true);
}
else if (value['_bsontype'] === 'Binary') {
index = serializeBinary(buffer, key, value, index, true);
}
else if (value['_bsontype'] === 'Symbol') {
index = serializeSymbol(buffer, key, value, index, true);
}
else if (value['_bsontype'] === 'DBRef') {
index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, true);
}
else if (value['_bsontype'] === 'BSONRegExp') {
index = serializeBSONRegExp(buffer, key, value, index, true);
}
else if (value['_bsontype'] === 'Int32') {
index = serializeInt32(buffer, key, value, index, true);
}
else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
index = serializeMinMax(buffer, key, value, index, true);
}
else if (typeof value['_bsontype'] !== 'undefined') {
throw new error_1.BSONTypeError("Unrecognized or invalid _bsontype: ".concat(String(value['_bsontype'])));
}
}
}
else if (object instanceof map_1.Map || (0, utils_1.isMap)(object)) {
var iterator = object.entries();
var done = false;
while (!done) {
// Unpack the next entry
var entry = iterator.next();
done = !!entry.done;
// Are we done, then skip and terminate
if (done)
continue;
// Get the entry values
var key = entry.value[0];
var value = entry.value[1];
// Check the type of the value
var type = typeof value;
// Check the key and throw error if it's illegal
if (typeof key === 'string' && !ignoreKeys.has(key)) {
if (key.match(regexp) != null) {
// The BSON spec doesn't allow keys with null bytes because keys are
// null-terminated.
throw Error('key ' + key + ' must not contain null bytes');
}
if (checkKeys) {
if ('$' === key[0]) {
throw Error('key ' + key + " must not start with '$'");
}
else if (~key.indexOf('.')) {
throw Error('key ' + key + " must not contain '.'");
}
}
}
if (type === 'string') {
index = serializeString(buffer, key, value, index);
}
else if (type === 'number') {
index = serializeNumber(buffer, key, value, index);
}
else if (type === 'bigint' || (0, utils_1.isBigInt64Array)(value) || (0, utils_1.isBigUInt64Array)(value)) {
throw new error_1.BSONTypeError('Unsupported type BigInt, please use Decimal128');
}
else if (type === 'boolean') {
index = serializeBoolean(buffer, key, value, index);
}
else if (value instanceof Date || (0, utils_1.isDate)(value)) {
index = serializeDate(buffer, key, value, index);
}
else if (value === null || (value === undefined && ignoreUndefined === false)) {
index = serializeNull(buffer, key, value, index);
}
else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
index = serializeObjectId(buffer, key, value, index);
}
else if ((0, utils_1.isUint8Array)(value)) {
index = serializeBuffer(buffer, key, value, index);
}
else if (value instanceof RegExp || (0, utils_1.isRegExp)(value)) {
index = serializeRegExp(buffer, key, value, index);
}
else if (type === 'object' && value['_bsontype'] == null) {
index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, false, path);
}
else if (type === 'object' && value['_bsontype'] === 'Decimal128') {
index = serializeDecimal128(buffer, key, value, index);
}
else if (value['_bsontype'] === 'Long' || value['_bsontype'] === 'Timestamp') {
index = serializeLong(buffer, key, value, index);
}
else if (value['_bsontype'] === 'Double') {
index = serializeDouble(buffer, key, value, index);
}
else if (value['_bsontype'] === 'Code') {
index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined);
}
else if (typeof value === 'function' && serializeFunctions) {
index = serializeFunction(buffer, key, value, index, checkKeys, depth, serializeFunctions);
}
else if (value['_bsontype'] === 'Binary') {
index = serializeBinary(buffer, key, value, index);
}
else if (value['_bsontype'] === 'Symbol') {
index = serializeSymbol(buffer, key, value, index);
}
else if (value['_bsontype'] === 'DBRef') {
index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions);
}
else if (value['_bsontype'] === 'BSONRegExp') {
index = serializeBSONRegExp(buffer, key, value, index);
}
else if (value['_bsontype'] === 'Int32') {
index = serializeInt32(buffer, key, value, index);
}
else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
index = serializeMinMax(buffer, key, value, index);
}
else if (typeof value['_bsontype'] !== 'undefined') {
throw new error_1.BSONTypeError("Unrecognized or invalid _bsontype: ".concat(String(value['_bsontype'])));
}
}
}
else {
if (typeof (object === null || object === void 0 ? void 0 : object.toBSON) === 'function') {
// Provided a custom serialization method
object = object.toBSON();
if (object != null && typeof object !== 'object') {
throw new error_1.BSONTypeError('toBSON function did not return an object');
}
}
// Iterate over all the keys
for (var key in object) {
var value = object[key];
// Is there an override value
if (typeof (value === null || value === void 0 ? void 0 : value.toBSON) === 'function') {
value = value.toBSON();
}
// Check the type of the value
var type = typeof value;
// Check the key and throw error if it's illegal
if (typeof key === 'string' && !ignoreKeys.has(key)) {
if (key.match(regexp) != null) {
// The BSON spec doesn't allow keys with null bytes because keys are
// null-terminated.
throw Error('key ' + key + ' must not contain null bytes');
}
if (checkKeys) {
if ('$' === key[0]) {
throw Error('key ' + key + " must not start with '$'");
}
else if (~key.indexOf('.')) {
throw Error('key ' + key + " must not contain '.'");
}
}
}
if (type === 'string') {
index = serializeString(buffer, key, value, index);
}
else if (type === 'number') {
index = serializeNumber(buffer, key, value, index);
}
else if (type === 'bigint') {
throw new error_1.BSONTypeError('Unsupported type BigInt, please use Decimal128');
}
else if (type === 'boolean') {
index = serializeBoolean(buffer, key, value, index);
}
else if (value instanceof Date || (0, utils_1.isDate)(value)) {
index = serializeDate(buffer, key, value, index);
}
else if (value === undefined) {
if (ignoreUndefined === false)
index = serializeNull(buffer, key, value, index);
}
else if (value === null) {
index = serializeNull(buffer, key, value, index);
}
else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
index = serializeObjectId(buffer, key, value, index);
}
else if ((0, utils_1.isUint8Array)(value)) {
index = serializeBuffer(buffer, key, value, index);
}
else if (value instanceof RegExp || (0, utils_1.isRegExp)(value)) {
index = serializeRegExp(buffer, key, value, index);
}
else if (type === 'object' && value['_bsontype'] == null) {
index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, false, path);
}
else if (type === 'object' && value['_bsontype'] === 'Decimal128') {
index = serializeDecimal128(buffer, key, value, index);
}
else if (value['_bsontype'] === 'Long' || value['_bsontype'] === 'Timestamp') {
index = serializeLong(buffer, key, value, index);
}
else if (value['_bsontype'] === 'Double') {
index = serializeDouble(buffer, key, value, index);
}
else if (value['_bsontype'] === 'Code') {
index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined);
}
else if (typeof value === 'function' && serializeFunctions) {
index = serializeFunction(buffer, key, value, index, checkKeys, depth, serializeFunctions);
}
else if (value['_bsontype'] === 'Binary') {
index = serializeBinary(buffer, key, value, index);
}
else if (value['_bsontype'] === 'Symbol') {
index = serializeSymbol(buffer, key, value, index);
}
else if (value['_bsontype'] === 'DBRef') {
index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions);
}
else if (value['_bsontype'] === 'BSONRegExp') {
index = serializeBSONRegExp(buffer, key, value, index);
}
else if (value['_bsontype'] === 'Int32') {
index = serializeInt32(buffer, key, value, index);
}
else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
index = serializeMinMax(buffer, key, value, index);
}
else if (typeof value['_bsontype'] !== 'undefined') {
throw new error_1.BSONTypeError("Unrecognized or invalid _bsontype: ".concat(String(value['_bsontype'])));
}
}
}
// Remove the path
path.pop();
// Final padding byte for object
buffer[index++] = 0x00;
// Final size
var size = index - startingIndex;
// Write the size of the object
buffer[startingIndex++] = size & 0xff;
buffer[startingIndex++] = (size >> 8) & 0xff;
buffer[startingIndex++] = (size >> 16) & 0xff;
buffer[startingIndex++] = (size >> 24) & 0xff;
return index;
}
exports.serializeInto = serializeInto;
//# sourceMappingURL=serializer.js.map
File diff suppressed because one or more lines are too long
+115
View File
@@ -0,0 +1,115 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deprecate = exports.isObjectLike = exports.isDate = exports.haveBuffer = exports.isMap = exports.isRegExp = exports.isBigUInt64Array = exports.isBigInt64Array = exports.isUint8Array = exports.isAnyArrayBuffer = exports.randomBytes = exports.normalizedFunctionString = void 0;
var buffer_1 = require("buffer");
var global_1 = require("../utils/global");
/**
* Normalizes our expected stringified form of a function across versions of node
* @param fn - The function to stringify
*/
function normalizedFunctionString(fn) {
return fn.toString().replace('function(', 'function (');
}
exports.normalizedFunctionString = normalizedFunctionString;
function isReactNative() {
var g = (0, global_1.getGlobal)();
return typeof g.navigator === 'object' && g.navigator.product === 'ReactNative';
}
var insecureRandomBytes = function insecureRandomBytes(size) {
var insecureWarning = isReactNative()
? 'BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values.'
: 'BSON: No cryptographic implementation for random bytes present, falling back to a less secure implementation.';
console.warn(insecureWarning);
var result = buffer_1.Buffer.alloc(size);
for (var i = 0; i < size; ++i)
result[i] = Math.floor(Math.random() * 256);
return result;
};
var detectRandomBytes = function () {
if (process.browser) {
if (typeof window !== 'undefined') {
// browser crypto implementation(s)
var target_1 = window.crypto || window.msCrypto; // allow for IE11
if (target_1 && target_1.getRandomValues) {
return function (size) { return target_1.getRandomValues(buffer_1.Buffer.alloc(size)); };
}
}
if (typeof global !== 'undefined' && global.crypto && global.crypto.getRandomValues) {
// allow for RN packages such as https://www.npmjs.com/package/react-native-get-random-values to populate global
return function (size) { return global.crypto.getRandomValues(buffer_1.Buffer.alloc(size)); };
}
return insecureRandomBytes;
}
else {
var requiredRandomBytes = void 0;
try {
requiredRandomBytes = require('crypto').randomBytes;
}
catch (e) {
// keep the fallback
}
// NOTE: in transpiled cases the above require might return null/undefined
return requiredRandomBytes || insecureRandomBytes;
}
};
exports.randomBytes = detectRandomBytes();
function isAnyArrayBuffer(value) {
return ['[object ArrayBuffer]', '[object SharedArrayBuffer]'].includes(Object.prototype.toString.call(value));
}
exports.isAnyArrayBuffer = isAnyArrayBuffer;
function isUint8Array(value) {
return Object.prototype.toString.call(value) === '[object Uint8Array]';
}
exports.isUint8Array = isUint8Array;
function isBigInt64Array(value) {
return Object.prototype.toString.call(value) === '[object BigInt64Array]';
}
exports.isBigInt64Array = isBigInt64Array;
function isBigUInt64Array(value) {
return Object.prototype.toString.call(value) === '[object BigUint64Array]';
}
exports.isBigUInt64Array = isBigUInt64Array;
function isRegExp(d) {
return Object.prototype.toString.call(d) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isMap(d) {
return Object.prototype.toString.call(d) === '[object Map]';
}
exports.isMap = isMap;
/** Call to check if your environment has `Buffer` */
function haveBuffer() {
return typeof global !== 'undefined' && typeof global.Buffer !== 'undefined';
}
exports.haveBuffer = haveBuffer;
// To ensure that 0.4 of node works correctly
function isDate(d) {
return isObjectLike(d) && Object.prototype.toString.call(d) === '[object Date]';
}
exports.isDate = isDate;
/**
* @internal
* this is to solve the `'someKey' in x` problem where x is unknown.
* https://github.com/typescript-eslint/typescript-eslint/issues/1071#issuecomment-541955753
*/
function isObjectLike(candidate) {
return typeof candidate === 'object' && candidate !== null;
}
exports.isObjectLike = isObjectLike;
function deprecate(fn, message) {
var warned = false;
function deprecated() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!warned) {
console.warn(message);
warned = true;
}
return fn.apply(this, args);
}
return deprecated;
}
exports.deprecate = deprecate;
//# sourceMappingURL=utils.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/parser/utils.ts"],"names":[],"mappings":"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"}