]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: fix -X importpath.name=value when import path needs escaping
authorRuss Cox <rsc@golang.org>
Tue, 25 Oct 2016 12:59:35 +0000 (08:59 -0400)
committerRuss Cox <rsc@golang.org>
Sat, 29 Oct 2016 18:24:52 +0000 (18:24 +0000)
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 <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/go/go_test.go
src/cmd/go/testdata/src/my.pkg/main/main.go [new file with mode: 0644]
src/cmd/go/testdata/src/my.pkg/pkg.go [new file with mode: 0644]
src/cmd/link/internal/ld/data.go

index c9bd9be03cc23837db76a7f5b9f2da84594fc31a..c96acb74c92a034c30bc8452524747f3b57bb20b 100644 (file)
@@ -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 (file)
index 0000000..397e8b6
--- /dev/null
@@ -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 (file)
index 0000000..0a5466e
--- /dev/null
@@ -0,0 +1,2 @@
+package pkg
+var Text = "unset"
index 73c0daa77ccfad8caf210ae9a665a491f9409364..5197cb99b49fd46f41d918de8a01b4946e94f45f 100644 (file)
@@ -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) {