isomorphic-git 1.37.3 → 1.37.5

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/index.cjs CHANGED
@@ -8,6 +8,7 @@ var AsyncLock = _interopDefault(require('async-lock'));
8
8
  var Hash = _interopDefault(require('sha.js/sha1.js'));
9
9
  var crc32 = _interopDefault(require('crc-32'));
10
10
  var pako = _interopDefault(require('pako'));
11
+ var crypto$1 = require('crypto');
11
12
  var pify = _interopDefault(require('pify'));
12
13
  var ignore = _interopDefault(require('ignore'));
13
14
  var cleanGitRef = _interopDefault(require('clean-git-ref'));
@@ -3273,12 +3274,13 @@ class GitPackIndex {
3273
3274
  0b1100000: 'ofs_delta',
3274
3275
  0b1110000: 'ref_delta',
3275
3276
  };
3276
- if (!this.pack) {
3277
+ const pack = await this.pack;
3278
+ if (!pack) {
3277
3279
  throw new InternalError(
3278
- 'Tried to read from a GitPackIndex with no packfile loaded into memory'
3280
+ 'Could not read packfile data. The packfile may be missing, corrupted, or too large to read into memory.'
3279
3281
  )
3280
3282
  }
3281
- const raw = (await this.pack).slice(start);
3283
+ const raw = pack.slice(start);
3282
3284
  const reader = new BufferCursor(raw);
3283
3285
  const byte = reader.readUInt8();
3284
3286
  // Object type is encoded in bits 654
@@ -3367,6 +3369,19 @@ function readPackIndex({
3367
3369
  return p
3368
3370
  }
3369
3371
 
3372
+ const SHA1_CHUNK_SIZE = 8 * 1024 * 1024;
3373
+
3374
+ async function shasumRange(
3375
+ buffer,
3376
+ { start = 0, end = buffer.length } = {}
3377
+ ) {
3378
+ const hash = crypto$1.createHash('sha1');
3379
+ for (let i = start; i < end; i += SHA1_CHUNK_SIZE) {
3380
+ hash.update(buffer.subarray(i, Math.min(i + SHA1_CHUNK_SIZE, end)));
3381
+ }
3382
+ return hash.digest('hex')
3383
+ }
3384
+
3370
3385
  async function readObjectPacked({
3371
3386
  fs,
3372
3387
  cache,
@@ -3390,12 +3405,18 @@ async function readObjectPacked({
3390
3405
  if (p.error) throw new InternalError(p.error)
3391
3406
  // If the packfile DOES have the oid we're looking for...
3392
3407
  if (p.offsets.has(oid)) {
3393
- // Get the resolved git object from the packfile
3408
+ // Derive the .pack path from the .idx path
3409
+ const packFile = indexFile.replace(/idx$/, 'pack');
3394
3410
  if (!p.pack) {
3395
- const packFile = indexFile.replace(/idx$/, 'pack');
3396
3411
  p.pack = fs.read(packFile);
3397
3412
  }
3398
3413
  const pack = await p.pack;
3414
+ if (!pack) {
3415
+ p.pack = null;
3416
+ throw new InternalError(
3417
+ `Could not read packfile at ${packFile}. The file may be missing, corrupted, or too large to read into memory.`
3418
+ )
3419
+ }
3399
3420
 
3400
3421
  // === Packfile Integrity Verification ===
3401
3422
  // Performance optimization: use _checksumVerified flag to verify only once per packfile
@@ -3414,11 +3435,12 @@ async function readObjectPacked({
3414
3435
  )
3415
3436
  }
3416
3437
 
3417
- // 2. Deep Integrity Check: Calculate actual SHA-1 of packfile payload
3418
- // This ensures true data integrity by verifying the entire packfile content
3419
- // Use subarray for zero-copy reading of large files
3420
- const payload = pack.subarray(0, -20);
3421
- const actualPayloadSha = await shasum(payload);
3438
+ // 2. Deep Integrity Check: Calculate actual SHA-1 of packfile payload.
3439
+ // The Node package build swaps in a chunked implementation for large packs.
3440
+ const actualPayloadSha = await shasumRange(pack, {
3441
+ start: 0,
3442
+ end: pack.length - 20,
3443
+ });
3422
3444
  if (actualPayloadSha !== expectedShaFromIndex) {
3423
3445
  throw new InternalError(
3424
3446
  `Packfile payload corrupted: calculated ${actualPayloadSha} but expected ${expectedShaFromIndex}. The packfile may have been tampered with.`
@@ -9304,8 +9326,8 @@ function filterCapabilities(server, client) {
9304
9326
 
9305
9327
  const pkg = {
9306
9328
  name: 'isomorphic-git',
9307
- version: '1.37.3',
9308
- agent: 'git/isomorphic-git@1.37.3',
9329
+ version: '1.37.5',
9330
+ agent: 'git/isomorphic-git@1.37.5',
9309
9331
  };
9310
9332
 
9311
9333
  class FIFO {
package/index.js CHANGED
@@ -3267,12 +3267,13 @@ class GitPackIndex {
3267
3267
  0b1100000: 'ofs_delta',
3268
3268
  0b1110000: 'ref_delta',
3269
3269
  };
3270
- if (!this.pack) {
3270
+ const pack = await this.pack;
3271
+ if (!pack) {
3271
3272
  throw new InternalError(
3272
- 'Tried to read from a GitPackIndex with no packfile loaded into memory'
3273
+ 'Could not read packfile data. The packfile may be missing, corrupted, or too large to read into memory.'
3273
3274
  )
3274
3275
  }
3275
- const raw = (await this.pack).slice(start);
3276
+ const raw = pack.slice(start);
3276
3277
  const reader = new BufferCursor(raw);
3277
3278
  const byte = reader.readUInt8();
3278
3279
  // Object type is encoded in bits 654
@@ -3361,6 +3362,13 @@ function readPackIndex({
3361
3362
  return p
3362
3363
  }
3363
3364
 
3365
+ async function shasumRange(
3366
+ buffer,
3367
+ { start = 0, end = buffer.length } = {}
3368
+ ) {
3369
+ return shasum(buffer.subarray(start, end))
3370
+ }
3371
+
3364
3372
  async function readObjectPacked({
3365
3373
  fs,
3366
3374
  cache,
@@ -3384,12 +3392,18 @@ async function readObjectPacked({
3384
3392
  if (p.error) throw new InternalError(p.error)
3385
3393
  // If the packfile DOES have the oid we're looking for...
3386
3394
  if (p.offsets.has(oid)) {
3387
- // Get the resolved git object from the packfile
3395
+ // Derive the .pack path from the .idx path
3396
+ const packFile = indexFile.replace(/idx$/, 'pack');
3388
3397
  if (!p.pack) {
3389
- const packFile = indexFile.replace(/idx$/, 'pack');
3390
3398
  p.pack = fs.read(packFile);
3391
3399
  }
3392
3400
  const pack = await p.pack;
3401
+ if (!pack) {
3402
+ p.pack = null;
3403
+ throw new InternalError(
3404
+ `Could not read packfile at ${packFile}. The file may be missing, corrupted, or too large to read into memory.`
3405
+ )
3406
+ }
3393
3407
 
3394
3408
  // === Packfile Integrity Verification ===
3395
3409
  // Performance optimization: use _checksumVerified flag to verify only once per packfile
@@ -3408,11 +3422,12 @@ async function readObjectPacked({
3408
3422
  )
3409
3423
  }
3410
3424
 
3411
- // 2. Deep Integrity Check: Calculate actual SHA-1 of packfile payload
3412
- // This ensures true data integrity by verifying the entire packfile content
3413
- // Use subarray for zero-copy reading of large files
3414
- const payload = pack.subarray(0, -20);
3415
- const actualPayloadSha = await shasum(payload);
3425
+ // 2. Deep Integrity Check: Calculate actual SHA-1 of packfile payload.
3426
+ // The Node package build swaps in a chunked implementation for large packs.
3427
+ const actualPayloadSha = await shasumRange(pack, {
3428
+ start: 0,
3429
+ end: pack.length - 20,
3430
+ });
3416
3431
  if (actualPayloadSha !== expectedShaFromIndex) {
3417
3432
  throw new InternalError(
3418
3433
  `Packfile payload corrupted: calculated ${actualPayloadSha} but expected ${expectedShaFromIndex}. The packfile may have been tampered with.`
@@ -9298,8 +9313,8 @@ function filterCapabilities(server, client) {
9298
9313
 
9299
9314
  const pkg = {
9300
9315
  name: 'isomorphic-git',
9301
- version: '1.37.3',
9302
- agent: 'git/isomorphic-git@1.37.3',
9316
+ version: '1.37.5',
9317
+ agent: 'git/isomorphic-git@1.37.5',
9303
9318
  };
9304
9319
 
9305
9320
  class FIFO {