From 7b9dd97689db400f2408ed50b04857d7d73d83e5 Mon Sep 17 00:00:00 2001 From: Agando Date: Tue, 29 Sep 2026 15:56:27 +0200 Subject: newOS4 v4.6.15: reentrant print-capture stack, AI tail -f block, read-only sed in safeRead, security test harness (21 checks) --- modules/ext/shell.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'modules/ext/shell.js') diff --git a/modules/ext/shell.js b/modules/ext/shell.js index 80bc841..9966e0f 100644 --- a/modules/ext/shell.js +++ b/modules/ext/shell.js @@ -366,9 +366,8 @@ class ShellModule { } // > or >> — capture output, write to file - const originalPrint = this.terminal.print.bind(this.terminal); let output = ''; - this.terminal.print = (text, type) => { output += text + '\n'; }; + this.terminal._pushPrintCapture(buf => { output += buf; }); let cmdOk = true; try { @@ -386,13 +385,12 @@ class ShellModule { fs.writeFile('__pipebuf__', pipeInput); } if (i < pipeParts.length - 1) { - const captPrint = this.terminal.print.bind(this.terminal); let capt = ''; - this.terminal.print = (t, ty) => { capt += t + '\n'; }; + this.terminal._pushPrintCapture(buf => { capt += buf; }); try { await this.terminal.dispatchCommand(pCmd, pArgs); } finally { - this.terminal.print = captPrint; + this.terminal._popPrintCapture(); } pipeInput = capt.trim(); } else { @@ -410,14 +408,18 @@ class ShellModule { } } catch(e) { cmdOk = false; - // Restore print before showing the error - this.terminal.print = originalPrint; + // Pop capture before showing the error + this.terminal._popPrintCapture(); this.terminal.print('Error: ' + e.message, 'error'); redirectInfo.exitOk = false; return; } finally { - // Always restore print — critical: without this, terminal is permanently broken - this.terminal.print = originalPrint; + // Always pop capture — critical: without this, terminal output stays captured + // (empty stack = normal DOM printing, so pop is idempotent-safe when already popped) + if (this.terminal._printCaptureStack && this.terminal._printCaptureStack.length > 0) { + // popped in catch path for error case; success path pops here + this.terminal._popPrintCapture(); + } } const captured = output.trimEnd(); -- cgit v1.2.3