Skip to content

Commit f062d7b

Browse files
ianlancetaylorgopherbot
authored andcommittedFeb 22, 2025
cmd/go: look at runes, not bytes, when printing env vars
For #58508 Fixes #71863 Change-Id: Ib1ebaf751bcc6900da6ffd01a9462dd237e2c89a Reviewed-on: https://go-review.googlesource.com/c/go/+/651295 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> Reviewed-by: Michael Matloob <matloob@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
1 parent e15d148 commit f062d7b

File tree

1 file changed

+29
-24
lines changed
  • src/cmd/go/internal/envcmd

1 file changed

+29
-24
lines changed
 

‎src/cmd/go/internal/envcmd/env.go

+29-24
Original file line numberDiff line numberDiff line change
@@ -522,51 +522,56 @@ func PrintEnv(w io.Writer, env []cfg.EnvVar, onlyChanged bool) {
522522
}
523523
}
524524

525+
// isWindowsUnquotableRune reports whether r can't be quoted in a
526+
// Windows "set" command.
527+
// These runes will be replaced by the Unicode replacement character.
528+
func isWindowsUnquotableRune(r rune) bool {
529+
if r == '\r' || r == '\n' {
530+
return true
531+
}
532+
return !unicode.IsGraphic(r) && !unicode.IsSpace(r)
533+
}
534+
525535
func hasNonGraphic(s string) bool {
526-
for _, c := range []byte(s) {
527-
if c == '\r' || c == '\n' || (!unicode.IsGraphic(rune(c)) && !unicode.IsSpace(rune(c))) {
528-
return true
529-
}
530-
}
531-
return false
536+
return strings.ContainsFunc(s, isWindowsUnquotableRune)
532537
}
533538

534539
func shellQuote(s string) string {
535-
var b bytes.Buffer
536-
b.WriteByte('\'')
537-
for _, x := range []byte(s) {
538-
if x == '\'' {
540+
var sb strings.Builder
541+
sb.WriteByte('\'')
542+
for _, r := range s {
543+
if r == '\'' {
539544
// Close the single quoted string, add an escaped single quote,
540545
// and start another single quoted string.
541-
b.WriteString(`'\''`)
546+
sb.WriteString(`'\''`)
542547
} else {
543-
b.WriteByte(x)
548+
sb.WriteRune(r)
544549
}
545550
}
546-
b.WriteByte('\'')
547-
return b.String()
551+
sb.WriteByte('\'')
552+
return sb.String()
548553
}
549554

550555
func batchEscape(s string) string {
551-
var b bytes.Buffer
552-
for _, x := range []byte(s) {
553-
if x == '\r' || x == '\n' || (!unicode.IsGraphic(rune(x)) && !unicode.IsSpace(rune(x))) {
554-
b.WriteRune(unicode.ReplacementChar)
556+
var sb strings.Builder
557+
for _, r := range s {
558+
if isWindowsUnquotableRune(r) {
559+
sb.WriteRune(unicode.ReplacementChar)
555560
continue
556561
}
557-
switch x {
562+
switch r {
558563
case '%':
559-
b.WriteString("%%")
564+
sb.WriteString("%%")
560565
case '<', '>', '|', '&', '^':
561566
// These are special characters that need to be escaped with ^. See
562567
// https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/set_1.
563-
b.WriteByte('^')
564-
b.WriteByte(x)
568+
sb.WriteByte('^')
569+
sb.WriteRune(r)
565570
default:
566-
b.WriteByte(x)
571+
sb.WriteRune(r)
567572
}
568573
}
569-
return b.String()
574+
return sb.String()
570575
}
571576

572577
func printEnvAsJSON(env []cfg.EnvVar, onlyChanged bool) {

0 commit comments

Comments
 (0)
Please sign in to comment.