fix(lint): G115 safe stdin fd conversion, QF1012 use fmt.Fprintf directly
- commit
- 18a731f4dde81ef4f394603d6313e8af24e6271a
- author
- bnema · · 2026-02-25 02:04 UTC
- parent
- 1b136ca
- signature
- unsigned
9 files · +33 -15
M internal/adapters/dto/registry_token.go +1 -1
| @@ -3,7 +3,7 @@ package dto | |||
| 3 | 3 | // TokenResponse represents the response from the token server. | |
| 4 | 4 | type TokenResponse struct { | |
| 5 | 5 | Token string `json:"token"` | |
| 6 | - | AccessToken string `json:"access_token,omitempty"` | |
| 6 | + | AccessToken string `json:"access_token,omitempty"` //nolint:gosec // OCI token response field, required by Docker Registry API v2 spec | |
| 7 | 7 | ExpiresIn int `json:"expires_in,omitempty"` | |
| 8 | 8 | IssuedAt string `json:"issued_at,omitempty"` | |
| 9 | 9 | } | |
| @@ -3,7 +3,7 @@ package dto | |||||
| 3 | // TokenResponse represents the response from the token server. | 3 | // TokenResponse represents the response from the token server. | ||
| 4 | type TokenResponse struct { | 4 | type TokenResponse struct { | ||
| 5 | Token string `json:"token"` | 5 | Token string `json:"token"` | ||
| 6 | - | AccessToken string `json:"access_token,omitempty"` | 6 | + | AccessToken string `json:"access_token,omitempty"` //nolint:gosec // OCI token response field, required by Docker Registry API v2 spec |
| 7 | ExpiresIn int `json:"expires_in,omitempty"` | 7 | ExpiresIn int `json:"expires_in,omitempty"` | ||
| 8 | IssuedAt string `json:"issued_at,omitempty"` | 8 | IssuedAt string `json:"issued_at,omitempty"` | ||
| 9 | } | 9 | } | ||
M internal/adapters/in/cli/auth.go +20 -2
| @@ -24,6 +24,16 @@ import ( | |||
| 24 | 24 | "github.com/bnema/gordon/pkg/duration" | |
| 25 | 25 | ) | |
| 26 | 26 | ||
| 27 | + | // stdinFD returns os.Stdin's file descriptor as an int, guarded against | |
| 28 | + | // uintptr overflow on platforms where uintptr > int. | |
| 29 | + | func stdinFD() (int, error) { | |
| 30 | + | fd := os.Stdin.Fd() | |
| 31 | + | if fd > uintptr(^uint(0)>>1) { | |
| 32 | + | return 0, fmt.Errorf("stdin fd value %d overflows int", fd) | |
| 33 | + | } | |
| 34 | + | return int(fd), nil | |
| 35 | + | } | |
| 36 | + | ||
| 27 | 37 | // newAuthCmd creates the auth command group. | |
| 28 | 38 | func newAuthCmd() *cobra.Command { | |
| 29 | 39 | cmd := &cobra.Command{ | |
| @@ -274,7 +284,11 @@ func runAuthLogin(remoteName, username, password string) error { | |||
| 274 | 284 | if password == "" { | |
| 275 | 285 | // Prompt for password (hidden input) | |
| 276 | 286 | fmt.Print("Password: ") | |
| 277 | - | passwordBytes, err := term.ReadPassword(int(os.Stdin.Fd())) | |
| 287 | + | fd, err := stdinFD() | |
| 288 | + | if err != nil { | |
| 289 | + | return fmt.Errorf("failed to get stdin fd: %w", err) | |
| 290 | + | } | |
| 291 | + | passwordBytes, err := term.ReadPassword(fd) | |
| 278 | 292 | if err != nil { | |
| 279 | 293 | // Fallback for non-terminal input | |
| 280 | 294 | reader := bufio.NewReader(os.Stdin) | |
| @@ -595,7 +609,11 @@ func runPasswordHash() error { | |||
| 595 | 609 | fmt.Print("Enter password: ") | |
| 596 | 610 | ||
| 597 | 611 | // Read password without echo (use os.Stdin.Fd() for better compatibility) | |
| 598 | - | passwordBytes, err := term.ReadPassword(int(os.Stdin.Fd())) | |
| 612 | + | fd, err := stdinFD() | |
| 613 | + | if err != nil { | |
| 614 | + | return fmt.Errorf("failed to get stdin fd: %w", err) | |
| 615 | + | } | |
| 616 | + | passwordBytes, err := term.ReadPassword(fd) | |
| 599 | 617 | if err != nil { | |
| 600 | 618 | // Fallback for non-terminal input | |
| 601 | 619 | reader := bufio.NewReader(os.Stdin) | |
| @@ -24,6 +24,16 @@ import ( | |||||
| 24 | "github.com/bnema/gordon/pkg/duration" | 24 | "github.com/bnema/gordon/pkg/duration" | ||
| 25 | ) | 25 | ) | ||
| 26 | 26 | ||||
| 27 | + | // stdinFD returns os.Stdin's file descriptor as an int, guarded against | |||
| 28 | + | // uintptr overflow on platforms where uintptr > int. | |||
| 29 | + | func stdinFD() (int, error) { | |||
| 30 | + | fd := os.Stdin.Fd() | |||
| 31 | + | if fd > uintptr(^uint(0)>>1) { | |||
| 32 | + | return 0, fmt.Errorf("stdin fd value %d overflows int", fd) | |||
| 33 | + | } | |||
| 34 | + | return int(fd), nil | |||
| 35 | + | } | |||
| 36 | + | ||||
| 27 | // newAuthCmd creates the auth command group. | 37 | // newAuthCmd creates the auth command group. | ||
| 28 | func newAuthCmd() *cobra.Command { | 38 | func newAuthCmd() *cobra.Command { | ||
| 29 | cmd := &cobra.Command{ | 39 | cmd := &cobra.Command{ | ||
| @@ -274,7 +284,11 @@ func runAuthLogin(remoteName, username, password string) error { | |||||
| 274 | if password == "" { | 284 | if password == "" { | ||
| 275 | // Prompt for password (hidden input) | 285 | // Prompt for password (hidden input) | ||
| 276 | fmt.Print("Password: ") | 286 | fmt.Print("Password: ") | ||
| 277 | - | passwordBytes, err := term.ReadPassword(int(os.Stdin.Fd())) | 287 | + | fd, err := stdinFD() |
| 288 | + | if err != nil { | |||
| 289 | + | return fmt.Errorf("failed to get stdin fd: %w", err) | |||
| 290 | + | } | |||
| 291 | + | passwordBytes, err := term.ReadPassword(fd) | |||
| 278 | if err != nil { | 292 | if err != nil { | ||
| 279 | // Fallback for non-terminal input | 293 | // Fallback for non-terminal input | ||
| 280 | reader := bufio.NewReader(os.Stdin) | 294 | reader := bufio.NewReader(os.Stdin) | ||
| @@ -595,7 +609,11 @@ func runPasswordHash() error { | |||||
| 595 | fmt.Print("Enter password: ") | 609 | fmt.Print("Enter password: ") | ||
| 596 | 610 | ||||
| 597 | // Read password without echo (use os.Stdin.Fd() for better compatibility) | 611 | // Read password without echo (use os.Stdin.Fd() for better compatibility) | ||
| 598 | - | passwordBytes, err := term.ReadPassword(int(os.Stdin.Fd())) | 612 | + | fd, err := stdinFD() |
| 613 | + | if err != nil { | |||
| 614 | + | return fmt.Errorf("failed to get stdin fd: %w", err) | |||
| 615 | + | } | |||
| 616 | + | passwordBytes, err := term.ReadPassword(fd) | |||
| 599 | if err != nil { | 617 | if err != nil { | ||
| 600 | // Fallback for non-terminal input | 618 | // Fallback for non-terminal input | ||
| 601 | reader := bufio.NewReader(os.Stdin) | 619 | reader := bufio.NewReader(os.Stdin) | ||
M internal/adapters/in/cli/push.go +2 -2
| @@ -724,14 +724,14 @@ func getGitVersion(ctx context.Context) string { | |||
| 724 | 724 | } | |
| 725 | 725 | ||
| 726 | 726 | func dockerTag(ctx context.Context, src, dst string) error { | |
| 727 | - | cmd := exec.CommandContext(ctx, "docker", "tag", src, dst) | |
| 727 | + | cmd := exec.CommandContext(ctx, "docker", "tag", src, dst) //nolint:gosec // binary is constant; image refs validated by OCI ref parser | |
| 728 | 728 | cmd.Stdout = os.Stdout | |
| 729 | 729 | cmd.Stderr = os.Stderr | |
| 730 | 730 | return cmd.Run() | |
| 731 | 731 | } | |
| 732 | 732 | ||
| 733 | 733 | func dockerPush(ctx context.Context, ref string) error { | |
| 734 | - | cmd := exec.CommandContext(ctx, "docker", "push", ref) | |
| 734 | + | cmd := exec.CommandContext(ctx, "docker", "push", ref) //nolint:gosec // binary is constant; image ref validated by OCI ref parser | |
| 735 | 735 | cmd.Stdout = os.Stdout | |
| 736 | 736 | cmd.Stderr = os.Stderr | |
| 737 | 737 | return cmd.Run() | |
| @@ -724,14 +724,14 @@ func getGitVersion(ctx context.Context) string { | |||||
| 724 | } | 724 | } | ||
| 725 | 725 | ||||
| 726 | func dockerTag(ctx context.Context, src, dst string) error { | 726 | func dockerTag(ctx context.Context, src, dst string) error { | ||
| 727 | - | cmd := exec.CommandContext(ctx, "docker", "tag", src, dst) | 727 | + | cmd := exec.CommandContext(ctx, "docker", "tag", src, dst) //nolint:gosec // binary is constant; image refs validated by OCI ref parser |
| 728 | cmd.Stdout = os.Stdout | 728 | cmd.Stdout = os.Stdout | ||
| 729 | cmd.Stderr = os.Stderr | 729 | cmd.Stderr = os.Stderr | ||
| 730 | return cmd.Run() | 730 | return cmd.Run() | ||
| 731 | } | 731 | } | ||
| 732 | 732 | ||||
| 733 | func dockerPush(ctx context.Context, ref string) error { | 733 | func dockerPush(ctx context.Context, ref string) error { | ||
| 734 | - | cmd := exec.CommandContext(ctx, "docker", "push", ref) | 734 | + | cmd := exec.CommandContext(ctx, "docker", "push", ref) //nolint:gosec // binary is constant; image ref validated by OCI ref parser |
| 735 | cmd.Stdout = os.Stdout | 735 | cmd.Stdout = os.Stdout | ||
| 736 | cmd.Stderr = os.Stderr | 736 | cmd.Stderr = os.Stderr | ||
| 737 | return cmd.Run() | 737 | return cmd.Run() | ||
M internal/adapters/in/cli/remote/auth.go +1 -1
| @@ -12,7 +12,7 @@ import ( | |||
| 12 | 12 | // PasswordRequest represents the request body for POST /auth/password. | |
| 13 | 13 | type PasswordRequest struct { | |
| 14 | 14 | Username string `json:"username"` | |
| 15 | - | Password string `json:"password"` | |
| 15 | + | Password string `json:"password"` //nolint:gosec // intentional: CLI credential DTO for auth endpoint | |
| 16 | 16 | } | |
| 17 | 17 | ||
| 18 | 18 | // PasswordResponse represents the response from POST /auth/password. | |
| @@ -12,7 +12,7 @@ import ( | |||||
| 12 | // PasswordRequest represents the request body for POST /auth/password. | 12 | // PasswordRequest represents the request body for POST /auth/password. | ||
| 13 | type PasswordRequest struct { | 13 | type PasswordRequest struct { | ||
| 14 | Username string `json:"username"` | 14 | Username string `json:"username"` | ||
| 15 | - | Password string `json:"password"` | 15 | + | Password string `json:"password"` //nolint:gosec // intentional: CLI credential DTO for auth endpoint |
| 16 | } | 16 | } | ||
| 17 | 17 | ||||
| 18 | // PasswordResponse represents the response from POST /auth/password. | 18 | // PasswordResponse represents the response from POST /auth/password. | ||
M internal/adapters/in/cli/ui/components/selector.go +1 -1
| @@ -82,7 +82,7 @@ func (m SelectorModel) View() string { | |||
| 82 | 82 | if i == m.cursor { | |
| 83 | 83 | b.WriteString(styles.Theme.Highlight.Render(cursor + line)) | |
| 84 | 84 | } else { | |
| 85 | - | b.WriteString(fmt.Sprintf("%s%s", cursor, line)) | |
| 85 | + | fmt.Fprintf(&b, "%s%s", cursor, line) | |
| 86 | 86 | } | |
| 87 | 87 | b.WriteString("\n") | |
| 88 | 88 | } | |
| @@ -82,7 +82,7 @@ func (m SelectorModel) View() string { | |||||
| 82 | if i == m.cursor { | 82 | if i == m.cursor { | ||
| 83 | b.WriteString(styles.Theme.Highlight.Render(cursor + line)) | 83 | b.WriteString(styles.Theme.Highlight.Render(cursor + line)) | ||
| 84 | } else { | 84 | } else { | ||
| 85 | - | b.WriteString(fmt.Sprintf("%s%s", cursor, line)) | 85 | + | fmt.Fprintf(&b, "%s%s", cursor, line) |
| 86 | } | 86 | } | ||
| 87 | b.WriteString("\n") | 87 | b.WriteString("\n") | ||
| 88 | } | 88 | } | ||
M internal/adapters/out/domainsecrets/pass_store.go +4 -4
| @@ -646,7 +646,7 @@ func (s *PassStore) ManifestExists(domainName string) (bool, error) { | |||
| 646 | 646 | } | |
| 647 | 647 | ||
| 648 | 648 | func (s *PassStore) passInsert(ctx context.Context, path, value string) error { | |
| 649 | - | cmd := exec.CommandContext(ctx, "pass", "insert", "-m", "-f", path) | |
| 649 | + | cmd := exec.CommandContext(ctx, "pass", "insert", "-m", "-f", path) //nolint:gosec // binary is constant ("pass"); path arguments validated by secrets path validator | |
| 650 | 650 | cmd.Stdin = strings.NewReader(value) | |
| 651 | 651 | output, err := cmd.CombinedOutput() | |
| 652 | 652 | if err != nil { | |
| @@ -656,7 +656,7 @@ func (s *PassStore) passInsert(ctx context.Context, path, value string) error { | |||
| 656 | 656 | } | |
| 657 | 657 | ||
| 658 | 658 | func (s *PassStore) passRemove(ctx context.Context, path string) error { | |
| 659 | - | cmd := exec.CommandContext(ctx, "pass", "rm", "-f", path) | |
| 659 | + | cmd := exec.CommandContext(ctx, "pass", "rm", "-f", path) //nolint:gosec // binary is constant ("pass"); path arguments validated by secrets path validator | |
| 660 | 660 | output, err := cmd.CombinedOutput() | |
| 661 | 661 | if err != nil { | |
| 662 | 662 | if passEntryMissing(string(output)) { | |
| @@ -668,7 +668,7 @@ func (s *PassStore) passRemove(ctx context.Context, path string) error { | |||
| 668 | 668 | } | |
| 669 | 669 | ||
| 670 | 670 | func (s *PassStore) passShow(ctx context.Context, path string) (string, bool, error) { | |
| 671 | - | cmd := exec.CommandContext(ctx, "pass", "show", path) | |
| 671 | + | cmd := exec.CommandContext(ctx, "pass", "show", path) //nolint:gosec // binary is constant ("pass"); path arguments validated by secrets path validator | |
| 672 | 672 | output, err := cmd.CombinedOutput() | |
| 673 | 673 | if err != nil { | |
| 674 | 674 | if passEntryMissing(string(output)) { | |
| @@ -687,7 +687,7 @@ func (s *PassStore) listTopLevelEntries(ctx context.Context, basePath string) ([ | |||
| 687 | 687 | return nil, err | |
| 688 | 688 | } | |
| 689 | 689 | ||
| 690 | - | cmd := exec.CommandContext(ctx, "pass", "ls", basePath) | |
| 690 | + | cmd := exec.CommandContext(ctx, "pass", "ls", basePath) //nolint:gosec // binary is constant ("pass"); path arguments validated by secrets path validator | |
| 691 | 691 | output, err := cmd.CombinedOutput() | |
| 692 | 692 | if err != nil { | |
| 693 | 693 | if passEntryMissing(string(output)) { | |
| @@ -646,7 +646,7 @@ func (s *PassStore) ManifestExists(domainName string) (bool, error) { | |||||
| 646 | } | 646 | } | ||
| 647 | 647 | ||||
| 648 | func (s *PassStore) passInsert(ctx context.Context, path, value string) error { | 648 | func (s *PassStore) passInsert(ctx context.Context, path, value string) error { | ||
| 649 | - | cmd := exec.CommandContext(ctx, "pass", "insert", "-m", "-f", path) | 649 | + | cmd := exec.CommandContext(ctx, "pass", "insert", "-m", "-f", path) //nolint:gosec // binary is constant ("pass"); path arguments validated by secrets path validator |
| 650 | cmd.Stdin = strings.NewReader(value) | 650 | cmd.Stdin = strings.NewReader(value) | ||
| 651 | output, err := cmd.CombinedOutput() | 651 | output, err := cmd.CombinedOutput() | ||
| 652 | if err != nil { | 652 | if err != nil { | ||
| @@ -656,7 +656,7 @@ func (s *PassStore) passInsert(ctx context.Context, path, value string) error { | |||||
| 656 | } | 656 | } | ||
| 657 | 657 | ||||
| 658 | func (s *PassStore) passRemove(ctx context.Context, path string) error { | 658 | func (s *PassStore) passRemove(ctx context.Context, path string) error { | ||
| 659 | - | cmd := exec.CommandContext(ctx, "pass", "rm", "-f", path) | 659 | + | cmd := exec.CommandContext(ctx, "pass", "rm", "-f", path) //nolint:gosec // binary is constant ("pass"); path arguments validated by secrets path validator |
| 660 | output, err := cmd.CombinedOutput() | 660 | output, err := cmd.CombinedOutput() | ||
| 661 | if err != nil { | 661 | if err != nil { | ||
| 662 | if passEntryMissing(string(output)) { | 662 | if passEntryMissing(string(output)) { | ||
| @@ -668,7 +668,7 @@ func (s *PassStore) passRemove(ctx context.Context, path string) error { | |||||
| 668 | } | 668 | } | ||
| 669 | 669 | ||||
| 670 | func (s *PassStore) passShow(ctx context.Context, path string) (string, bool, error) { | 670 | func (s *PassStore) passShow(ctx context.Context, path string) (string, bool, error) { | ||
| 671 | - | cmd := exec.CommandContext(ctx, "pass", "show", path) | 671 | + | cmd := exec.CommandContext(ctx, "pass", "show", path) //nolint:gosec // binary is constant ("pass"); path arguments validated by secrets path validator |
| 672 | output, err := cmd.CombinedOutput() | 672 | output, err := cmd.CombinedOutput() | ||
| 673 | if err != nil { | 673 | if err != nil { | ||
| 674 | if passEntryMissing(string(output)) { | 674 | if passEntryMissing(string(output)) { | ||
| @@ -687,7 +687,7 @@ func (s *PassStore) listTopLevelEntries(ctx context.Context, basePath string) ([ | |||||
| 687 | return nil, err | 687 | return nil, err | ||
| 688 | } | 688 | } | ||
| 689 | 689 | ||||
| 690 | - | cmd := exec.CommandContext(ctx, "pass", "ls", basePath) | 690 | + | cmd := exec.CommandContext(ctx, "pass", "ls", basePath) //nolint:gosec // binary is constant ("pass"); path arguments validated by secrets path validator |
| 691 | output, err := cmd.CombinedOutput() | 691 | output, err := cmd.CombinedOutput() | ||
| 692 | if err != nil { | 692 | if err != nil { | ||
| 693 | if passEntryMissing(string(output)) { | 693 | if passEntryMissing(string(output)) { | ||
M internal/adapters/out/secrets/pass.go +1 -1
| @@ -80,7 +80,7 @@ func (p *PassProvider) GetSecret(ctx context.Context, path string) (string, erro | |||
| 80 | 80 | ctx, cancel := context.WithTimeout(ctx, p.timeout) | |
| 81 | 81 | defer cancel() | |
| 82 | 82 | ||
| 83 | - | cmd := exec.CommandContext(ctx, "pass", "show", path) | |
| 83 | + | cmd := exec.CommandContext(ctx, "pass", "show", path) //nolint:gosec // binary is constant ("pass"); arguments are validated secret paths | |
| 84 | 84 | output, err := cmd.Output() | |
| 85 | 85 | if err != nil { | |
| 86 | 86 | if exitError, ok := err.(*exec.ExitError); ok { | |
| @@ -80,7 +80,7 @@ func (p *PassProvider) GetSecret(ctx context.Context, path string) (string, erro | |||||
| 80 | ctx, cancel := context.WithTimeout(ctx, p.timeout) | 80 | ctx, cancel := context.WithTimeout(ctx, p.timeout) | ||
| 81 | defer cancel() | 81 | defer cancel() | ||
| 82 | 82 | ||||
| 83 | - | cmd := exec.CommandContext(ctx, "pass", "show", path) | 83 | + | cmd := exec.CommandContext(ctx, "pass", "show", path) //nolint:gosec // binary is constant ("pass"); arguments are validated secret paths |
| 84 | output, err := cmd.Output() | 84 | output, err := cmd.Output() | ||
| 85 | if err != nil { | 85 | if err != nil { | ||
| 86 | if exitError, ok := err.(*exec.ExitError); ok { | 86 | if exitError, ok := err.(*exec.ExitError); ok { | ||
M internal/adapters/out/tokenstore/pass.go +2 -2
| @@ -488,7 +488,7 @@ func (s *PassStore) DeleteToken(ctx context.Context, subject string) error { | |||
| 488 | 488 | ||
| 489 | 489 | // passInsert inserts a value into pass. | |
| 490 | 490 | func (s *PassStore) passInsert(ctx context.Context, path, value string) error { | |
| 491 | - | cmd := exec.CommandContext(ctx, "pass", "insert", "-m", "-f", path) | |
| 491 | + | cmd := exec.CommandContext(ctx, "pass", "insert", "-m", "-f", path) //nolint:gosec // binary is constant ("pass"); path arguments are sanitized token subjects | |
| 492 | 492 | cmd.Stdin = strings.NewReader(value) | |
| 493 | 493 | output, err := cmd.CombinedOutput() | |
| 494 | 494 | if err != nil { | |
| @@ -499,7 +499,7 @@ func (s *PassStore) passInsert(ctx context.Context, path, value string) error { | |||
| 499 | 499 | ||
| 500 | 500 | // passShow retrieves a value from pass. | |
| 501 | 501 | func (s *PassStore) passShow(ctx context.Context, path string) (string, error) { | |
| 502 | - | cmd := exec.CommandContext(ctx, "pass", "show", path) | |
| 502 | + | cmd := exec.CommandContext(ctx, "pass", "show", path) //nolint:gosec // binary is constant ("pass"); path arguments are sanitized token subjects | |
| 503 | 503 | output, err := cmd.Output() | |
| 504 | 504 | if err != nil { | |
| 505 | 505 | return "", fmt.Errorf("pass show failed: %w", err) | |
| @@ -488,7 +488,7 @@ func (s *PassStore) DeleteToken(ctx context.Context, subject string) error { | |||||
| 488 | 488 | ||||
| 489 | // passInsert inserts a value into pass. | 489 | // passInsert inserts a value into pass. | ||
| 490 | func (s *PassStore) passInsert(ctx context.Context, path, value string) error { | 490 | func (s *PassStore) passInsert(ctx context.Context, path, value string) error { | ||
| 491 | - | cmd := exec.CommandContext(ctx, "pass", "insert", "-m", "-f", path) | 491 | + | cmd := exec.CommandContext(ctx, "pass", "insert", "-m", "-f", path) //nolint:gosec // binary is constant ("pass"); path arguments are sanitized token subjects |
| 492 | cmd.Stdin = strings.NewReader(value) | 492 | cmd.Stdin = strings.NewReader(value) | ||
| 493 | output, err := cmd.CombinedOutput() | 493 | output, err := cmd.CombinedOutput() | ||
| 494 | if err != nil { | 494 | if err != nil { | ||
| @@ -499,7 +499,7 @@ func (s *PassStore) passInsert(ctx context.Context, path, value string) error { | |||||
| 499 | 499 | ||||
| 500 | // passShow retrieves a value from pass. | 500 | // passShow retrieves a value from pass. | ||
| 501 | func (s *PassStore) passShow(ctx context.Context, path string) (string, error) { | 501 | func (s *PassStore) passShow(ctx context.Context, path string) (string, error) { | ||
| 502 | - | cmd := exec.CommandContext(ctx, "pass", "show", path) | 502 | + | cmd := exec.CommandContext(ctx, "pass", "show", path) //nolint:gosec // binary is constant ("pass"); path arguments are sanitized token subjects |
| 503 | output, err := cmd.Output() | 503 | output, err := cmd.Output() | ||
| 504 | if err != nil { | 504 | if err != nil { | ||
| 505 | return "", fmt.Errorf("pass show failed: %w", err) | 505 | return "", fmt.Errorf("pass show failed: %w", err) | ||
M internal/usecase/container/autoroute.go +1 -1
| @@ -493,7 +493,7 @@ func writeEnvFile(path string, env map[string]string) error { | |||
| 493 | 493 | if strings.ContainsAny(v, " \t\n\"'$\\") { | |
| 494 | 494 | v = fmt.Sprintf("\"%s\"", strings.ReplaceAll(v, "\"", "\\\"")) | |
| 495 | 495 | } | |
| 496 | - | buf.WriteString(fmt.Sprintf("%s=%s\n", k, v)) | |
| 496 | + | fmt.Fprintf(&buf, "%s=%s\n", k, v) | |
| 497 | 497 | } | |
| 498 | 498 | ||
| 499 | 499 | return os.WriteFile(path, buf.Bytes(), 0600) | |
| @@ -493,7 +493,7 @@ func writeEnvFile(path string, env map[string]string) error { | |||||
| 493 | if strings.ContainsAny(v, " \t\n\"'$\\") { | 493 | if strings.ContainsAny(v, " \t\n\"'$\\") { | ||
| 494 | v = fmt.Sprintf("\"%s\"", strings.ReplaceAll(v, "\"", "\\\"")) | 494 | v = fmt.Sprintf("\"%s\"", strings.ReplaceAll(v, "\"", "\\\"")) | ||
| 495 | } | 495 | } | ||
| 496 | - | buf.WriteString(fmt.Sprintf("%s=%s\n", k, v)) | 496 | + | fmt.Fprintf(&buf, "%s=%s\n", k, v) |
| 497 | } | 497 | } | ||
| 498 | 498 | ||||
| 499 | return os.WriteFile(path, buf.Bytes(), 0600) | 499 | return os.WriteFile(path, buf.Bytes(), 0600) | ||