@@ -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+ 
12301256func  mkname (sym  * types.Sym ) * Node  {
12311257	n  :=  oldname (sym )
12321258	if  n .Name  !=  nil  &&  n .Name .Pack  !=  nil  {
0 commit comments