fix: 口令会随 -Verbose 落进日志(DEBUG 下打印整条命令行)

缺陷:Invoke-ExternalCommand 在 DEBUG 级打印整条命令行,而 7z / RAR 只接受命令行
口令(-p<口令>),所以口令必然出现在参数表里。一旦 -Verbose(Backup.ps1 / Restore.ps1
都会因它打开 DEBUG),logs\*.log 里就是明文口令 —— 与 BackupConfig.psd1 和文档里
"口令不落盘、不写进仓库"的承诺直接冲突。

修法:打印前把 -p 参数换成占位符;真正执行的仍然是原参数。在**参数级别**替换而不是
对拼好的命令行做正则 —— 含空格的口令会被引号包起来("-pmy pass"),正则在那种形态上
很容易漏掉,而漏掉的代价是口令明文入日志。

回归断言(零依赖与 Pester 各一份):打开 DEBUG、把日志指向临时目录、带一个哨兵口令
跑一次外部命令,然后读日志文件断言哨兵不在里面、占位符在里面。另加一条"测试的测试":
断言那行 DEBUG 记录确实写进去了 —— 否则前两条会在"压根没记录"时空跑通过。

断言有效性做了红绿证明:把遮蔽改回 $startInfo.Arguments 后断言变红并指名"口令明文
进了日志",还原后转绿。

验收:test.ps1 9/9 全绿;tests\Run-RealSmoke.ps1 4/4 全绿。
This commit is contained in:
Shuery committed 2026-09-26 22:41:52 +08:00
1 parent d32d4b511f
commit e17cdcda79
3 files changed
+59 -1

No files matched your search

+11 -1
View File
@@ -262,7 +262,17 @@ function Invoke-ExternalCommand {
$startInfo.WorkingDirectory = $WorkingDirectory
}
Write-Log ('执行: {0} {1}' -f $FilePath, $startInfo.Arguments) -Level DEBUG
# 打印的那一行必须把口令遮蔽掉:7z / RAR 只接受命令行口令(`-p<口令>`),所以口令
# 必然出现在参数表里;一旦 -Verbose 打开 DEBUG,整条命令行就会落进 logs\*.log ——
# 而 BackupConfig.psd1 与文档都承诺过"口令不落盘、不写进仓库"。真正执行的仍然是
# $startInfo.Arguments,这里只改日志。
#
# 在**参数级别**遮蔽,而不是对拼好的命令行做正则:含空格的口令会被引号包起来
# ("-pmy pass"),正则在那种形态上很容易漏掉,而漏掉的代价是口令明文入日志。
$loggableArguments = @($ArgumentList | ForEach-Object {
if ($_ -is [string] -and $_ -like '-p*') { '-p<口令已隐藏>' } else { $_ }
})
Write-Log ('执行: {0} {1}' -f $FilePath, (ConvertTo-NativeArgumentString -ArgumentList $loggableArguments)) -Level DEBUG
$process = [System.Diagnostics.Process]::Start($startInfo)
try {