print.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  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. // This file contains tests for the printf checker.
  5. package print
  6. import (
  7. "fmt"
  8. logpkg "log" // renamed to make it harder to see
  9. "math"
  10. "os"
  11. "testing"
  12. "unsafe" // just for test case printing unsafe.Pointer
  13. // For testing printf-like functions from external package.
  14. // "github.com/foobar/externalprintf"
  15. )
  16. func UnsafePointerPrintfTest() {
  17. var up unsafe.Pointer
  18. fmt.Printf("%p, %x %X", up, up, up)
  19. }
  20. // Error methods that do not satisfy the Error interface and should be checked.
  21. type errorTest1 int
  22. func (errorTest1) Error(...interface{}) string {
  23. return "hi"
  24. }
  25. type errorTest2 int // Analogous to testing's *T type.
  26. func (errorTest2) Error(...interface{}) {
  27. }
  28. type errorTest3 int
  29. func (errorTest3) Error() { // No return value.
  30. }
  31. type errorTest4 int
  32. func (errorTest4) Error() int { // Different return type.
  33. return 3
  34. }
  35. type errorTest5 int
  36. func (errorTest5) error() { // niladic; don't complain if no args (was bug)
  37. }
  38. // This function never executes, but it serves as a simple test for the program.
  39. // Test with make test.
  40. func PrintfTests() {
  41. var b bool
  42. var i int
  43. var r rune
  44. var s string
  45. var x float64
  46. var p *int
  47. var imap map[int]int
  48. var fslice []float64
  49. var c complex64
  50. // Some good format/argtypes
  51. fmt.Printf("")
  52. fmt.Printf("%b %b %b", 3, i, x)
  53. fmt.Printf("%c %c %c %c", 3, i, 'x', r)
  54. fmt.Printf("%d %d %d", 3, i, imap)
  55. fmt.Printf("%e %e %e %e", 3e9, x, fslice, c)
  56. fmt.Printf("%E %E %E %E", 3e9, x, fslice, c)
  57. fmt.Printf("%f %f %f %f", 3e9, x, fslice, c)
  58. fmt.Printf("%F %F %F %F", 3e9, x, fslice, c)
  59. fmt.Printf("%g %g %g %g", 3e9, x, fslice, c)
  60. fmt.Printf("%G %G %G %G", 3e9, x, fslice, c)
  61. fmt.Printf("%b %b %b %b", 3e9, x, fslice, c)
  62. fmt.Printf("%o %o", 3, i)
  63. fmt.Printf("%p", p)
  64. fmt.Printf("%q %q %q %q", 3, i, 'x', r)
  65. fmt.Printf("%s %s %s", "hi", s, []byte{65})
  66. fmt.Printf("%t %t", true, b)
  67. fmt.Printf("%T %T", 3, i)
  68. fmt.Printf("%U %U", 3, i)
  69. fmt.Printf("%v %v", 3, i)
  70. fmt.Printf("%x %x %x %x %x %x %x", 3, i, "hi", s, x, c, fslice)
  71. fmt.Printf("%X %X %X %X %X %X %X", 3, i, "hi", s, x, c, fslice)
  72. fmt.Printf("%.*s %d %g", 3, "hi", 23, 2.3)
  73. fmt.Printf("%s", &stringerv)
  74. fmt.Printf("%v", &stringerv)
  75. fmt.Printf("%T", &stringerv)
  76. fmt.Printf("%s", &embeddedStringerv)
  77. fmt.Printf("%v", &embeddedStringerv)
  78. fmt.Printf("%T", &embeddedStringerv)
  79. fmt.Printf("%v", notstringerv)
  80. fmt.Printf("%T", notstringerv)
  81. fmt.Printf("%q", stringerarrayv)
  82. fmt.Printf("%v", stringerarrayv)
  83. fmt.Printf("%s", stringerarrayv)
  84. fmt.Printf("%v", notstringerarrayv)
  85. fmt.Printf("%T", notstringerarrayv)
  86. fmt.Printf("%d", new(fmt.Formatter))
  87. fmt.Printf("%*%", 2) // Ridiculous but allowed.
  88. fmt.Printf("%s", interface{}(nil)) // Nothing useful we can say.
  89. fmt.Printf("%g", 1+2i)
  90. fmt.Printf("%#e %#E %#f %#F %#g %#G", 1.2, 1.2, 1.2, 1.2, 1.2, 1.2) // OK since Go 1.9
  91. // Some bad format/argTypes
  92. fmt.Printf("%b", "hi") // ERROR "Printf format %b has arg \x22hi\x22 of wrong type string"
  93. fmt.Printf("%t", c) // ERROR "Printf format %t has arg c of wrong type complex64"
  94. fmt.Printf("%t", 1+2i) // ERROR "Printf format %t has arg 1 \+ 2i of wrong type complex128"
  95. fmt.Printf("%c", 2.3) // ERROR "Printf format %c has arg 2.3 of wrong type float64"
  96. fmt.Printf("%d", 2.3) // ERROR "Printf format %d has arg 2.3 of wrong type float64"
  97. fmt.Printf("%e", "hi") // ERROR "Printf format %e has arg \x22hi\x22 of wrong type string"
  98. fmt.Printf("%E", true) // ERROR "Printf format %E has arg true of wrong type bool"
  99. fmt.Printf("%f", "hi") // ERROR "Printf format %f has arg \x22hi\x22 of wrong type string"
  100. fmt.Printf("%F", 'x') // ERROR "Printf format %F has arg 'x' of wrong type rune"
  101. fmt.Printf("%g", "hi") // ERROR "Printf format %g has arg \x22hi\x22 of wrong type string"
  102. fmt.Printf("%g", imap) // ERROR "Printf format %g has arg imap of wrong type map\[int\]int"
  103. fmt.Printf("%G", i) // ERROR "Printf format %G has arg i of wrong type int"
  104. fmt.Printf("%o", x) // ERROR "Printf format %o has arg x of wrong type float64"
  105. fmt.Printf("%p", nil) // ERROR "Printf format %p has arg nil of wrong type untyped nil"
  106. fmt.Printf("%p", 23) // ERROR "Printf format %p has arg 23 of wrong type int"
  107. fmt.Printf("%q", x) // ERROR "Printf format %q has arg x of wrong type float64"
  108. fmt.Printf("%s", b) // ERROR "Printf format %s has arg b of wrong type bool"
  109. fmt.Printf("%s", byte(65)) // ERROR "Printf format %s has arg byte\(65\) of wrong type byte"
  110. fmt.Printf("%t", 23) // ERROR "Printf format %t has arg 23 of wrong type int"
  111. fmt.Printf("%U", x) // ERROR "Printf format %U has arg x of wrong type float64"
  112. fmt.Printf("%x", nil) // ERROR "Printf format %x has arg nil of wrong type untyped nil"
  113. fmt.Printf("%s", stringerv) // ERROR "Printf format %s has arg stringerv of wrong type .*print.ptrStringer"
  114. fmt.Printf("%t", stringerv) // ERROR "Printf format %t has arg stringerv of wrong type .*print.ptrStringer"
  115. fmt.Printf("%s", embeddedStringerv) // ERROR "Printf format %s has arg embeddedStringerv of wrong type .*print.embeddedStringer"
  116. fmt.Printf("%t", embeddedStringerv) // ERROR "Printf format %t has arg embeddedStringerv of wrong type .*print.embeddedStringer"
  117. fmt.Printf("%q", notstringerv) // ERROR "Printf format %q has arg notstringerv of wrong type .*print.notstringer"
  118. fmt.Printf("%t", notstringerv) // ERROR "Printf format %t has arg notstringerv of wrong type .*print.notstringer"
  119. fmt.Printf("%t", stringerarrayv) // ERROR "Printf format %t has arg stringerarrayv of wrong type .*print.stringerarray"
  120. fmt.Printf("%t", notstringerarrayv) // ERROR "Printf format %t has arg notstringerarrayv of wrong type .*print.notstringerarray"
  121. fmt.Printf("%q", notstringerarrayv) // ERROR "Printf format %q has arg notstringerarrayv of wrong type .*print.notstringerarray"
  122. fmt.Printf("%d", BoolFormatter(true)) // ERROR "Printf format %d has arg BoolFormatter\(true\) of wrong type .*print.BoolFormatter"
  123. fmt.Printf("%z", FormatterVal(true)) // correct (the type is responsible for formatting)
  124. fmt.Printf("%d", FormatterVal(true)) // correct (the type is responsible for formatting)
  125. fmt.Printf("%s", nonemptyinterface) // correct (the type is responsible for formatting)
  126. fmt.Printf("%.*s %d %6g", 3, "hi", 23, 'x') // ERROR "Printf format %6g has arg 'x' of wrong type rune"
  127. fmt.Println() // not an error
  128. fmt.Println("%s", "hi") // ERROR "Println call has possible formatting directive %s"
  129. fmt.Println("%v", "hi") // ERROR "Println call has possible formatting directive %v"
  130. fmt.Println("%T", "hi") // ERROR "Println call has possible formatting directive %T"
  131. fmt.Println("0.0%") // correct (trailing % couldn't be a formatting directive)
  132. fmt.Printf("%s", "hi", 3) // ERROR "Printf call needs 1 arg but has 2 args"
  133. _ = fmt.Sprintf("%"+("s"), "hi", 3) // ERROR "Sprintf call needs 1 arg but has 2 args"
  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 x", 3, 3, 3, 3) // ERROR "Printf call needs 2 args but has 4 args"
  139. fmt.Printf("%.*d x", "hi", 3) // ERROR "Printf format %.*d uses non-int \x22hi\x22 as argument of \*"
  140. fmt.Printf("%.*d x", i, 3) // correct
  141. fmt.Printf("%.*d x", s, 3) // ERROR "Printf format %.\*d uses non-int s as argument of \*"
  142. fmt.Printf("%*% x", 0.22) // ERROR "Printf format %\*% uses non-int 0.22 as argument of \*"
  143. fmt.Printf("%q %q", multi()...) // ok
  144. fmt.Printf("%#q", `blah`) // ok
  145. // printf("now is the time", "buddy") // no error "printf call has arguments but no formatting directives"
  146. Printf("now is the time", "buddy") // ERROR "Printf call has arguments but no formatting directives"
  147. Printf("hi") // ok
  148. const format = "%s %s\n"
  149. Printf(format, "hi", "there")
  150. Printf(format, "hi") // ERROR "Printf format %s reads arg #2, but call has 1 arg$"
  151. Printf("%s %d %.3v %q", "str", 4) // ERROR "Printf format %.3v reads arg #3, but call has 2 args"
  152. f := new(ptrStringer)
  153. f.Warn(0, "%s", "hello", 3) // ERROR "Warn call has possible formatting directive %s"
  154. f.Warnf(0, "%s", "hello", 3) // ERROR "Warnf call needs 1 arg but has 2 args"
  155. f.Warnf(0, "%r", "hello") // ERROR "Warnf format %r has unknown verb r"
  156. f.Warnf(0, "%#s", "hello") // ERROR "Warnf format %#s has unrecognized flag #"
  157. f.Warn2(0, "%s", "hello", 3) // ERROR "Warn2 call has possible formatting directive %s"
  158. f.Warnf2(0, "%s", "hello", 3) // ERROR "Warnf2 call needs 1 arg but has 2 args"
  159. f.Warnf2(0, "%r", "hello") // ERROR "Warnf2 format %r has unknown verb r"
  160. f.Warnf2(0, "%#s", "hello") // ERROR "Warnf2 format %#s has unrecognized flag #"
  161. f.Wrap(0, "%s", "hello", 3) // ERROR "Wrap call has possible formatting directive %s"
  162. f.Wrapf(0, "%s", "hello", 3) // ERROR "Wrapf call needs 1 arg but has 2 args"
  163. f.Wrapf(0, "%r", "hello") // ERROR "Wrapf format %r has unknown verb r"
  164. f.Wrapf(0, "%#s", "hello") // ERROR "Wrapf format %#s has unrecognized flag #"
  165. f.Wrap2(0, "%s", "hello", 3) // ERROR "Wrap2 call has possible formatting directive %s"
  166. f.Wrapf2(0, "%s", "hello", 3) // ERROR "Wrapf2 call needs 1 arg but has 2 args"
  167. f.Wrapf2(0, "%r", "hello") // ERROR "Wrapf2 format %r has unknown verb r"
  168. f.Wrapf2(0, "%#s", "hello") // ERROR "Wrapf2 format %#s has unrecognized flag #"
  169. fmt.Printf("%#s", FormatterVal(true)) // correct (the type is responsible for formatting)
  170. Printf("d%", 2) // ERROR "Printf format % is missing verb at end of string"
  171. Printf("%d", percentDV)
  172. Printf("%d", &percentDV)
  173. Printf("%d", notPercentDV) // ERROR "Printf format %d has arg notPercentDV of wrong type .*print.notPercentDStruct"
  174. Printf("%d", &notPercentDV) // ERROR "Printf format %d has arg &notPercentDV of wrong type \*.*print.notPercentDStruct"
  175. Printf("%p", &notPercentDV) // Works regardless: we print it as a pointer.
  176. Printf("%q", &percentDV) // ERROR "Printf format %q has arg &percentDV of wrong type \*.*print.percentDStruct"
  177. Printf("%s", percentSV)
  178. Printf("%s", &percentSV)
  179. // Good argument reorderings.
  180. Printf("%[1]d", 3)
  181. Printf("%[1]*d", 3, 1)
  182. Printf("%[2]*[1]d", 1, 3)
  183. Printf("%[2]*.[1]*[3]d", 2, 3, 4)
  184. fmt.Fprintf(os.Stderr, "%[2]*.[1]*[3]d", 2, 3, 4) // Use Fprintf to make sure we count arguments correctly.
  185. // Bad argument reorderings.
  186. Printf("%[xd", 3) // ERROR "Printf format %\[xd is missing closing \]"
  187. Printf("%[x]d x", 3) // ERROR "Printf format has invalid argument index \[x\]"
  188. Printf("%[3]*s x", "hi", 2) // ERROR "Printf format has invalid argument index \[3\]"
  189. _ = fmt.Sprintf("%[3]d x", 2) // ERROR "Sprintf format has invalid argument index \[3\]"
  190. Printf("%[2]*.[1]*[3]d x", 2, "hi", 4) // ERROR "Printf format %\[2]\*\.\[1\]\*\[3\]d uses non-int \x22hi\x22 as argument of \*"
  191. Printf("%[0]s x", "arg1") // ERROR "Printf format has invalid argument index \[0\]"
  192. Printf("%[0]d x", 1) // ERROR "Printf format has invalid argument index \[0\]"
  193. // Something that satisfies the error interface.
  194. var e error
  195. fmt.Println(e.Error()) // ok
  196. // Something that looks like an error interface but isn't, such as the (*T).Error method
  197. // in the testing package.
  198. var et1 *testing.T
  199. et1.Error() // ok
  200. et1.Error("hi") // ok
  201. et1.Error("%d", 3) // ERROR "Error call has possible formatting directive %d"
  202. var et3 errorTest3
  203. et3.Error() // ok, not an error method.
  204. var et4 errorTest4
  205. et4.Error() // ok, not an error method.
  206. var et5 errorTest5
  207. et5.error() // ok, not an error method.
  208. // Interfaces can be used with any verb.
  209. var iface interface {
  210. ToTheMadness() bool // Method ToTheMadness usually returns false
  211. }
  212. fmt.Printf("%f", iface) // ok: fmt treats interfaces as transparent and iface may well have a float concrete type
  213. // Can't print a function.
  214. Printf("%d", someFunction) // ERROR "Printf format %d arg someFunction is a func value, not called"
  215. Printf("%v", someFunction) // ERROR "Printf format %v arg someFunction is a func value, not called"
  216. Println(someFunction) // ERROR "Println arg someFunction is a func value, not called"
  217. Printf("%p", someFunction) // ok: maybe someone wants to see the pointer
  218. Printf("%T", someFunction) // ok: maybe someone wants to see the type
  219. // Bug: used to recur forever.
  220. Printf("%p %x", recursiveStructV, recursiveStructV.next)
  221. Printf("%p %x", recursiveStruct1V, recursiveStruct1V.next) // ERROR "Printf format %x has arg recursiveStruct1V\.next of wrong type \*.*print\.RecursiveStruct2"
  222. Printf("%p %x", recursiveSliceV, recursiveSliceV)
  223. Printf("%p %x", recursiveMapV, recursiveMapV)
  224. // Special handling for Log.
  225. math.Log(3) // OK
  226. var t *testing.T
  227. t.Log("%d", 3) // ERROR "Log call has possible formatting directive %d"
  228. t.Logf("%d", 3)
  229. t.Logf("%d", "hi") // ERROR "Logf format %d has arg \x22hi\x22 of wrong type string"
  230. Errorf(1, "%d", 3) // OK
  231. Errorf(1, "%d", "hi") // ERROR "Errorf format %d has arg \x22hi\x22 of wrong type string"
  232. // Multiple string arguments before variadic args
  233. errorf("WARNING", "foobar") // OK
  234. errorf("INFO", "s=%s, n=%d", "foo", 1) // OK
  235. errorf("ERROR", "%d") // ERROR "errorf format %d reads arg #1, but call has 0 args"
  236. // Printf from external package
  237. // externalprintf.Printf("%d", 42) // OK
  238. // externalprintf.Printf("foobar") // OK
  239. // level := 123
  240. // externalprintf.Logf(level, "%d", 42) // OK
  241. // externalprintf.Errorf(level, level, "foo %q bar", "foobar") // OK
  242. // externalprintf.Logf(level, "%d") // no error "Logf format %d reads arg #1, but call has 0 args"
  243. // var formatStr = "%s %s"
  244. // externalprintf.Sprintf(formatStr, "a", "b") // OK
  245. // externalprintf.Logf(level, formatStr, "a", "b") // OK
  246. // user-defined Println-like functions
  247. ss := &someStruct{}
  248. ss.Log(someFunction, "foo") // OK
  249. ss.Error(someFunction, someFunction) // OK
  250. ss.Println() // OK
  251. ss.Println(1.234, "foo") // OK
  252. ss.Println(1, someFunction) // no error "Println arg someFunction is a func value, not called"
  253. ss.log(someFunction) // OK
  254. ss.log(someFunction, "bar", 1.33) // OK
  255. ss.log(someFunction, someFunction) // no error "log arg someFunction is a func value, not called"
  256. // indexed arguments
  257. Printf("%d %[3]d %d %[2]d x", 1, 2, 3, 4) // OK
  258. Printf("%d %[0]d %d %[2]d x", 1, 2, 3, 4) // ERROR "Printf format has invalid argument index \[0\]"
  259. Printf("%d %[3]d %d %[-2]d x", 1, 2, 3, 4) // ERROR "Printf format has invalid argument index \[-2\]"
  260. Printf("%d %[3]d %d %[2234234234234]d x", 1, 2, 3, 4) // ERROR "Printf format has invalid argument index \[2234234234234\]"
  261. Printf("%d %[3]d %-10d %[2]d x", 1, 2, 3) // ERROR "Printf format %-10d reads arg #4, but call has 3 args"
  262. Printf("%[1][3]d x", 1, 2) // ERROR "Printf format %\[1\]\[ has unknown verb \["
  263. Printf("%[1]d x", 1, 2) // OK
  264. Printf("%d %[3]d %d %[2]d x", 1, 2, 3, 4, 5) // OK
  265. // wrote Println but meant Fprintln
  266. Printf("%p\n", os.Stdout) // OK
  267. Println(os.Stdout, "hello") // ERROR "Println does not take io.Writer but has first arg os.Stdout"
  268. Printf(someString(), "hello") // OK
  269. // Printf wrappers in package log should be detected automatically
  270. logpkg.Fatal("%d", 1) // ERROR "Fatal call has possible formatting directive %d"
  271. logpkg.Fatalf("%d", "x") // ERROR "Fatalf format %d has arg \x22x\x22 of wrong type string"
  272. logpkg.Fatalln("%d", 1) // ERROR "Fatalln call has possible formatting directive %d"
  273. logpkg.Panic("%d", 1) // ERROR "Panic call has possible formatting directive %d"
  274. logpkg.Panicf("%d", "x") // ERROR "Panicf format %d has arg \x22x\x22 of wrong type string"
  275. logpkg.Panicln("%d", 1) // ERROR "Panicln call has possible formatting directive %d"
  276. logpkg.Print("%d", 1) // ERROR "Print call has possible formatting directive %d"
  277. logpkg.Printf("%d", "x") // ERROR "Printf format %d has arg \x22x\x22 of wrong type string"
  278. logpkg.Println("%d", 1) // ERROR "Println call has possible formatting directive %d"
  279. // Methods too.
  280. var l *logpkg.Logger
  281. l.Fatal("%d", 1) // ERROR "Fatal call has possible formatting directive %d"
  282. l.Fatalf("%d", "x") // ERROR "Fatalf format %d has arg \x22x\x22 of wrong type string"
  283. l.Fatalln("%d", 1) // ERROR "Fatalln call has possible formatting directive %d"
  284. l.Panic("%d", 1) // ERROR "Panic call has possible formatting directive %d"
  285. l.Panicf("%d", "x") // ERROR "Panicf format %d has arg \x22x\x22 of wrong type string"
  286. l.Panicln("%d", 1) // ERROR "Panicln call has possible formatting directive %d"
  287. l.Print("%d", 1) // ERROR "Print call has possible formatting directive %d"
  288. l.Printf("%d", "x") // ERROR "Printf format %d has arg \x22x\x22 of wrong type string"
  289. l.Println("%d", 1) // ERROR "Println call has possible formatting directive %d"
  290. // Issue 26486
  291. dbg("", 1) // no error "call has arguments but no formatting directive"
  292. }
  293. func someString() string { return "X" }
  294. type someStruct struct{}
  295. // Log is non-variadic user-define Println-like function.
  296. // Calls to this func must be skipped when checking
  297. // for Println-like arguments.
  298. func (ss *someStruct) Log(f func(), s string) {}
  299. // Error is variadic user-define Println-like function.
  300. // Calls to this func mustn't be checked for Println-like arguments,
  301. // since variadic arguments type isn't interface{}.
  302. func (ss *someStruct) Error(args ...func()) {}
  303. // Println is variadic user-defined Println-like function.
  304. // Calls to this func must be checked for Println-like arguments.
  305. func (ss *someStruct) Println(args ...interface{}) {}
  306. // log is variadic user-defined Println-like function.
  307. // Calls to this func must be checked for Println-like arguments.
  308. func (ss *someStruct) log(f func(), args ...interface{}) {}
  309. // A function we use as a function value; it has no other purpose.
  310. func someFunction() {}
  311. // Printf is used by the test so we must declare it.
  312. func Printf(format string, args ...interface{}) {
  313. fmt.Printf(format, args...)
  314. }
  315. // Println is used by the test so we must declare it.
  316. func Println(args ...interface{}) {
  317. fmt.Println(args...)
  318. }
  319. // printf is used by the test so we must declare it.
  320. func printf(format string, args ...interface{}) {
  321. fmt.Printf(format, args...)
  322. }
  323. // Errorf is used by the test for a case in which the first parameter
  324. // is not a format string.
  325. func Errorf(i int, format string, args ...interface{}) {
  326. _ = fmt.Errorf(format, args...)
  327. }
  328. // errorf is used by the test for a case in which the function accepts multiple
  329. // string parameters before variadic arguments
  330. func errorf(level, format string, args ...interface{}) {
  331. _ = fmt.Errorf(format, args...)
  332. }
  333. // multi is used by the test.
  334. func multi() []interface{} {
  335. panic("don't call - testing only")
  336. }
  337. type stringer int
  338. func (stringer) String() string { return "string" }
  339. type ptrStringer float64
  340. var stringerv ptrStringer
  341. func (*ptrStringer) String() string {
  342. return "string"
  343. }
  344. func (p *ptrStringer) Warn2(x int, args ...interface{}) string {
  345. return p.Warn(x, args...)
  346. }
  347. func (p *ptrStringer) Warnf2(x int, format string, args ...interface{}) string {
  348. return p.Warnf(x, format, args...)
  349. }
  350. func (*ptrStringer) Warn(x int, args ...interface{}) string {
  351. return "warn"
  352. }
  353. func (*ptrStringer) Warnf(x int, format string, args ...interface{}) string {
  354. return "warnf"
  355. }
  356. func (p *ptrStringer) Wrap2(x int, args ...interface{}) string {
  357. return p.Wrap(x, args...)
  358. }
  359. func (p *ptrStringer) Wrapf2(x int, format string, args ...interface{}) string {
  360. return p.Wrapf(x, format, args...)
  361. }
  362. func (*ptrStringer) Wrap(x int, args ...interface{}) string {
  363. return fmt.Sprint(args...)
  364. }
  365. func (*ptrStringer) Wrapf(x int, format string, args ...interface{}) string {
  366. return fmt.Sprintf(format, args...)
  367. }
  368. func (*ptrStringer) BadWrap(x int, args ...interface{}) string {
  369. return fmt.Sprint(args) // ERROR "missing ... in args forwarded to print-like function"
  370. }
  371. func (*ptrStringer) BadWrapf(x int, format string, args ...interface{}) string {
  372. return fmt.Sprintf(format, args) // ERROR "missing ... in args forwarded to printf-like function"
  373. }
  374. func (*ptrStringer) WrapfFalsePositive(x int, arg1 string, arg2 ...interface{}) string {
  375. return fmt.Sprintf("%s %v", arg1, arg2)
  376. }
  377. type embeddedStringer struct {
  378. foo string
  379. ptrStringer
  380. bar int
  381. }
  382. var embeddedStringerv embeddedStringer
  383. type notstringer struct {
  384. f float64
  385. }
  386. var notstringerv notstringer
  387. type stringerarray [4]float64
  388. func (stringerarray) String() string {
  389. return "string"
  390. }
  391. var stringerarrayv stringerarray
  392. type notstringerarray [4]float64
  393. var notstringerarrayv notstringerarray
  394. var nonemptyinterface = interface {
  395. f()
  396. }(nil)
  397. // A data type we can print with "%d".
  398. type percentDStruct struct {
  399. a int
  400. b []byte
  401. c *float64
  402. }
  403. var percentDV percentDStruct
  404. // A data type we cannot print correctly with "%d".
  405. type notPercentDStruct struct {
  406. a int
  407. b []byte
  408. c bool
  409. }
  410. var notPercentDV notPercentDStruct
  411. // A data type we can print with "%s".
  412. type percentSStruct struct {
  413. a string
  414. b []byte
  415. C stringerarray
  416. }
  417. var percentSV percentSStruct
  418. type recursiveStringer int
  419. func (s recursiveStringer) String() string {
  420. _ = fmt.Sprintf("%d", s)
  421. _ = fmt.Sprintf("%#v", s)
  422. _ = fmt.Sprintf("%v", s) // ERROR "Sprintf format %v with arg s causes recursive .*String method call"
  423. _ = fmt.Sprintf("%v", &s) // ERROR "Sprintf format %v with arg &s causes recursive .*String method call"
  424. _ = fmt.Sprintf("%T", s) // ok; does not recursively call String
  425. return fmt.Sprintln(s) // ERROR "Sprintln arg s causes recursive call to .*String method"
  426. }
  427. type recursivePtrStringer int
  428. func (p *recursivePtrStringer) String() string {
  429. _ = fmt.Sprintf("%v", *p)
  430. _ = fmt.Sprint(&p) // ok; prints address
  431. return fmt.Sprintln(p) // ERROR "Sprintln arg p causes recursive call to .*String method"
  432. }
  433. type BoolFormatter bool
  434. func (*BoolFormatter) Format(fmt.State, rune) {
  435. }
  436. // Formatter with value receiver
  437. type FormatterVal bool
  438. func (FormatterVal) Format(fmt.State, rune) {
  439. }
  440. type RecursiveSlice []RecursiveSlice
  441. var recursiveSliceV = &RecursiveSlice{}
  442. type RecursiveMap map[int]RecursiveMap
  443. var recursiveMapV = make(RecursiveMap)
  444. type RecursiveStruct struct {
  445. next *RecursiveStruct
  446. }
  447. var recursiveStructV = &RecursiveStruct{}
  448. type RecursiveStruct1 struct {
  449. next *RecursiveStruct2
  450. }
  451. type RecursiveStruct2 struct {
  452. next *RecursiveStruct1
  453. }
  454. var recursiveStruct1V = &RecursiveStruct1{}
  455. type unexportedInterface struct {
  456. f interface{}
  457. }
  458. // Issue 17798: unexported ptrStringer cannot be formatted.
  459. type unexportedStringer struct {
  460. t ptrStringer
  461. }
  462. type unexportedStringerOtherFields struct {
  463. s string
  464. t ptrStringer
  465. S string
  466. }
  467. // Issue 17798: unexported error cannot be formatted.
  468. type unexportedError struct {
  469. e error
  470. }
  471. type unexportedErrorOtherFields struct {
  472. s string
  473. e error
  474. S string
  475. }
  476. type errorer struct{}
  477. func (e errorer) Error() string { return "errorer" }
  478. type unexportedCustomError struct {
  479. e errorer
  480. }
  481. type errorInterface interface {
  482. error
  483. ExtraMethod()
  484. }
  485. type unexportedErrorInterface struct {
  486. e errorInterface
  487. }
  488. func UnexportedStringerOrError() {
  489. fmt.Printf("%s", unexportedInterface{"foo"}) // ok; prints {foo}
  490. fmt.Printf("%s", unexportedInterface{3}) // ok; we can't see the problem
  491. us := unexportedStringer{}
  492. fmt.Printf("%s", us) // ERROR "Printf format %s has arg us of wrong type .*print.unexportedStringer"
  493. fmt.Printf("%s", &us) // ERROR "Printf format %s has arg &us of wrong type [*].*print.unexportedStringer"
  494. usf := unexportedStringerOtherFields{
  495. s: "foo",
  496. S: "bar",
  497. }
  498. fmt.Printf("%s", usf) // ERROR "Printf format %s has arg usf of wrong type .*print.unexportedStringerOtherFields"
  499. fmt.Printf("%s", &usf) // ERROR "Printf format %s has arg &usf of wrong type [*].*print.unexportedStringerOtherFields"
  500. ue := unexportedError{
  501. e: &errorer{},
  502. }
  503. fmt.Printf("%s", ue) // ERROR "Printf format %s has arg ue of wrong type .*print.unexportedError"
  504. fmt.Printf("%s", &ue) // ERROR "Printf format %s has arg &ue of wrong type [*].*print.unexportedError"
  505. uef := unexportedErrorOtherFields{
  506. s: "foo",
  507. e: &errorer{},
  508. S: "bar",
  509. }
  510. fmt.Printf("%s", uef) // ERROR "Printf format %s has arg uef of wrong type .*print.unexportedErrorOtherFields"
  511. fmt.Printf("%s", &uef) // ERROR "Printf format %s has arg &uef of wrong type [*].*print.unexportedErrorOtherFields"
  512. uce := unexportedCustomError{
  513. e: errorer{},
  514. }
  515. fmt.Printf("%s", uce) // ERROR "Printf format %s has arg uce of wrong type .*print.unexportedCustomError"
  516. uei := unexportedErrorInterface{}
  517. fmt.Printf("%s", uei) // ERROR "Printf format %s has arg uei of wrong type .*print.unexportedErrorInterface"
  518. fmt.Println("foo\n", "bar") // not an error
  519. fmt.Println("foo\n") // ERROR "Println arg list ends with redundant newline"
  520. fmt.Println("foo\\n") // not an error
  521. fmt.Println(`foo\n`) // not an error
  522. intSlice := []int{3, 4}
  523. fmt.Printf("%s", intSlice) // ERROR "Printf format %s has arg intSlice of wrong type \[\]int"
  524. nonStringerArray := [1]unexportedStringer{{}}
  525. fmt.Printf("%s", nonStringerArray) // ERROR "Printf format %s has arg nonStringerArray of wrong type \[1\].*print.unexportedStringer"
  526. fmt.Printf("%s", []stringer{3, 4}) // not an error
  527. fmt.Printf("%s", [2]stringer{3, 4}) // not an error
  528. }
  529. // TODO: Disable complaint about '0' for Go 1.10. To be fixed properly in 1.11.
  530. // See issues 23598 and 23605.
  531. func DisableErrorForFlag0() {
  532. fmt.Printf("%0t", true)
  533. }
  534. // Issue 26486.
  535. func dbg(format string, args ...interface{}) {
  536. if format == "" {
  537. format = "%v"
  538. }
  539. fmt.Printf(format, args...)
  540. }
  541. func PointersToCompoundTypes() {
  542. stringSlice := []string{"a", "b"}
  543. fmt.Printf("%s", &stringSlice) // not an error
  544. intSlice := []int{3, 4}
  545. fmt.Printf("%s", &intSlice) // ERROR "Printf format %s has arg &intSlice of wrong type \*\[\]int"
  546. stringArray := [2]string{"a", "b"}
  547. fmt.Printf("%s", &stringArray) // not an error
  548. intArray := [2]int{3, 4}
  549. fmt.Printf("%s", &intArray) // ERROR "Printf format %s has arg &intArray of wrong type \*\[2\]int"
  550. stringStruct := struct{ F string }{"foo"}
  551. fmt.Printf("%s", &stringStruct) // not an error
  552. intStruct := struct{ F int }{3}
  553. fmt.Printf("%s", &intStruct) // ERROR "Printf format %s has arg &intStruct of wrong type \*struct{F int}"
  554. stringMap := map[string]string{"foo": "bar"}
  555. fmt.Printf("%s", &stringMap) // not an error
  556. intMap := map[int]int{3: 4}
  557. fmt.Printf("%s", &intMap) // ERROR "Printf format %s has arg &intMap of wrong type \*map\[int\]int"
  558. type T2 struct {
  559. X string
  560. }
  561. type T1 struct {
  562. X *T2
  563. }
  564. fmt.Printf("%s\n", T1{&T2{"x"}}) // ERROR "Printf format %s has arg T1{&T2{.x.}} of wrong type .*print\.T1"
  565. }