Home | History | Annotate | Download | only in testdata
      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 // This file contains tests for the printf checker.
      6 
      7 package testdata
      8 
      9 import (
     10 	"fmt"
     11 	"math"
     12 	"os"
     13 	"unsafe" // just for test case printing unsafe.Pointer
     14 )
     15 
     16 func UnsafePointerPrintfTest() {
     17 	var up unsafe.Pointer
     18 	fmt.Printf("%p, %x %X", up, up, up)
     19 }
     20 
     21 // Error methods that do not satisfy the Error interface and should be checked.
     22 type errorTest1 int
     23 
     24 func (errorTest1) Error(...interface{}) string {
     25 	return "hi"
     26 }
     27 
     28 type errorTest2 int // Analogous to testing's *T type.
     29 func (errorTest2) Error(...interface{}) {
     30 }
     31 
     32 type errorTest3 int
     33 
     34 func (errorTest3) Error() { // No return value.
     35 }
     36 
     37 type errorTest4 int
     38 
     39 func (errorTest4) Error() int { // Different return type.
     40 	return 3
     41 }
     42 
     43 type errorTest5 int
     44 
     45 func (errorTest5) error() { // niladic; don't complain if no args (was bug)
     46 }
     47 
     48 // This function never executes, but it serves as a simple test for the program.
     49 // Test with make test.
     50 func PrintfTests() {
     51 	var b bool
     52 	var i int
     53 	var r rune
     54 	var s string
     55 	var x float64
     56 	var p *int
     57 	var imap map[int]int
     58 	var fslice []float64
     59 	var c complex64
     60 	// Some good format/argtypes
     61 	fmt.Printf("")
     62 	fmt.Printf("%b %b %b", 3, i, x)
     63 	fmt.Printf("%c %c %c %c", 3, i, 'x', r)
     64 	fmt.Printf("%d %d %d", 3, i, imap)
     65 	fmt.Printf("%e %e %e %e", 3e9, x, fslice, c)
     66 	fmt.Printf("%E %E %E %E", 3e9, x, fslice, c)
     67 	fmt.Printf("%f %f %f %f", 3e9, x, fslice, c)
     68 	fmt.Printf("%F %F %F %F", 3e9, x, fslice, c)
     69 	fmt.Printf("%g %g %g %g", 3e9, x, fslice, c)
     70 	fmt.Printf("%G %G %G %G", 3e9, x, fslice, c)
     71 	fmt.Printf("%b %b %b %b", 3e9, x, fslice, c)
     72 	fmt.Printf("%o %o", 3, i)
     73 	fmt.Printf("%p %p", p, nil)
     74 	fmt.Printf("%q %q %q %q", 3, i, 'x', r)
     75 	fmt.Printf("%s %s %s", "hi", s, []byte{65})
     76 	fmt.Printf("%t %t", true, b)
     77 	fmt.Printf("%T %T", 3, i)
     78 	fmt.Printf("%U %U", 3, i)
     79 	fmt.Printf("%v %v", 3, i)
     80 	fmt.Printf("%x %x %x %x", 3, i, "hi", s)
     81 	fmt.Printf("%X %X %X %X", 3, i, "hi", s)
     82 	fmt.Printf("%.*s %d %g", 3, "hi", 23, 2.3)
     83 	fmt.Printf("%s", &stringerv)
     84 	fmt.Printf("%v", &stringerv)
     85 	fmt.Printf("%T", &stringerv)
     86 	fmt.Printf("%v", notstringerv)
     87 	fmt.Printf("%T", notstringerv)
     88 	fmt.Printf("%q", stringerarrayv)
     89 	fmt.Printf("%v", stringerarrayv)
     90 	fmt.Printf("%s", stringerarrayv)
     91 	fmt.Printf("%v", notstringerarrayv)
     92 	fmt.Printf("%T", notstringerarrayv)
     93 	fmt.Printf("%d", new(Formatter))
     94 	fmt.Printf("%*%", 2)               // Ridiculous but allowed.
     95 	fmt.Printf("%s", interface{}(nil)) // Nothing useful we can say.
     96 
     97 	fmt.Printf("%g", 1+2i)
     98 	// Some bad format/argTypes
     99 	fmt.Printf("%b", "hi")                     // ERROR "arg .hi. for printf verb %b of wrong type"
    100 	fmt.Printf("%t", c)                        // ERROR "arg c for printf verb %t of wrong type"
    101 	fmt.Printf("%t", 1+2i)                     // ERROR "arg 1 \+ 2i for printf verb %t of wrong type"
    102 	fmt.Printf("%c", 2.3)                      // ERROR "arg 2.3 for printf verb %c of wrong type"
    103 	fmt.Printf("%d", 2.3)                      // ERROR "arg 2.3 for printf verb %d of wrong type"
    104 	fmt.Printf("%e", "hi")                     // ERROR "arg .hi. for printf verb %e of wrong type"
    105 	fmt.Printf("%E", true)                     // ERROR "arg true for printf verb %E of wrong type"
    106 	fmt.Printf("%f", "hi")                     // ERROR "arg .hi. for printf verb %f of wrong type"
    107 	fmt.Printf("%F", 'x')                      // ERROR "arg 'x' for printf verb %F of wrong type"
    108 	fmt.Printf("%g", "hi")                     // ERROR "arg .hi. for printf verb %g of wrong type"
    109 	fmt.Printf("%g", imap)                     // ERROR "arg imap for printf verb %g of wrong type"
    110 	fmt.Printf("%G", i)                        // ERROR "arg i for printf verb %G of wrong type"
    111 	fmt.Printf("%o", x)                        // ERROR "arg x for printf verb %o of wrong type"
    112 	fmt.Printf("%p", 23)                       // ERROR "arg 23 for printf verb %p of wrong type"
    113 	fmt.Printf("%q", x)                        // ERROR "arg x for printf verb %q of wrong type"
    114 	fmt.Printf("%s", b)                        // ERROR "arg b for printf verb %s of wrong type"
    115 	fmt.Printf("%s", byte(65))                 // ERROR "arg byte\(65\) for printf verb %s of wrong type"
    116 	fmt.Printf("%t", 23)                       // ERROR "arg 23 for printf verb %t of wrong type"
    117 	fmt.Printf("%U", x)                        // ERROR "arg x for printf verb %U of wrong type"
    118 	fmt.Printf("%x", nil)                      // ERROR "arg nil for printf verb %x of wrong type"
    119 	fmt.Printf("%X", 2.3)                      // ERROR "arg 2.3 for printf verb %X of wrong type"
    120 	fmt.Printf("%s", stringerv)                // ERROR "arg stringerv for printf verb %s of wrong type"
    121 	fmt.Printf("%t", stringerv)                // ERROR "arg stringerv for printf verb %t of wrong type"
    122 	fmt.Printf("%q", notstringerv)             // ERROR "arg notstringerv for printf verb %q of wrong type"
    123 	fmt.Printf("%t", notstringerv)             // ERROR "arg notstringerv for printf verb %t of wrong type"
    124 	fmt.Printf("%t", stringerarrayv)           // ERROR "arg stringerarrayv for printf verb %t of wrong type"
    125 	fmt.Printf("%t", notstringerarrayv)        // ERROR "arg notstringerarrayv for printf verb %t of wrong type"
    126 	fmt.Printf("%q", notstringerarrayv)        // ERROR "arg notstringerarrayv for printf verb %q of wrong type"
    127 	fmt.Printf("%d", Formatter(true))          // correct (the type is responsible for formatting)
    128 	fmt.Printf("%s", nonemptyinterface)        // correct (the dynamic type of nonemptyinterface may be a stringer)
    129 	fmt.Printf("%.*s %d %g", 3, "hi", 23, 'x') // ERROR "arg 'x' for printf verb %g of wrong type"
    130 	fmt.Println()                              // not an error
    131 	fmt.Println("%s", "hi")                    // ERROR "possible formatting directive in Println call"
    132 	fmt.Printf("%s", "hi", 3)                  // ERROR "wrong number of args for format in Printf call"
    133 	_ = fmt.Sprintf("%"+("s"), "hi", 3)        // ERROR "wrong number of args for format in Sprintf call"
    134 	fmt.Printf("%s%%%d", "hi", 3)              // correct
    135 	fmt.Printf("%08s", "woo")                  // correct
    136 	fmt.Printf("% 8s", "woo")                  // correct
    137 	fmt.Printf("%.*d", 3, 3)                   // correct
    138 	fmt.Printf("%.*d", 3, 3, 3, 3)             // ERROR "wrong number of args for format in Printf call.*4 args"
    139 	fmt.Printf("%.*d", "hi", 3)                // ERROR "arg .hi. for \* in printf format not of type int"
    140 	fmt.Printf("%.*d", i, 3)                   // correct
    141 	fmt.Printf("%.*d", s, 3)                   // ERROR "arg s for \* in printf format not of type int"
    142 	fmt.Printf("%*%", 0.22)                    // ERROR "arg 0.22 for \* in printf format not of type int"
    143 	fmt.Printf("%q %q", multi()...)            // ok
    144 	fmt.Printf("%#q", `blah`)                  // ok
    145 	printf("now is the time", "buddy")         // ERROR "no formatting directive"
    146 	Printf("now is the time", "buddy")         // ERROR "no formatting directive"
    147 	Printf("hi")                               // ok
    148 	const format = "%s %s\n"
    149 	Printf(format, "hi", "there")
    150 	Printf(format, "hi")              // ERROR "missing argument for Printf..%s..: format reads arg 2, have only 1"
    151 	Printf("%s %d %.3v %q", "str", 4) // ERROR "missing argument for Printf..%.3v..: format reads arg 3, have only 2"
    152 	f := new(stringer)
    153 	f.Warn(0, "%s", "hello", 3)  // ERROR "possible formatting directive in Warn call"
    154 	f.Warnf(0, "%s", "hello", 3) // ERROR "wrong number of args for format in Warnf call"
    155 	f.Warnf(0, "%r", "hello")    // ERROR "unrecognized printf verb"
    156 	f.Warnf(0, "%#s", "hello")   // ERROR "unrecognized printf flag"
    157 	Printf("d%", 2)              // ERROR "missing verb at end of format string in Printf call"
    158 	Printf("%d", percentDV)
    159 	Printf("%d", &percentDV)
    160 	Printf("%d", notPercentDV)  // ERROR "arg notPercentDV for printf verb %d of wrong type"
    161 	Printf("%d", &notPercentDV) // ERROR "arg &notPercentDV for printf verb %d of wrong type"
    162 	Printf("%p", &notPercentDV) // Works regardless: we print it as a pointer.
    163 	Printf("%s", percentSV)
    164 	Printf("%s", &percentSV)
    165 	// Good argument reorderings.
    166 	Printf("%[1]d", 3)
    167 	Printf("%[1]*d", 3, 1)
    168 	Printf("%[2]*[1]d", 1, 3)
    169 	Printf("%[2]*.[1]*[3]d", 2, 3, 4)
    170 	fmt.Fprintf(os.Stderr, "%[2]*.[1]*[3]d", 2, 3, 4) // Use Fprintf to make sure we count arguments correctly.
    171 	// Bad argument reorderings.
    172 	Printf("%[xd", 3)                    // ERROR "illegal syntax for printf argument index"
    173 	Printf("%[x]d", 3)                   // ERROR "illegal syntax for printf argument index"
    174 	Printf("%[3]*s", "hi", 2)            // ERROR "missing argument for Printf.* reads arg 3, have only 2"
    175 	_ = fmt.Sprintf("%[3]d", 2)          // ERROR "missing argument for Sprintf.* reads arg 3, have only 1"
    176 	Printf("%[2]*.[1]*[3]d", 2, "hi", 4) // ERROR "arg .hi. for \* in printf format not of type int"
    177 	Printf("%[0]s", "arg1")              // ERROR "index value \[0\] for Printf.*; indexes start at 1"
    178 	Printf("%[0]d", 1)                   // ERROR "index value \[0\] for Printf.*; indexes start at 1"
    179 	// Something that satisfies the error interface.
    180 	var e error
    181 	fmt.Println(e.Error()) // ok
    182 	// Something that looks like an error interface but isn't, such as the (*T).Error method
    183 	// in the testing package.
    184 	var et1 errorTest1
    185 	fmt.Println(et1.Error())        // ERROR "no args in Error call"
    186 	fmt.Println(et1.Error("hi"))    // ok
    187 	fmt.Println(et1.Error("%d", 3)) // ERROR "possible formatting directive in Error call"
    188 	var et2 errorTest2
    189 	et2.Error()        // ERROR "no args in Error call"
    190 	et2.Error("hi")    // ok, not an error method.
    191 	et2.Error("%d", 3) // ERROR "possible formatting directive in Error call"
    192 	var et3 errorTest3
    193 	et3.Error() // ok, not an error method.
    194 	var et4 errorTest4
    195 	et4.Error() // ok, not an error method.
    196 	var et5 errorTest5
    197 	et5.error() // ok, not an error method.
    198 	// Bug: used to recur forever.
    199 	Printf("%p %x", recursiveStructV, recursiveStructV.next)
    200 	Printf("%p %x", recursiveStruct1V, recursiveStruct1V.next)
    201 	Printf("%p %x", recursiveSliceV, recursiveSliceV)
    202 	Printf("%p %x", recursiveMapV, recursiveMapV)
    203 	// Special handling for Log.
    204 	math.Log(3)  // OK
    205 	Log(3)       // OK
    206 	Log("%d", 3) // ERROR "possible formatting directive in Log call"
    207 	Logf("%d", 3)
    208 	Logf("%d", "hi") // ERROR "arg .hi. for printf verb %d of wrong type: untyped string"
    209 
    210 }
    211 
    212 // Printf is used by the test so we must declare it.
    213 func Printf(format string, args ...interface{}) {
    214 	panic("don't call - testing only")
    215 }
    216 
    217 // printf is used by the test so we must declare it.
    218 func printf(format string, args ...interface{}) {
    219 	panic("don't call - testing only")
    220 }
    221 
    222 // multi is used by the test.
    223 func multi() []interface{} {
    224 	panic("don't call - testing only")
    225 }
    226 
    227 type stringer float64
    228 
    229 var stringerv stringer
    230 
    231 func (*stringer) String() string {
    232 	return "string"
    233 }
    234 
    235 func (*stringer) Warn(int, ...interface{}) string {
    236 	return "warn"
    237 }
    238 
    239 func (*stringer) Warnf(int, string, ...interface{}) string {
    240 	return "warnf"
    241 }
    242 
    243 type notstringer struct {
    244 	f float64
    245 }
    246 
    247 var notstringerv notstringer
    248 
    249 type stringerarray [4]float64
    250 
    251 func (stringerarray) String() string {
    252 	return "string"
    253 }
    254 
    255 var stringerarrayv stringerarray
    256 
    257 type notstringerarray [4]float64
    258 
    259 var notstringerarrayv notstringerarray
    260 
    261 var nonemptyinterface = interface {
    262 	f()
    263 }(nil)
    264 
    265 // A data type we can print with "%d".
    266 type percentDStruct struct {
    267 	a int
    268 	b []byte
    269 	c *float64
    270 }
    271 
    272 var percentDV percentDStruct
    273 
    274 // A data type we cannot print correctly with "%d".
    275 type notPercentDStruct struct {
    276 	a int
    277 	b []byte
    278 	c bool
    279 }
    280 
    281 var notPercentDV notPercentDStruct
    282 
    283 // A data type we can print with "%s".
    284 type percentSStruct struct {
    285 	a string
    286 	b []byte
    287 	c stringerarray
    288 }
    289 
    290 var percentSV percentSStruct
    291 
    292 type recursiveStringer int
    293 
    294 func (s recursiveStringer) String() string {
    295 	_ = fmt.Sprintf("%d", s)
    296 	_ = fmt.Sprintf("%#v", s)
    297 	_ = fmt.Sprintf("%v", s)  // ERROR "arg s for printf causes recursive call to String method"
    298 	_ = fmt.Sprintf("%v", &s) // ERROR "arg &s for printf causes recursive call to String method"
    299 	_ = fmt.Sprintf("%T", s)  // ok; does not recursively call String
    300 	return fmt.Sprintln(s)    // ERROR "arg s for print causes recursive call to String method"
    301 }
    302 
    303 type recursivePtrStringer int
    304 
    305 func (p *recursivePtrStringer) String() string {
    306 	_ = fmt.Sprintf("%v", *p)
    307 	return fmt.Sprintln(p) // ERROR "arg p for print causes recursive call to String method"
    308 }
    309 
    310 type Formatter bool
    311 
    312 func (*Formatter) Format(fmt.State, rune) {
    313 }
    314 
    315 type RecursiveSlice []RecursiveSlice
    316 
    317 var recursiveSliceV = &RecursiveSlice{}
    318 
    319 type RecursiveMap map[int]RecursiveMap
    320 
    321 var recursiveMapV = make(RecursiveMap)
    322 
    323 type RecursiveStruct struct {
    324 	next *RecursiveStruct
    325 }
    326 
    327 var recursiveStructV = &RecursiveStruct{}
    328 
    329 type RecursiveStruct1 struct {
    330 	next *Recursive2Struct
    331 }
    332 
    333 type RecursiveStruct2 struct {
    334 	next *Recursive1Struct
    335 }
    336 
    337 var recursiveStruct1V = &RecursiveStruct1{}
    338 
    339 // Fix for issue 7149: Missing return type on String method caused fault.
    340 func (int) String() {
    341 	return ""
    342 }
    343