Skip to content

Commit 1df777f

Browse files
hirochachachaianlancetaylor
authored andcommitted
go/build: accept spaces in cgo directives
Fixes #7906 Change-Id: Ibcf9cd670593241921ab3c426ff7357f799ebc3e Reviewed-on: https://go-review.googlesource.com/43072 Reviewed-by: Ian Lance Taylor <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 69972ae commit 1df777f

File tree

3 files changed

+73
-15
lines changed

3 files changed

+73
-15
lines changed

src/cmd/go/go_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ func init() {
7878
// (temp) directory.
7979
var testGOROOT string
8080

81+
var testCC string
82+
8183
// The TestMain function creates a go command for testing purposes and
8284
// deletes it after the tests have been run.
8385
func TestMain(m *testing.M) {
@@ -99,6 +101,13 @@ func TestMain(m *testing.M) {
99101
}
100102
testGOROOT = strings.TrimSpace(string(out))
101103

104+
out, err = exec.Command("go", "env", "CC").CombinedOutput()
105+
if err != nil {
106+
fmt.Fprintf(os.Stderr, "could not find testing CC: %v\n%s", err, out)
107+
os.Exit(2)
108+
}
109+
testCC = strings.TrimSpace(string(out))
110+
102111
if out, err := exec.Command("./testgo"+exeSuffix, "env", "CGO_ENABLED").Output(); err != nil {
103112
fmt.Fprintf(os.Stderr, "running testgo failed: %v\n", err)
104113
canRun = false
@@ -4037,3 +4046,58 @@ func main() {}`)
40374046
tg.run("build", "-x", "-buildmode=c-archive", "-gcflags=-shared=false", tg.path("override.go"))
40384047
tg.grepStderr("compile .*-shared .*-shared=false", "user can not override code generation flag")
40394048
}
4049+
4050+
func TestCgoFlagContainsSpace(t *testing.T) {
4051+
if !canCgo {
4052+
t.Skip("skipping because cgo not enabled")
4053+
}
4054+
4055+
tg := testgo(t)
4056+
defer tg.cleanup()
4057+
4058+
tg.tempFile("src/cc/main.go", fmt.Sprintf(`package main
4059+
import (
4060+
"os"
4061+
"os/exec"
4062+
)
4063+
4064+
func main() {
4065+
var success bool
4066+
for _, arg := range os.Args {
4067+
switch arg {
4068+
case "-Ic flags":
4069+
if success {
4070+
panic("duplicate CFLAGS")
4071+
}
4072+
success = true
4073+
case "-Lld flags":
4074+
if success {
4075+
panic("duplicate LDFLAGS")
4076+
}
4077+
success = true
4078+
}
4079+
}
4080+
if !success {
4081+
panic("args should contains '-Ic flags' or '-Lld flags'")
4082+
}
4083+
cmd := exec.Command(%q, os.Args[1:]...)
4084+
cmd.Stdin = os.Stdin
4085+
cmd.Stdout = os.Stdout
4086+
err := cmd.Run()
4087+
if err != nil {
4088+
panic(err)
4089+
}
4090+
}
4091+
`, testCC))
4092+
tg.cd(tg.path("src/cc"))
4093+
tg.run("build")
4094+
tg.setenv("CC", tg.path("src/cc/cc"))
4095+
tg.tempFile("src/cgo/cgo.go", `package main
4096+
// #cgo CFLAGS: -I"c flags"
4097+
// #cgo LDFLAGS: -L"ld flags"
4098+
import "C"
4099+
func main() {}
4100+
`)
4101+
path := tg.path("src/cgo/cgo.go")
4102+
tg.run("run", path)
4103+
}

src/go/build/build.go

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,16 +1302,15 @@ func expandSrcDir(str string, srcdir string) (string, bool) {
13021302
// to "/" before starting (eg: on windows).
13031303
srcdir = filepath.ToSlash(srcdir)
13041304

1305-
// Spaces are tolerated in ${SRCDIR}, but not anywhere else.
13061305
chunks := strings.Split(str, "${SRCDIR}")
13071306
if len(chunks) < 2 {
1308-
return str, safeCgoName(str, false)
1307+
return str, safeCgoName(str)
13091308
}
13101309
ok := true
13111310
for _, chunk := range chunks {
1312-
ok = ok && (chunk == "" || safeCgoName(chunk, false))
1311+
ok = ok && (chunk == "" || safeCgoName(chunk))
13131312
}
1314-
ok = ok && (srcdir == "" || safeCgoName(srcdir, true))
1313+
ok = ok && (srcdir == "" || safeCgoName(srcdir))
13151314
res := strings.Join(chunks, srcdir)
13161315
return res, ok && res != ""
13171316
}
@@ -1321,21 +1320,14 @@ func expandSrcDir(str string, srcdir string) (string, bool) {
13211320
// See golang.org/issue/6038.
13221321
// The @ is for OS X. See golang.org/issue/13720.
13231322
// The % is for Jenkins. See golang.org/issue/16959.
1324-
const safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$@%"
1325-
const safeSpaces = " "
1323+
const safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$@% "
13261324

1327-
var safeBytes = []byte(safeSpaces + safeString)
1328-
1329-
func safeCgoName(s string, spaces bool) bool {
1325+
func safeCgoName(s string) bool {
13301326
if s == "" {
13311327
return false
13321328
}
1333-
safe := safeBytes
1334-
if !spaces {
1335-
safe = safe[len(safeSpaces):]
1336-
}
13371329
for i := 0; i < len(s); i++ {
1338-
if c := s[i]; c < utf8.RuneSelf && bytes.IndexByte(safe, c) < 0 {
1330+
if c := s[i]; c < utf8.RuneSelf && strings.IndexByte(safeString, c) < 0 {
13391331
return false
13401332
}
13411333
}

src/go/build/build_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,11 @@ func TestShellSafety(t *testing.T) {
285285
{"-I${SRCDIR}/../include", "/projects/src/issue 11868", "-I/projects/src/issue 11868/../include", true},
286286
{"-I${SRCDIR}", "wtf$@%", "-Iwtf$@%", true},
287287
{"-X${SRCDIR}/1,${SRCDIR}/2", "/projects/src/issue 11868", "-X/projects/src/issue 11868/1,/projects/src/issue 11868/2", true},
288-
{"-I/tmp -I/tmp", "/tmp2", "-I/tmp -I/tmp", false},
288+
{"-I/tmp -I/tmp", "/tmp2", "-I/tmp -I/tmp", true},
289289
{"-I/tmp", "/tmp/[0]", "-I/tmp", true},
290290
{"-I${SRCDIR}/dir", "/tmp/[0]", "-I/tmp/[0]/dir", false},
291+
{"-I${SRCDIR}/dir", "/tmp/go go", "-I/tmp/go go/dir", true},
292+
{"-I${SRCDIR}/dir dir", "/tmp/go", "-I/tmp/go/dir dir", true},
291293
}
292294
for _, test := range tests {
293295
output, ok := expandSrcDir(test.input, test.srcdir)

0 commit comments

Comments
 (0)