aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2023-05-15 11:49:56 -0400
committerGopher Robot <gobot@golang.org>2023-06-20 00:36:17 +0000
commit49594244d388401a2cec34ab22d28f4e66d46de1 (patch)
treef7b6d4dd93857aa31f5d39f83bc9d2e0d52f43ef
parent471904821134ee52c289cc5b17630313d812c32a (diff)
downloadgo-49594244d388401a2cec34ab22d28f4e66d46de1.tar.gz
go-49594244d388401a2cec34ab22d28f4e66d46de1.zip
[release-branch.go1.20] 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 #60516. Updates #60167. Change-Id: I6dc039392d59fc3a5a6121ef6ca97b0ab0da5288 Reviewed-on: https://go-review.googlesource.com/c/go/+/501577 Auto-Submit: Bryan Mills <bcmills@google.com> Run-TryBot: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> (cherry picked from commit 3d78c735fc7d213e23383b9744297bd5251dc0e3) Reviewed-on: https://go-review.googlesource.com/c/go/+/501818 Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
-rw-r--r--src/cmd/cover/cover.go10
-rw-r--r--src/cmd/cover/cover_test.go31
2 files changed, 41 insertions, 0 deletions
diff --git a/src/cmd/cover/cover.go b/src/cmd/cover/cover.go
index 74bb500cb9..5fd8b95272 100644
--- a/src/cmd/cover/cover.go
+++ b/src/cmd/cover/cover.go
@@ -568,6 +568,11 @@ func annotate(names []string) {
}
// TODO: process files in parallel here if it matters.
for k, name := range names {
+ if strings.ContainsAny(name, "\r\n") {
+ // annotateFile uses '//line' directives, which don't permit newlines.
+ log.Fatalf("cover: input path contains newline character: %q", name)
+ }
+
last := false
if k == len(names)-1 {
last = true
@@ -645,6 +650,11 @@ func (p *Package) annotateFile(name string, fd io.Writer, last bool) {
}
newContent := file.edit.Bytes()
+ if strings.ContainsAny(name, "\r\n") {
+ // This should have been checked by the caller already, but we double check
+ // here just to be sure we haven't missed a caller somewhere.
+ panic(fmt.Sprintf("annotateFile: name contains unexpected newline character: %q", name))
+ }
fmt.Fprintf(fd, "//line %s:1:1\n", name)
fd.Write(newContent)
diff --git a/src/cmd/cover/cover_test.go b/src/cmd/cover/cover_test.go
index af266b5e83..6ed4ae4675 100644
--- a/src/cmd/cover/cover_test.go
+++ b/src/cmd/cover/cover_test.go
@@ -574,3 +574,34 @@ func runExpectingError(c *exec.Cmd, t *testing.T) string {
}
return string(out)
}
+
+func TestSrcPathWithNewline(t *testing.T) {
+ testenv.MustHaveExec(t)
+ t.Parallel()
+
+ // srcPath is intentionally not clean so that the path passed to testcover
+ // will not normalize the trailing / to a \ on Windows.
+ srcPath := t.TempDir() + string(filepath.Separator) + "\npackage main\nfunc main() { panic(string([]rune{'u', 'h', '-', 'o', 'h'}))\n/*/main.go"
+ mainSrc := ` package main
+
+func main() {
+ /* nothing here */
+ println("ok")
+}
+`
+ if err := os.MkdirAll(filepath.Dir(srcPath), 0777); err != nil {
+ t.Skipf("creating directory with bogus path: %v", err)
+ }
+ if err := os.WriteFile(srcPath, []byte(mainSrc), 0666); err != nil {
+ t.Skipf("writing file with bogus directory: %v", err)
+ }
+
+ cmd := testenv.Command(t, testcover(t), "-mode=atomic", srcPath)
+ cmd.Stderr = new(bytes.Buffer)
+ out, err := cmd.Output()
+ t.Logf("%v:\n%s", cmd, out)
+ t.Logf("stderr:\n%s", cmd.Stderr)
+ if err == nil {
+ t.Errorf("unexpected success; want failure due to newline in file path")
+ }
+}