Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ All notable changes to Sourcegraph are documented in this file.
- OpenTelemetry Collector has been upgraded to v0.81, and OpenTelemetry packages have been upgraded to v1.16. [#54969](https://github.com/sourcegraph/sourcegraph/pull/54969), [#54999](https://github.com/sourcegraph/sourcegraph/pull/54999)
- Bitbucket Cloud code host connections no longer automatically syncs the repository of the username used. The appropriate workspace name will have to be added to the `teams` list if repositories for that account need to be synced. [#55095](https://github.com/sourcegraph/sourcegraph/pull/55095)
- Pressing `Mod-f` will always select the input value in the file view search [#55546](https://github.com/sourcegraph/sourcegraph/pull/55546)
- The commit message defined in a batch spec will now be passed to `git commit` on stdin using `--file=-` instead of being included inline with `git commit -m` to improve how the message is interpreted by `git` in certain edge cases, such as when the commit message begins with a dash, and to prevent extra quotes being added to the message. This may mean that previous escaping strategies will behave differently.

### Fixed

Expand Down
25 changes: 9 additions & 16 deletions cmd/gitserver/server/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"time"

"github.com/sourcegraph/log"

"github.com/sourcegraph/sourcegraph/internal/api"

"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
Expand Down Expand Up @@ -227,11 +228,14 @@ func (s *Server) createCommitFromPatch(ctx context.Context, req protocol.CreateC
committerEmail = authorEmail
}

gitCommitArgs := []string{"commit"}
for _, m := range messages {
gitCommitArgs = append(gitCommitArgs, "-m", stylizeCommitMessage(m))
}
cmd = exec.CommandContext(ctx, "git", gitCommitArgs...)
// Commit messages can be arbitrary strings, so using `-m` runs into problems.
// Instead, feed the commit messages to stdin.
cmd = exec.CommandContext(ctx, "git", "commit", "-F", "-")
// NOTE: join messages with a blank line in between ("\n\n")
// because the previous behavior was to use multiple -m arguments,
// which concatenate with a blank line in between.
// Gerrit is the only code host that usees multiple messages at the moment
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Gerrit is the only code host that usees multiple messages at the moment
// Gerrit is the only code host that uses multiple messages at the moment

cmd.Stdin = strings.NewReader(strings.Join(messages, "\n\n"))

cmd.Dir = tmpRepoDir
cmd.Env = append(os.Environ(), []string{
Expand Down Expand Up @@ -395,17 +399,6 @@ func (s *Server) repoRemoteRefs(ctx context.Context, remoteURL *vcs.URL, repoNam
return refs, nil
}

func stylizeCommitMessage(message string) string {
if styleMessage(message) {
return fmt.Sprintf("%q", message)
}
return message
}

func styleMessage(message string) bool {
return !strings.HasPrefix(message, "Change-Id: I")
}

func (s *Server) shelveChangelist(ctx context.Context, req protocol.CreateCommitFromPatchRequest, patchCommit string, remoteURL *vcs.URL, tmpGitPathEnv, altObjectsEnv string) (string, error) {

repo := string(req.Repo)
Expand Down
31 changes: 31 additions & 0 deletions internal/gitserver/gitdomain/exec.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gitdomain

import (
"fmt"
"os"
"strconv"
"strings"
Expand Down Expand Up @@ -141,8 +142,20 @@ func IsAllowedGitCmd(logger log.Logger, args []string) bool {
logger.Warn("command not allowed", log.String("cmd", cmd))
return false
}

// I hate state machines, but I hate them less than complicated multi-argument checking
checkFileInput := false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we get a test for this new added behavior?

for i, arg := range args[1:] {
if checkFileInput {
if arg == "-" {
checkFileInput = false
continue
}
logger.Warn("IsAllowedGitCmd: unallowed file input for `git commit`", log.String("cmd", cmd), log.String("arg", arg))
return false
}
if strings.HasPrefix(arg, "-") {
fmt.Printf("EVALUATING ARGUMENT %d: %s\n", i, arg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fmt.Printf("EVALUATING ARGUMENT %d: %s\n", i, arg)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t feel super strongly about the other comments, but I think we should address this one in a follow up 🙂

// Special-case `git log -S` and `git log -G`, which interpret any characters
// after their 'S' or 'G' as part of the query. There is no long form of this
// flags (such as --something=query), so if we did not special-case these, there
Expand All @@ -162,6 +175,24 @@ func IsAllowedGitCmd(logger log.Logger, args []string) bool {
continue // this arg is OK
}

// For `git commit`, allow reading the commit message from stdin
// but don't just blindly accept the `--file` or `-F` args
// because they could be used to read arbitrary files.
// Instead, accept only the forms that read from stdin.
if cmd == "commit" {
if arg == "--file=-" {
continue
}
// checking `-F` requires a second check for `-` in the next argument
// Instead of an obtuse check of next and previous arguments, set state and check it the next time around
// Here's the alternative obtuse check of previous and next arguments:
// (arg == "-F" && len(args) > i+2 && args[i+2] == "-") || (arg == "-" && args[i] == "-F")
if arg == "-F" {
checkFileInput = true
continue
}
}

if !isAllowedGitArg(allowedArgs, arg) {
logger.Warn("IsAllowedGitCmd.isAllowedGitArgcmd", log.String("cmd", cmd), log.String("arg", arg))
return false
Expand Down