bson 6.4.0 → 6.6.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/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, options) {
134
+ super(`${message}. offset: ${offset}`, options);
135
+ this.offset = offset;
136
+ }
137
+ }
129
138
 
130
139
  const FIRST_BIT = 0x80;
131
140
  const FIRST_TWO_BITS = 0xc0;
@@ -524,16 +533,16 @@ class Binary extends BSONValue {
524
533
  return this.position;
525
534
  }
526
535
  toJSON() {
527
- return ByteUtils.toBase64(this.buffer);
536
+ return ByteUtils.toBase64(this.buffer.subarray(0, this.position));
528
537
  }
529
538
  toString(encoding) {
530
539
  if (encoding === 'hex')
531
- return ByteUtils.toHex(this.buffer);
540
+ return ByteUtils.toHex(this.buffer.subarray(0, this.position));
532
541
  if (encoding === 'base64')
533
- return ByteUtils.toBase64(this.buffer);
542
+ return ByteUtils.toBase64(this.buffer.subarray(0, this.position));
534
543
  if (encoding === 'utf8' || encoding === 'utf-8')
535
- return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength, false);
536
- return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength, false);
544
+ return ByteUtils.toUTF8(this.buffer, 0, this.position, false);
545
+ return ByteUtils.toUTF8(this.buffer, 0, this.position, false);
537
546
  }
