Skip to content

fix: bound captured script output across execution engines - #633

Merged
Sev7eNup merged 1 commit into
mainfrom
fix/572-bound-script-output
Oct 24, 2026
Merged

Sev7eNup merged 1 commit into
mainfrom
fix/572-bound-script-output

Conversation

@Sev7eNup

@Sev7eNup Sev7eNup commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

What & why

Stop process, runspace and WinRM execution when the shared output budget is exceeded. Drain streams incrementally and preserve cancellation semantics.

Add Engine:MaxCapturedOutputChars (default 16777216) and regression coverage for oversized and infinite output.

Fixes #572

The default accommodates Start Program's existing two capped 1 MiB streams even with JSON escape expansion. Smaller configured budgets still apply across all streams.

Testing

Engine.Tests: FullyQualifiedName~PowerShell|FullyQualifiedName~WinRmSession|FullyQualifiedName~StartProgram — 450 passed. Regressions cover shared stream budgets, oversized and endless output, WinRM invalidation, cancellation, and both Start Program streams at their cap including JSON-escaped control characters.

git diff --check passed. Full CI runs on this PR.

Stop process, runspace and WinRM execution when the shared output budget is exceeded. Drain streams incrementally and preserve cancellation semantics.

Add Engine:MaxCapturedOutputChars (default 16777216) and regression coverage for oversized and infinite output.

Fixes #572
@Sev7eNup
Sev7eNup force-pushed the fix/572-bound-script-output branch from 7c5f6fb to 5705ee6 Compare October 24, 2026 15:50
if (baseObj is string s) return s;
try { return baseObj?.ToString() ?? string.Empty; } catch { }
try { return ps.ToString() ?? string.Empty; } catch { }
return $"<{baseObj?.GetType().Name ?? "PSObject"}: ToString failed>";
public async Task Capture_ConcurrentStreams_ShareOneBudgetAndContinueDraining()
{
using var budget = new ScriptOutputBudget(4096);
var stdout = new ProcessExecutionEngine.OutputCapture(new StringReader(new string('o', 10000)),
using var budget = new ScriptOutputBudget(4096);
var stdout = new ProcessExecutionEngine.OutputCapture(new StringReader(new string('o', 10000)),
TestContext.Current.CancellationToken, budget.CreateBuffer());
var stderr = new ProcessExecutionEngine.OutputCapture(new StringReader(new string('e', 10000)),
{
var baseObj = ps.BaseObject;
if (baseObj is string s) return s;
try { return baseObj?.ToString() ?? string.Empty; } catch { }
{
var baseObj = ps.BaseObject;
if (baseObj is string s) return s;
try { return baseObj?.ToString() ?? string.Empty; } catch { }
var baseObj = ps.BaseObject;
if (baseObj is string s) return s;
try { return baseObj?.ToString() ?? string.Empty; } catch { }
try { return ps.ToString() ?? string.Empty; } catch { }
var baseObj = ps.BaseObject;
if (baseObj is string s) return s;
try { return baseObj?.ToString() ?? string.Empty; } catch { }
try { return ps.ToString() ?? string.Empty; } catch { }
return $"<{baseObj?.GetType().Name ?? "PSObject"}: ToString failed>";
}
try { return value.ToString() ?? string.Empty; }
catch { return $"<{value.GetType().Name}: ToString failed>"; }
{
try { ps.Stop(); } catch { /* best-effort: pipeline may already be torn down */ }
});
_ = Task.Run(() => { try { ps.Stop(); } catch { /* pipeline may already be torn down */ } }));
@Sev7eNup
Sev7eNup merged commit a992435 into main Oct 24, 2026
17 checks passed
@Sev7eNup
Sev7eNup deleted the fix/572-bound-script-output branch October 24, 2026 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bound script output capture to prevent host memory exhaustion

2 participants