From 1773cdd0811620fd59b44136a77ecef4d728ae18 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 25 Oct 2016 08:59:35 -0400 Subject: [PATCH] cmd/link: fix -X importpath.name=value when import path needs escaping After the final slash, dots are %-escaped when constructing a symbol name, so that in the actual symbol table, the import path githost.com/my.git becomes githost.com/my%2egit. In this case, -X githost.com/my.git.Value=foo needs to set githost.com/my%2egit.Value. This is a detail of the object format and not something users should know or depend on, so apply the escaping as needed. People who have run across this already and figured out and started using the escaped forms with -X will find those forms not working anymore. That is, -X githost.com/my%2egit.Value=foo is the Go 1.7 workaround but will stop working in Go 1.8 once this proper fix is in place. People who need to keep scripts working with older and newer versions of Go can safely pass both forms, and one will be ignored: -X githost.com/my%2egit.Value=foo -X githost.com/my.git.Value=foo Fixes #16710. Change-Id: I0e994ccdd412a4eb8349fefce9aeb3bfc9a83cd8 Reviewed-on: https://go-review.googlesource.com/31970 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/cmd/go/go_test.go | 18 ++++++++++++++++++ src/cmd/go/testdata/src/my.pkg/main/main.go | 5 +++++ src/cmd/go/testdata/src/my.pkg/pkg.go | 2 ++ src/cmd/link/internal/ld/data.go | 7 ++++--- 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 src/cmd/go/testdata/src/my.pkg/main/main.go create mode 100644 src/cmd/go/testdata/src/my.pkg/pkg.go diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go index c9bd9be03c..c96acb74c9 100644 --- a/src/cmd/go/go_test.go +++ b/src/cmd/go/go_test.go @@ -3432,3 +3432,21 @@ func TestMatchesOnlySubtestParallelIsOK(t *testing.T) { tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]") tg.grepBoth(okPattern, "go test did not say ok") } + +func TestLinkXImportPathEscape(t *testing.T) { + // golang.org/issue/16710 + tg := testgo(t) + defer tg.cleanup() + tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) + exe := "./linkx" + exeSuffix + tg.creatingTemp(exe) + tg.run("build", "-o", exe, "-ldflags", "-X=my.pkg.Text=linkXworked", "my.pkg/main") + out, err := exec.Command(exe).CombinedOutput() + if err != nil { + tg.t.Fatal(err) + } + if string(out) != "linkXworked\n" { + tg.t.Log(string(out)) + tg.t.Fatal(`incorrect output: expected "linkXworked\n"`) + } +} diff --git a/src/cmd/go/testdata/src/my.pkg/main/main.go b/src/cmd/go/testdata/src/my.pkg/main/main.go new file mode 100644 index 0000000000..397e8b66a2 --- /dev/null +++ b/src/cmd/go/testdata/src/my.pkg/main/main.go @@ -0,0 +1,5 @@ +package main +import "my.pkg" +func main() { + println(pkg.Text) +} diff --git a/src/cmd/go/testdata/src/my.pkg/pkg.go b/src/cmd/go/testdata/src/my.pkg/pkg.go new file mode 100644 index 0000000000..0a5466ef17 --- /dev/null +++ b/src/cmd/go/testdata/src/my.pkg/pkg.go @@ -0,0 +1,2 @@ +package pkg +var Text = "unset" diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 73c0daa77c..5197cb99b4 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -1025,11 +1025,12 @@ func strnputPad(s string, n int, pad []byte) { var strdata []*Symbol func addstrdata1(ctxt *Link, arg string) { - i := strings.Index(arg, "=") - if i < 0 { + eq := strings.Index(arg, "=") + dot := strings.LastIndex(arg[:eq+1], ".") + if eq < 0 || dot < 0 { Exitf("-X flag requires argument of the form importpath.name=value") } - addstrdata(ctxt, arg[:i], arg[i+1:]) + addstrdata(ctxt, pathtoprefix(arg[:dot])+arg[dot:eq], arg[eq+1:]) } func addstrdata(ctxt *Link, name string, value string) { -- 2.48.1