diff --git a/packages/tar-parser/src/lib/tar.test.ts b/packages/tar-parser/src/lib/tar.test.ts index 2db408360ff..4c669759756 100644 --- a/packages/tar-parser/src/lib/tar.test.ts +++ b/packages/tar-parser/src/lib/tar.test.ts @@ -497,4 +497,18 @@ describe('tar-stream test cases', () => { ], ]) }) + + it('parses large github repo', async () => { + let response = await fetch( + 'https://codeload.github.com/vercel/next.js/tar.gz/refs/heads/canary', + ) + if (!response.ok) { + throw new Error(`Failed to fetch tar.gz: ${response.status} ${response.statusText}`) + } + let entries: [TarHeader][] = [] + await parseTar(response.body!.pipeThrough(new DecompressionStream('gzip')), async (entry) => { + entries.push([entry.header]) + }) + assert.ok(entries.length > 1000) + }) }) diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts index c4072ea7757..f13bc88fed6 100644 --- a/packages/tar-parser/src/lib/tar.ts +++ b/packages/tar-parser/src/lib/tar.ts @@ -315,7 +315,6 @@ export class TarParser { } this.#header = parseTarHeader(block, this.#options) - switch (this.#header.type) { case 'gnu-long-path': case 'gnu-long-link-path': @@ -399,6 +398,13 @@ export class TarParser { this.#bodyController!.enqueue(this.#buffer!) this.#missing -= this.#buffer!.length this.#buffer = null + + // Check if we've finished reading the entire body + if (this.#missing === 0) { + this.#bodyController!.close() + this.#bodyController = null + this.#missing = overflow(this.#header!.size) + } } else { this.#bodyController!.enqueue(this.#read(this.#missing)) this.#bodyController!.close()