Fix for test-stdin-from-file closing fd '0' (#18559)

This commit is contained in:
pfg
2025-03-27 21:38:50 -07:00
committed by GitHub
parent 9ea577efc0
commit 8e0c8a143e
3 changed files with 30 additions and 7 deletions

View File

@@ -198,18 +198,18 @@ pub const FDImpl = packed struct {
};
}
/// This function will prevent stdout and stderr from being closed.
/// This function will prevent stdin, stdout, and stderr from being closed.
pub fn close(this: FDImpl) ?bun.sys.Error {
if (environment.os != .windows or this.kind == .uv) {
// This branch executes always on linux (uv() is no-op),
// or on Windows when given a UV file descriptor.
const fd = this.uv();
if (fd == 1 or fd == 2) {
if (fd == 0 or fd == 1 or fd == 2) {
log("close({}) SKIPPED", .{fd});
return null;
}
}
return this.closeAllowingStdoutAndStderr();
return this.closeAllowingStdinStdoutAndStderr();
}
/// Assumes given a valid file descriptor
@@ -227,7 +227,7 @@ pub const FDImpl = packed struct {
};
}
pub fn closeAllowingStdoutAndStderr(this: FDImpl) ?bun.sys.Error {
pub fn closeAllowingStdinStdoutAndStderr(this: FDImpl) ?bun.sys.Error {
if (allow_assert) {
bun.assert(this.value.as_system != invalid_value); // probably a UAF
}

View File

@@ -1835,11 +1835,11 @@ pub fn close2(fd: bun.FileDescriptor) ?Syscall.Error {
return null;
}
return closeAllowingStdoutAndStderr(fd);
return closeAllowingStdinStdoutAndStderr(fd);
}
pub fn closeAllowingStdoutAndStderr(fd: bun.FileDescriptor) ?Syscall.Error {
return bun.FDImpl.decode(fd).closeAllowingStdoutAndStderr();
pub fn closeAllowingStdinStdoutAndStderr(fd: bun.FileDescriptor) ?Syscall.Error {
return bun.FDImpl.decode(fd).closeAllowingStdinStdoutAndStderr();
}
pub const max_count = switch (builtin.os.tag) {

View File

@@ -0,0 +1,23 @@
'use strict';
const common = require('../common');
const fixtures = require('../common/fixtures');
const tmpdir = require('../common/tmpdir');
const assert = require('assert');
const childProcess = require('child_process');
const fs = require('fs');
const stdoutScript = fixtures.path('echo-close-check.js');
const tmpFile = tmpdir.resolve('stdin.txt');
const string = fixtures.utf8TestText;
tmpdir.refresh();
fs.writeFileSync(tmpFile, string);
childProcess.exec(...common.escapePOSIXShell`"${process.argv0}" "${stdoutScript}" < "${tmpFile}"`, common.mustCall(function(err, stdout, stderr) {
fs.unlinkSync(tmpFile);
assert.ifError(err);
assert.strictEqual(stdout, `hello world\r\n${string}`);
assert.strictEqual(stderr, '');
}));