Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

fs: cpSync copyDir fast path can terminate on filesystem errors

未关闭
#63,970 1 条评论 2 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@ChrisChan0668 已经在做这个了。

开始于 2026年6月18日。

  • #63971 来自 @ChrisChan0668 —— 未关闭

评估

难度
4/5
预计耗时
3-5 天
新手友好度
64/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
冷清

调研方向

使用 issue 中的脚本重现 Windows 失败,然后检查 src/node_file.cc 和 CpSyncCopyDir 的实现。跟踪目录迭代、路径规范化和文件类型检查,并验证文件系统失败会变成可捕获的 JavaScript 异常,而不是终止进程。

由索引模型根据 Issue 内容生成。

描述

fs
Version

v22.17.0 and later; verified against v27.0.0-pre built from current main.

Platform
Microsoft Windows NT 10.0.26100.0 x64
Subsystem

fs

What steps will reproduce the bug?

Run this script on Windows:

'use strict';

const assert = require('node:assert');
const { execFileSync, spawnSync } = require('node:child_process');
const {
  cpSync,
  existsSync,
  mkdirSync,
  rmSync,
  writeFileSync,
} = require('node:fs');
const { tmpdir } = require('node:os');
const { join } = require('node:path');

function run(command, args) {
  return execFileSync(command, args, {
    encoding: 'utf8',
    stdio: ['ignore', 'pipe', 'pipe'],
  });
}

function currentWindowsUser() {
  return run('whoami', []).trim();
}

function restrictDirectory(dir) {
  run('icacls', [dir, '/deny', `${currentWindowsUser()}:(OI)(CI)(RX)`]);
}

function restoreDirectory(dir) {
  if (existsSync(dir)) {
    run('icacls', [dir, '/remove:d', currentWindowsUser()]);
  }
}

if (process.argv[2] === 'child') {
  assert.throws(() => {
    cpSync(process.argv[3], process.argv[4], { recursive: true });
  });
  process.exit(0);
}

const root = join(tmpdir(), `node-cpsync-${process.pid}`);
const src = join(root, 'src');
const dest = join(root, 'dest');
const restrictedDir = join(src, 'restricted');

mkdirSync(restrictedDir, { recursive: true });
writeFileSync(join(src, 'readable.txt'), 'readable\n');
writeFileSync(join(restrictedDir, 'blocked.txt'), 'blocked\n');

restrictDirectory(restrictedDir);

try {
  const child = spawnSync(process.execPath, [__filename, 'child', src, dest], {
    encoding: 'utf8',
  });
  console.log({
    status: child.status,
    signal: child.signal,
    stdout: child.stdout,
    stderr: child.stderr,
  });
} finally {
  restoreDirectory(restrictedDir);
  rmSync(root, { recursive: true, force: true });
}

The important part is that fs.cpSync(src, dest, { recursive: true }) is called without a filter option, so it uses the native copyDir fast path.

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

It reproduces when the native fs.cpSync() copyDir fast path encounters a filesystem error during directory iteration, path canonicalization, or file type checks.

The fast path is used for recursive directory copies when no filter option is provided. Passing filter: () => true avoids this path and falls back to the JavaScript implementation.

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

fs.cpSync() should report the filesystem failure as a JavaScript exception that callers can catch with try/catch or assert.throws().

Filesystem APIs should convert native filesystem failures into JavaScript errors instead of terminating the process.

What do you see instead?

Some std::filesystem calls in the native copyDir implementation use throwing overloads. When those operations fail, the C++ exception can bypass Node's normal error conversion.

Instead of a catchable JavaScript exception, the process can terminate in the native layer.

Additional information

This appears to come from src/node_file.cc's CpSyncCopyDir implementation. Some calls already use std::error_code, but others use throwing std::filesystem overloads, including directory iteration and file type/path checks.

The fix is to use non-throwing std::filesystem overloads throughout the copyDir path and convert each failure with ThrowStdErrException.

主要语言
JavaScript
星标
122k
派生
38.4k
平均合并
3 天 22 小时
30 天内合并 PR
273

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

nodejs/node 的其他 Issue

查看 nodejs/node 的全部 Issue

相似的 Issue

更多 JavaScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。