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