From 4958ea5100ebf8d4ff9fd818b7bc59d01989feb4 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Mon, 23 Mar 2026 08:08:57 +0200 Subject: fix: address all HIGH-severity code quality audit findings - lsp/server.go: track request goroutines in inflight WaitGroup to prevent use-after-close writes on shutdown - lsp/llm_client_registry.go: acquire write lock before calling build() to eliminate TOCTOU race on cache population - lsp/handlers_codeaction.go: resolveSimplifyCodeAction now uses PromptCodeActionSimplify{System,User} (was wrongly using rewrite prompts) - askcli/taskexport.go: remove exported MustParseTaskExport to prevent panic on malformed external input; move to unexported test helper - cmd/ask/main.go: print error to stderr before os.Exit - llm/{openai,ollama,openrouter}.go: add interface satisfaction assertions - integrationtests/ask_test.go: replace type assertions with errors.As for robust exec.ExitError unwrapping Co-Authored-By: Claude Sonnet 4.6 --- internal/askcli/taskexport.go | 8 -------- internal/askcli/taskexport_test.go | 20 +++++++++++++++----- 2 files changed, 15 insertions(+), 13 deletions(-) (limited to 'internal/askcli') diff --git a/internal/askcli/taskexport.go b/internal/askcli/taskexport.go index 9841821..ca67ef5 100644 --- a/internal/askcli/taskexport.go +++ b/internal/askcli/taskexport.go @@ -32,11 +32,3 @@ func ParseTaskExport(r io.Reader) ([]TaskExport, error) { } return tasks, nil } - -func MustParseTaskExport(data []byte) []TaskExport { - var tasks []TaskExport - if err := json.Unmarshal(data, &tasks); err != nil { - panic(fmt.Sprintf("failed to parse task export JSON: %v", err)) - } - return tasks -} diff --git a/internal/askcli/taskexport_test.go b/internal/askcli/taskexport_test.go index e7779aa..799415a 100644 --- a/internal/askcli/taskexport_test.go +++ b/internal/askcli/taskexport_test.go @@ -2,11 +2,21 @@ package askcli import ( "encoding/json" + "fmt" "io" "strings" "testing" ) +// mustParseTaskExport is a test-only helper that panics on parse failure. +func mustParseTaskExport(data []byte) []TaskExport { + var tasks []TaskExport + if err := json.Unmarshal(data, &tasks); err != nil { + panic(fmt.Sprintf("failed to parse task export JSON: %v", err)) + } + return tasks +} + func TestParseTaskExport_ValidJSON(t *testing.T) { data := `[{"uuid":"abc123","description":"Test task","status":"pending","priority":"M","tags":["cli"],"urgency":10.5,"depends":[]}]` tasks, err := ParseTaskExport(strings.NewReader(data)) @@ -31,18 +41,18 @@ func TestParseTaskExport_InvalidJSON(t *testing.T) { } } -func TestMustParseTaskExport_Panics(t *testing.T) { +func TestMustParseTaskExportHelper_Panics(t *testing.T) { defer func() { if r := recover(); r == nil { - t.Fatal("MustParseTaskExport should panic on invalid JSON") + t.Fatal("mustParseTaskExport should panic on invalid JSON") } }() - MustParseTaskExport([]byte("not json")) + mustParseTaskExport([]byte("not json")) } -func TestMustParseTaskExport_ValidJSON(t *testing.T) { +func TestMustParseTaskExportHelper_ValidJSON(t *testing.T) { data := []byte(`[{"uuid":"xyz789","description":"Another task","status":"completed","priority":"H","tags":["agent"],"urgency":15.0,"depends":["dep1"]}]`) - tasks := MustParseTaskExport(data) + tasks := mustParseTaskExport(data) if len(tasks) != 1 { t.Fatalf("len(tasks) = %d, want 1", len(tasks)) } -- cgit v1.2.3