fix(desktop): strip installer escapes from the manifest-failure banner too

Only Log lines were sanitized at the emitter; the manifest-step error string
was still built from the raw child stderr/stdout tail, so a failing
`install.sh --manifest` (print_error writes `${RED}✗${NC}`) put escape bytes
straight into the Setup failure banner. Run stripAnsi / strip_ansi over the
embedded tail on both the Electron and the Tauri bootstrap surfaces (#112675).
This commit is contained in:
teknium1
2026-09-16 12:29:21 -07:00
committed by Teknium
parent 6e58dcdbe7
commit 1503d40aba
3 changed files with 30 additions and 4 deletions

View File

@@ -583,7 +583,7 @@ async fn run_bootstrap(
let err = format!(
"install.ps1 -Manifest failed: exit {:?}\n{}",
manifest_result.exit_code,
manifest_result.stderr.trim()
crate::events::strip_ansi(manifest_result.stderr.trim())
);
emit_event(
&app,

View File

@@ -289,3 +289,27 @@ test('installer log lines reach the emitter without escape sequences; \\r redraw
// Plain multi-byte text is untouched.
assert.equal(cleanInstallerLogLine('Ready — café ✓ 中文'), 'Ready — café ✓ 中文')
})
test.skipIf(process.platform === 'win32')(
'a manifest-step failure surfaces the installer tail without escape sequences',
async () => {
const home = mkTmpHome()
fs.mkdirSync(path.join(home, 'scripts'))
fs.writeFileSync(
path.join(home, 'scripts', 'install.sh'),
'#!/usr/bin/env bash\nprintf "\\033[0;31m\\xe2\\x9c\\x97\\033[0m manifest broke\\n" >&2\nexit 3\n'
)
const result = await runBootstrap({
installStamp: null,
activeRoot: home,
sourceRepoRoot: home,
hermesHome: home,
logRoot: home,
onEvent: () => {}
})
assert.equal(result.ok, false)
assert.equal(result.error, 'install.sh --manifest failed: exit 3\n✗ manifest broke')
}
)

View File

@@ -737,9 +737,11 @@ async function fetchManifest({
})
if (result.code !== 0) {
throw new Error(
`${isPosix ? 'install.sh --manifest' : 'install.ps1 -Manifest'} failed: exit ${result.code}\n${result.stderr || result.stdout}`
)
// The tail lands in the Setup failure banner, not the log ring, so strip
// the installer's colour/OSC bytes here too (#112675).
const tail = stripAnsi(result.stderr || result.stdout).trim()
throw new Error(`${isPosix ? 'install.sh --manifest' : 'install.ps1 -Manifest'} failed: exit ${result.code}\n${tail}`)
}
// The manifest is the LAST JSON line on stdout (install.ps1 may print