This commit is contained in:
2026-10-16 16:34:15 +08:00
parent 7a3769670b
commit ff366a4daf
80 changed files with 9961 additions and 888 deletions

38
main/generate-tmp-path.js Normal file
View File

@@ -0,0 +1,38 @@
// main/file-ops.js atomicWriteFile —— tmp 路径生成(audit P2-1)
//
// 背景:原 inline 实现 `Math.random().toString(36).slice(2, 8)`
// - Math.random() 不加密安全,并发同毫秒 + 同 pid + 同 dst 可能撞名
// (虽然 36^6 ≈ 21 亿,实际不撞,但语义上 audit 要求与 crypto.randomUUID 对齐)
// - 仓库其它路径已用 crypto.randomUUID(),统一风格
//
// 设计:
// - 抽 generateTmpPath(dst, { crypto, pid, now }) 工厂
// - 注入 crypto / pid / now 便于单测验证随机性来源
// - 默认走 node:crypto.randomUUID()(128-bit 加密安全)
// - 路径格式:${dst}.tmp.${pid}.${ts}.${randomId}
// 保持现有格式不破坏 fs-watcher(fs-watcher 旧逻辑只匹配 .tmp.* 前缀,randomId
// 改成 UUID 不影响匹配)
//
// 调用方:atomicWriteFile 在 fs.open 之前构造 tmpPath。
'use strict';
/**
* 生成 atomicWriteFile 用的 tmp 路径。
* @param {string} dst 目标文件完整路径
* @param {{
* crypto?: { randomUUID: () => string },
* pid?: number,
* now?: () => number,
* }} [opts] 注入依赖,便于单测
* @returns {string} `${dst}.tmp.${pid}.${ts}.${randomId}`
*/
function generateTmpPath(dst, opts) {
const cryptoImpl = (opts && opts.crypto) || require('node:crypto');
const pid = (opts && typeof opts.pid === 'number') ? opts.pid : process.pid;
const now = (opts && typeof opts.now === 'function') ? opts.now : Date.now;
const randomId = cryptoImpl.randomUUID();
return `${dst}.tmp.${pid}.${now()}.${randomId}`;
}
module.exports = { generateTmpPath };