Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package gosec for openSUSE:Factory checked in at 2025-09-22 19:29:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/gosec (Old) and /work/SRC/openSUSE:Factory/.gosec.new.27445 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gosec" Mon Sep 22 19:29:23 2025 rev:27 rq:1306580 version:2.22.9 Changes: -------- --- /work/SRC/openSUSE:Factory/gosec/gosec.changes 2025-08-18 16:09:49.398839454 +0200 +++ /work/SRC/openSUSE:Factory/.gosec.new.27445/gosec.changes 2025-09-22 19:29:42.642936502 +0200 @@ -1,0 +2,19 @@ +Mon Sep 22 12:36:33 UTC 2025 - Felix Niederwanger <[email protected]> + +- Update to version 2.22.9: + * Update cosign to v2.6.0 and go in the CI to latest version + * fix(autofix): unnecessary conversion + * feat(autofix): update gemini sdk and add anthropic claude + * feat(G304): add os.Root remediation hint (Autofix) when Go >= 1.24 + * chore(deps): update all dependencies + * refactor(G304): remove unused trackJoin helper; no functional change + * style: gofmt rules/readfile.go + * test(g304): add samples for var perm and var flag with cleaned path\n\n- Ensure G304 does not fire when only non-path args (flag/perm) are variables\n- Both samples use filepath.Clean on the path arg\n- Rules suite remains green (42 passed) + * rules(G304): analyze only path arg; ignore flag/perm vars; track Clean and safe Join; fix nil-context panic\n\n- Limit G304 checks to first arg (path) for os.Open/OpenFile/ReadFile, avoiding false positives when flag/perm are variables\n- Track filepath.Clean so cleaned identifiers are treated as safe\n- Consider safe joins: filepath.Join(const|resolvedBase, Clean(var)|cleanedIdent)\n- Record Join(...) assigned to identifiers and allow if later cleaned\n- Fix panic by passing non-nil context in trackJoinAssignStmt\n- All rules tests: 42 passed + * rules(G202): detect SQL concat in ValueSpec declarations; add test sample\n\n- Handle var query string = 'SELECT ...' + user style declarations\n- Reuse existing binary expr detection on ValueSpec.Values\n- Add postgres sample mirroring issue #1309 report\n- Rules tests: 42 passed + * chore(deps): update all dependencies + * chore(deps): update all dependencies + * chore(deps): update all dependencies + * Update gosec version to v2.22.8 in the Github action + +------------------------------------------------------------------- Old: ---- gosec-2.22.8.obscpio New: ---- gosec-2.22.9.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gosec.spec ++++++ --- /var/tmp/diff_new_pack.n7wk1u/_old 2025-09-22 19:29:44.399010454 +0200 +++ /var/tmp/diff_new_pack.n7wk1u/_new 2025-09-22 19:29:44.399010454 +0200 @@ -17,7 +17,7 @@ Name: gosec -Version: 2.22.8 +Version: 2.22.9 Release: 0 Summary: CLI tool to scan the Go AST and SSA code representations for security problems License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.n7wk1u/_old 2025-09-22 19:29:44.439012139 +0200 +++ /var/tmp/diff_new_pack.n7wk1u/_new 2025-09-22 19:29:44.443012307 +0200 @@ -4,7 +4,7 @@ <param name="filename">gosec</param> <param name="url">https://github.com/securego/gosec.git</param> <param name="scm">git</param> - <param name="revision">v2.22.8</param> + <param name="revision">v2.22.9</param> <param name="match-tag">v*</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.n7wk1u/_old 2025-09-22 19:29:44.459012981 +0200 +++ /var/tmp/diff_new_pack.n7wk1u/_new 2025-09-22 19:29:44.463013149 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/securego/gosec.git</param> - <param name="changesrevision">c9453023c4e81ebdb6dde29e22d9cd5e2285fb16</param></service></servicedata> + <param name="changesrevision">15d5c61e866bc2e2e8389376a31f1e5e09bde7d8</param></service></servicedata> (No newline at EOF) ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2025-02-13 15:25:36.000000000 +0100 @@ -0,0 +1,3 @@ +.osc +/gosec +/gosec-*.*.*.tar.xz ++++++ gosec-2.22.8.obscpio -> gosec-2.22.9.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/.github/workflows/ci.yml new/gosec-2.22.9/.github/workflows/ci.yml --- old/gosec-2.22.8/.github/workflows/ci.yml 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/.github/workflows/ci.yml 2025-09-22 10:42:03.000000000 +0200 @@ -11,20 +11,20 @@ strategy: matrix: version: - - go-version: '1.24.6' - golangci: 'latest' - - go-version: '1.25.0' - golangci: 'latest' + - go-version: "1.24.7" + golangci: "latest" + - go-version: "1.25.1" + golangci: "latest" runs-on: ubuntu-latest env: GO111MODULE: on steps: - name: Setup go ${{ matrix.version.go-version }} - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ matrix.version.go-version }} - name: Checkout Source - uses: actions/checkout@v4 + uses: actions/checkout@v5 - uses: actions/cache@v4 with: path: ~/go/pkg/mod @@ -34,7 +34,7 @@ - name: lint uses: golangci/golangci-lint-action@v8 with: - version: ${{ matrix.version.golangci }} + version: ${{ matrix.version.golangci }} - name: Run Gosec Security Scanner uses: securego/gosec@master with: @@ -50,11 +50,11 @@ GO111MODULE: on steps: - name: Setup go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: - go-version: '1.25.0' + go-version: "1.25.1" - name: Checkout Source - uses: actions/checkout@v4 + uses: actions/checkout@v5 - uses: actions/cache@v4 with: path: ~/go/pkg/mod diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/.github/workflows/release.yml new/gosec-2.22.9/.github/workflows/release.yml --- old/gosec-2.22.8/.github/workflows/release.yml 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/.github/workflows/release.yml 2025-09-22 10:42:03.000000000 +0200 @@ -2,7 +2,7 @@ on: push: tags: - - 'v*' + - "v*" jobs: build: runs-on: ubuntu-latest @@ -11,17 +11,17 @@ ACTIONS_ALLOW_UNSECURE_COMMANDS: true steps: - name: Checkout Source - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Unshallow run: git fetch --prune --unshallow - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: - go-version: '1.25.0' + go-version: "1.25.1" - name: Install Cosign uses: sigstore/cosign-installer@v3 with: - cosign-release: 'v2.5.3' + cosign-release: "v2.6.0" - name: Store Cosign private key in a file run: 'echo "$COSIGN_KEY" > /tmp/cosign.key' shell: bash diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/.github/workflows/scan.yml new/gosec-2.22.9/.github/workflows/scan.yml --- old/gosec-2.22.8/.github/workflows/scan.yml 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/.github/workflows/scan.yml 2025-09-22 10:42:03.000000000 +0200 @@ -13,7 +13,7 @@ runs-on: ubuntu-latest steps: - name: Check out code into the Go module directory - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Security Scan uses: securego/gosec@master with: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/action.yml new/gosec-2.22.9/action.yml --- old/gosec-2.22.8/action.yml 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/action.yml 2025-09-22 10:42:03.000000000 +0200 @@ -10,7 +10,7 @@ runs: using: 'docker' - image: 'docker://securego/gosec:2.22.7' + image: 'docker://securego/gosec:2.22.8' args: - ${{ inputs.args }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/autofix/ai.go new/gosec-2.22.9/autofix/ai.go --- old/gosec-2.22.8/autofix/ai.go 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/autofix/ai.go 2025-09-22 10:42:03.000000000 +0200 @@ -4,97 +4,53 @@ "context" "errors" "fmt" + "strings" "time" - "github.com/google/generative-ai-go/genai" - "google.golang.org/api/option" - "github.com/securego/gosec/v2/issue" ) const ( - GeminiModel = "gemini-1.5-flash" - AIPrompt = `Provide a brief explanation and a solution to fix this security issue + AIProviderFlagHelp = `AI API provider to generate auto fixes to issues. Valid options are: +- gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite, gemini-2.0-flash, gemini-2.0-flash-lite (gemini, default); +- claude-sonnet-4-0 (claude, default), claude-opus-4-0, claude-opus-4-1, claude-sonnet-3-7` + + AIPrompt = `Provide a brief explanation and a solution to fix this security issue in Go programming language: %q. Answer in markdown format and keep the response limited to 200 words.` - GeminiProvider = "gemini" timeout = 30 * time.Second ) -// GenAIClient defines the interface for the GenAI client. type GenAIClient interface { - // Close clean up and close the client. - Close() error - // GenerativeModel build the generative mode. - GenerativeModel(name string) GenAIGenerativeModel + GenerateSolution(ctx context.Context, prompt string) (string, error) } -// GenAIGenerativeModel defines the interface for the Generative Model. -type GenAIGenerativeModel interface { - // GenerateContent generates an response for given prompt. - GenerateContent(ctx context.Context, prompt string) (string, error) -} - -// genAIClientWrapper wraps the genai.Client to implement GenAIClient. -type genAIClientWrapper struct { - client *genai.Client -} - -// Close closes the gen AI client. -func (w *genAIClientWrapper) Close() error { - return w.client.Close() -} - -// GenerativeModel builds the generative Model. -func (w *genAIClientWrapper) GenerativeModel(name string) GenAIGenerativeModel { - return &genAIGenerativeModelWrapper{model: w.client.GenerativeModel(name)} -} - -// genAIGenerativeModelWrapper wraps the genai.GenerativeModel to implement GenAIGenerativeModel -type genAIGenerativeModelWrapper struct { - // model is the underlying generative model - model *genai.GenerativeModel -} - -// GenerateContent generates a response for the given prompt using gemini API. -func (w *genAIGenerativeModelWrapper) GenerateContent(ctx context.Context, prompt string) (string, error) { - resp, err := w.model.GenerateContent(ctx, genai.Text(prompt)) - if err != nil { - return "", fmt.Errorf("generating autofix: %w", err) - } - if len(resp.Candidates) == 0 { - return "", errors.New("no autofix returned by gemini") - } - - if len(resp.Candidates[0].Content.Parts) == 0 { - return "", errors.New("nothing found in the first autofix returned by gemini") - } - - // Return the first candidate - return fmt.Sprintf("%+v", resp.Candidates[0].Content.Parts[0]), nil -} +// GenerateSolution generates a solution for the given issues using the specified AI provider +func GenerateSolution(model, aiAPIKey string, issues []*issue.Issue) (err error) { + var client GenAIClient -// NewGenAIClient creates a new gemini API client. -func NewGenAIClient(ctx context.Context, aiAPIKey, endpoint string) (GenAIClient, error) { - clientOptions := []option.ClientOption{option.WithAPIKey(aiAPIKey)} - if endpoint != "" { - clientOptions = append(clientOptions, option.WithEndpoint(endpoint)) + switch { + case strings.HasPrefix(model, "claude"): + client, err = NewClaudeClient(model, aiAPIKey) + case strings.HasPrefix(model, "gemini"): + client, err = NewGeminiClient(model, aiAPIKey) } - client, err := genai.NewClient(ctx, clientOptions...) - if err != nil { - return nil, fmt.Errorf("calling gemini API: %w", err) + switch { + case err != nil: + return fmt.Errorf("initializing AI client: %w", err) + case client == nil: + return fmt.Errorf("unsupported AI backend: %s", model) } - return &genAIClientWrapper{client: client}, nil + return generateSolution(client, issues) } -func generateSolutionByGemini(client GenAIClient, issues []*issue.Issue) error { +func generateSolution(client GenAIClient, issues []*issue.Issue) error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - model := client.GenerativeModel(GeminiModel) cachedAutofix := make(map[string]string) for _, issue := range issues { if val, ok := cachedAutofix[issue.What]; ok { @@ -103,7 +59,7 @@ } prompt := fmt.Sprintf(AIPrompt, issue.What) - resp, err := model.GenerateContent(ctx, prompt) + resp, err := client.GenerateSolution(ctx, prompt) if err != nil { return fmt.Errorf("generating autofix with gemini: %w", err) } @@ -117,26 +73,3 @@ } return nil } - -// GenerateSolution generates a solution for the given issues using the specified AI provider -func GenerateSolution(aiAPIProvider, aiAPIKey, endpoint string, issues []*issue.Issue) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - var client GenAIClient - - switch aiAPIProvider { - case GeminiProvider: - var err error - client, err = NewGenAIClient(ctx, aiAPIKey, endpoint) - if err != nil { - return fmt.Errorf("generating autofix: %w", err) - } - default: - return errors.New("ai provider not supported") - } - - defer client.Close() - - return generateSolutionByGemini(client, issues) -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/autofix/ai_test.go new/gosec-2.22.9/autofix/ai_test.go --- old/gosec-2.22.8/autofix/ai_test.go 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/autofix/ai_test.go 2025-09-22 10:42:03.000000000 +0200 @@ -17,22 +17,7 @@ mock.Mock } -func (m *MockGenAIClient) Close() error { - args := m.Called() - return args.Error(0) -} - -func (m *MockGenAIClient) GenerativeModel(name string) GenAIGenerativeModel { - args := m.Called(name) - return args.Get(0).(GenAIGenerativeModel) -} - -// MockGenAIGenerativeModel is a mock of the GenAIGenerativeModel interface -type MockGenAIGenerativeModel struct { - mock.Mock -} - -func (m *MockGenAIGenerativeModel) GenerateContent(ctx context.Context, prompt string) (string, error) { +func (m *MockGenAIClient) GenerateSolution(ctx context.Context, prompt string) (string, error) { args := m.Called(ctx, prompt) return args.String(0), args.Error(1) } @@ -44,17 +29,15 @@ } mockClient := new(MockGenAIClient) - mockModel := new(MockGenAIGenerativeModel) - mockClient.On("GenerativeModel", GeminiModel).Return(mockModel).Once() - mockModel.On("GenerateContent", mock.Anything, mock.Anything).Return("Autofix for issue 1", nil).Once() + mockClient.On("GenerateSolution", mock.Anything, mock.Anything).Return("Autofix for issue 1", nil).Once() // Act - err := generateSolutionByGemini(mockClient, issues) + err := generateSolution(mockClient, issues) // Assert require.NoError(t, err) assert.Equal(t, []*issue.Issue{{What: "Example issue 1", Autofix: "Autofix for issue 1"}}, issues) - mock.AssertExpectationsForObjects(t, mockClient, mockModel) + mock.AssertExpectationsForObjects(t, mockClient) } func TestGenerateSolutionByGemini_NoCandidates(t *testing.T) { @@ -64,16 +47,14 @@ } mockClient := new(MockGenAIClient) - mockModel := new(MockGenAIGenerativeModel) - mockClient.On("GenerativeModel", GeminiModel).Return(mockModel).Once() - mockModel.On("GenerateContent", mock.Anything, mock.Anything).Return("", nil).Once() + mockClient.On("GenerateSolution", mock.Anything, mock.Anything).Return("", nil).Once() // Act - err := generateSolutionByGemini(mockClient, issues) + err := generateSolution(mockClient, issues) // Assert require.EqualError(t, err, "no autofix returned by gemini") - mock.AssertExpectationsForObjects(t, mockClient, mockModel) + mock.AssertExpectationsForObjects(t, mockClient) } func TestGenerateSolutionByGemini_APIError(t *testing.T) { @@ -83,16 +64,14 @@ } mockClient := new(MockGenAIClient) - mockModel := new(MockGenAIGenerativeModel) - mockClient.On("GenerativeModel", GeminiModel).Return(mockModel).Once() - mockModel.On("GenerateContent", mock.Anything, mock.Anything).Return("", errors.New("API error")).Once() + mockClient.On("GenerateSolution", mock.Anything, mock.Anything).Return("", errors.New("API error")).Once() // Act - err := generateSolutionByGemini(mockClient, issues) + err := generateSolution(mockClient, issues) // Assert require.EqualError(t, err, "generating autofix with gemini: API error") - mock.AssertExpectationsForObjects(t, mockClient, mockModel) + mock.AssertExpectationsForObjects(t, mockClient) } func TestGenerateSolution_UnsupportedProvider(t *testing.T) { @@ -102,8 +81,8 @@ } // Act - err := GenerateSolution("unsupported-provider", "test-api-key", "", issues) + err := GenerateSolution("unsupported-provider", "test-api-key", issues) // Assert - require.EqualError(t, err, "ai provider not supported") + require.EqualError(t, err, "unsupported AI backend: unsupported-provider") } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/autofix/claude.go new/gosec-2.22.9/autofix/claude.go --- old/gosec-2.22.8/autofix/claude.go 1970-01-01 01:00:00.000000000 +0100 +++ new/gosec-2.22.9/autofix/claude.go 2025-09-22 10:42:03.000000000 +0200 @@ -0,0 +1,74 @@ +package autofix + +import ( + "context" + "errors" + "fmt" + + "github.com/anthropics/anthropic-sdk-go" + "github.com/anthropics/anthropic-sdk-go/option" +) + +const ( + ModelClaudeOpus4_0 = anthropic.ModelClaudeOpus4_0 + ModelClaudeOpus4_1 = anthropic.ModelClaudeOpus4_1_20250805 + ModelClaudeSonnet4_0 = anthropic.ModelClaudeSonnet4_0 +) + +var _ GenAIClient = (*claudeWrapper)(nil) + +type claudeWrapper struct { + client anthropic.Client + model anthropic.Model +} + +func NewClaudeClient(model, apiKey string) (GenAIClient, error) { + var options []option.RequestOption + + if apiKey != "" { + options = append(options, option.WithAPIKey(apiKey)) + } + + anthropicModel := parseAnthropicModel(model) + + return &claudeWrapper{ + client: anthropic.NewClient(options...), + model: anthropicModel, + }, nil +} + +func (c *claudeWrapper) GenerateSolution(ctx context.Context, prompt string) (string, error) { + resp, err := c.client.Messages.New(ctx, anthropic.MessageNewParams{ + Model: c.model, + MaxTokens: 1024, + Messages: []anthropic.MessageParam{ + anthropic.NewUserMessage(anthropic.NewTextBlock(prompt)), + }, + }) + if err != nil { + return "", fmt.Errorf("generating autofix: %w", err) + } + + if resp == nil || len(resp.Content) == 0 { + return "", errors.New("no autofix returned by claude") + } + + if len(resp.Content[0].Text) == 0 { + return "", errors.New("nothing found in the first autofix returned by claude") + } + + return resp.Content[0].Text, nil +} + +func parseAnthropicModel(model string) anthropic.Model { + switch model { + case "claude-sonnet-3-7": + return anthropic.ModelClaude3_7SonnetLatest + case "claude-opus", "claude-opus-4-0": + return anthropic.ModelClaudeOpus4_0 + case "claude-opus-4-1": + return anthropic.ModelClaudeOpus4_1_20250805 + } + + return anthropic.ModelClaudeSonnet4_0 +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/autofix/gemini.go new/gosec-2.22.9/autofix/gemini.go --- old/gosec-2.22.8/autofix/gemini.go 1970-01-01 01:00:00.000000000 +0100 +++ new/gosec-2.22.9/autofix/gemini.go 2025-09-22 10:42:03.000000000 +0200 @@ -0,0 +1,91 @@ +package autofix + +import ( + "context" + "errors" + "fmt" + + "google.golang.org/genai" +) + +// https://ai.google.dev/gemini-api/docs/models +type GenAIModel string + +const ( + ModelGeminiPro2_5 GenAIModel = "gemini-2.5-pro" + ModelGeminiFlash2_5 GenAIModel = "gemini-2.5-flash" + ModelGeminiFlash2_5Lite GenAIModel = "gemini-2.5-flash-lite" + ModelGeminiFlash2_0 GenAIModel = "gemini-2.0-flash" + ModelGeminiFlash2_0Lite GenAIModel = "gemini-2.0-flash-lite" + // Deprecated: Use Gemini 2.x models. + ModelGeminiFlash1_5 GenAIModel = "gemini-1.5-flash" +) + +var _ GenAIClient = (*geminiWrapper)(nil) + +type geminiWrapper struct { + client *genai.Client + model GenAIModel +} + +func NewGeminiClient(model, apiKey string) (GenAIClient, error) { + ctx := context.Background() + + genaiModel, err := parseGeminiModel(model) + if err != nil { + return nil, err + } + + config := genai.ClientConfig{ + APIKey: apiKey, + Backend: genai.BackendUnspecified, + } + + client, err := genai.NewClient(ctx, &config) + if err != nil { + return nil, fmt.Errorf("creating gemini client: %w", err) + } + + return &geminiWrapper{ + client: client, + model: genaiModel, + }, nil +} + +func (g *geminiWrapper) GenerateSolution(ctx context.Context, prompt string) (string, error) { + var config genai.GenerateContentConfig + + resp, err := g.client.Models.GenerateContent(ctx, string(g.model), genai.Text(prompt), &config) + if err != nil { + return "", fmt.Errorf("generating autofix: %w", err) + } + + if resp == nil || len(resp.Candidates) == 0 { + return "", errors.New("no autofix returned by gemini") + } + + if len(resp.Candidates[0].Content.Parts) == 0 { + return "", errors.New("nothing found in the first autofix returned by gemini") + } + + return resp.Text(), nil +} + +func parseGeminiModel(model string) (GenAIModel, error) { + switch model { + case "gemini-2.5-pro": + return ModelGeminiPro2_5, nil + case "gemini-2.5-flash": + return ModelGeminiFlash2_5, nil + case "gemini-2.5-flash-lite": + return ModelGeminiFlash2_5Lite, nil + case "gemini-2.0-flash": + return ModelGeminiFlash2_0, nil + case "gemini-2.0-flash-lite", "gemini": // Default + return ModelGeminiFlash2_0Lite, nil + case "gemini-1.5-flash": + return ModelGeminiFlash1_5, nil + } + + return "", fmt.Errorf("unsupported gemini model: %s", model) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/cmd/gosec/main.go new/gosec-2.22.9/cmd/gosec/main.go --- old/gosec-2.22.8/cmd/gosec/main.go 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/cmd/gosec/main.go 2025-09-22 10:42:03.000000000 +0200 @@ -154,14 +154,11 @@ flagTerse = flag.Bool("terse", false, "Shows only the results and summary") // AI platform provider to generate solutions to issues - flagAiAPIProvider = flag.String("ai-api-provider", "", "AI API provider to generate auto fixes to issues.\nValid options are: gemini") + flagAiAPIProvider = flag.String("ai-api-provider", "", autofix.AIProviderFlagHelp) // key to implementing AI provider services flagAiAPIKey = flag.String("ai-api-key", "", "Key to access the AI API") - // endpoint to the AI provider - flagAiEndpoint = flag.String("ai-endpoint", "", "Endpoint AI API.\nThis is optional, the default API endpoint will be used when not provided.") - // exclude the folders from scan flagDirsExclude arrayFlags @@ -508,8 +505,11 @@ if aiAPIKey == "" { aiAPIKey = *flagAiAPIKey } - if *flagAiAPIProvider != "" && aiAPIKey != "" { - err := autofix.GenerateSolution(*flagAiAPIProvider, aiAPIKey, *flagAiEndpoint, issues) + + aiEnabled := *flagAiAPIProvider != "" + + if len(issues) > 0 && aiEnabled { + err := autofix.GenerateSolution(*flagAiAPIProvider, aiAPIKey, issues) if err != nil { logger.Print(err) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/go.mod new/gosec-2.22.9/go.mod --- old/gosec-2.22.8/go.mod 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/go.mod 2025-09-22 10:42:03.000000000 +0200 @@ -1,59 +1,59 @@ module github.com/securego/gosec/v2 require ( + github.com/anthropics/anthropic-sdk-go v1.12.0 github.com/ccojocar/zxcvbn-go v1.0.4 - github.com/google/generative-ai-go v0.20.1 github.com/google/uuid v1.6.0 - github.com/gookit/color v1.5.4 + github.com/gookit/color v1.6.0 github.com/lib/pq v1.10.9 github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5 - github.com/onsi/ginkgo/v2 v2.23.4 - github.com/onsi/gomega v1.38.0 - github.com/stretchr/testify v1.10.0 - golang.org/x/crypto v0.41.0 - golang.org/x/text v0.28.0 - golang.org/x/tools v0.36.0 - google.golang.org/api v0.246.0 + github.com/onsi/ginkgo/v2 v2.25.3 + github.com/onsi/gomega v1.38.2 + github.com/stretchr/testify v1.11.1 + golang.org/x/crypto v0.42.0 + golang.org/x/text v0.29.0 + golang.org/x/tools v0.37.0 + google.golang.org/genai v1.25.0 gopkg.in/yaml.v3 v3.0.1 ) require ( cloud.google.com/go v0.121.2 // indirect - cloud.google.com/go/ai v0.12.1 // indirect - cloud.google.com/go/auth v0.16.3 // indirect - cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect - cloud.google.com/go/compute/metadata v0.7.0 // indirect - cloud.google.com/go/longrunning v0.6.7 // indirect + cloud.google.com/go/auth v0.16.5 // indirect + cloud.google.com/go/compute/metadata v0.8.0 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a // indirect + github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/objx v0.5.2 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tidwall/sjson v1.2.5 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.36.0 // indirect - go.opentelemetry.io/otel/metric v1.36.0 // indirect - go.opentelemetry.io/otel/trace v1.36.0 // indirect + go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/trace v1.37.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect - golang.org/x/mod v0.27.0 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/time v0.12.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect ) go 1.24.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/go.sum new/gosec-2.22.9/go.sum --- old/gosec-2.22.8/go.sum 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/go.sum 2025-09-22 10:42:03.000000000 +0200 @@ -15,24 +15,18 @@ cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= cloud.google.com/go v0.121.2 h1:v2qQpN6Dx9x2NmwrqlesOt3Ys4ol5/lFZ6Mg1B7OJCg= cloud.google.com/go v0.121.2/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw= -cloud.google.com/go/ai v0.12.1 h1:m1n/VjUuHS+pEO/2R4/VbuuEIkgk0w67fDQvFaMngM0= -cloud.google.com/go/ai v0.12.1/go.mod h1:5vIPNe1ZQsVZqCliXIPL4QnhObQQY4d9hAGHdVc4iw4= -cloud.google.com/go/auth v0.16.3 h1:kabzoQ9/bobUmnseYnBO6qQG7q4a/CffFRlJSxv2wCc= -cloud.google.com/go/auth v0.16.3/go.mod h1:NucRGjaXfzP1ltpcQ7On/VTZ0H4kWB5Jy+Y9Dnm76fA= -cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= -cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI= +cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= -cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA= +cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= -cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -50,12 +44,16 @@ github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/anthropics/anthropic-sdk-go v1.12.0 h1:xPqlGnq7rWrTiHazIvCiumA0u7mGQnwDQtvA1M82h9U= +github.com/anthropics/anthropic-sdk-go v1.12.0/go.mod h1:WTz31rIUHUHqai2UslPpw5CwXrQP3geYBioRV4WOLvE= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -160,8 +158,6 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs= -github.com/google/generative-ai-go v0.20.1 h1:6dEIujpgN2V0PgLhr6c/M1ynRdc7ARtiIDPFzj45uNQ= -github.com/google/generative-ai-go v0.20.1/go.mod h1:TjOnZJmZKzarWbjUJgy+r3Ee7HGBRVLhOIgupnwR4Bg= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -179,8 +175,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18= -github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA= +github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY= +github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= @@ -196,13 +192,17 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= -github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= -github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= +github.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0= +github.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj0VX2E= +github.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA= +github.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs= github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= @@ -290,11 +290,11 @@ github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= -github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= +github.com/onsi/ginkgo/v2 v2.25.3 h1:Ty8+Yi/ayDAGtk4XxmmfUy4GabvM+MegeB4cDLRi6nw= +github.com/onsi/ginkgo/v2 v2.25.3/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY= -github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -352,8 +352,18 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -383,20 +393,18 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= -go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -408,6 +416,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -417,8 +427,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -452,8 +462,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -486,15 +496,13 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -504,8 +512,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -546,25 +554,23 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -611,11 +617,13 @@ golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -632,8 +640,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.246.0 h1:H0ODDs5PnMZVZAEtdLMn2Ul2eQi7QNjqM2DIFp8TlTM= -google.golang.org/api v0.246.0/go.mod h1:dMVhVcylamkirHdzEBAIQWUCgqY885ivNeZYd7VAVr8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -641,6 +647,8 @@ google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genai v1.25.0 h1:Cpyh2nmEoOS1eM3mT9XKuA/qWTEDoktfP2gsN3EduPE= +google.golang.org/genai v1.25.0/go.mod h1:OClfdf+r5aaD+sCd4aUSkPzJItmg2wD/WON9lQnRPaY= google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -672,12 +680,8 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 h1:MAKi5q709QWfnkkpNQ0M12hYJ1+e8qYVDyowc4U1XZM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -692,8 +696,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -704,8 +708,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/report/html/template.html new/gosec-2.22.9/report/html/template.html --- old/gosec-2.22.8/report/html/template.html 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/report/html/template.html 2025-09-22 10:42:03.000000000 +0200 @@ -10,7 +10,7 @@ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/go.min.js" integrity="sha512-weC0VNVf2qQR6OY675qO0AEL92gt3h5f2VGjhMUvi/UqFHaWzIEL5S/8Dt763fWfKftchzb7GryvEj/2HC9Exw==" crossorigin="anonymous"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.7.0/react.min.js" integrity="sha512-+TFn1Gqbwx/qgwW3NU1/YtFYTfHGeD1e/8YfJZzkb6TFEZP4SUwp1Az9DMeWh3qC0F+YPKXbV3YclMUwBTvO3g==" crossorigin="anonymous"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js" integrity="sha512-8C49ZG/SaQnWaUgCHTU1o8uIQNYE6R8me38SwF26g2Q0byEXF4Jlvm+T/JAMHMeTBiEVPslSZRv9Xt4AV0pfmw==" crossorigin="anonymous"></script> - <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.28.2/babel.min.js" integrity="sha512-AEhA/tSQr2Jwvfb/CmMAIVkOmPdIB5EBZXiHs3TXmarNdhcwX7ufSddMMVh2dVD2/8M33nWExg2KK33MLen09Q==" crossorigin="anonymous"></script> + <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.28.4/babel.min.js" integrity="sha512-BCw4VuBF2HKIgxDP8K7DRHcHzazAAND+5+2E7GgX3CC1u1pteJ415mMJlQfUORjkFT64irzu1jIV93Vfvzkevw==" crossorigin="anonymous"></script> <style> .field-label { min-width: 80px; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/rules/readfile.go new/gosec-2.22.9/rules/readfile.go --- old/gosec-2.22.8/rules/readfile.go 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/rules/readfile.go 2025-09-22 10:42:03.000000000 +0200 @@ -25,9 +25,12 @@ type readfile struct { issue.MetaData gosec.CallList - pathJoin gosec.CallList - clean gosec.CallList + pathJoin gosec.CallList + clean gosec.CallList + // cleanedVar maps the declaration node of an identifier to the Clean() call node cleanedVar map[any]ast.Node + // joinedVar maps the declaration node of an identifier to the Join() call node + joinedVar map[any]ast.Node } // ID returns the identifier for this rule @@ -61,6 +64,7 @@ // isFilepathClean checks if there is a filepath.Clean for given variable func (r *readfile) isFilepathClean(n *ast.Ident, c *gosec.Context) bool { + // quick lookup: was this var's declaration recorded as a Clean() call? if _, ok := r.cleanedVar[n.Obj.Decl]; ok { return true } @@ -90,35 +94,170 @@ } } -// Match inspects AST nodes to determine if the match the methods `os.Open` or `ioutil.ReadFile` +// trackJoinAssignStmt tracks assignments where RHS is a Join(...) call and LHS is an identifier +func (r *readfile) trackJoinAssignStmt(node *ast.AssignStmt, c *gosec.Context) { + if len(node.Rhs) == 0 { + return + } + if call, ok := node.Rhs[0].(*ast.CallExpr); ok { + if r.pathJoin.ContainsPkgCallExpr(call, c, false) != nil { + // LHS must be an identifier (simple case) + if len(node.Lhs) > 0 { + if ident, ok := node.Lhs[0].(*ast.Ident); ok && ident.Obj != nil { + r.joinedVar[ident.Obj.Decl] = call + } + } + } + } +} + +// osRootSuggestion returns an Autofix suggesting the use of os.Root where supported +// to constrain file access under a fixed directory and mitigate traversal risks. +func (r *readfile) osRootSuggestion() string { + major, minor, _ := gosec.GoVersion() + if major == 1 && minor >= 24 { + return "Consider using os.Root to scope file access under a fixed root (Go >=1.24). Prefer root.Open/root.Stat over os.Open/os.Stat to prevent directory traversal." + } + return "" +} + +// isSafeJoin checks if path is baseDir + filepath.Clean(fn) joined. +// improvements over earlier naive version: +// - allow baseDir as a BasicLit or as an identifier that resolves to a string constant +// - accept Clean(...) being either a CallExpr or an identifier previously recorded as Clean result +func (r *readfile) isSafeJoin(call *ast.CallExpr, c *gosec.Context) bool { + join := r.pathJoin.ContainsPkgCallExpr(call, c, false) + if join == nil { + return false + } + + // We expect join.Args to include a baseDir-like arg and a cleaned path arg. + var foundBaseDir bool + var foundCleanArg bool + + for _, arg := range join.Args { + switch a := arg.(type) { + case *ast.BasicLit: + // literal string or similar — treat as possible baseDir + foundBaseDir = true + case *ast.Ident: + // If ident is resolvable to a constant string (TryResolve true), treat as baseDir. + // Or if ident refers to a variable that was itself assigned from a constant BasicLit, + // it's considered safe as baseDir. + if gosec.TryResolve(a, c) { + foundBaseDir = true + } else { + // It might be a cleaned variable: e.g. cleanPath := filepath.Clean(fn) + if r.isFilepathClean(a, c) { + foundCleanArg = true + } + } + case *ast.CallExpr: + // If an argument is a Clean() call directly, mark clean arg found. + if r.clean.ContainsPkgCallExpr(a, c, false) != nil { + foundCleanArg = true + } + default: + // ignore other types + } + } + + return foundBaseDir && foundCleanArg +} + func (r *readfile) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { + // Track filepath.Clean usages so identifiers assigned from Clean() are known. if node := r.clean.ContainsPkgCallExpr(n, c, false); node != nil { r.trackFilepathClean(n) return nil, nil - } else if node := r.ContainsPkgCallExpr(n, c, false); node != nil { - for _, arg := range node.Args { - // handles path joining functions in Arg - // eg. os.Open(filepath.Join("/tmp/", file)) - if callExpr, ok := arg.(*ast.CallExpr); ok { - if r.isJoinFunc(callExpr, c) { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil + } + + // Track Join assignments if we see an AssignStmt whose RHS is a Join call. + if assign, ok := n.(*ast.AssignStmt); ok { + // track join result assigned to a variable, e.g., fullPath := filepath.Join(baseDir, cleanPath) + r.trackJoinAssignStmt(assign, c) + // also track Clean assignment if present on RHS + if len(assign.Rhs) > 0 { + if call, ok := assign.Rhs[0].(*ast.CallExpr); ok { + if r.clean.ContainsPkgCallExpr(call, c, false) != nil { + r.trackFilepathClean(call) } } - // handles binary string concatenation eg. ioutil.Readfile("/tmp/" + file + "/blob") - if binExp, ok := arg.(*ast.BinaryExpr); ok { - // resolve all found identities from the BinaryExpr - if _, ok := gosec.FindVarIdentities(binExp, c); ok { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil + } + // continue, don't return here — other checks may apply + } + + // Now check for file-reading calls (os.Open, os.OpenFile, ioutil.ReadFile etc.) + if node := r.ContainsPkgCallExpr(n, c, false); node != nil { + if len(node.Args) == 0 { + return nil, nil + } + arg := node.Args[0] + + // If argument is a call expression, check for Join/Clean patterns. + if callExpr, ok := arg.(*ast.CallExpr); ok { + // If this call matches a safe Join(baseDir, Clean(...)) pattern, treat as safe. + if r.isSafeJoin(callExpr, c) { + // safe pattern detected; do not raise an issue + return nil, nil + } + // If the argument is a Join call but not safe per above, flag it (as before) + if r.isJoinFunc(callExpr, c) { + iss := c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence) + if s := r.osRootSuggestion(); s != "" { + iss.Autofix = s + } + return iss, nil + } + } + + // If arg is an identifier that was assigned from a Join(...) call, check that recorded Join call. + if ident, ok := arg.(*ast.Ident); ok { + if ident.Obj != nil { + if joinCall, ok := r.joinedVar[ident.Obj.Decl]; ok { + // If the identifier itself was later cleaned, treat as safe regardless of original Join args + if r.isFilepathClean(ident, c) { + return nil, nil + } + // joinCall is a *ast.CallExpr; check if that join is a safe join + if jc, ok := joinCall.(*ast.CallExpr); ok { + if r.isSafeJoin(jc, c) { + return nil, nil + } + // join exists but is not safe: flag it + iss := c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence) + if s := r.osRootSuggestion(); s != "" { + iss.Autofix = s + } + return iss, nil + } } } + } - if ident, ok := arg.(*ast.Ident); ok { - obj := c.Info.ObjectOf(ident) - if _, ok := obj.(*types.Var); ok && - !gosec.TryResolve(ident, c) && - !r.isFilepathClean(ident, c) { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil + // handles binary string concatenation eg. ioutil.Readfile("/tmp/" + file + "/blob") + if binExp, ok := arg.(*ast.BinaryExpr); ok { + // resolve all found identities from the BinaryExpr + if _, ok := gosec.FindVarIdentities(binExp, c); ok { + iss := c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence) + if s := r.osRootSuggestion(); s != "" { + iss.Autofix = s + } + return iss, nil + } + } + + // if it's a plain identifier, and not resolved and not cleaned, flag it + if ident, ok := arg.(*ast.Ident); ok { + obj := c.Info.ObjectOf(ident) + if _, ok := obj.(*types.Var); ok && + !gosec.TryResolve(ident, c) && + !r.isFilepathClean(ident, c) { + iss := c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence) + if s := r.osRootSuggestion(); s != "" { + iss.Autofix = s } + return iss, nil } } } @@ -138,6 +277,7 @@ Confidence: issue.High, }, cleanedVar: map[any]ast.Node{}, + joinedVar: map[any]ast.Node{}, } rule.pathJoin.Add("path/filepath", "Join") rule.pathJoin.Add("path", "Join") @@ -149,5 +289,5 @@ rule.Add("os", "Open") rule.Add("os", "OpenFile") rule.Add("os", "Create") - return rule, []ast.Node{(*ast.CallExpr)(nil)} + return rule, []ast.Node{(*ast.CallExpr)(nil), (*ast.AssignStmt)(nil)} } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/rules/sql.go new/gosec-2.22.9/rules/sql.go --- old/gosec-2.22.8/rules/sql.go 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/rules/sql.go 2025-09-22 10:42:03.000000000 +0200 @@ -191,6 +191,11 @@ if injection := s.findInjectionInBranch(ctx, decl.Rhs); injection != nil { return ctx.NewIssue(injection, s.ID(), s.What, s.Severity, s.Confidence), nil } + case *ast.ValueSpec: + // handle: var query string = "SELECT ...'" + user + if injection := s.findInjectionInBranch(ctx, decl.Values); injection != nil { + return ctx.NewIssue(injection, s.ID(), s.What, s.Severity, s.Confidence), nil + } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/testutils/g202_samples.go new/gosec-2.22.9/testutils/g202_samples.go --- old/gosec-2.22.8/testutils/g202_samples.go 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/testutils/g202_samples.go 2025-09-22 10:42:03.000000000 +0200 @@ -308,4 +308,32 @@ fmt.Println(result) } `}, 0, gosec.NewConfig()}, + {[]string{` +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" +) + +func main() { + db, err := sql.Open("postgres", "user=postgres password=password dbname=mydb sslmode=disable") + if err!= nil { + panic(err) + } + defer db.Close() + + var username string + fmt.Println("请输入用户名:") + fmt.Scanln(&username) + + var query string = "SELECT * FROM users WHERE username = '" + username + "'" + rows, err := db.Query(query) + if err!= nil { + panic(err) + } + defer rows.Close() +} +`}, 1, gosec.NewConfig()}, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gosec-2.22.8/testutils/g304_samples.go new/gosec-2.22.9/testutils/g304_samples.go --- old/gosec-2.22.8/testutils/g304_samples.go 2025-08-14 14:38:12.000000000 +0200 +++ new/gosec-2.22.9/testutils/g304_samples.go 2025-09-22 10:42:03.000000000 +0200 @@ -302,4 +302,46 @@ var THEWD string `}, 0, gosec.NewConfig()}, + {[]string{` +package main + +import ( + "os" + "path/filepath" +) + +func open(fn string, perm os.FileMode) { + fh, err := os.OpenFile(filepath.Clean(fn), os.O_RDONLY, perm) + if err != nil { + panic(err) + } + defer fh.Close() +} + +func main() { + fn := "filename" + open(fn, 0o600) +} +`}, 0, gosec.NewConfig()}, + {[]string{` +package main + +import ( + "os" + "path/filepath" +) + +func open(fn string, flag int) { + fh, err := os.OpenFile(filepath.Clean(fn), flag, 0o600) + if err != nil { + panic(err) + } + defer fh.Close() +} + +func main() { + fn := "filename" + open(fn, os.O_RDONLY) +} +`}, 0, gosec.NewConfig()}, } ++++++ gosec.obsinfo ++++++ --- /var/tmp/diff_new_pack.n7wk1u/_old 2025-09-22 19:29:44.695022920 +0200 +++ /var/tmp/diff_new_pack.n7wk1u/_new 2025-09-22 19:29:44.699023089 +0200 @@ -1,5 +1,5 @@ name: gosec -version: 2.22.8 -mtime: 1755175092 -commit: c9453023c4e81ebdb6dde29e22d9cd5e2285fb16 +version: 2.22.9 +mtime: 1758530523 +commit: 15d5c61e866bc2e2e8389376a31f1e5e09bde7d8 ++++++ vendor.tar.xz ++++++ ++++ 222683 lines of diff (skipped)
