Skip to content

Commit c482283

Browse files
Bryan C. Millsgopherbot
Bryan C. Mills
authored andcommitted
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 #60167. Change-Id: I8581cea74d6c08f82e86ed87127e81252e1bf78c Reviewed-on: https://go-review.googlesource.com/c/go/+/501576 TryBot-Result: Gopher Robot <[email protected]> Auto-Submit: Bryan Mills <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Run-TryBot: Bryan Mills <[email protected]>
1 parent e2b1c0b commit c482283

File tree

4 files changed

+33
-0
lines changed

4 files changed

+33
-0
lines changed

src/cmd/cgo/ast.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ func (f *File) ParseGo(abspath string, src []byte) {
7979
cg = decl.Doc
8080
}
8181
if cg != nil {
82+
if strings.ContainsAny(abspath, "\r\n") {
83+
// This should have been checked when the file path was first resolved,
84+
// but we double check here just to be sure.
85+
fatalf("internal error: ParseGo: abspath contains unexpected newline character: %q", abspath)
86+
}
8287
f.Preamble += fmt.Sprintf("#line %d %q\n", sourceLine(cg), abspath)
8388
f.Preamble += commentText(cg) + "\n"
8489
f.Preamble += "#line 1 \"cgo-generated-wrapper\"\n"

src/cmd/cgo/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,12 @@ func main() {
363363

364364
// Apply trimpath to the file path. The path won't be read from after this point.
365365
input, _ = objabi.ApplyRewrites(input, *trimpath)
366+
if strings.ContainsAny(input, "\r\n") {
367+
// ParseGo, (*Package).writeOutput, and printer.Fprint in SourcePos mode
368+
// all emit line directives, which don't permit newlines in the file path.
369+
// Bail early if we see anything newline-like in the trimmed path.
370+
fatalf("input path contains newline character: %q", input)
371+
}
366372
goFiles[i] = input
367373

368374
f := new(File)

src/cmd/cgo/out.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,11 @@ func (p *Package) writeOutput(f *File, srcfile string) {
644644

645645
// Write Go output: Go input with rewrites of C.xxx to _C_xxx.
646646
fmt.Fprintf(fgo1, "// Code generated by cmd/cgo; DO NOT EDIT.\n\n")
647+
if strings.ContainsAny(srcfile, "\r\n") {
648+
// This should have been checked when the file path was first resolved,
649+
// but we double check here just to be sure.
650+
fatalf("internal error: writeOutput: srcfile contains unexpected newline character: %q", srcfile)
651+
}
647652
fmt.Fprintf(fgo1, "//line %s:1:1\n", srcfile)
648653
fgo1.Write(f.Edit.Bytes())
649654

src/cmd/go/testdata/script/build_cwd_newline.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ stderr 'package command-line-arguments: invalid package directory .*uh-oh'
3838
go list -compiled -e -f '{{with .CompiledGoFiles}}{{.}}{{end}}' .
3939
! stdout .
4040
! stderr .
41+
! exists obj_
42+
43+
44+
# The cgo tool should only accept the source file if the working directory
45+
# is not written in line directives in the resulting files.
46+
47+
[cgo] ! go tool cgo main.go
48+
[cgo] stderr 'cgo: input path contains newline character: .*uh-oh'
49+
[cgo] ! exists _obj
50+
51+
[cgo] go tool cgo -trimpath=$PWD main.go
52+
[cgo] grep '//line main\.go:1:1' _obj/main.cgo1.go
53+
[cgo] ! grep 'uh-oh' _obj/main.cgo1.go
54+
[cgo] rm _obj
4155

4256

4357
# Since we do preserve $PWD (or set it appropriately) for commands, and we do
@@ -89,6 +103,9 @@ go test -v .
89103
! stderr panic
90104
stdout '^ok$' # 'go test' combines the test's stdout into stderr
91105

106+
[cgo] go tool cgo main.go
107+
[cgo] grep '//line .*'${/}'link'${/}'main\.go:1:1' _obj/main.cgo1.go
108+
[cgo] ! grep 'uh-oh' _obj/main.cgo1.go
92109

93110
-- $WORK/go.mod --
94111
module example

0 commit comments

Comments
 (0)