@@ -1190,8 +1190,22 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
1190
1190
}
1191
1191
p .linknames = append (p .linknames , linkname {pos , f [1 ], f [2 ]})
1192
1192
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
1193
1206
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.
1195
1209
// Exception: they are allowed in the standard library, for runtime and syscall.
1196
1210
if ! isCgoGeneratedFile (pos ) && ! compiling_std {
1197
1211
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 {
1227
1241
return strings .HasPrefix (filepath .Base (filepath .Clean (pos .AbsFilename ())), "_cgo_" )
1228
1242
}
1229
1243
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
+
1230
1256
func mkname (sym * types.Sym ) * Node {
1231
1257
n := oldname (sym )
1232
1258
if n .Name != nil && n .Name .Pack != nil {
0 commit comments