@@ -37,7 +37,10 @@ func NewExecGitClient() *ExecGitClient {
3737// @requires repoDir points to a valid git working tree
3838// @ensures returned file paths are trimmed and exclude blank lines
3939func (g * ExecGitClient ) ChangedFiles (ctx context.Context , repoDir , baseRef string ) ([]string , error ) {
40- out , err := runGitLimited (ctx , repoDir , []string {"diff" , "--name-only" , baseRef })
40+ if err := validateBaseRef (baseRef ); err != nil {
41+ return nil , err
42+ }
43+ out , err := runGitLimited (ctx , repoDir , []string {"-c" , "core.quotePath=false" , "diff" , "--name-only" , baseRef , "--" })
4144 if err != nil {
4245 return nil , trace .Wrap (err , "git diff --name-only" )
4346 }
@@ -66,7 +69,10 @@ func (g *ExecGitClient) ChangedFiles(ctx context.Context, repoDir, baseRef strin
6669// @requires repoDir points to a valid git working tree
6770// @ensures each returned hunk has a file path and inclusive start/end lines
6871func (g * ExecGitClient ) DiffHunks (ctx context.Context , repoDir , baseRef string , paths []string ) ([]Hunk , error ) {
69- args := []string {"diff" , "-U0" , baseRef , "--" }
72+ if err := validateBaseRef (baseRef ); err != nil {
73+ return nil , err
74+ }
75+ args := []string {"-c" , "core.quotePath=false" , "diff" , "-U0" , baseRef , "--" }
7076 args = append (args , paths ... )
7177 out , err := runGitLimited (ctx , repoDir , args )
7278 if err != nil {
@@ -98,6 +104,19 @@ func (g *ExecGitClient) DiffHunks(ctx context.Context, repoDir, baseRef string,
98104 return hunks , nil
99105}
100106
107+ // validateBaseRef rejects base revisions that git would parse as command options.
108+ // @intent block git argument injection through the caller-supplied base ref, which sits
109+ // before the "--" separator and would otherwise be interpreted as a diff flag.
110+ func validateBaseRef (baseRef string ) error {
111+ if baseRef == "" {
112+ return fmt .Errorf ("base ref must not be empty" )
113+ }
114+ if strings .HasPrefix (baseRef , "-" ) {
115+ return fmt .Errorf ("invalid base ref %q: must not start with '-'" , baseRef )
116+ }
117+ return nil
118+ }
119+
101120// runGitLimited runs a git subcommand with the default output size cap.
102121// @intent share a single bounded git invocation helper across diff operations
103122func runGitLimited (ctx context.Context , repoDir string , args []string ) ([]byte , error ) {
0 commit comments