538
547
  toExtendedJSON(options) {
539
548
  options = options || {};
@@ -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,7 +2135,18 @@ 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 = {
2141
+ getNonnegativeInt32LE(source, offset) {
2142
+ if (source[offset + 3] > 127) {
2143
+ throw new RangeError(`Size cannot be negative at offset: ${offset}`);
2144
+ }
2145
+ return (source[offset] |
2146
+ (source[offset + 1] << 8) |
2147
+ (source[offset + 2] << 16) |
2148
+ (source[offset + 3] << 24));
2149
+ },
2129
2150
  getInt32LE(source, offset) {
2130
2151
  return (source[offset] |
2131
2152
  (source[offset + 1] << 8) |
@@ -2149,17 +2170,29 @@ const NumberUtils = {
2149
2170
  const hi = NumberUtils.getUint32LE(source, offset + 4);
2150
2171
  return (BigInt(hi) << BigInt(32)) + BigInt(lo);
2151
2172
  },
2152
- getFloat64LE(source, offset) {
2153
- FLOAT_BYTES[0] = source[offset];
2154
- FLOAT_BYTES[1] = source[offset + 1];
2155
- FLOAT_BYTES[2] = source[offset + 2];
2156
- FLOAT_BYTES[3] = source[offset + 3];
2157
- FLOAT_BYTES[4] = source[offset + 4];
2158
- FLOAT_BYTES[5] = source[offset + 5];
2159
- FLOAT_BYTES[6] = source[offset + 6];
2160
- FLOAT_BYTES[7] = source[offset + 7];
2161
- return FLOAT[0];
2162
- },
2173
+ getFloat64LE: isBigEndian
2174
+ ? (source, offset) => {
2175
+ FLOAT_BYTES[7] = source[offset];
2176
+ FLOAT_BYTES[6] = source[offset + 1];
2177
+ FLOAT_BYTES[5] = source[offset + 2];
2178
+ FLOAT_BYTES[4] = source[offset + 3];
2179
+ FLOAT_BYTES[3] = source[offset + 4];
2180
+ FLOAT_BYTES[2] = source[offset + 5];
2181
+ FLOAT_BYTES[1] = source[offset + 6];
2182
+ FLOAT_BYTES[0] = source[offset + 7];
2183
+ return FLOAT[0];
2184
+ }
2185
+ : (source, offset) => {
2186
+ FLOAT_BYTES[0] = source[offset];
2187
+ FLOAT_BYTES[1] = source[offset + 1];
2188
+ FLOAT_BYTES[2] = source[offset + 2];
2189
+ FLOAT_BYTES[3] = source[offset + 3];
2190
+ FLOAT_BYTES[4] = source[offset + 4];
2191
+ FLOAT_BYTES[5] = source[offset + 5];
2192
+ FLOAT_BYTES[6] = source[offset + 6];
2193
+ FLOAT_BYTES[7] = source[offset + 7];
2194
+ return FLOAT[0];
2195
+ },
2163
2196
  setInt32BE(destination, offset, value) {
2164
2197
  destination[offset + 3] = value;
2165
2198
  value >>>= 8;
@@ -2200,18 +2233,31 @@ const NumberUtils = {
2200
2233
  destination[offset + 7] = hi;
2201
2234
  return 8;
2202
2235
  },
2203
- setFloat64LE(destination, offset, value) {
2204
- FLOAT[0] = value;
2205
- destination[offset] = FLOAT_BYTES[0];
2206
- destination[offset + 1] = FLOAT_BYTES[1];
2207
- destination[offset + 2] = FLOAT_BYTES[2];
2208
- destination[offset + 3] = FLOAT_BYTES[3];
2209
- destination[offset + 4] = FLOAT_BYTES[4];
2210
- destination[offset + 5] = FLOAT_BYTES[5];
2211
- destination[offset + 6] = FLOAT_BYTES[6];
2212
- destination[offset + 7] = FLOAT_BYTES[7];
2213
- return 8;
2214
- }
2236
+ setFloat64LE: isBigEndian
2237
+ ? (destination, offset, value) => {
2238
+ FLOAT[0] = value;
2239
+ destination[offset] = FLOAT_BYTES[7];
2240
+ destination[offset + 1] = FLOAT_BYTES[6];
2241
+ destination[offset + 2] = FLOAT_BYTES[5];
2242
+ destination[offset + 3] = FLOAT_BYTES[4];
2243
+ destination[offset + 4] = FLOAT_BYTES[3];
2244
+ destination[offset + 5] = FLOAT_BYTES[2];
2245
+ destination[offset + 6] = FLOAT_BYTES[1];
2246
+ destination[offset + 7] = FLOAT_BYTES[0];
2247
+ return 8;
2248
+ }
2249
+ : (destination, offset, value) => {
2250
+ FLOAT[0] = value;
2251
+ destination[offset] = FLOAT_BYTES[0];
2252
+ destination[offset + 1] = FLOAT_BYTES[1];
2253
+ destination[offset + 2] = FLOAT_BYTES[2];
2254
+ destination[offset + 3] = FLOAT_BYTES[3];
2255
+ destination[offset + 4] = FLOAT_BYTES[4];
2256
+ destination[offset + 5] = FLOAT_BYTES[5];
2257
+ destination[offset + 6] = FLOAT_BYTES[6];
2258
+ destination[offset + 7] = FLOAT_BYTES[7];
2259
+ return 8;
2260
+ }
2215
2261
  };
2216
2262
 
2217
2263
  const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
@@ -4089,6 +4135,113 @@ EJSON.serialize = EJSONserialize;
4089
4135
  EJSON.deserialize = EJSONdeserialize;
4090
4136
  Object.freeze(EJSON);
4091
4137
 
4138
+ function getSize(source, offset) {
4139
+ try {
4140
+ return NumberUtils.getNonnegativeInt32LE(source, offset);
4141
+ }
4142
+ catch (cause) {
4143
+ throw new BSONOffsetError('BSON size cannot be negative', offset, { cause });
4144
+ }
4145
+ }
4146
+ function findNull(bytes, offset) {
4147
+ let nullTerminatorOffset = offset;
4148
+ for (; bytes[nullTerminatorOffset] !== 0x00; nullTerminatorOffset++)
4149
+ ;
4150
+ if (nullTerminatorOffset === bytes.length - 1) {
4151
+ throw new BSONOffsetError('Null terminator not found', offset);
4152
+ }
4153
+ return nullTerminatorOffset;
4154
+ }
4155
+ function parseToElements(bytes, startOffset = 0) {
4156
+ startOffset ??= 0;
4157
+ if (bytes.length < 5) {
4158
+ throw new BSONOffsetError(`Input must be at least 5 bytes, got ${bytes.length} bytes`, startOffset);
4159
+ }
4160
+ const documentSize = getSize(bytes, startOffset);
4161
+ if (documentSize > bytes.length - startOffset) {
4162
+ throw new BSONOffsetError(`Parsed documentSize (${documentSize} bytes) does not match input length (${bytes.length} bytes)`, startOffset);
4163
+ }
4164
+ if (bytes[startOffset + documentSize - 1] !== 0x00) {
4165
+ throw new BSONOffsetError('BSON documents must end in 0x00', startOffset + documentSize);
4166
+ }
4167
+ const elements = [];
4168
+ let offset = startOffset + 4;
4169
+ while (offset <= documentSize + startOffset) {
4170
+ const type = bytes[offset];
4171
+ offset += 1;
4172
+ if (type === 0) {
4173
+ if (offset - startOffset !== documentSize) {
4174
+ throw new BSONOffsetError(`Invalid 0x00 type byte`, offset);
4175
+ }
4176
+ break;
4177
+ }
4178
+ const nameOffset = offset;
4179
+ const nameLength = findNull(bytes, offset) - nameOffset;
4180
+ offset += nameLength + 1;
4181
+ let length;
4182
+ if (type === 1 ||
4183
+ type === 18 ||
4184
+ type === 9 ||
4185
+ type === 17) {
4186
+ length = 8;
4187
+ }
4188
+ else if (type === 16) {
4189
+ length = 4;
4190
+ }
4191
+ else if (type === 7) {
4192
+ length = 12;
4193
+ }
4194
+ else if (type === 19) {
4195
+ length = 16;
4196
+ }
4197
+ else if (type === 8) {
4198
+ length = 1;
4199
+ }
4200
+ else if (type === 10 ||
4201
+ type === 6 ||
4202
+ type === 127 ||
4203
+ type === 255) {
4204
+ length = 0;
4205
+ }
4206
+ else if (type === 11) {
4207
+ length = findNull(bytes, findNull(bytes, offset) + 1) + 1 - offset;
4208
+ }
4209
+ else if (type === 3 ||
4210
+ type === 4 ||
4211
+ type === 15) {
4212
+ length = getSize(bytes, offset);
4213
+ }
4214
+ else if (type === 2 ||
4215
+ type === 5 ||
4216
+ type === 12 ||
4217
+ type === 13 ||
4218
+ type === 14) {
4219
+ length = getSize(bytes, offset) + 4;
4220
+ if (type === 5) {
4221
+ length += 1;
4222
+ }
4223
+ if (type === 12) {
4224
+ length += 12;
4225
+ }
4226
+ }
4227
+ else {
4228
+ throw new BSONOffsetError(`Invalid 0x${type.toString(16).padStart(2, '0')} type byte`, offset);
4229
+ }
4230
+ if (length > documentSize) {
4231
+ throw new BSONOffsetError('value reports length larger than document', offset);
4232
+ }
4233
+ elements.push([type, nameOffset, nameLength, offset, length]);
4234
+ offset += length;
4235
+ }
4236
+ return elements;
4237
+ }
4238
+
4239
+ const onDemand = Object.create(null);
4240
+ onDemand.parseToElements = parseToElements;
4241
+ onDemand.ByteUtils = ByteUtils;
4242
+ onDemand.NumberUtils = NumberUtils;
4243
+ Object.freeze(onDemand);
4244
+
4092
4245
  const MAXSIZE = 1024 * 1024 * 17;
4093
4246
  let buffer = ByteUtils.allocate(MAXSIZE);
4094
4247
  function setInternalBufferSize(size) {
@@ -4143,6 +4296,7 @@ function deserializeStream(data, startIndex, numberOfDocuments, documents, docSt
4143
4296
  var bson = /*#__PURE__*/Object.freeze({
4144
4297
  __proto__: null,
4145
4298
  BSONError: BSONError,
4299
+ BSONOffsetError: BSONOffsetError,
4146
4300
  BSONRegExp: BSONRegExp,
4147
4301
  BSONRuntimeError: BSONRuntimeError,
4148
4302
  BSONSymbol: BSONSymbol,
@@ -4165,6 +4319,7 @@ var bson = /*#__PURE__*/Object.freeze({
4165
4319
  calculateObjectSize: calculateObjectSize,
4166
4320
  deserialize: deserialize,
4167
4321
  deserializeStream: deserializeStream,
4322
+ onDemand: onDemand,
4168
4323
  serialize: serialize,
4169
4324
  serializeWithBufferAndIndex: serializeWithBufferAndIndex,
4170
4325
  setInternalBufferSize: setInternalBufferSize
@@ -4172,6 +4327,7 @@ var bson = /*#__PURE__*/Object.freeze({
4172
4327
 
4173
4328
  exports.BSON = bson;
4174
4329
  exports.BSONError = BSONError;
4330
+ exports.BSONOffsetError = BSONOffsetError;
4175
4331
  exports.BSONRegExp = BSONRegExp;
4176
4332
  exports.BSONRuntimeError = BSONRuntimeError;
4177
4333
  exports.BSONSymbol = BSONSymbol;
@@ -4194,6 +4350,7 @@ exports.UUID = UUID;
4194
4350
  exports.calculateObjectSize = calculateObjectSize;
4195
4351
  exports.deserialize = deserialize;
4196
4352
  exports.deserializeStream = deserializeStream;
4353
+ exports.onDemand = onDemand;
4197
4354
  exports.serialize = serialize;
4198
4355
  exports.serializeWithBufferAndIndex = serializeWithBufferAndIndex;
4199
4356
  exports.setInternalBufferSize = setInternalBufferSize;