1// Copyright 2010 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package printf defines an Analyzer that checks consistency
6// of Printf format strings and arguments.
7package printf
8
9import (
10	"bytes"
11	"fmt"
12	"go/ast"
13	"go/constant"
14	"go/token"
15	"go/types"
16	"reflect"
17	"regexp"
18	"sort"
19	"strconv"
20	"strings"
21	"unicode/utf8"
22
23	"golang.org/x/tools/go/analysis"
24	"golang.org/x/tools/go/analysis/passes/inspect"
25	"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
26	"golang.org/x/tools/go/ast/inspector"
27	"golang.org/x/tools/go/types/typeutil"
28)
29
30func init() {
31	Analyzer.Flags.Var(isPrint, "funcs", "comma-separated list of print function names to check")
32}
33
34var Analyzer = &analysis.Analyzer{
35	Name:       "printf",
36	Doc:        Doc,
37	Requires:   []*analysis.Analyzer{inspect.Analyzer},
38	Run:        run,
39	ResultType: reflect.TypeOf((*Result)(nil)),
40	FactTypes:  []analysis.Fact{new(isWrapper)},
41}
42
43const Doc = `check consistency of Printf format strings and arguments
44
45The check applies to known functions (for example, those in package fmt)
46as well as any detected wrappers of known functions.
47
48A function that wants to avail itself of printf checking but is not
49found by this analyzer's heuristics (for example, due to use of
50dynamic calls) can insert a bogus call:
51
52	if false {
53		_ = fmt.Sprintf(format, args...) // enable printf checking
54	}
55
56The -funcs flag specifies a comma-separated list of names of additional
57known formatting functions or methods. If the name contains a period,
58it must denote a specific function using one of the following forms:
59
60	dir/pkg.Function
61	dir/pkg.Type.Method
62	(*dir/pkg.Type).Method
63
64Otherwise the name is interpreted as a case-insensitive unqualified
65identifier such as "errorf". Either way, if a listed name ends in f, the
66function is assumed to be Printf-like, taking a format string before the
67argument list. Otherwise it is assumed to be Print-like, taking a list
68of arguments with no format string.
69`
70
71// Kind is a kind of fmt function behavior.
72type Kind int
73
74const (
75	KindNone   Kind = iota // not a fmt wrapper function
76	KindPrint              // function behaves like fmt.Print
77	KindPrintf             // function behaves like fmt.Printf
78	KindErrorf             // function behaves like fmt.Errorf
79)
80
81func (kind Kind) String() string {
82	switch kind {
83	case KindPrint:
84		return "print"
85	case KindPrintf:
86		return "printf"
87	case KindErrorf:
88		return "errorf"
89	}
90	return ""
91}
92
93// Result is the printf analyzer's result type. Clients may query the result
94// to learn whether a function behaves like fmt.Print or fmt.Printf.
95type Result struct {
96	funcs map[*types.Func]Kind
97}
98
99// Kind reports whether fn behaves like fmt.Print or fmt.Printf.
100func (r *Result) Kind(fn *types.Func) Kind {
101	_, ok := isPrint[fn.FullName()]
102	if !ok {
103		// Next look up just "printf", for use with -printf.funcs.
104		_, ok = isPrint[strings.ToLower(fn.Name())]
105	}
106	if ok {
107		if strings.HasSuffix(fn.Name(), "f") {
108			return KindPrintf
109		} else {
110			return KindPrint
111		}
112	}
113
114	return r.funcs[fn]
115}
116
117// isWrapper is a fact indicating that a function is a print or printf wrapper.
118type isWrapper struct{ Kind Kind }
119
120func (f *isWrapper) AFact() {}
121
122func (f *isWrapper) String() string {
123	switch f.Kind {
124	case KindPrintf:
125		return "printfWrapper"
126	case KindPrint:
127		return "printWrapper"
128	case KindErrorf:
129		return "errorfWrapper"
130	default:
131		return "unknownWrapper"
132	}
133}
134
135func run(pass *analysis.Pass) (interface{}, error) {
136	res := &Result{
137		funcs: make(map[*types.Func]Kind),
138	}
139	findPrintfLike(pass, res)
140	checkCall(pass)
141	return res, nil
142}
143
144type printfWrapper struct {
145	obj     *types.Func
146	fdecl   *ast.FuncDecl
147	format  *types.Var
148	args    *types.Var
149	callers []printfCaller
150	failed  bool // if true, not a printf wrapper
151}
152
153type printfCaller struct {
154	w    *printfWrapper
155	call *ast.CallExpr
156}
157
158// maybePrintfWrapper decides whether decl (a declared function) may be a wrapper
159// around a fmt.Printf or fmt.Print function. If so it returns a printfWrapper
160// function describing the declaration. Later processing will analyze the
161// graph of potential printf wrappers to pick out the ones that are true wrappers.
162// A function may be a Printf or Print wrapper if its last argument is ...interface{}.
163// If the next-to-last argument is a string, then this may be a Printf wrapper.
164// Otherwise it may be a Print wrapper.
165func maybePrintfWrapper(info *types.Info, decl ast.Decl) *printfWrapper {
166	// Look for functions with final argument type ...interface{}.
167	fdecl, ok := decl.(*ast.FuncDecl)
168	if !ok || fdecl.Body == nil {
169		return nil
170	}
171	fn, ok := info.Defs[fdecl.Name].(*types.Func)
172	// Type information may be incomplete.
173	if !ok {
174		return nil
175	}
176
177	sig := fn.Type().(*types.Signature)
178	if !sig.Variadic() {
179		return nil // not variadic
180	}
181
182	params := sig.Params()
183	nparams := params.Len() // variadic => nonzero
184
185	args := params.At(nparams - 1)
186	iface, ok := args.Type().(*types.Slice).Elem().(*types.Interface)
187	if !ok || !iface.Empty() {
188		return nil // final (args) param is not ...interface{}
189	}
190
191	// Is second last param 'format string'?
192	var format *types.Var
193	if nparams >= 2 {
194		if p := params.At(nparams - 2); p.Type() == types.Typ[types.String] {
195			format = p
196		}
197	}
198
199	return &printfWrapper{
200		obj:    fn,
201		fdecl:  fdecl,
202		format: format,
203		args:   args,
204	}
205}
206
207// findPrintfLike scans the entire package to find printf-like functions.
208func findPrintfLike(pass *analysis.Pass, res *Result) (interface{}, error) {
209	// Gather potential wrappers and call graph between them.
210	byObj := make(map[*types.Func]*printfWrapper)
211	var wrappers []*printfWrapper
212	for _, file := range pass.Files {
213		for _, decl := range file.Decls {
214			w := maybePrintfWrapper(pass.TypesInfo, decl)
215			if w == nil {
216				continue
217			}
218			byObj[w.obj] = w
219			wrappers = append(wrappers, w)
220		}
221	}
222
223	// Walk the graph to figure out which are really printf wrappers.
224	for _, w := range wrappers {
225		// Scan function for calls that could be to other printf-like functions.
226		ast.Inspect(w.fdecl.Body, func(n ast.Node) bool {
227			if w.failed {
228				return false
229			}
230
231			// TODO: Relax these checks; issue 26555.
232			if assign, ok := n.(*ast.AssignStmt); ok {
233				for _, lhs := range assign.Lhs {
234					if match(pass.TypesInfo, lhs, w.format) ||
235						match(pass.TypesInfo, lhs, w.args) {
236						// Modifies the format
237						// string or args in
238						// some way, so not a
239						// simple wrapper.
240						w.failed = true
241						return false
242					}
243				}
244			}
245			if un, ok := n.(*ast.UnaryExpr); ok && un.Op == token.AND {
246				if match(pass.TypesInfo, un.X, w.format) ||
247					match(pass.TypesInfo, un.X, w.args) {
248					// Taking the address of the
249					// format string or args,
250					// so not a simple wrapper.
251					w.failed = true
252					return false
253				}
254			}
255
256			call, ok := n.(*ast.CallExpr)
257			if !ok || len(call.Args) == 0 || !match(pass.TypesInfo, call.Args[len(call.Args)-1], w.args) {
258				return true
259			}
260
261			fn, kind := printfNameAndKind(pass, call)
262			if kind != 0 {
263				checkPrintfFwd(pass, w, call, kind, res)
264				return true
265			}
266
267			// If the call is to another function in this package,
268			// maybe we will find out it is printf-like later.
269			// Remember this call for later checking.
270			if fn != nil && fn.Pkg() == pass.Pkg && byObj[fn] != nil {
271				callee := byObj[fn]
272				callee.callers = append(callee.callers, printfCaller{w, call})
273			}
274
275			return true
276		})
277	}
278	return nil, nil
279}
280
281func match(info *types.Info, arg ast.Expr, param *types.Var) bool {
282	id, ok := arg.(*ast.Ident)
283	return ok && info.ObjectOf(id) == param
284}
285
286// checkPrintfFwd checks that a printf-forwarding wrapper is forwarding correctly.
287// It diagnoses writing fmt.Printf(format, args) instead of fmt.Printf(format, args...).
288func checkPrintfFwd(pass *analysis.Pass, w *printfWrapper, call *ast.CallExpr, kind Kind, res *Result) {
289	matched := kind == KindPrint ||
290		kind != KindNone && len(call.Args) >= 2 && match(pass.TypesInfo, call.Args[len(call.Args)-2], w.format)
291	if !matched {
292		return
293	}
294
295	if !call.Ellipsis.IsValid() {
296		typ, ok := pass.TypesInfo.Types[call.Fun].Type.(*types.Signature)
297		if !ok {
298			return
299		}
300		if len(call.Args) > typ.Params().Len() {
301			// If we're passing more arguments than what the
302			// print/printf function can take, adding an ellipsis
303			// would break the program. For example:
304			//
305			//   func foo(arg1 string, arg2 ...interface{} {
306			//       fmt.Printf("%s %v", arg1, arg2)
307			//   }
308			return
309		}
310		desc := "printf"
311		if kind == KindPrint {
312			desc = "print"
313		}
314		pass.ReportRangef(call, "missing ... in args forwarded to %s-like function", desc)
315		return
316	}
317	fn := w.obj
318	var fact isWrapper
319	if !pass.ImportObjectFact(fn, &fact) {
320		fact.Kind = kind
321		pass.ExportObjectFact(fn, &fact)
322		res.funcs[fn] = kind
323		for _, caller := range w.callers {
324			checkPrintfFwd(pass, caller.w, caller.call, kind, res)
325		}
326	}
327}
328
329// isPrint records the print functions.
330// If a key ends in 'f' then it is assumed to be a formatted print.
331//
332// Keys are either values returned by (*types.Func).FullName,
333// or case-insensitive identifiers such as "errorf".
334//
335// The -funcs flag adds to this set.
336//
337// The set below includes facts for many important standard library
338// functions, even though the analysis is capable of deducing that, for
339// example, fmt.Printf forwards to fmt.Fprintf. We avoid relying on the
340// driver applying analyzers to standard packages because "go vet" does
341// not do so with gccgo, and nor do some other build systems.
342// TODO(adonovan): eliminate the redundant facts once this restriction
343// is lifted.
344//
345var isPrint = stringSet{
346	"fmt.Errorf":   true,
347	"fmt.Fprint":   true,
348	"fmt.Fprintf":  true,
349	"fmt.Fprintln": true,
350	"fmt.Print":    true,
351	"fmt.Printf":   true,
352	"fmt.Println":  true,
353	"fmt.Sprint":   true,
354	"fmt.Sprintf":  true,
355	"fmt.Sprintln": true,
356
357	"runtime/trace.Logf": true,
358
359	"log.Print":             true,
360	"log.Printf":            true,
361	"log.Println":           true,
362	"log.Fatal":             true,
363	"log.Fatalf":            true,
364	"log.Fatalln":           true,
365	"log.Panic":             true,
366	"log.Panicf":            true,
367	"log.Panicln":           true,
368	"(*log.Logger).Fatal":   true,
369	"(*log.Logger).Fatalf":  true,
370	"(*log.Logger).Fatalln": true,
371	"(*log.Logger).Panic":   true,
372	"(*log.Logger).Panicf":  true,
373	"(*log.Logger).Panicln": true,
374	"(*log.Logger).Print":   true,
375	"(*log.Logger).Printf":  true,
376	"(*log.Logger).Println": true,
377
378	"(*testing.common).Error":  true,
379	"(*testing.common).Errorf": true,
380	"(*testing.common).Fatal":  true,
381	"(*testing.common).Fatalf": true,
382	"(*testing.common).Log":    true,
383	"(*testing.common).Logf":   true,
384	"(*testing.common).Skip":   true,
385	"(*testing.common).Skipf":  true,
386	// *testing.T and B are detected by induction, but testing.TB is
387	// an interface and the inference can't follow dynamic calls.
388	"(testing.TB).Error":  true,
389	"(testing.TB).Errorf": true,
390	"(testing.TB).Fatal":  true,
391	"(testing.TB).Fatalf": true,
392	"(testing.TB).Log":    true,
393	"(testing.TB).Logf":   true,
394	"(testing.TB).Skip":   true,
395	"(testing.TB).Skipf":  true,
396}
397
398// formatString returns the format string argument and its index within
399// the given printf-like call expression.
400//
401// The last parameter before variadic arguments is assumed to be
402// a format string.
403//
404// The first string literal or string constant is assumed to be a format string
405// if the call's signature cannot be determined.
406//
407// If it cannot find any format string parameter, it returns ("", -1).
408func formatString(pass *analysis.Pass, call *ast.CallExpr) (format string, idx int) {
409	typ := pass.TypesInfo.Types[call.Fun].Type
410	if typ != nil {
411		if sig, ok := typ.(*types.Signature); ok {
412			if !sig.Variadic() {
413				// Skip checking non-variadic functions.
414				return "", -1
415			}
416			idx := sig.Params().Len() - 2
417			if idx < 0 {
418				// Skip checking variadic functions without
419				// fixed arguments.
420				return "", -1
421			}
422			s, ok := stringConstantArg(pass, call, idx)
423			if !ok {
424				// The last argument before variadic args isn't a string.
425				return "", -1
426			}
427			return s, idx
428		}
429	}
430
431	// Cannot determine call's signature. Fall back to scanning for the first
432	// string constant in the call.
433	for idx := range call.Args {
434		if s, ok := stringConstantArg(pass, call, idx); ok {
435			return s, idx
436		}
437		if pass.TypesInfo.Types[call.Args[idx]].Type == types.Typ[types.String] {
438			// Skip checking a call with a non-constant format
439			// string argument, since its contents are unavailable
440			// for validation.
441			return "", -1
442		}
443	}
444	return "", -1
445}
446
447// stringConstantArg returns call's string constant argument at the index idx.
448//
449// ("", false) is returned if call's argument at the index idx isn't a string
450// constant.
451func stringConstantArg(pass *analysis.Pass, call *ast.CallExpr, idx int) (string, bool) {
452	if idx >= len(call.Args) {
453		return "", false
454	}
455	arg := call.Args[idx]
456	lit := pass.TypesInfo.Types[arg].Value
457	if lit != nil && lit.Kind() == constant.String {
458		return constant.StringVal(lit), true
459	}
460	return "", false
461}
462
463// checkCall triggers the print-specific checks if the call invokes a print function.
464func checkCall(pass *analysis.Pass) {
465	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
466	nodeFilter := []ast.Node{
467		(*ast.CallExpr)(nil),
468	}
469	inspect.Preorder(nodeFilter, func(n ast.Node) {
470		call := n.(*ast.CallExpr)
471		fn, kind := printfNameAndKind(pass, call)
472		switch kind {
473		case KindPrintf, KindErrorf:
474			checkPrintf(pass, kind, call, fn)
475		case KindPrint:
476			checkPrint(pass, call, fn)
477		}
478	})
479}
480
481func printfNameAndKind(pass *analysis.Pass, call *ast.CallExpr) (fn *types.Func, kind Kind) {
482	fn, _ = typeutil.Callee(pass.TypesInfo, call).(*types.Func)
483	if fn == nil {
484		return nil, 0
485	}
486
487	_, ok := isPrint[fn.FullName()]
488	if !ok {
489		// Next look up just "printf", for use with -printf.funcs.
490		_, ok = isPrint[strings.ToLower(fn.Name())]
491	}
492	if ok {
493		if fn.Name() == "Errorf" {
494			kind = KindErrorf
495		} else if strings.HasSuffix(fn.Name(), "f") {
496			kind = KindPrintf
497		} else {
498			kind = KindPrint
499		}
500		return fn, kind
501	}
502
503	var fact isWrapper
504	if pass.ImportObjectFact(fn, &fact) {
505		return fn, fact.Kind
506	}
507
508	return fn, KindNone
509}
510
511// isFormatter reports whether t could satisfy fmt.Formatter.
512// The only interface method to look for is "Format(State, rune)".
513func isFormatter(typ types.Type) bool {
514	// If the type is an interface, the value it holds might satisfy fmt.Formatter.
515	if _, ok := typ.Underlying().(*types.Interface); ok {
516		return true
517	}
518	obj, _, _ := types.LookupFieldOrMethod(typ, false, nil, "Format")
519	fn, ok := obj.(*types.Func)
520	if !ok {
521		return false
522	}
523	sig := fn.Type().(*types.Signature)
524	return sig.Params().Len() == 2 &&
525		sig.Results().Len() == 0 &&
526		isNamed(sig.Params().At(0).Type(), "fmt", "State") &&
527		types.Identical(sig.Params().At(1).Type(), types.Typ[types.Rune])
528}
529
530func isNamed(T types.Type, pkgpath, name string) bool {
531	named, ok := T.(*types.Named)
532	return ok && named.Obj().Pkg().Path() == pkgpath && named.Obj().Name() == name
533}
534
535// formatState holds the parsed representation of a printf directive such as "%3.*[4]d".
536// It is constructed by parsePrintfVerb.
537type formatState struct {
538	verb     rune   // the format verb: 'd' for "%d"
539	format   string // the full format directive from % through verb, "%.3d".
540	name     string // Printf, Sprintf etc.
541	flags    []byte // the list of # + etc.
542	argNums  []int  // the successive argument numbers that are consumed, adjusted to refer to actual arg in call
543	firstArg int    // Index of first argument after the format in the Printf call.
544	// Used only during parse.
545	pass         *analysis.Pass
546	call         *ast.CallExpr
547	argNum       int  // Which argument we're expecting to format now.
548	hasIndex     bool // Whether the argument is indexed.
549	indexPending bool // Whether we have an indexed argument that has not resolved.
550	nbytes       int  // number of bytes of the format string consumed.
551}
552
553// checkPrintf checks a call to a formatted print routine such as Printf.
554func checkPrintf(pass *analysis.Pass, kind Kind, call *ast.CallExpr, fn *types.Func) {
555	format, idx := formatString(pass, call)
556	if idx < 0 {
557		if false {
558			pass.Reportf(call.Lparen, "can't check non-constant format in call to %s", fn.FullName())
559		}
560		return
561	}
562
563	firstArg := idx + 1 // Arguments are immediately after format string.
564	if !strings.Contains(format, "%") {
565		if len(call.Args) > firstArg {
566			pass.Reportf(call.Lparen, "%s call has arguments but no formatting directives", fn.FullName())
567		}
568		return
569	}
570	// Hard part: check formats against args.
571	argNum := firstArg
572	maxArgNum := firstArg
573	anyIndex := false
574	anyW := false
575	for i, w := 0, 0; i < len(format); i += w {
576		w = 1
577		if format[i] != '%' {
578			continue
579		}
580		state := parsePrintfVerb(pass, call, fn.FullName(), format[i:], firstArg, argNum)
581		if state == nil {
582			return
583		}
584		w = len(state.format)
585		if !okPrintfArg(pass, call, state) { // One error per format is enough.
586			return
587		}
588		if state.hasIndex {
589			anyIndex = true
590		}
591		if state.verb == 'w' {
592			switch kind {
593			case KindNone, KindPrint:
594				pass.Reportf(call.Pos(), "%s does not support error-wrapping directive %%w", state.name)
595				return
596			case KindPrintf:
597				pass.Reportf(call.Pos(), "%s call has error-wrapping directive %%w, which is only supported for functions backed by fmt.Errorf", state.name)
598				return
599			}
600			if anyW {
601				pass.Reportf(call.Pos(), "%s call has more than one error-wrapping directive %%w", state.name)
602				return
603			}
604			anyW = true
605		}
606		if len(state.argNums) > 0 {
607			// Continue with the next sequential argument.
608			argNum = state.argNums[len(state.argNums)-1] + 1
609		}
610		for _, n := range state.argNums {
611			if n >= maxArgNum {
612				maxArgNum = n + 1
613			}
614		}
615	}
616	// Dotdotdot is hard.
617	if call.Ellipsis.IsValid() && maxArgNum >= len(call.Args)-1 {
618		return
619	}
620	// If any formats are indexed, extra arguments are ignored.
621	if anyIndex {
622		return
623	}
624	// There should be no leftover arguments.
625	if maxArgNum != len(call.Args) {
626		expect := maxArgNum - firstArg
627		numArgs := len(call.Args) - firstArg
628		pass.ReportRangef(call, "%s call needs %v but has %v", fn.FullName(), count(expect, "arg"), count(numArgs, "arg"))
629	}
630}
631
632// parseFlags accepts any printf flags.
633func (s *formatState) parseFlags() {
634	for s.nbytes < len(s.format) {
635		switch c := s.format[s.nbytes]; c {
636		case '#', '0', '+', '-', ' ':
637			s.flags = append(s.flags, c)
638			s.nbytes++
639		default:
640			return
641		}
642	}
643}
644
645// scanNum advances through a decimal number if present.
646func (s *formatState) scanNum() {
647	for ; s.nbytes < len(s.format); s.nbytes++ {
648		c := s.format[s.nbytes]
649		if c < '0' || '9' < c {
650			return
651		}
652	}
653}
654
655// parseIndex scans an index expression. It returns false if there is a syntax error.
656func (s *formatState) parseIndex() bool {
657	if s.nbytes == len(s.format) || s.format[s.nbytes] != '[' {
658		return true
659	}
660	// Argument index present.
661	s.nbytes++ // skip '['
662	start := s.nbytes
663	s.scanNum()
664	ok := true
665	if s.nbytes == len(s.format) || s.nbytes == start || s.format[s.nbytes] != ']' {
666		ok = false
667		s.nbytes = strings.Index(s.format, "]")
668		if s.nbytes < 0 {
669			s.pass.ReportRangef(s.call, "%s format %s is missing closing ]", s.name, s.format)
670			return false
671		}
672	}
673	arg32, err := strconv.ParseInt(s.format[start:s.nbytes], 10, 32)
674	if err != nil || !ok || arg32 <= 0 || arg32 > int64(len(s.call.Args)-s.firstArg) {
675		s.pass.ReportRangef(s.call, "%s format has invalid argument index [%s]", s.name, s.format[start:s.nbytes])
676		return false
677	}
678	s.nbytes++ // skip ']'
679	arg := int(arg32)
680	arg += s.firstArg - 1 // We want to zero-index the actual arguments.
681	s.argNum = arg
682	s.hasIndex = true
683	s.indexPending = true
684	return true
685}
686
687// parseNum scans a width or precision (or *). It returns false if there's a bad index expression.
688func (s *formatState) parseNum() bool {
689	if s.nbytes < len(s.format) && s.format[s.nbytes] == '*' {
690		if s.indexPending { // Absorb it.
691			s.indexPending = false
692		}
693		s.nbytes++
694		s.argNums = append(s.argNums, s.argNum)
695		s.argNum++
696	} else {
697		s.scanNum()
698	}
699	return true
700}
701
702// parsePrecision scans for a precision. It returns false if there's a bad index expression.
703func (s *formatState) parsePrecision() bool {
704	// If there's a period, there may be a precision.
705	if s.nbytes < len(s.format) && s.format[s.nbytes] == '.' {
706		s.flags = append(s.flags, '.') // Treat precision as a flag.
707		s.nbytes++
708		if !s.parseIndex() {
709			return false
710		}
711		if !s.parseNum() {
712			return false
713		}
714	}
715	return true
716}
717
718// parsePrintfVerb looks the formatting directive that begins the format string
719// and returns a formatState that encodes what the directive wants, without looking
720// at the actual arguments present in the call. The result is nil if there is an error.
721func parsePrintfVerb(pass *analysis.Pass, call *ast.CallExpr, name, format string, firstArg, argNum int) *formatState {
722	state := &formatState{
723		format:   format,
724		name:     name,
725		flags:    make([]byte, 0, 5),
726		argNum:   argNum,
727		argNums:  make([]int, 0, 1),
728		nbytes:   1, // There's guaranteed to be a percent sign.
729		firstArg: firstArg,
730		pass:     pass,
731		call:     call,
732	}
733	// There may be flags.
734	state.parseFlags()
735	// There may be an index.
736	if !state.parseIndex() {
737		return nil
738	}
739	// There may be a width.
740	if !state.parseNum() {
741		return nil
742	}
743	// There may be a precision.
744	if !state.parsePrecision() {
745		return nil
746	}
747	// Now a verb, possibly prefixed by an index (which we may already have).
748	if !state.indexPending && !state.parseIndex() {
749		return nil
750	}
751	if state.nbytes == len(state.format) {
752		pass.ReportRangef(call.Fun, "%s format %s is missing verb at end of string", name, state.format)
753		return nil
754	}
755	verb, w := utf8.DecodeRuneInString(state.format[state.nbytes:])
756	state.verb = verb
757	state.nbytes += w
758	if verb != '%' {
759		state.argNums = append(state.argNums, state.argNum)
760	}
761	state.format = state.format[:state.nbytes]
762	return state
763}
764
765// printfArgType encodes the types of expressions a printf verb accepts. It is a bitmask.
766type printfArgType int
767
768const (
769	argBool printfArgType = 1 << iota
770	argInt
771	argRune
772	argString
773	argFloat
774	argComplex
775	argPointer
776	argError
777	anyType printfArgType = ^0
778)
779
780type printVerb struct {
781	verb  rune   // User may provide verb through Formatter; could be a rune.
782	flags string // known flags are all ASCII
783	typ   printfArgType
784}
785
786// Common flag sets for printf verbs.
787const (
788	noFlag       = ""
789	numFlag      = " -+.0"
790	sharpNumFlag = " -+.0#"
791	allFlags     = " -+.0#"
792)
793
794// printVerbs identifies which flags are known to printf for each verb.
795var printVerbs = []printVerb{
796	// '-' is a width modifier, always valid.
797	// '.' is a precision for float, max width for strings.
798	// '+' is required sign for numbers, Go format for %v.
799	// '#' is alternate format for several verbs.
800	// ' ' is spacer for numbers
801	{'%', noFlag, 0},
802	{'b', sharpNumFlag, argInt | argFloat | argComplex | argPointer},
803	{'c', "-", argRune | argInt},
804	{'d', numFlag, argInt | argPointer},
805	{'e', sharpNumFlag, argFloat | argComplex},
806	{'E', sharpNumFlag, argFloat | argComplex},
807	{'f', sharpNumFlag, argFloat | argComplex},
808	{'F', sharpNumFlag, argFloat | argComplex},
809	{'g', sharpNumFlag, argFloat | argComplex},
810	{'G', sharpNumFlag, argFloat | argComplex},
811	{'o', sharpNumFlag, argInt | argPointer},
812	{'O', sharpNumFlag, argInt | argPointer},
813	{'p', "-#", argPointer},
814	{'q', " -+.0#", argRune | argInt | argString},
815	{'s', " -+.0", argString},
816	{'t', "-", argBool},
817	{'T', "-", anyType},
818	{'U', "-#", argRune | argInt},
819	{'v', allFlags, anyType},
820	{'w', allFlags, argError},
821	{'x', sharpNumFlag, argRune | argInt | argString | argPointer | argFloat | argComplex},
822	{'X', sharpNumFlag, argRune | argInt | argString | argPointer | argFloat | argComplex},
823}
824
825// okPrintfArg compares the formatState to the arguments actually present,
826// reporting any discrepancies it can discern. If the final argument is ellipsissed,
827// there's little it can do for that.
828func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (ok bool) {
829	var v printVerb
830	found := false
831	// Linear scan is fast enough for a small list.
832	for _, v = range printVerbs {
833		if v.verb == state.verb {
834			found = true
835			break
836		}
837	}
838
839	// Could current arg implement fmt.Formatter?
840	formatter := false
841	if state.argNum < len(call.Args) {
842		if tv, ok := pass.TypesInfo.Types[call.Args[state.argNum]]; ok {
843			formatter = isFormatter(tv.Type)
844		}
845	}
846
847	if !formatter {
848		if !found {
849			pass.ReportRangef(call, "%s format %s has unknown verb %c", state.name, state.format, state.verb)
850			return false
851		}
852		for _, flag := range state.flags {
853			// TODO: Disable complaint about '0' for Go 1.10. To be fixed properly in 1.11.
854			// See issues 23598 and 23605.
855			if flag == '0' {
856				continue
857			}
858			if !strings.ContainsRune(v.flags, rune(flag)) {
859				pass.ReportRangef(call, "%s format %s has unrecognized flag %c", state.name, state.format, flag)
860				return false
861			}
862		}
863	}
864	// Verb is good. If len(state.argNums)>trueArgs, we have something like %.*s and all
865	// but the final arg must be an integer.
866	trueArgs := 1
867	if state.verb == '%' {
868		trueArgs = 0
869	}
870	nargs := len(state.argNums)
871	for i := 0; i < nargs-trueArgs; i++ {
872		argNum := state.argNums[i]
873		if !argCanBeChecked(pass, call, i, state) {
874			return
875		}
876		arg := call.Args[argNum]
877		if !matchArgType(pass, argInt, nil, arg) {
878			pass.ReportRangef(call, "%s format %s uses non-int %s as argument of *", state.name, state.format, analysisutil.Format(pass.Fset, arg))
879			return false
880		}
881	}
882
883	if state.verb == '%' || formatter {
884		return true
885	}
886	argNum := state.argNums[len(state.argNums)-1]
887	if !argCanBeChecked(pass, call, len(state.argNums)-1, state) {
888		return false
889	}
890	arg := call.Args[argNum]
891	if isFunctionValue(pass, arg) && state.verb != 'p' && state.verb != 'T' {
892		pass.ReportRangef(call, "%s format %s arg %s is a func value, not called", state.name, state.format, analysisutil.Format(pass.Fset, arg))
893		return false
894	}
895	if !matchArgType(pass, v.typ, nil, arg) {
896		typeString := ""
897		if typ := pass.TypesInfo.Types[arg].Type; typ != nil {
898			typeString = typ.String()
899		}
900		pass.ReportRangef(call, "%s format %s has arg %s of wrong type %s", state.name, state.format, analysisutil.Format(pass.Fset, arg), typeString)
901		return false
902	}
903	if v.typ&argString != 0 && v.verb != 'T' && !bytes.Contains(state.flags, []byte{'#'}) {
904		if methodName, ok := recursiveStringer(pass, arg); ok {
905			pass.ReportRangef(call, "%s format %s with arg %s causes recursive %s method call", state.name, state.format, analysisutil.Format(pass.Fset, arg), methodName)
906			return false
907		}
908	}
909	return true
910}
911
912// recursiveStringer reports whether the argument e is a potential
913// recursive call to stringer or is an error, such as t and &t in these examples:
914//
915// 	func (t *T) String() string { printf("%s",  t) }
916// 	func (t  T) Error() string { printf("%s",  t) }
917// 	func (t  T) String() string { printf("%s", &t) }
918func recursiveStringer(pass *analysis.Pass, e ast.Expr) (string, bool) {
919	typ := pass.TypesInfo.Types[e].Type
920
921	// It's unlikely to be a recursive stringer if it has a Format method.
922	if isFormatter(typ) {
923		return "", false
924	}
925
926	// Does e allow e.String() or e.Error()?
927	strObj, _, _ := types.LookupFieldOrMethod(typ, false, pass.Pkg, "String")
928	strMethod, strOk := strObj.(*types.Func)
929	errObj, _, _ := types.LookupFieldOrMethod(typ, false, pass.Pkg, "Error")
930	errMethod, errOk := errObj.(*types.Func)
931	if !strOk && !errOk {
932		return "", false
933	}
934
935	// Is the expression e within the body of that String or Error method?
936	var method *types.Func
937	if strOk && strMethod.Pkg() == pass.Pkg && strMethod.Scope().Contains(e.Pos()) {
938		method = strMethod
939	} else if errOk && errMethod.Pkg() == pass.Pkg && errMethod.Scope().Contains(e.Pos()) {
940		method = errMethod
941	} else {
942		return "", false
943	}
944
945	sig := method.Type().(*types.Signature)
946	if !isStringer(sig) {
947		return "", false
948	}
949
950	// Is it the receiver r, or &r?
951	if u, ok := e.(*ast.UnaryExpr); ok && u.Op == token.AND {
952		e = u.X // strip off & from &r
953	}
954	if id, ok := e.(*ast.Ident); ok {
955		if pass.TypesInfo.Uses[id] == sig.Recv() {
956			return method.FullName(), true
957		}
958	}
959	return "", false
960}
961
962// isStringer reports whether the method signature matches the String() definition in fmt.Stringer.
963func isStringer(sig *types.Signature) bool {
964	return sig.Params().Len() == 0 &&
965		sig.Results().Len() == 1 &&
966		sig.Results().At(0).Type() == types.Typ[types.String]
967}
968
969// isFunctionValue reports whether the expression is a function as opposed to a function call.
970// It is almost always a mistake to print a function value.
971func isFunctionValue(pass *analysis.Pass, e ast.Expr) bool {
972	if typ := pass.TypesInfo.Types[e].Type; typ != nil {
973		_, ok := typ.(*types.Signature)
974		return ok
975	}
976	return false
977}
978
979// argCanBeChecked reports whether the specified argument is statically present;
980// it may be beyond the list of arguments or in a terminal slice... argument, which
981// means we can't see it.
982func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, formatArg int, state *formatState) bool {
983	argNum := state.argNums[formatArg]
984	if argNum <= 0 {
985		// Shouldn't happen, so catch it with prejudice.
986		panic("negative arg num")
987	}
988	if argNum < len(call.Args)-1 {
989		return true // Always OK.
990	}
991	if call.Ellipsis.IsValid() {
992		return false // We just can't tell; there could be many more arguments.
993	}
994	if argNum < len(call.Args) {
995		return true
996	}
997	// There are bad indexes in the format or there are fewer arguments than the format needs.
998	// This is the argument number relative to the format: Printf("%s", "hi") will give 1 for the "hi".
999	arg := argNum - state.firstArg + 1 // People think of arguments as 1-indexed.
1000	pass.ReportRangef(call, "%s format %s reads arg #%d, but call has %v", state.name, state.format, arg, count(len(call.Args)-state.firstArg, "arg"))
1001	return false
1002}
1003
1004// printFormatRE is the regexp we match and report as a possible format string
1005// in the first argument to unformatted prints like fmt.Print.
1006// We exclude the space flag, so that printing a string like "x % y" is not reported as a format.
1007var printFormatRE = regexp.MustCompile(`%` + flagsRE + numOptRE + `\.?` + numOptRE + indexOptRE + verbRE)
1008
1009const (
1010	flagsRE    = `[+\-#]*`
1011	indexOptRE = `(\[[0-9]+\])?`
1012	numOptRE   = `([0-9]+|` + indexOptRE + `\*)?`
1013	verbRE     = `[bcdefgopqstvxEFGTUX]`
1014)
1015
1016// checkPrint checks a call to an unformatted print routine such as Println.
1017func checkPrint(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) {
1018	firstArg := 0
1019	typ := pass.TypesInfo.Types[call.Fun].Type
1020	if typ == nil {
1021		// Skip checking functions with unknown type.
1022		return
1023	}
1024	if sig, ok := typ.(*types.Signature); ok {
1025		if !sig.Variadic() {
1026			// Skip checking non-variadic functions.
1027			return
1028		}
1029		params := sig.Params()
1030		firstArg = params.Len() - 1
1031
1032		typ := params.At(firstArg).Type()
1033		typ = typ.(*types.Slice).Elem()
1034		it, ok := typ.(*types.Interface)
1035		if !ok || !it.Empty() {
1036			// Skip variadic functions accepting non-interface{} args.
1037			return
1038		}
1039	}
1040	args := call.Args
1041	if len(args) <= firstArg {
1042		// Skip calls without variadic args.
1043		return
1044	}
1045	args = args[firstArg:]
1046
1047	if firstArg == 0 {
1048		if sel, ok := call.Args[0].(*ast.SelectorExpr); ok {
1049			if x, ok := sel.X.(*ast.Ident); ok {
1050				if x.Name == "os" && strings.HasPrefix(sel.Sel.Name, "Std") {
1051					pass.ReportRangef(call, "%s does not take io.Writer but has first arg %s", fn.FullName(), analysisutil.Format(pass.Fset, call.Args[0]))
1052				}
1053			}
1054		}
1055	}
1056
1057	arg := args[0]
1058	if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
1059		// Ignore trailing % character in lit.Value.
1060		// The % in "abc 0.0%" couldn't be a formatting directive.
1061		s := strings.TrimSuffix(lit.Value, `%"`)
1062		if strings.Contains(s, "%") {
1063			m := printFormatRE.FindStringSubmatch(s)
1064			if m != nil {
1065				pass.ReportRangef(call, "%s call has possible formatting directive %s", fn.FullName(), m[0])
1066			}
1067		}
1068	}
1069	if strings.HasSuffix(fn.Name(), "ln") {
1070		// The last item, if a string, should not have a newline.
1071		arg = args[len(args)-1]
1072		if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
1073			str, _ := strconv.Unquote(lit.Value)
1074			if strings.HasSuffix(str, "\n") {
1075				pass.ReportRangef(call, "%s arg list ends with redundant newline", fn.FullName())
1076			}
1077		}
1078	}
1079	for _, arg := range args {
1080		if isFunctionValue(pass, arg) {
1081			pass.ReportRangef(call, "%s arg %s is a func value, not called", fn.FullName(), analysisutil.Format(pass.Fset, arg))
1082		}
1083		if methodName, ok := recursiveStringer(pass, arg); ok {
1084			pass.ReportRangef(call, "%s arg %s causes recursive call to %s method", fn.FullName(), analysisutil.Format(pass.Fset, arg), methodName)
1085		}
1086	}
1087}
1088
1089// count(n, what) returns "1 what" or "N whats"
1090// (assuming the plural of what is whats).
1091func count(n int, what string) string {
1092	if n == 1 {
1093		return "1 " + what
1094	}
1095	return fmt.Sprintf("%d %ss", n, what)
1096}
1097
1098// stringSet is a set-of-nonempty-strings-valued flag.
1099// Note: elements without a '.' get lower-cased.
1100type stringSet map[string]bool
1101
1102func (ss stringSet) String() string {
1103	var list []string
1104	for name := range ss {
1105		list = append(list, name)
1106	}
1107	sort.Strings(list)
1108	return strings.Join(list, ",")
1109}
1110
1111func (ss stringSet) Set(flag string) error {
1112	for _, name := range strings.Split(flag, ",") {
1113		if len(name) == 0 {
1114			return fmt.Errorf("empty string")
1115		}
1116		if !strings.Contains(name, ".") {
1117			name = strings.ToLower(name)
1118		}
1119		ss[name] = true
1120	}
1121	return nil
1122}
1123