From 73e862eced80553479b7f19d572e9ca4e07bf585 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Tue, 4 Dec 2018 15:42:32 -0500 Subject: [PATCH] cmd/go/internal/get: use a strings.Replacer in expand This should be a no-op, but produces deterministic (and more correct) behavior if we have accidentally failed to sanitize one of the inputs. Updates #29231 Change-Id: I1271d0ffd01a691ec8c84906c4e02d9e2be19c72 Reviewed-on: https://team-review.git.corp.google.com/c/370575 Reviewed-by: Russ Cox Reviewed-by: Dmitri Shuralyov Reviewed-on: https://go-review.googlesource.com/c/154103 Reviewed-by: Bryan C. Mills --- src/cmd/go/internal/get/vcs.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cmd/go/internal/get/vcs.go b/src/cmd/go/internal/get/vcs.go index 173934b84e..052c82b7b5 100644 --- a/src/cmd/go/internal/get/vcs.go +++ b/src/cmd/go/internal/get/vcs.go @@ -963,10 +963,14 @@ func matchGoImport(imports []metaImport, importPath string) (metaImport, error) // expand rewrites s to replace {k} with match[k] for each key k in match. func expand(match map[string]string, s string) string { + // We want to replace each match exactly once, and the result of expansion + // must not depend on the iteration order through the map. + // A strings.Replacer has exactly the properties we're looking for. + oldNew := make([]string, 0, 2*len(match)) for k, v := range match { - s = strings.ReplaceAll(s, "{"+k+"}", v) + oldNew = append(oldNew, "{"+k+"}", v) } - return s + return strings.NewReplacer(oldNew...).Replace(s) } // vcsPaths defines the meaning of import paths referring to -- 2.48.1