From: Bryan C. Mills Date: Tue, 31 Jul 2018 18:37:43 +0000 (-0400) Subject: cmd/go/internal/modfetch/codehost: quote arguments to commands printed from -x X-Git-Tag: go1.11beta3~43 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f152f83a6e3aba0eb7d5ce2f0c73463ac307ec55;p=gostls13.git cmd/go/internal/modfetch/codehost: quote arguments to commands printed from -x Some of the arguments — particularly format strings passed to git commands — may contain spaces, and it's useful to be able to paste commands from 'go get -x foo' directly into a shell to reproduce their output. Change-Id: I4f0c0b4e05db8b5232458e9a271f2ccbb665e85a Reviewed-on: https://go-review.googlesource.com/126955 Run-TryBot: Bryan C. Mills Reviewed-by: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/go/internal/modfetch/codehost/codehost.go b/src/cmd/go/internal/modfetch/codehost/codehost.go index 9c07b96957..4103ddc717 100644 --- a/src/cmd/go/internal/modfetch/codehost/codehost.go +++ b/src/cmd/go/internal/modfetch/codehost/codehost.go @@ -201,6 +201,10 @@ func Run(dir string, cmdline ...interface{}) ([]byte, error) { return RunWithStdin(dir, nil, cmdline...) } +// bashQuoter escapes characters that have special meaning in double-quoted strings in the bash shell. +// See https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html. +var bashQuoter = strings.NewReplacer(`"`, `\"`, `$`, `\$`, "`", "\\`", `\`, `\\`) + func RunWithStdin(dir string, stdin io.Reader, cmdline ...interface{}) ([]byte, error) { if dir != "" { muIface, ok := dirLock.Load(dir) @@ -214,11 +218,31 @@ func RunWithStdin(dir string, stdin io.Reader, cmdline ...interface{}) ([]byte, cmd := str.StringList(cmdline...) if cfg.BuildX { - var text string + text := new(strings.Builder) if dir != "" { - text = "cd " + dir + "; " + text.WriteString("cd ") + text.WriteString(dir) + text.WriteString("; ") + } + for i, arg := range cmd { + if i > 0 { + text.WriteByte(' ') + } + switch { + case strings.ContainsAny(arg, "'"): + // Quote args that could be mistaken for quoted args. + text.WriteByte('"') + text.WriteString(bashQuoter.Replace(arg)) + text.WriteByte('"') + case strings.ContainsAny(arg, "$`\\*?[\"\t\n\v\f\r \u0085\u00a0"): + // Quote args that contain special characters, glob patterns, or spaces. + text.WriteByte('\'') + text.WriteString(arg) + text.WriteByte('\'') + default: + text.WriteString(arg) + } } - text += strings.Join(cmd, " ") fmt.Fprintf(os.Stderr, "%s\n", text) start := time.Now() defer func() {