// 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.

// The unmarshal package defines an Analyzer that checks for passing
// non-pointer or non-interface types to unmarshal and decode functions.
package unmarshal

import (
	"go/ast"
	"go/types"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/inspect"
	"golang.org/x/tools/go/ast/inspector"
	"golang.org/x/tools/go/types/typeutil"
)

const Doc = `report passing non-pointer or non-interface values to unmarshal

The unmarshal analysis reports calls to functions such as json.Unmarshal
in which the argument type is not a pointer or an interface.`

var Analyzer = &analysis.Analyzer{
	Name:     "unmarshal",
	Doc:      Doc,
	Requires: []*analysis.Analyzer{inspect.Analyzer},
	Run:      run,
}

func run(pass *analysis.Pass) (interface{}, error) {
	switch pass.Pkg.Path() {
	case "encoding/gob", "encoding/json", "encoding/xml", "encoding/asn1":
		// These packages know how to use their own APIs.
		// Sometimes they are testing what happens to incorrect programs.
		return nil, nil
	}

	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)

	nodeFilter := []ast.Node{
		(*ast.CallExpr)(nil),
	}
	inspect.Preorder(nodeFilter, func(n ast.Node) {
		call := n.(*ast.CallExpr)
		fn := typeutil.StaticCallee(pass.TypesInfo, call)
		if fn == nil {
			return // not a static call
		}

		// Classify the callee (without allocating memory).
		argidx := -1
		recv := fn.Type().(*types.Signature).Recv()
		if fn.Name() == "Unmarshal" && recv == nil {
			// "encoding/json".Unmarshal
			// "encoding/xml".Unmarshal
			// "encoding/asn1".Unmarshal
			switch fn.Pkg().Path() {
			case "encoding/json", "encoding/xml", "encoding/asn1":
				argidx = 1 // func([]byte, interface{})
			}
		} else if fn.Name() == "Decode" && recv != nil {
			// (*"encoding/json".Decoder).Decode
			// (* "encoding/gob".Decoder).Decode
			// (* "encoding/xml".Decoder).Decode
			t := recv.Type()
			if ptr, ok := t.(*types.Pointer); ok {
				t = ptr.Elem()
			}
			tname := t.(*types.Named).Obj()
			if tname.Name() == "Decoder" {
				switch tname.Pkg().Path() {
				case "encoding/json", "encoding/xml", "encoding/gob":
					argidx = 0 // func(interface{})
				}
			}
		}
		if argidx < 0 {
			return // not a function we are interested in
		}

		if len(call.Args) < argidx+1 {
			return // not enough arguments, e.g. called with return values of another function
		}

		t := pass.TypesInfo.Types[call.Args[argidx]].Type
		switch t.Underlying().(type) {
		case *types.Pointer, *types.Interface:
			return
		}

		switch argidx {
		case 0:
			pass.Reportf(call.Lparen, "call of %s passes non-pointer", fn.Name())
		case 1:
			pass.Reportf(call.Lparen, "call of %s passes non-pointer as second argument", fn.Name())
		}
	})
	return nil, nil
}
