bson 6.4.0 → 6.5.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 +50 -0
- package/lib/bson.bundle.js +160 -23
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +160 -23
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +160 -24
- package/lib/bson.mjs.map +1 -1
- package/lib/bson.rn.cjs +161 -23
- package/lib/bson.rn.cjs.map +1 -1
- package/package.json +1 -1
- package/src/binary.ts +2 -0
- package/src/bson.ts +1 -0
- package/src/constants.ts +3 -0
- package/src/error.ts +22 -0
- package/src/parser/on_demand/index.ts +28 -0
- package/src/parser/on_demand/parse_to_elements.ts +174 -0
- package/src/utils/number_utils.ts +53 -23
package/lib/bson.cjs
CHANGED
|
@@ -126,6 +126,15 @@ class BSONRuntimeError extends BSONError {
|
|
|
126
126
|
super(message);
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
|
+
class BSONOffsetError extends BSONError {
|
|
130
|
+
get name() {
|
|
131
|
+
return 'BSONOffsetError';
|
|
132
|
+
}
|
|
133
|
+
constructor(message, offset) {
|
|
134
|
+
super(`${message}. offset: ${offset}`);
|
|
135
|
+
this.offset = offset;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
129
138
|
|
|
130
139
|
const FIRST_BIT = 0x80;
|
|
131
140
|
const FIRST_TWO_BITS = 0xc0;
|
|
@@ -607,6 +616,7 @@ Binary.SUBTYPE_UUID = 4;
|
|
|
607
616
|
Binary.SUBTYPE_MD5 = 5;
|
|
608
617
|
Binary.SUBTYPE_ENCRYPTED = 6;
|
|
609
618
|
Binary.SUBTYPE_COLUMN = 7;
|
|
619
|
+
Binary.SUBTYPE_SENSITIVE = 8;
|
|
610
620
|
Binary.SUBTYPE_USER_DEFINED = 128;
|
|
611
621
|
const UUID_BYTE_LENGTH = 16;
|
|
612
622
|
const UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i;
|
|
@@ -2125,6 +2135,8 @@ class MinKey extends BSONValue {
|
|
|
2125
2135
|
|
|
2126
2136
|
const FLOAT = new Float64Array(1);
|
|
2127
2137
|
const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
|
|
2138
|
+
FLOAT[0] = -1;
|
|
2139
|
+
const isBigEndian = FLOAT_BYTES[7] === 0;
|
|
2128
2140
|
const NumberUtils = {
|
|
2129
2141
|
getInt32LE(source, offset) {
|
|
2130
2142
|
return (source[offset] |
|
|
@@ -2149,17 +2161,29 @@ const NumberUtils = {
|
|
|
2149
2161
|
const hi = NumberUtils.getUint32LE(source, offset + 4);
|
|
2150
2162
|
return (BigInt(hi) << BigInt(32)) + BigInt(lo);
|
|
2151
2163
|
},
|
|
2152
|
-
getFloat64LE
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2164
|
+
getFloat64LE: isBigEndian
|
|
2165
|
+
? (source, offset) => {
|
|
2166
|
+
FLOAT_BYTES[7] = source[offset];
|
|
2167
|
+
FLOAT_BYTES[6] = source[offset + 1];
|
|
2168
|
+
FLOAT_BYTES[5] = source[offset + 2];
|
|
2169
|
+
FLOAT_BYTES[4] = source[offset + 3];
|
|
2170
|
+
FLOAT_BYTES[3] = source[offset + 4];
|
|
2171
|
+
FLOAT_BYTES[2] = source[offset + 5];
|
|
2172
|
+
FLOAT_BYTES[1] = source[offset + 6];
|
|
2173
|
+
FLOAT_BYTES[0] = source[offset + 7];
|
|
2174
|
+
return FLOAT[0];
|
|
2175
|
+
}
|
|
2176
|
+
: (source, offset) => {
|
|
2177
|
+
FLOAT_BYTES[0] = source[offset];
|
|
2178
|
+
FLOAT_BYTES[1] = source[offset + 1];
|
|
2179
|
+
FLOAT_BYTES[2] = source[offset + 2];
|
|
2180
|
+
FLOAT_BYTES[3] = source[offset + 3];
|
|
2181
|
+
FLOAT_BYTES[4] = source[offset + 4];
|
|
2182
|
+
FLOAT_BYTES[5] = source[offset + 5];
|
|
2183
|
+
FLOAT_BYTES[6] = source[offset + 6];
|
|
2184
|
+
FLOAT_BYTES[7] = source[offset + 7];
|
|
2185
|
+
return FLOAT[0];
|
|
2186
|
+
},
|
|
2163
2187
|
setInt32BE(destination, offset, value) {
|
|
2164
2188
|
destination[offset + 3] = value;
|
|
2165
2189
|
value >>>= 8;
|
|
@@ -2200,18 +2224,31 @@ const NumberUtils = {
|
|
|
2200
2224
|
destination[offset + 7] = hi;
|
|
2201
2225
|
return 8;
|
|
2202
2226
|
},
|
|
2203
|
-
setFloat64LE
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2227
|
+
setFloat64LE: isBigEndian
|
|
2228
|
+
? (destination, offset, value) => {
|
|
2229
|
+
FLOAT[0] = value;
|
|
2230
|
+
destination[offset] = FLOAT_BYTES[7];
|
|
2231
|
+
destination[offset + 1] = FLOAT_BYTES[6];
|
|
2232
|
+
destination[offset + 2] = FLOAT_BYTES[5];
|
|
2233
|
+
destination[offset + 3] = FLOAT_BYTES[4];
|
|
2234
|
+
destination[offset + 4] = FLOAT_BYTES[3];
|
|
2235
|
+
destination[offset + 5] = FLOAT_BYTES[2];
|
|
2236
|
+
destination[offset + 6] = FLOAT_BYTES[1];
|
|
2237
|
+
destination[offset + 7] = FLOAT_BYTES[0];
|
|
2238
|
+
return 8;
|
|
2239
|
+
}
|
|
2240
|
+
: (destination, offset, value) => {
|
|
2241
|
+
FLOAT[0] = value;
|
|
2242
|
+
destination[offset] = FLOAT_BYTES[0];
|
|
2243
|
+
destination[offset + 1] = FLOAT_BYTES[1];
|
|
2244
|
+
destination[offset + 2] = FLOAT_BYTES[2];
|
|
2245
|
+
destination[offset + 3] = FLOAT_BYTES[3];
|
|
2246
|
+
destination[offset + 4] = FLOAT_BYTES[4];
|
|
2247
|
+
destination[offset + 5] = FLOAT_BYTES[5];
|
|
2248
|
+
destination[offset + 6] = FLOAT_BYTES[6];
|
|
2249
|
+
destination[offset + 7] = FLOAT_BYTES[7];
|
|
2250
|
+
return 8;
|
|
2251
|
+
}
|
|
2215
2252
|
};
|
|
2216
2253
|
|
|
2217
2254
|
const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
|
|
@@ -4089,6 +4126,104 @@ EJSON.serialize = EJSONserialize;
|
|
|
4089
4126
|
EJSON.deserialize = EJSONdeserialize;
|
|
4090
4127
|
Object.freeze(EJSON);
|
|
4091
4128
|
|
|
4129
|
+
function getSize(source, offset) {
|
|
4130
|
+
if (source[offset + 3] > 127) {
|
|
4131
|
+
throw new BSONOffsetError('BSON size cannot be negative', offset);
|
|
4132
|
+
}
|
|
4133
|
+
return (source[offset] |
|
|
4134
|
+
(source[offset + 1] << 8) |
|
|
4135
|
+
(source[offset + 2] << 16) |
|
|
4136
|
+
(source[offset + 3] << 24));
|
|
4137
|
+
}
|
|
4138
|
+
function findNull(bytes, offset) {
|
|
4139
|
+
let nullTerminatorOffset = offset;
|
|
4140
|
+
for (; bytes[nullTerminatorOffset] !== 0x00; nullTerminatorOffset++)
|
|
4141
|
+
;
|
|
4142
|
+
if (nullTerminatorOffset === bytes.length - 1) {
|
|
4143
|
+
throw new BSONOffsetError('Null terminator not found', offset);
|
|
4144
|
+
}
|
|
4145
|
+
return nullTerminatorOffset;
|
|
4146
|
+
}
|
|
4147
|
+
function parseToElements(bytes, startOffset = 0) {
|
|
4148
|
+
if (bytes.length < 5) {
|
|
4149
|
+
throw new BSONOffsetError(`Input must be at least 5 bytes, got ${bytes.length} bytes`, startOffset);
|
|
4150
|
+
}
|
|
4151
|
+
const documentSize = getSize(bytes, startOffset);
|
|
4152
|
+
if (documentSize > bytes.length - startOffset) {
|
|
4153
|
+
throw new BSONOffsetError(`Parsed documentSize (${documentSize} bytes) does not match input length (${bytes.length} bytes)`, startOffset);
|
|
4154
|
+
}
|
|
4155
|
+
if (bytes[startOffset + documentSize - 1] !== 0x00) {
|
|
4156
|
+
throw new BSONOffsetError('BSON documents must end in 0x00', startOffset + documentSize);
|
|
4157
|
+
}
|
|
4158
|
+
const elements = [];
|
|
4159
|
+
let offset = startOffset + 4;
|
|
4160
|
+
while (offset <= documentSize + startOffset) {
|
|
4161
|
+
const type = bytes[offset];
|
|
4162
|
+
offset += 1;
|
|
4163
|
+
if (type === 0) {
|
|
4164
|
+
if (offset - startOffset !== documentSize) {
|
|
4165
|
+
throw new BSONOffsetError(`Invalid 0x00 type byte`, offset);
|
|
4166
|
+
}
|
|
4167
|
+
break;
|
|
4168
|
+
}
|
|
4169
|
+
const nameOffset = offset;
|
|
4170
|
+
const nameLength = findNull(bytes, offset) - nameOffset;
|
|
4171
|
+
offset += nameLength + 1;
|
|
4172
|
+
let length;
|
|
4173
|
+
if (type === 1 || type === 18 || type === 9 || type === 17) {
|
|
4174
|
+
length = 8;
|
|
4175
|
+
}
|
|
4176
|
+
else if (type === 16) {
|
|
4177
|
+
length = 4;
|
|
4178
|
+
}
|
|
4179
|
+
else if (type === 7) {
|
|
4180
|
+
length = 12;
|
|
4181
|
+
}
|
|
4182
|
+
else if (type === 19) {
|
|
4183
|
+
length = 16;
|
|
4184
|
+
}
|
|
4185
|
+
else if (type === 8) {
|
|
4186
|
+
length = 1;
|
|
4187
|
+
}
|
|
4188
|
+
else if (type === 10 || type === 6 || type === 127 || type === 255) {
|
|
4189
|
+
length = 0;
|
|
4190
|
+
}
|
|
4191
|
+
else if (type === 11) {
|
|
4192
|
+
length = findNull(bytes, findNull(bytes, offset) + 1) + 1 - offset;
|
|
4193
|
+
}
|
|
4194
|
+
else if (type === 3 || type === 4 || type === 15) {
|
|
4195
|
+
length = getSize(bytes, offset);
|
|
4196
|
+
}
|
|
4197
|
+
else if (type === 2 ||
|
|
4198
|
+
type === 5 ||
|
|
4199
|
+
type === 12 ||
|
|
4200
|
+
type === 13 ||
|
|
4201
|
+
type === 14) {
|
|
4202
|
+
length = getSize(bytes, offset) + 4;
|
|
4203
|
+
if (type === 5) {
|
|
4204
|
+
length += 1;
|
|
4205
|
+
}
|
|
4206
|
+
if (type === 12) {
|
|
4207
|
+
length += 12;
|
|
4208
|
+
}
|
|
4209
|
+
}
|
|
4210
|
+
else {
|
|
4211
|
+
throw new BSONOffsetError(`Invalid 0x${type.toString(16).padStart(2, '0')} type byte`, offset);
|
|
4212
|
+
}
|
|
4213
|
+
if (length > documentSize) {
|
|
4214
|
+
throw new BSONOffsetError('value reports length larger than document', offset);
|
|
4215
|
+
}
|
|
4216
|
+
elements.push([type, nameOffset, nameLength, offset, length]);
|
|
4217
|
+
offset += length;
|
|
4218
|
+
}
|
|
4219
|
+
return elements;
|
|
4220
|
+
}
|
|
4221
|
+
|
|
4222
|
+
const onDemand = Object.create(null);
|
|
4223
|
+
onDemand.parseToElements = parseToElements;
|
|
4224
|
+
onDemand.BSONOffsetError = BSONOffsetError;
|
|
4225
|
+
Object.freeze(onDemand);
|
|
4226
|
+
|
|
4092
4227
|
const MAXSIZE = 1024 * 1024 * 17;
|
|
4093
4228
|
let buffer = ByteUtils.allocate(MAXSIZE);
|
|
4094
4229
|
function setInternalBufferSize(size) {
|
|
@@ -4165,6 +4300,7 @@ var bson = /*#__PURE__*/Object.freeze({
|
|
|
4165
4300
|
calculateObjectSize: calculateObjectSize,
|
|
4166
4301
|
deserialize: deserialize,
|
|
4167
4302
|
deserializeStream: deserializeStream,
|
|
4303
|
+
onDemand: onDemand,
|
|
4168
4304
|
serialize: serialize,
|
|
4169
4305
|
serializeWithBufferAndIndex: serializeWithBufferAndIndex,
|
|
4170
4306
|
setInternalBufferSize: setInternalBufferSize
|
|
@@ -4194,6 +4330,7 @@ exports.UUID = UUID;
|
|
|
4194
4330
|
exports.calculateObjectSize = calculateObjectSize;
|
|
4195
4331
|
exports.deserialize = deserialize;
|
|
4196
4332
|
exports.deserializeStream = deserializeStream;
|
|
4333
|
+
exports.onDemand = onDemand;
|
|
4197
4334
|
exports.serialize = serialize;
|
|
4198
4335
|
exports.serializeWithBufferAndIndex = serializeWithBufferAndIndex;
|
|
4199
4336
|
exports.setInternalBufferSize = setInternalBufferSize;
|