From: Matthew Dempsky Date: Tue, 21 Nov 2017 19:27:20 +0000 (-0800) Subject: cmd/link: fix export data truncation bug X-Git-Tag: go1.10beta1~166 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5e423ed8553b8eec01273597f7eb89ce73f47b86;p=gostls13.git cmd/link: fix export data truncation bug Similar fix as in CL 60773 for fixing cmd/pack. Fixes #21703. Change-Id: I457ed8a3be828fd458abc5c8c1cc766a9f7aab13 Reviewed-on: https://go-review.googlesource.com/79135 Run-TryBot: Matthew Dempsky TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 81f8e4cb44..cd8b45cd2e 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -1474,13 +1474,29 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, } } - /* skip over exports and other info -- ends with \n!\n */ + // Skip over exports and other info -- ends with \n!\n. + // + // Note: It's possible for "\n!\n" to appear within the binary + // package export data format. To avoid truncating the package + // definition prematurely (issue 21703), we keep keep track of + // how many "$$" delimiters we've seen. + import0 := f.Offset() c1 = '\n' // the last line ended in \n c2 = bgetc(f) c3 = bgetc(f) - for c1 != '\n' || c2 != '!' || c3 != '\n' { + markers := 0 + for { + if c1 == '\n' { + if markers%2 == 0 && c2 == '!' && c3 == '\n' { + break + } + if c2 == '$' && c3 == '$' { + markers++ + } + } + c1 = c2 c2 = c3 c3 = bgetc(f) diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go index 4ef184518e..4ec03abc85 100644 --- a/src/cmd/link/link_test.go +++ b/src/cmd/link/link_test.go @@ -1,6 +1,13 @@ package main -import "testing" +import ( + "internal/testenv" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "testing" +) var AuthorPaidByTheColumnInch struct { fog int ` @@ -28,3 +35,38 @@ func TestLargeSymName(t *testing.T) { // the bufio buffer. Issue #15104. _ = AuthorPaidByTheColumnInch } + +func TestIssue21703(t *testing.T) { + testenv.MustHaveGoBuild(t) + + const source = ` +package main +const X = "\n!\n" +func main() {} +` + + tmpdir, err := ioutil.TempDir("", "issue21703") + if err != nil { + t.Fatalf("failed to create temp dir: %v\n", err) + } + defer os.RemoveAll(tmpdir) + + err = ioutil.WriteFile(filepath.Join(tmpdir, "main.go"), []byte(source), 0666) + if err != nil { + t.Fatalf("failed to write main.go: %v\n", err) + } + + cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "main.go") + cmd.Dir = tmpdir + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("failed to compile main.go: %v, output: %s\n", err, out) + } + + cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "main.o") + cmd.Dir = tmpdir + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("failed to link main.o: %v, output: %s\n", err, out) + } +}