Invalid Printf

ID

go.invalid_printf

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Go

Tags

reliability, suspicious

Description

Reports a Printf-family call (fmt.Printf, fmt.Sprintf, fmt.Fprintf, fmt.Errorf) whose constant format string does not match the number of value arguments supplied. Each % verb consumes one argument, so a mismatch always produces broken output.

Rationale

The compiler does not check that the verbs in a format string line up with the arguments, so a wrong count only shows up in the formatted text at runtime: a missing argument prints %!d(MISSING) and an extra one prints %!(EXTRA …​). The check counts verbs exactly — %% consumes no argument, a * width or precision consumes an extra integer, and a format using explicit argument indices (%[1]d) is left alone because positional counting no longer applies. A non-constant format is left to go.printf_dynamic_format.

fmt.Printf("%s is %d\n", name)      // FLAW — 2 verbs, 1 argument
fmt.Printf("%s\n", name, age)       // FLAW — 1 verb, 2 arguments

fmt.Printf("%s is %d\n", name, age) // OK
fmt.Printf("100%% done\n")          // OK — escaped percent, no arguments
fmt.Printf(name)                    // OK — non-constant format

Remediation

Supply exactly one argument per verb, and use %% to print a literal percent sign. If the argument list is correct, fix the format string to match it.