diff options
author | Bryan C. Mills <bcmills@google.com> | 2023-05-15 12:13:25 -0400 |
---|---|---|
committer | Michael Pratt <mpratt@google.com> | 2023-06-13 19:59:45 +0000 |
commit | 516ef2da14ac166984f0945df88b2bb3676a5064 (patch) | |
tree | 1a8df433f510a27034541fc91af8b7a1cf8811cc | |
parent | 0f7675d910cf726f91189459fe7bfa3002b94c48 (diff) | |
download | go-516ef2da14ac166984f0945df88b2bb3676a5064.tar.gz go-516ef2da14ac166984f0945df88b2bb3676a5064.zip |
[release-branch.go1.19] cmd/cgo: error out if the source path used in line directives would contain a newline
cmd/cgo uses '//line' directives to map generated source
files back to the original source file and line nmubers.
The line directives have no way to escape newline characters,
so cmd/cgo must not be used if the line directives would contain
such characters.
Updates #60515.
Updates #60167.
Change-Id: I8581cea74d6c08f82e86ed87127e81252e1bf78c
Reviewed-on: https://go-review.googlesource.com/c/go/+/501576
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
(cherry picked from commit c48228312e7fdd9580078f58f5f4a287ce1185d5)
Reviewed-on: https://go-review.googlesource.com/c/go/+/501821
TryBot-Bypass: Bryan Mills <bcmills@google.com>
-rw-r--r-- | src/cmd/cgo/ast.go | 5 | ||||
-rw-r--r-- | src/cmd/cgo/main.go | 6 | ||||
-rw-r--r-- | src/cmd/cgo/out.go | 5 | ||||
-rw-r--r-- | src/cmd/go/testdata/script/build_cwd_newline.txt | 16 |
4 files changed, 32 insertions, 0 deletions
diff --git a/src/cmd/cgo/ast.go b/src/cmd/cgo/ast.go index 28879e349c..a78640f8e8 100644 --- a/src/cmd/cgo/ast.go +++ b/src/cmd/cgo/ast.go @@ -80,6 +80,11 @@ func (f *File) ParseGo(abspath string, src []byte) { cg = d.Doc } if cg != nil { + if strings.ContainsAny(abspath, "\r\n") { + // This should have been checked when the file path was first resolved, + // but we double check here just to be sure. + fatalf("internal error: ParseGo: abspath contains unexpected newline character: %q", abspath) + } f.Preamble += fmt.Sprintf("#line %d %q\n", sourceLine(cg), abspath) f.Preamble += commentText(cg) + "\n" f.Preamble += "#line 1 \"cgo-generated-wrapper\"\n" diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go index e3434598b2..e2aa71acd8 100644 --- a/src/cmd/cgo/main.go +++ b/src/cmd/cgo/main.go @@ -357,6 +357,12 @@ func main() { // Apply trimpath to the file path. The path won't be read from after this point. input, _ = objabi.ApplyRewrites(input, *trimpath) + if strings.ContainsAny(input, "\r\n") { + // ParseGo, (*Package).writeOutput, and printer.Fprint in SourcePos mode + // all emit line directives, which don't permit newlines in the file path. + // Bail early if we see anything newline-like in the trimmed path. + fatalf("input path contains newline character: %q", input) + } goFiles[i] = input f := new(File) diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go index 6eb302b62b..090931e36f 100644 --- a/src/cmd/cgo/out.go +++ b/src/cmd/cgo/out.go @@ -642,6 +642,11 @@ func (p *Package) writeOutput(f *File, srcfile string) { // Write Go output: Go input with rewrites of C.xxx to _C_xxx. fmt.Fprintf(fgo1, "// Code generated by cmd/cgo; DO NOT EDIT.\n\n") + if strings.ContainsAny(srcfile, "\r\n") { + // This should have been checked when the file path was first resolved, + // but we double check here just to be sure. + fatalf("internal error: writeOutput: srcfile contains unexpected newline character: %q", srcfile) + } fmt.Fprintf(fgo1, "//line %s:1:1\n", srcfile) fgo1.Write(f.Edit.Bytes()) diff --git a/src/cmd/go/testdata/script/build_cwd_newline.txt b/src/cmd/go/testdata/script/build_cwd_newline.txt index 8f74c01c81..e80235698a 100644 --- a/src/cmd/go/testdata/script/build_cwd_newline.txt +++ b/src/cmd/go/testdata/script/build_cwd_newline.txt @@ -43,6 +43,19 @@ stderr 'package example: invalid package directory .*uh-oh' ! stdout . ! exists obj_ +# The cgo tool should only accept the source file if the working directory +# is not written in line directives in the resulting files. + +[cgo] ! go tool cgo main.go +[cgo] stderr 'cgo: input path contains newline character: .*uh-oh' +[cgo] ! exists _obj + +[cgo] go tool cgo -trimpath=$PWD main.go +[cgo] grep '//line main\.go:1:1' _obj/main.cgo1.go +[cgo] ! grep 'uh-oh' _obj/main.cgo1.go +[cgo] rm _obj + + # Since we do preserve $PWD (or set it appropriately) for commands, and we do # not resolve symlinks unnecessarily, referring to the contents of the unsafe # directory via a safe symlink should be ok, and should not inject the data from @@ -92,6 +105,9 @@ go test -v . ! stderr panic stdout '^ok$' # 'go test' combines the test's stdout into stderr +[cgo] go tool cgo main.go +[cgo] grep '//line .*'${/}'link'${/}'main\.go:1:1' _obj/main.cgo1.go +[cgo] ! grep 'uh-oh' _obj/main.cgo1.go -- $WORK/go.mod -- module example |