Skip to content

zlib: ZipFile.close() hangs after partially consuming file-backed contentIterator() #65277

Description

@trivikr

Version

main

Platform

macOS 26.6.1

Subsystem

zlib

What steps will reproduce the bug?

import { mkdtempSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { ZipEntry, createZipArchiveSync, ZipFile } from 'node:zlib';

const dir = mkdtempSync(join(tmpdir(), 'zip-close-hang-'));
const file = join(dir, 'archive.zip');

const chunks = [];
const entry = ZipEntry.createSync(
  'big.txt',
  Buffer.alloc(1024 * 1024, 0x61),
  { method: 'store' },
);

for (const chunk of createZipArchiveSync([entry])) {
  chunks.push(chunk);
}
writeFileSync(file, Buffer.concat(chunks));

const zip = ZipFile.openSync(file);
const readEntry = zip.getSync('big.txt');

const iterator = readEntry.contentIterator();
const first = await iterator.next();
console.log('read first chunk:', first.value.length);

const result = await Promise.race([
  zip.close().then(() => 'close resolved'),
  new Promise((resolve) => setTimeout(() => resolve('close timed out'), 1000)),
]);

console.log(result);

await iterator.return();
await zip.close();

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

zip.close() should either close promptly or otherwise not wait forever for a paused iterator that is not actively performing an fd read.

What do you see instead?

read first chunk: 1048576
close timed out

After one chunk is consumed, zip.close() does not settle while the iterator is paused, so the repro prints close timed out.

Additional information

No response

Metadata

Metadata

Assignees

Labels

zlibIssues and PRs related to the zlib subsystem.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions