]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: error out if the source path used in line directives would contain a newline
authorBryan C. Mills <bcmills@google.com>
Mon, 15 May 2023 16:13:25 +0000 (12:13 -0400)
committerGopher Robot <gobot@golang.org>
Wed, 7 Jun 2023 16:54:27 +0000 (16:54 +0000)
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 <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>

src/cmd/cgo/ast.go
src/cmd/cgo/main.go
src/cmd/cgo/out.go
src/cmd/go/testdata/script/build_cwd_newline.txt

index 6a1cf387208e5e15f5f532a118c5b853d1dd25b9..3cbbeafdca87358d6ac8a9259c058372069b67cb 100644 (file)
@@ -79,6 +79,11 @@ func (f *File) ParseGo(abspath string, src []byte) {
                                        cg = decl.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"
index f78969e696cfcdacf21b6d98595ba1d3cfc8fae8..78020aedbe5aa696397fdc1e9a77d0c55e5b8b29 100644 (file)
@@ -363,6 +363,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)
index a48f52105628a3ef7641bd54f03ab71779448627..b2933e2d82e80e381f57dc909eaeb72b3ae5c25b 100644 (file)
@@ -644,6 +644,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())
 
index d39674cc4c711d76a05d0a61b783f5d360814d52..91cb57fa49e8219c18fcf16ee290676a2966353e 100644 (file)
@@ -38,6 +38,20 @@ stderr 'package command-line-arguments: invalid package directory .*uh-oh'
 go list -compiled -e -f '{{with .CompiledGoFiles}}{{.}}{{end}}' .
 ! stdout .
 ! stderr .
+! 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
@@ -89,6 +103,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