Skip to content

Commit 3d78c73

Browse files
Bryan C. Millsgopherbot
Bryan C. Mills
authored andcommitted
cmd/cover: error out if a requested source file contains a newline
cmd/cover uses '//line' directives to map instrumented source files back to the original source file and line numbers. Line directives have no way to escape newline characters, so cmd/cover must not be used with source file paths that contain such characters. Updates #60167. Change-Id: I6dc039392d59fc3a5a6121ef6ca97b0ab0da5288 Reviewed-on: https://go-review.googlesource.com/c/go/+/501577 Auto-Submit: Bryan Mills <[email protected]> Run-TryBot: Bryan Mills <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent c482283 commit 3d78c73

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

src/cmd/cover/cover.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,11 @@ func annotate(names []string) {
577577
}
578578
// TODO: process files in parallel here if it matters.
579579
for k, name := range names {
580+
if strings.ContainsAny(name, "\r\n") {
581+
// annotateFile uses '//line' directives, which don't permit newlines.
582+
log.Fatalf("cover: input path contains newline character: %q", name)
583+
}
584+
580585
fd := os.Stdout
581586
isStdout := true
582587
if *pkgcfg != "" {
@@ -660,6 +665,11 @@ func (p *Package) annotateFile(name string, fd io.Writer) {
660665
}
661666
newContent := file.edit.Bytes()
662667

668+
if strings.ContainsAny(name, "\r\n") {
669+
// This should have been checked by the caller already, but we double check
670+
// here just to be sure we haven't missed a caller somewhere.
671+
panic(fmt.Sprintf("annotateFile: name contains unexpected newline character: %q", name))
672+
}
663673
fmt.Fprintf(fd, "//line %s:1:1\n", name)
664674
fd.Write(newContent)
665675

src/cmd/cover/cover_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,3 +616,34 @@ func TestCoverage(t *testing.T) { }
616616
cmd.Dir = noeolDir
617617
run(cmd, t)
618618
}
619+
620+
func TestSrcPathWithNewline(t *testing.T) {
621+
testenv.MustHaveExec(t)
622+
t.Parallel()
623+
624+
// srcPath is intentionally not clean so that the path passed to testcover
625+
// will not normalize the trailing / to a \ on Windows.
626+
srcPath := t.TempDir() + string(filepath.Separator) + "\npackage main\nfunc main() { panic(string([]rune{'u', 'h', '-', 'o', 'h'}))\n/*/main.go"
627+
mainSrc := ` package main
628+
629+
func main() {
630+
/* nothing here */
631+
println("ok")
632+
}
633+
`
634+
if err := os.MkdirAll(filepath.Dir(srcPath), 0777); err != nil {
635+
t.Skipf("creating directory with bogus path: %v", err)
636+
}
637+
if err := os.WriteFile(srcPath, []byte(mainSrc), 0666); err != nil {
638+
t.Skipf("writing file with bogus directory: %v", err)
639+
}
640+
641+
cmd := testenv.Command(t, testcover(t), "-mode=atomic", srcPath)
642+
cmd.Stderr = new(bytes.Buffer)
643+
out, err := cmd.Output()
644+
t.Logf("%v:\n%s", cmd, out)
645+
t.Logf("stderr:\n%s", cmd.Stderr)
646+
if err == nil {
647+
t.Errorf("unexpected success; want failure due to newline in file path")
648+
}
649+
}

0 commit comments

Comments
 (0)