Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / go / analysis / passes / printf / printf.go
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.
7 package printf
8
9 import (
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
30 func init() {
31         Analyzer.Flags.Var(isPrint, "funcs", "comma-separated list of print function names to check")
32 }
33
34 var 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
43 const Doc = `check consistency of Printf format strings and arguments
44
45 The check applies to known functions (for example, those in package fmt)
46 as well as any detected wrappers of known functions.
47
48 A function that wants to avail itself of printf checking but is not
49 found by this analyzer's heuristics (for example, due to use of
50 dynamic calls) can insert a bogus call:
51
52         if false {
53                 _ = fmt.Sprintf(format, args...) // enable printf checking
54         }
55
56 The -funcs flag specifies a comma-separated list of names of additional
57 known formatting functions or methods. If the name contains a period,
58 it 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
64 Otherwise the name is interpreted as a case-insensitive unqualified
65 identifier such as "errorf". Either way, if a listed name ends in f, the
66 function is assumed to be Printf-like, taking a format string before the
67 argument list. Otherwise it is assumed to be Print-like, taking a list
68 of arguments with no format string.
69 `
70
71 // Kind is a kind of fmt function behavior.
72 type Kind int
73
74 const (
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
81 func (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.
95 type Result struct {
96         funcs map[*types.Func]Kind
97 }
98
99 // Kind reports whether fn behaves like fmt.Print or fmt.Printf.
100 func (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.
118 type isWrapper struct{ Kind Kind }
119
120 func (f *isWrapper) AFact() {}
121
122 func (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
135 func 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
144 type 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
153 type 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.
165 func 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.
208 func 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
281 func 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...).
288 func 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 //
345 var 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).
408 func 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.
451 func 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.
464 func 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
481 func 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)".
513 func 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
530 func 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.
537 type 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.
554 func 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.Name())
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.Name())
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.Name(), 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                         if kind != KindErrorf {
593                                 pass.Reportf(call.Pos(), "%s call has error-wrapping directive %%w", state.name)
594                                 return
595                         }
596                         if anyW {
597                                 pass.Reportf(call.Pos(), "%s call has more than one error-wrapping directive %%w", state.name)
598                                 return
599                         }
600                         anyW = true
601                 }
602                 if len(state.argNums) > 0 {
603                         // Continue with the next sequential argument.
604                         argNum = state.argNums[len(state.argNums)-1] + 1
605                 }
606                 for _, n := range state.argNums {
607                         if n >= maxArgNum {
608                                 maxArgNum = n + 1
609                         }
610                 }
611         }
612         // Dotdotdot is hard.
613         if call.Ellipsis.IsValid() && maxArgNum >= len(call.Args)-1 {
614                 return
615         }
616         // If any formats are indexed, extra arguments are ignored.
617         if anyIndex {
618                 return
619         }
620         // There should be no leftover arguments.
621         if maxArgNum != len(call.Args) {
622                 expect := maxArgNum - firstArg
623                 numArgs := len(call.Args) - firstArg
624                 pass.ReportRangef(call, "%s call needs %v but has %v", fn.Name(), count(expect, "arg"), count(numArgs, "arg"))
625         }
626 }
627
628 // parseFlags accepts any printf flags.
629 func (s *formatState) parseFlags() {
630         for s.nbytes < len(s.format) {
631                 switch c := s.format[s.nbytes]; c {
632                 case '#', '0', '+', '-', ' ':
633                         s.flags = append(s.flags, c)
634                         s.nbytes++
635                 default:
636                         return
637                 }
638         }
639 }
640
641 // scanNum advances through a decimal number if present.
642 func (s *formatState) scanNum() {
643         for ; s.nbytes < len(s.format); s.nbytes++ {
644                 c := s.format[s.nbytes]
645                 if c < '0' || '9' < c {
646                         return
647                 }
648         }
649 }
650
651 // parseIndex scans an index expression. It returns false if there is a syntax error.
652 func (s *formatState) parseIndex() bool {
653         if s.nbytes == len(s.format) || s.format[s.nbytes] != '[' {
654                 return true
655         }
656         // Argument index present.
657         s.nbytes++ // skip '['
658         start := s.nbytes
659         s.scanNum()
660         ok := true
661         if s.nbytes == len(s.format) || s.nbytes == start || s.format[s.nbytes] != ']' {
662                 ok = false
663                 s.nbytes = strings.Index(s.format, "]")
664                 if s.nbytes < 0 {
665                         s.pass.ReportRangef(s.call, "%s format %s is missing closing ]", s.name, s.format)
666                         return false
667                 }
668         }
669         arg32, err := strconv.ParseInt(s.format[start:s.nbytes], 10, 32)
670         if err != nil || !ok || arg32 <= 0 || arg32 > int64(len(s.call.Args)-s.firstArg) {
671                 s.pass.ReportRangef(s.call, "%s format has invalid argument index [%s]", s.name, s.format[start:s.nbytes])
672                 return false
673         }
674         s.nbytes++ // skip ']'
675         arg := int(arg32)
676         arg += s.firstArg - 1 // We want to zero-index the actual arguments.
677         s.argNum = arg
678         s.hasIndex = true
679         s.indexPending = true
680         return true
681 }
682
683 // parseNum scans a width or precision (or *). It returns false if there's a bad index expression.
684 func (s *formatState) parseNum() bool {
685         if s.nbytes < len(s.format) && s.format[s.nbytes] == '*' {
686                 if s.indexPending { // Absorb it.
687                         s.indexPending = false
688                 }
689                 s.nbytes++
690                 s.argNums = append(s.argNums, s.argNum)
691                 s.argNum++
692         } else {
693                 s.scanNum()
694         }
695         return true
696 }
697
698 // parsePrecision scans for a precision. It returns false if there's a bad index expression.
699 func (s *formatState) parsePrecision() bool {
700         // If there's a period, there may be a precision.
701         if s.nbytes < len(s.format) && s.format[s.nbytes] == '.' {
702                 s.flags = append(s.flags, '.') // Treat precision as a flag.
703                 s.nbytes++
704                 if !s.parseIndex() {
705                         return false
706                 }
707                 if !s.parseNum() {
708                         return false
709                 }
710         }
711         return true
712 }
713
714 // parsePrintfVerb looks the formatting directive that begins the format string
715 // and returns a formatState that encodes what the directive wants, without looking
716 // at the actual arguments present in the call. The result is nil if there is an error.
717 func parsePrintfVerb(pass *analysis.Pass, call *ast.CallExpr, name, format string, firstArg, argNum int) *formatState {
718         state := &formatState{
719                 format:   format,
720                 name:     name,
721                 flags:    make([]byte, 0, 5),
722                 argNum:   argNum,
723                 argNums:  make([]int, 0, 1),
724                 nbytes:   1, // There's guaranteed to be a percent sign.
725                 firstArg: firstArg,
726                 pass:     pass,
727                 call:     call,
728         }
729         // There may be flags.
730         state.parseFlags()
731         // There may be an index.
732         if !state.parseIndex() {
733                 return nil
734         }
735         // There may be a width.
736         if !state.parseNum() {
737                 return nil
738         }
739         // There may be a precision.
740         if !state.parsePrecision() {
741                 return nil
742         }
743         // Now a verb, possibly prefixed by an index (which we may already have).
744         if !state.indexPending && !state.parseIndex() {
745                 return nil
746         }
747         if state.nbytes == len(state.format) {
748                 pass.ReportRangef(call.Fun, "%s format %s is missing verb at end of string", name, state.format)
749                 return nil
750         }
751         verb, w := utf8.DecodeRuneInString(state.format[state.nbytes:])
752         state.verb = verb
753         state.nbytes += w
754         if verb != '%' {
755                 state.argNums = append(state.argNums, state.argNum)
756         }
757         state.format = state.format[:state.nbytes]
758         return state
759 }
760
761 // printfArgType encodes the types of expressions a printf verb accepts. It is a bitmask.
762 type printfArgType int
763
764 const (
765         argBool printfArgType = 1 << iota
766         argInt
767         argRune
768         argString
769         argFloat
770         argComplex
771         argPointer
772         argError
773         anyType printfArgType = ^0
774 )
775
776 type printVerb struct {
777         verb  rune   // User may provide verb through Formatter; could be a rune.
778         flags string // known flags are all ASCII
779         typ   printfArgType
780 }
781
782 // Common flag sets for printf verbs.
783 const (
784         noFlag       = ""
785         numFlag      = " -+.0"
786         sharpNumFlag = " -+.0#"
787         allFlags     = " -+.0#"
788 )
789
790 // printVerbs identifies which flags are known to printf for each verb.
791 var printVerbs = []printVerb{
792         // '-' is a width modifier, always valid.
793         // '.' is a precision for float, max width for strings.
794         // '+' is required sign for numbers, Go format for %v.
795         // '#' is alternate format for several verbs.
796         // ' ' is spacer for numbers
797         {'%', noFlag, 0},
798         {'b', sharpNumFlag, argInt | argFloat | argComplex | argPointer},
799         {'c', "-", argRune | argInt},
800         {'d', numFlag, argInt | argPointer},
801         {'e', sharpNumFlag, argFloat | argComplex},
802         {'E', sharpNumFlag, argFloat | argComplex},
803         {'f', sharpNumFlag, argFloat | argComplex},
804         {'F', sharpNumFlag, argFloat | argComplex},
805         {'g', sharpNumFlag, argFloat | argComplex},
806         {'G', sharpNumFlag, argFloat | argComplex},
807         {'o', sharpNumFlag, argInt | argPointer},
808         {'O', sharpNumFlag, argInt | argPointer},
809         {'p', "-#", argPointer},
810         {'q', " -+.0#", argRune | argInt | argString},
811         {'s', " -+.0", argString},
812         {'t', "-", argBool},
813         {'T', "-", anyType},
814         {'U', "-#", argRune | argInt},
815         {'v', allFlags, anyType},
816         {'w', allFlags, argError},
817         {'x', sharpNumFlag, argRune | argInt | argString | argPointer | argFloat | argComplex},
818         {'X', sharpNumFlag, argRune | argInt | argString | argPointer | argFloat | argComplex},
819 }
820
821 // okPrintfArg compares the formatState to the arguments actually present,
822 // reporting any discrepancies it can discern. If the final argument is ellipsissed,
823 // there's little it can do for that.
824 func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (ok bool) {
825         var v printVerb
826         found := false
827         // Linear scan is fast enough for a small list.
828         for _, v = range printVerbs {
829                 if v.verb == state.verb {
830                         found = true
831                         break
832                 }
833         }
834
835         // Could current arg implement fmt.Formatter?
836         formatter := false
837         if state.argNum < len(call.Args) {
838                 if tv, ok := pass.TypesInfo.Types[call.Args[state.argNum]]; ok {
839                         formatter = isFormatter(tv.Type)
840                 }
841         }
842
843         if !formatter {
844                 if !found {
845                         pass.ReportRangef(call, "%s format %s has unknown verb %c", state.name, state.format, state.verb)
846                         return false
847                 }
848                 for _, flag := range state.flags {
849                         // TODO: Disable complaint about '0' for Go 1.10. To be fixed properly in 1.11.
850                         // See issues 23598 and 23605.
851                         if flag == '0' {
852                                 continue
853                         }
854                         if !strings.ContainsRune(v.flags, rune(flag)) {
855                                 pass.ReportRangef(call, "%s format %s has unrecognized flag %c", state.name, state.format, flag)
856                                 return false
857                         }
858                 }
859         }
860         // Verb is good. If len(state.argNums)>trueArgs, we have something like %.*s and all
861         // but the final arg must be an integer.
862         trueArgs := 1
863         if state.verb == '%' {
864                 trueArgs = 0
865         }
866         nargs := len(state.argNums)
867         for i := 0; i < nargs-trueArgs; i++ {
868                 argNum := state.argNums[i]
869                 if !argCanBeChecked(pass, call, i, state) {
870                         return
871                 }
872                 arg := call.Args[argNum]
873                 if !matchArgType(pass, argInt, nil, arg) {
874                         pass.ReportRangef(call, "%s format %s uses non-int %s as argument of *", state.name, state.format, analysisutil.Format(pass.Fset, arg))
875                         return false
876                 }
877         }
878
879         if state.verb == '%' || formatter {
880                 return true
881         }
882         argNum := state.argNums[len(state.argNums)-1]
883         if !argCanBeChecked(pass, call, len(state.argNums)-1, state) {
884                 return false
885         }
886         arg := call.Args[argNum]
887         if isFunctionValue(pass, arg) && state.verb != 'p' && state.verb != 'T' {
888                 pass.ReportRangef(call, "%s format %s arg %s is a func value, not called", state.name, state.format, analysisutil.Format(pass.Fset, arg))
889                 return false
890         }
891         if !matchArgType(pass, v.typ, nil, arg) {
892                 typeString := ""
893                 if typ := pass.TypesInfo.Types[arg].Type; typ != nil {
894                         typeString = typ.String()
895                 }
896                 pass.ReportRangef(call, "%s format %s has arg %s of wrong type %s", state.name, state.format, analysisutil.Format(pass.Fset, arg), typeString)
897                 return false
898         }
899         if v.typ&argString != 0 && v.verb != 'T' && !bytes.Contains(state.flags, []byte{'#'}) {
900                 if methodName, ok := recursiveStringer(pass, arg); ok {
901                         pass.ReportRangef(call, "%s format %s with arg %s causes recursive %s method call", state.name, state.format, analysisutil.Format(pass.Fset, arg), methodName)
902                         return false
903                 }
904         }
905         return true
906 }
907
908 // recursiveStringer reports whether the argument e is a potential
909 // recursive call to stringer or is an error, such as t and &t in these examples:
910 //
911 //      func (t *T) String() string { printf("%s",  t) }
912 //      func (t  T) Error() string { printf("%s",  t) }
913 //      func (t  T) String() string { printf("%s", &t) }
914 func recursiveStringer(pass *analysis.Pass, e ast.Expr) (string, bool) {
915         typ := pass.TypesInfo.Types[e].Type
916
917         // It's unlikely to be a recursive stringer if it has a Format method.
918         if isFormatter(typ) {
919                 return "", false
920         }
921
922         // Does e allow e.String() or e.Error()?
923         strObj, _, _ := types.LookupFieldOrMethod(typ, false, pass.Pkg, "String")
924         strMethod, strOk := strObj.(*types.Func)
925         errObj, _, _ := types.LookupFieldOrMethod(typ, false, pass.Pkg, "Error")
926         errMethod, errOk := errObj.(*types.Func)
927         if !strOk && !errOk {
928                 return "", false
929         }
930
931         // Is the expression e within the body of that String or Error method?
932         var method *types.Func
933         if strOk && strMethod.Pkg() == pass.Pkg && strMethod.Scope().Contains(e.Pos()) {
934                 method = strMethod
935         } else if errOk && errMethod.Pkg() == pass.Pkg && errMethod.Scope().Contains(e.Pos()) {
936                 method = errMethod
937         } else {
938                 return "", false
939         }
940
941         sig := method.Type().(*types.Signature)
942         if !isStringer(sig) {
943                 return "", false
944         }
945
946         // Is it the receiver r, or &r?
947         if u, ok := e.(*ast.UnaryExpr); ok && u.Op == token.AND {
948                 e = u.X // strip off & from &r
949         }
950         if id, ok := e.(*ast.Ident); ok {
951                 if pass.TypesInfo.Uses[id] == sig.Recv() {
952                         return method.Name(), true
953                 }
954         }
955         return "", false
956 }
957
958 // isStringer reports whether the method signature matches the String() definition in fmt.Stringer.
959 func isStringer(sig *types.Signature) bool {
960         return sig.Params().Len() == 0 &&
961                 sig.Results().Len() == 1 &&
962                 sig.Results().At(0).Type() == types.Typ[types.String]
963 }
964
965 // isFunctionValue reports whether the expression is a function as opposed to a function call.
966 // It is almost always a mistake to print a function value.
967 func isFunctionValue(pass *analysis.Pass, e ast.Expr) bool {
968         if typ := pass.TypesInfo.Types[e].Type; typ != nil {
969                 _, ok := typ.(*types.Signature)
970                 return ok
971         }
972         return false
973 }
974
975 // argCanBeChecked reports whether the specified argument is statically present;
976 // it may be beyond the list of arguments or in a terminal slice... argument, which
977 // means we can't see it.
978 func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, formatArg int, state *formatState) bool {
979         argNum := state.argNums[formatArg]
980         if argNum <= 0 {
981                 // Shouldn't happen, so catch it with prejudice.
982                 panic("negative arg num")
983         }
984         if argNum < len(call.Args)-1 {
985                 return true // Always OK.
986         }
987         if call.Ellipsis.IsValid() {
988                 return false // We just can't tell; there could be many more arguments.
989         }
990         if argNum < len(call.Args) {
991                 return true
992         }
993         // There are bad indexes in the format or there are fewer arguments than the format needs.
994         // This is the argument number relative to the format: Printf("%s", "hi") will give 1 for the "hi".
995         arg := argNum - state.firstArg + 1 // People think of arguments as 1-indexed.
996         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"))
997         return false
998 }
999
1000 // printFormatRE is the regexp we match and report as a possible format string
1001 // in the first argument to unformatted prints like fmt.Print.
1002 // We exclude the space flag, so that printing a string like "x % y" is not reported as a format.
1003 var printFormatRE = regexp.MustCompile(`%` + flagsRE + numOptRE + `\.?` + numOptRE + indexOptRE + verbRE)
1004
1005 const (
1006         flagsRE    = `[+\-#]*`
1007         indexOptRE = `(\[[0-9]+\])?`
1008         numOptRE   = `([0-9]+|` + indexOptRE + `\*)?`
1009         verbRE     = `[bcdefgopqstvxEFGTUX]`
1010 )
1011
1012 // checkPrint checks a call to an unformatted print routine such as Println.
1013 func checkPrint(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) {
1014         firstArg := 0
1015         typ := pass.TypesInfo.Types[call.Fun].Type
1016         if typ == nil {
1017                 // Skip checking functions with unknown type.
1018                 return
1019         }
1020         if sig, ok := typ.(*types.Signature); ok {
1021                 if !sig.Variadic() {
1022                         // Skip checking non-variadic functions.
1023                         return
1024                 }
1025                 params := sig.Params()
1026                 firstArg = params.Len() - 1
1027
1028                 typ := params.At(firstArg).Type()
1029                 typ = typ.(*types.Slice).Elem()
1030                 it, ok := typ.(*types.Interface)
1031                 if !ok || !it.Empty() {
1032                         // Skip variadic functions accepting non-interface{} args.
1033                         return
1034                 }
1035         }
1036         args := call.Args
1037         if len(args) <= firstArg {
1038                 // Skip calls without variadic args.
1039                 return
1040         }
1041         args = args[firstArg:]
1042
1043         if firstArg == 0 {
1044                 if sel, ok := call.Args[0].(*ast.SelectorExpr); ok {
1045                         if x, ok := sel.X.(*ast.Ident); ok {
1046                                 if x.Name == "os" && strings.HasPrefix(sel.Sel.Name, "Std") {
1047                                         pass.ReportRangef(call, "%s does not take io.Writer but has first arg %s", fn.Name(), analysisutil.Format(pass.Fset, call.Args[0]))
1048                                 }
1049                         }
1050                 }
1051         }
1052
1053         arg := args[0]
1054         if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
1055                 // Ignore trailing % character in lit.Value.
1056                 // The % in "abc 0.0%" couldn't be a formatting directive.
1057                 s := strings.TrimSuffix(lit.Value, `%"`)
1058                 if strings.Contains(s, "%") {
1059                         m := printFormatRE.FindStringSubmatch(s)
1060                         if m != nil {
1061                                 pass.ReportRangef(call, "%s call has possible formatting directive %s", fn.Name(), m[0])
1062                         }
1063                 }
1064         }
1065         if strings.HasSuffix(fn.Name(), "ln") {
1066                 // The last item, if a string, should not have a newline.
1067                 arg = args[len(args)-1]
1068                 if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
1069                         str, _ := strconv.Unquote(lit.Value)
1070                         if strings.HasSuffix(str, "\n") {
1071                                 pass.ReportRangef(call, "%s arg list ends with redundant newline", fn.Name())
1072                         }
1073                 }
1074         }
1075         for _, arg := range args {
1076                 if isFunctionValue(pass, arg) {
1077                         pass.ReportRangef(call, "%s arg %s is a func value, not called", fn.Name(), analysisutil.Format(pass.Fset, arg))
1078                 }
1079                 if methodName, ok := recursiveStringer(pass, arg); ok {
1080                         pass.ReportRangef(call, "%s arg %s causes recursive call to %s method", fn.Name(), analysisutil.Format(pass.Fset, arg), methodName)
1081                 }
1082         }
1083 }
1084
1085 // count(n, what) returns "1 what" or "N whats"
1086 // (assuming the plural of what is whats).
1087 func count(n int, what string) string {
1088         if n == 1 {
1089                 return "1 " + what
1090         }
1091         return fmt.Sprintf("%d %ss", n, what)
1092 }
1093
1094 // stringSet is a set-of-nonempty-strings-valued flag.
1095 // Note: elements without a '.' get lower-cased.
1096 type stringSet map[string]bool
1097
1098 func (ss stringSet) String() string {
1099         var list []string
1100         for name := range ss {
1101                 list = append(list, name)
1102         }
1103         sort.Strings(list)
1104         return strings.Join(list, ",")
1105 }
1106
1107 func (ss stringSet) Set(flag string) error {
1108         for _, name := range strings.Split(flag, ",") {
1109                 if len(name) == 0 {
1110                         return fmt.Errorf("empty string")
1111                 }
1112                 if !strings.Contains(name, ".") {
1113                         name = strings.ToLower(name)
1114                 }
1115                 ss[name] = true
1116         }
1117         return nil
1118 }