Skip to content

Commit 45207d4

Browse files
ysyneuclaude
andcommitted
fix: resolve all golangci-lint warnings
- G706 (log injection): exclude globally — slog structured logging is inherently safe against injection - G204 (subprocess with variable): add nolint for intentional exec calls (MCP stdio, bash workspace, rg grep) - G118 (context cancel): nolint — cancel is stored in runningTask map - S1017: use strings.TrimPrefix instead of if+slice - QF1012: use fmt.Fprintf instead of WriteString(fmt.Sprintf(...)) - noctx: use exec.CommandContext for system info commands - prealloc: preallocate grep cmdArgs slice Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f22ba4f commit 45207d4

7 files changed

Lines changed: 19 additions & 17 deletions

File tree

.golangci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,12 @@ linters:
4747
# Exclude G301 (directory permissions) - workspace needs readable directories
4848
# Exclude G304 (file inclusion) - paths are validated via safePath()
4949
# Exclude G306 (file permissions) - workspace files need to be readable
50+
# Exclude G706 (log injection) - we use slog structured logging which is inherently safe
5051
excludes:
5152
- G301
5253
- G304
5354
- G306
55+
- G706
5456

5557
formatters:
5658
enable:

mcp/client.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,7 @@ func headersCacheKey(headers, dynamicHeaders map[string]string) string {
214214
}
215215

216216
func maskKey(key string) string {
217-
// Strip "Bearer " prefix if present
218-
if strings.HasPrefix(key, "Bearer ") {
219-
key = key[7:]
220-
}
217+
key = strings.TrimPrefix(key, "Bearer ")
221218
if len(key) <= 6 {
222219
return key
223220
}

mcp/transport.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package mcp
22

33
import (
4+
"context"
45
"log/slog"
56
"net/http"
67
"os"
@@ -12,7 +13,7 @@ import (
1213

1314
// NewStdioTransport creates a new stdio transport for MCP.
1415
func NewStdioTransport(command string, args []string, env map[string]string) sdk_mcp.Transport {
15-
cmd := exec.Command(command, args...)
16+
cmd := exec.CommandContext(context.Background(), command, args...) //nolint:gosec // G204: command comes from cloud-controlled MCP server config
1617
cmd.Env = buildEnv(env)
1718
return &sdk_mcp.CommandTransport{
1819
Command: cmd,

workspace/large_output.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,18 @@ func (p *LargeOutputProcessor) truncateContent(content string, filePath string)
134134
// Build truncation message
135135
var sb strings.Builder
136136
sb.WriteString("<output_truncated>\n")
137-
sb.WriteString(fmt.Sprintf("Output too large (%d chars, %d lines).", len(content), totalLines))
137+
fmt.Fprintf(&sb, "Output too large (%d chars, %d lines).", len(content), totalLines)
138138

139139
if filePath != "" {
140-
sb.WriteString(fmt.Sprintf(" Full content saved to: %s\n\n", filePath))
140+
fmt.Fprintf(&sb, " Full content saved to: %s\n\n", filePath)
141141
} else {
142142
sb.WriteString(" Could not save full content.\n\n")
143143
}
144144

145-
sb.WriteString(fmt.Sprintf("Preview (first %d lines):\n```\n%s\n```\n\n", previewLines, preview))
145+
fmt.Fprintf(&sb, "Preview (first %d lines):\n```\n%s\n```\n\n", previewLines, preview)
146146

147147
if filePath != "" {
148-
sb.WriteString(fmt.Sprintf("To read more: read(\"%s\", offset=%d, limit=100)\n", filePath, previewLines))
148+
fmt.Fprintf(&sb, "To read more: read(\"%s\", offset=%d, limit=100)\n", filePath, previewLines)
149149
}
150150

151151
sb.WriteString("</output_truncated>")

workspace/workspace.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ func (w *Workspace) Grep(ctx context.Context, args *protocol.GrepArgs) (*protoco
252252
// Build content string
253253
var sb strings.Builder
254254
for _, match := range res.Matches {
255-
sb.WriteString(fmt.Sprintf("%s:%d:%s\n", match.Path, match.LineNumber, match.Content))
255+
fmt.Fprintf(&sb, "%s:%d:%s\n", match.Path, match.LineNumber, match.Content)
256256
}
257257
content := sb.String()
258258

@@ -274,13 +274,14 @@ func (w *Workspace) Grep(ctx context.Context, args *protocol.GrepArgs) (*protoco
274274
}
275275

276276
func (w *Workspace) grepWithRipgrep(ctx context.Context, args *protocol.GrepArgs) (*protocol.GrepResult, error) {
277-
cmdArgs := []string{"--column", "--line-number", "--no-heading", "--color", "never", "--smart-case"}
277+
cmdArgs := make([]string, 0, 6+2*len(args.Include)+2)
278+
cmdArgs = append(cmdArgs, "--column", "--line-number", "--no-heading", "--color", "never", "--smart-case")
278279
for _, inc := range args.Include {
279280
cmdArgs = append(cmdArgs, "--glob", inc)
280281
}
281282
cmdArgs = append(cmdArgs, args.Pattern, ".")
282283

283-
cmd := exec.CommandContext(ctx, "rg", cmdArgs...)
284+
cmd := exec.CommandContext(ctx, "rg", cmdArgs...) //nolint:gosec // G204: args built from validated grep parameters
284285
cmd.Dir = w.root
285286

286287
var stdout strings.Builder
@@ -393,7 +394,7 @@ func (w *Workspace) executeBashCommand(ctx context.Context, command, workdir str
393394
ctx, cancel := context.WithTimeout(ctx, timeout)
394395
defer cancel()
395396

396-
cmd := exec.CommandContext(ctx, "bash", "-c", command)
397+
cmd := exec.CommandContext(ctx, "bash", "-c", command) //nolint:gosec // G204: command is user-initiated via workspace tool
397398
cmd.Dir = workdir
398399

399400
// Use a limited writer to prevent OOM from very large outputs

ws/client.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,10 @@ func getLinuxVersion() string {
518518
return ""
519519
}
520520

521-
// getCommandOutput executes a command and returns its trimmed output.
522521
func getCommandOutput(name string, args ...string) string {
523-
out, err := exec.Command(name, args...).Output()
522+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
523+
defer cancel()
524+
out, err := exec.CommandContext(ctx, name, args...).Output() //nolint:gosec // G204: args are hardcoded system info commands
524525
if err == nil {
525526
return strings.TrimSpace(string(out))
526527
}
@@ -550,7 +551,7 @@ func getDefaultShell() string {
550551
func getTotalMemoryMB() int64 {
551552
switch runtime.GOOS {
552553
case "darwin":
553-
out, err := exec.Command("sysctl", "-n", "hw.memsize").Output()
554+
out, err := exec.CommandContext(context.Background(), "sysctl", "-n", "hw.memsize").Output() //nolint:gosec // G204: hardcoded command
554555
if err == nil {
555556
var bytes int64
556557
if _, err := fmt.Sscanf(strings.TrimSpace(string(out)), "%d", &bytes); err == nil {

ws/handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func (h *Handler) handleTaskRequest(ctx context.Context, msg *protocol.Message)
100100
"operation", req.Operation,
101101
)
102102

103-
taskCtx, cancel := context.WithCancel(ctx)
103+
taskCtx, cancel := context.WithCancel(ctx) //nolint:gosec // G118: cancel is stored in h.runningTask and called on task completion/cancellation
104104
h.mu.Lock()
105105
h.runningTask[req.TaskID] = cancel
106106
h.mu.Unlock()

0 commit comments

Comments
 (0)