fix: expand local session results and reject unsafe search targets

This commit is contained in:
2026-09-06 01:24:50 +08:00
parent 93f4583737
commit c35a4a1051
16 changed files with 557 additions and 46 deletions
@@ -0,0 +1,48 @@
param(
[Parameter(Mandatory=$true)][string]$Executable,
[Parameter(Mandatory=$true)][string]$OutputDirectory,
[string]$Query='交流',
[string]$Target='消息测试专用群组',
[int]$ExpectedCount=10
)
$ErrorActionPreference='Stop'
$exe=(Resolve-Path $Executable).Path
if(Test-Path $OutputDirectory){throw 'Use a fresh evidence directory.'}
$directory=(New-Item -ItemType Directory $OutputDirectory).FullName
& $exe doctor | Out-File "$directory\doctor.json" -Encoding UTF8
$doctorCode=$LASTEXITCODE
& $exe inspect-ui --output "$directory\baseline-ui.json" | Out-Null
$baselineCode=$LASTEXITCODE
& $exe smoke --output "$directory\smoke-ui.json" | Out-File "$directory\smoke.json" -Encoding UTF8
$smokeCode=$LASTEXITCODE
$search=(& $exe session search --query $Query --ui-output "$directory\expanded-ui.json" --timeout 30 | Out-String) | ConvertFrom-Json
$searchCode=$LASTEXITCODE
$rows=@($search.results)
$targetInQuery=@($rows | Where-Object {$_.Name -ceq $Target}).Count
$negativeCode=$null
if($targetInQuery -eq 0){
$negative=(& $exe session open --query $Query --name $Target --timeout 30 | Out-String) | ConvertFrom-Json
$negativeCode=$LASTEXITCODE
$negativeAccepted=($negativeCode -ne 0 -and $negative.error -eq 'ControlNotFound')
}else{$negativeAccepted=$true}
$opened=(& $exe session open --query $Target --name $Target --timeout 30 | Out-String) | ConvertFrom-Json
$openCode=$LASTEXITCODE
$current=(& $exe session current --timeout 20 | Out-String) | ConvertFrom-Json
$currentCode=$LASTEXITCODE
& $exe inspect-ui --output "$directory\selected-ui.json" | Out-Null
$inspectCode=$LASTEXITCODE
$result=@{
DoctorExit=$doctorCode;BaselineInspectExit=$baselineCode;SmokeExit=$smokeCode;SearchExit=$searchCode;
ExpandedCount=$rows.Count;ExpectedCount=$ExpectedCount;TargetInKeywordResults=$targetInQuery;
LocalCategoriesOnly=(@($rows | Where-Object {$_.Category -notin @('群聊','联系人','功能','最常使用')}).Count -eq 0);
MissingExactTargetRejected=$negativeAccepted;NegativeExit=$negativeCode;
OpenExit=$openCode;OpenError=$opened.error;OpenMessage=$opened.message;CurrentExit=$currentCode;InspectExit=$inspectCode;
OpenedTargetMatches=($opened.Name -ceq $Target);CurrentTargetMatches=($current.session.Name -ceq $Target);
GroupMessagesSent=0;BinarySha256=(Get-FileHash $exe -Algorithm SHA256).Hash
}
$result.Success=($doctorCode -eq 0 -and $baselineCode -eq 0 -and $smokeCode -eq 0 -and
$searchCode -eq 0 -and $rows.Count -eq $ExpectedCount -and $result.LocalCategoriesOnly -and
$negativeAccepted -and $openCode -eq 0 -and $currentCode -eq 0 -and $inspectCode -eq 0 -and
$result.OpenedTargetMatches -and $result.CurrentTargetMatches)
$result | ConvertTo-Json -Depth 5 | Set-Content "$directory\summary.json" -Encoding UTF8
if(!$result.Success){exit 1}
+39
View File
@@ -0,0 +1,39 @@
param(
[Parameter(Mandatory=$true)][string]$Executable,
[Parameter(Mandatory=$true)][string]$OutputDirectory
)
$ErrorActionPreference='Stop'
$exe=(Resolve-Path $Executable).Path
$directory=[IO.Path]::GetFullPath($OutputDirectory)
if (Test-Path $directory) { throw 'Use a new evidence directory.' }
[IO.Directory]::CreateDirectory($directory) | Out-Null
$targets=@('文件传输助手','消息测试专用群组')
$processes=@()
try {
for($i=0;$i -lt $targets.Count;$i++) {
$arguments=@('chat','monitor','--independent','--session',('"'+$targets[$i]+'"'),
'--seconds','8','--state-file',('"'+$directory+'\state-'+$i+'.json"'),'--timeout','20')
$process=Start-Process $exe -ArgumentList $arguments -PassThru -NoNewWindow `
-RedirectStandardOutput "$directory\events-$i.jsonl" -RedirectStandardError "$directory\stderr-$i.txt"
$null=$process.Handle # Retain the process handle so PowerShell 5 can retrieve ExitCode after exit.
$processes+=$process
}
$checks=@()
for($i=0;$i -lt $processes.Count;$i++) {
$process=$processes[$i]
if (!$process.WaitForExit(30000)) { throw 'Named listener exceeded its deadline.' }
$exitCode=$process.ExitCode
$statePath="$directory\state-$i.json"
$state=if(Test-Path $statePath){ Get-Content $statePath -Raw | ConvertFrom-Json }else{$null}
& $exe inspect-ui --window-title $targets[$i] --output "$directory\ui-$i.json" --timeout 20 | Out-Null
$inspectCode=$LASTEXITCODE
$checks+=@{Index=$i;ExitCode=$exitCode;CheckpointSaved=($null -ne $state);
SessionMatches=($state.session -eq $targets[$i]);FingerprintCount=if($null -ne $state){@($state.fingerprints).Count}else{0};InspectExit=$inspectCode}
}
$passed=@($checks | Where-Object {$_.ExitCode -ne 0 -or !$_.CheckpointSaved -or !$_.SessionMatches -or $_.FingerprintCount -lt 1 -or $_.InspectExit -ne 0}).Count -eq 0
$result=@{Checks=$checks;Passed=$passed;MessagesSent=0;Scope='Parallel named-window baseline only; not incoming-message delivery or endurance.'}
[IO.File]::WriteAllText("$directory\summary.json",($result | ConvertTo-Json -Depth 5),(New-Object Text.UTF8Encoding($false)))
if(!$passed){exit 2}
} finally {
foreach($process in $processes){ if(!$process.HasExited){$process.Kill();$process.WaitForExit()};$process.Dispose() }
}