}
}
- /* 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)
package main
-import "testing"
+import (
+ "internal/testenv"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "testing"
+)
var AuthorPaidByTheColumnInch struct {
fog int `
// 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)
+ }
+}