Files
node/test/parallel/test-fs-negative-zero.js
T
Christian Aurich Zanettini Martins 1e17275dea fs: fix crash on negative zero file descriptor
`isInt32()` accepts -0 because `-0 === (-0 | 0)`, but V8 does not
represent -0 as an Int32 value, so `Value::IsInt32()` rejects it. The
utf8 fast paths of `readFileSync()` and `writeFileSync()` hand the value
straight to the binding, which then took it for a path and aborted on
the null check.

Coerce -0 to 0 before the call, matching `getValidatedFd()` and the rest
of fs, where -0 is a valid way to name file descriptor 0.

Signed-off-by: Christian Aurich <christian.aurichzm@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65888
Fixes: https://github.com/nodejs/node/issues/65886
Reviewed-By: Xuguang Mei <meixuguang@gmail.com>
2026-09-26 19:52:53 +00:00

49 lines
1.3 KiB
JavaScript

'use strict';
require('../common');
const assert = require('assert');
const { spawnSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const os = require('os');
const missing = path.join(
os.tmpdir(),
`node-fs-negative-zero-${process.pid}`,
'entry',
);
function ignoreExpectedError(fn) {
try {
fn();
} catch {
// Ignore expected file system errors from the missing path.
}
}
const fd = fs.openSync(process.execPath, -0);
fs.closeSync(fd);
ignoreExpectedError(() => fs.openSync(process.execPath, 'r', -0));
ignoreExpectedError(() => fs.readFileSync(process.execPath, { flag: -0 }));
ignoreExpectedError(() => fs.mkdirSync(missing, { mode: -0 }));
ignoreExpectedError(() => fs.chmodSync(missing, -0));
ignoreExpectedError(() => fs.writeFileSync(missing, '', { mode: -0 }));
// -0 is accepted as file descriptor 0. Writing an empty string reaches the
// utf8 fast path without issuing a write on the descriptor.
fs.writeFileSync(-0, '');
fs.appendFileSync(-0, '');
const child = spawnSync(
process.execPath,
['-e', 'process.stdout.write(require("fs").readFileSync(-0, "utf8"))'],
{ input: 'hello' },
);
assert.strictEqual(child.status, 0);
assert.strictEqual(child.stdout.toString(), 'hello');
fs.watchFile(missing, { interval: -0 }, () => {});
fs.unwatchFile(missing);