diff --git a/go.mod b/go.mod index dd9aa34..278b8be 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module mvdan.cc/garble go 1.14 -require github.com/rogpeppe/go-internal v1.5.0 +require ( + github.com/rogpeppe/go-internal v1.5.0 + golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd +) diff --git a/go.sum b/go.sum index 72d9f51..0520a94 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,19 @@ +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/rogpeppe/go-internal v1.5.0 h1:Usqs0/lDK/NqTkvrmKSwA/3XkZAs7ZAW/eLeQ2MVBTw= github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd h1:Zc7EU2PqpsNeIfOoVA7hvQX4cS3YDJEs5KlfatT3hLo= +golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= diff --git a/main.go b/main.go index 17d4b60..3432415 100644 --- a/main.go +++ b/main.go @@ -22,6 +22,8 @@ import ( "os/exec" "path/filepath" "strings" + + "golang.org/x/tools/go/ast/astutil" ) var flagSet = flag.NewFlagSet("garble", flag.ContinueOnError) @@ -186,8 +188,9 @@ func transformCompile(args []string) ([]string, error) { return nil, fmt.Errorf("typecheck error: %v", err) } - for i, file := range files { - file := transformGoFile(file, info) + args = flags + for _, file := range files { + file := transformGo(file, info) f, err := ioutil.TempFile("", "garble") if err != nil { return nil, err @@ -203,9 +206,9 @@ func transformCompile(args []string) ([]string, error) { deferred = append(deferred, func() error { return os.Remove(f.Name()) }) - paths[i] = f.Name() + args = append(args, f.Name()) } - return append(flags, paths...), nil + return args, nil } func readBuildIDs(flags []string) error { @@ -284,12 +287,14 @@ func hashWith(salt, value string) string { return "z" + sum[:length] } -// transformGoFile creates a garbled copy of the Go file at path, and returns -// the path to the copy. -func transformGoFile(file *ast.File, info *types.Info) *ast.File { - ast.Inspect(file, func(node ast.Node) bool { - switch node := node.(type) { +// transformGo garbles the provided Go syntax node. +func transformGo(node ast.Node, info *types.Info) ast.Node { + pre := func(cursor *astutil.Cursor) bool { + switch node := cursor.Node().(type) { case *ast.Ident: + if node.Name == "_" { + return true // unnamed remains unnamed + } obj := info.ObjectOf(node) switch obj.(type) { case *types.Var: @@ -300,28 +305,36 @@ func transformGoFile(file *ast.File, info *types.Info) *ast.File { case "main", "init": return true // don't break them } + case nil: + switch cursor.Parent().(type) { + case *ast.AssignStmt: + // symbolic var v in v := expr.(type) + default: + return true + } default: return true // we only want to rename the above } - pkg := obj.Pkg() - if pkg == nil { - return true // universe scope - } - path := pkg.Path() - if !strings.Contains(path, ".") { - return true // std isn't transformed - } - buildID := buildInfo.buildID - if id := buildInfo.imports[path].buildID; id != "" { - buildID = id + if obj != nil { + pkg := obj.Pkg() + if pkg == nil { + return true // universe scope + } + path := pkg.Path() + if !strings.Contains(path, ".") { + return true // std isn't transformed + } + if id := buildInfo.imports[path].buildID; id != "" { + buildID = id + } } // log.Printf("%#v\n", node.Obj) node.Name = hashWith(buildID, node.Name) } return true - }) - return file + } + return astutil.Apply(node, pre, nil) } func transformLink(args []string) ([]string, error) { diff --git a/testdata/scripts/syntax.txt b/testdata/scripts/syntax.txt new file mode 100644 index 0000000..8147e88 --- /dev/null +++ b/testdata/scripts/syntax.txt @@ -0,0 +1,19 @@ +garble build main.go +exec ./main +cmp stderr main.stderr + +-- main.go -- +package main + +var V interface{} + +func main() { + switch V := V.(type) { + case int: + var _ int = V + case nil: + println("nil case") + } +} +-- main.stderr -- +nil case