Skip to content

Commit

Permalink
cmd/cgo: reject names that are likely to be mangled C name
Browse files Browse the repository at this point in the history
Fixes golang#28721

Change-Id: I00356f3a9b0c2fb21dc9c2237dd5296fcb3b319b
Reviewed-on: https://go-review.googlesource.com/c/152657
Run-TryBot: Ian Lance Taylor <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
  • Loading branch information
hirochachacha authored and ianlancetaylor committed Dec 5, 2018
1 parent 897e080 commit 5e17278
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 1 deletion.
1 change: 1 addition & 0 deletions misc/cgo/errors/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ func TestReportsTypeErrors(t *testing.T) {
"issue16591.go",
"issue18452.go",
"issue18889.go",
"issue28721.go",
} {
check(t, file)
}
Expand Down
29 changes: 29 additions & 0 deletions misc/cgo/errors/src/issue28721.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// cgo should reject the use of mangled C names.

package main

/*
typedef struct a {
int i;
} a;
void fn(void) {}
*/
import "C"

type B _Ctype_struct_a // ERROR HERE

var a _Ctype_struct_a // ERROR HERE

type A struct {
a *_Ctype_struct_a // ERROR HERE
}

var notExist _Ctype_NotExist // ERROR HERE

func main() {
_Cfunc_fn() // ERROR HERE
}
9 changes: 9 additions & 0 deletions src/cmd/cgo/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ func (f *File) ParseGo(name string, src []byte) {
if f.Ref == nil {
f.Ref = make([]*Ref, 0, 8)
}
f.walk(ast2, ctxProg, (*File).validateIdents)
f.walk(ast2, ctxProg, (*File).saveExprs)

// Accumulate exported functions.
Expand Down Expand Up @@ -181,6 +182,14 @@ func commentText(g *ast.CommentGroup) string {
return strings.Join(pieces, "")
}

func (f *File) validateIdents(x interface{}, context astContext) {
if x, ok := x.(*ast.Ident); ok {
if f.isMangledName(x.Name) {
error_(x.Pos(), "identifier %q may conflict with identifiers generated by cgo", x.Name)
}
}
}

// Save various references we are going to need later.
func (f *File) saveExprs(x interface{}, context astContext) {
switch x := x.(type) {
Expand Down
13 changes: 13 additions & 0 deletions src/cmd/cgo/gcc.go
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,19 @@ func (p *Package) mangleName(n *Name) {
n.Mangle = prefix + n.Kind + "_" + n.Go
}

func (f *File) isMangledName(s string) bool {
prefix := "_C"
if strings.HasPrefix(s, prefix) {
t := s[len(prefix):]
for _, k := range nameKinds {
if strings.HasPrefix(t, k+"_") {
return true
}
}
}
return false
}

// rewriteCalls rewrites all calls that pass pointers to check that
// they follow the rules for passing pointers between Go and C.
// This reports whether the package needs to import unsafe as _cgo_unsafe.
Expand Down
4 changes: 3 additions & 1 deletion src/cmd/cgo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,15 @@ func (r *Ref) Pos() token.Pos {
return (*r.Expr).Pos()
}

var nameKinds = []string{"iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "macro", "not-type"}

// A Name collects information about C.xxx.
type Name struct {
Go string // name used in Go referring to package C
Mangle string // name used in generated Go
C string // name used in C
Define string // #define expansion
Kind string // "iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "macro", "not-type"
Kind string // one of the nameKinds
Type *Type // the type of xxx
FuncType *FuncType
AddError bool
Expand Down

0 comments on commit 5e17278

Please sign in to comment.