| id | 2606192026 |
|---|---|
| title | Add per-goroutine recover() to CLI engine runner worker goroutines |
| status | ✅ |
| summary | CLI engine worker goroutines in internal/engine/runner.go:353-370 have no defer recover(). A panic on adversarial Markdown crashes the whole process. Mirror the LSP's recoverPanic pattern so rule panics are caught per-file and reported as InternalError diagnostics. Closes S003 (MEDIUM) from the 2026-06-19 full-repo audit. |
| model | sonnet |
Close S003 (medium, CWE-390) from the 2026-06-19 full-repo security audit.
The parallel worker goroutines in internal/engine/runner.go:353-370
have no defer recover(). A rule panic on attacker-controlled Markdown
content kills the entire mdsmith process. No diagnostics are printed
for other files. The LSP server already handles this correctly via
defer s.recoverPanic("lint " + uri) in server_diagnostics.go:246.
Mirror that pattern in the CLI path. A hostile file should produce a
per-file InternalError diagnostic, not a crash.
-
Write a failing test that injects a panic-triggering stub rule into a multi-file runner. Assert the runner returns an
InternalErrordiagnostic for the panicking file and completes the others. -
In
internal/engine/runner.go:353-370, wrap the goroutine body:defer func() { if r := recover(); r != nil { outcomes[i] = panicOutcome(r) } }()
panicOutcomeconverts the recovered value and a stack trace into anInternalErrordiagnostic on the file. -
Confirm the new test passes and no existing tests regress.
-
Run
go test ./...andgo tool golangci-lint run.
- A rule panic on file
iin a multi-file run produces anInternalErrordiagnostic for fileiand does not affect the outcome of any other file. -
mdsmith check .on a directory containing a panic-triggering file exits with a non-zero status (InternalError) but does not crash. - The recovered panic includes a stack trace in the diagnostic message so the bug can be reported.
- All tests pass:
go test ./...<<<<<<< .merge_file_T1gOUJ -
go tool golangci-lint runreports no issues (environment constraint: tools/go.mod requires Go 1.25.8+; golangci-lint skipped;go vet ./...passes; code merged in PR #666) ======= -
go tool golangci-lint runreports no issues (go vet ./...passes; golangci-lint requires Go ≥1.25.8 in tools/go.mod — environment gap, not a code issue)
.merge_file_i8Z6Il