Skip to content

Commit 50f6572

Browse files
ianlancetaylorandybons
authored andcommitted
[release-branch.go1.9] cmd/compile: permit go:cgo_import_dynamic anywhere
It's used on Solaris to import symbols from shared libraries, e.g., in golang.org/x/sys/unix and golang.org/x/net/internal/socket. We could use a different directive but that would require build tags in all the places that use it. Fixes #23939 Change-Id: I47fcf72a6d2862e304204705979c2056c2f78ec5 Reviewed-on: https://go-review.googlesource.com/94018 Run-TryBot: Andrew Bonventre <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> (cherry picked from commit 41d3d15) Reviewed-on: https://go-review.googlesource.com/110077 Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 93cfaa0 commit 50f6572

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

src/cmd/compile/internal/gc/noder.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1190,8 +1190,22 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
11901190
}
11911191
p.linknames = append(p.linknames, linkname{pos, f[1], f[2]})
11921192

1193+
case strings.HasPrefix(text, "go:cgo_import_dynamic "):
1194+
// This is permitted for general use because Solaris
1195+
// code relies on it in golang.org/x/sys/unix and others.
1196+
fields := pragmaFields(text)
1197+
if len(fields) >= 4 {
1198+
lib := strings.Trim(fields[3], `"`)
1199+
if lib != "" && !safeArg(lib) && !isCgoGeneratedFile(pos) {
1200+
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("invalid library name %q in cgo_import_dynamic directive", lib)})
1201+
}
1202+
p.pragcgobuf += p.pragcgo(pos, text)
1203+
return pragmaValue("go:cgo_import_dynamic")
1204+
}
1205+
fallthrough
11931206
case strings.HasPrefix(text, "go:cgo_"):
1194-
// For security, we disallow //go:cgo_* directives outside cgo-generated files.
1207+
// For security, we disallow //go:cgo_* directives other
1208+
// than cgo_import_dynamic outside cgo-generated files.
11951209
// Exception: they are allowed in the standard library, for runtime and syscall.
11961210
if !isCgoGeneratedFile(pos) && !compiling_std {
11971211
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in cgo-generated code", text)})
@@ -1227,6 +1241,18 @@ func isCgoGeneratedFile(pos src.Pos) bool {
12271241
return strings.HasPrefix(filepath.Base(filepath.Clean(pos.AbsFilename())), "_cgo_")
12281242
}
12291243

1244+
// safeArg reports whether arg is a "safe" command-line argument,
1245+
// meaning that when it appears in a command-line, it probably
1246+
// doesn't have some special meaning other than its own name.
1247+
// This is copied from SafeArg in cmd/go/internal/load/pkg.go.
1248+
func safeArg(name string) bool {
1249+
if name == "" {
1250+
return false
1251+
}
1252+
c := name[0]
1253+
return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
1254+
}
1255+
12301256
func mkname(sym *types.Sym) *Node {
12311257
n := oldname(sym)
12321258
if n.Name != nil && n.Name.Pack != nil {

src/cmd/go/internal/load/pkg.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) *Package
12181218
// GNU binutils flagfile specifiers, sometimes called "response files").
12191219
// To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII.
12201220
// We accept leading . _ and / as likely in file system paths.
1221+
// There is a copy of this function in cmd/compile/internal/gc/noder.go.
12211222
func SafeArg(name string) bool {
12221223
if name == "" {
12231224
return false

0 commit comments

Comments
 (0)