83 lines
2.7 KiB
Plaintext
83 lines
2.7 KiB
Plaintext
== Why is this an issue?
|
|
|
|
`printf` format strings contain placeholders, represented by special characters such as ``++%s++``.
|
|
These placeholders are interpreted at runtime rather than validated by the compiler.
|
|
Using incorrect placeholders or with inappropriate arguments can result in the wrong string being created or undefined behavior.
|
|
|
|
Starting with {cpp}20, ``++std::format++`` should be preferred:
|
|
it is more readable and validated at compile-time, making it more secure.
|
|
Rule S6494 covers that.
|
|
Furthermore, {cpp}23 provides ``++std::print++``, which is similar to ``++std::format++`` but directly prints its output instead of generating a ``++std::string++``.
|
|
|
|
S2275 covers errors leading to undefined behavior. +
|
|
This rule is about errors that produce an unexpected string.
|
|
|
|
These problems are detected when the format string is a string literal:
|
|
|
|
* Every argument should be used:
|
|
+
|
|
[source,cpp]
|
|
----
|
|
printf("Numbers: %d", 1, 2); // Noncompliant: the second argument "2" is unused
|
|
----
|
|
+
|
|
You should either remove the extra arguments or add the relevant placeholders.
|
|
|
|
* The formatting flags `0` and `-` are mutually exclusive:
|
|
+
|
|
[source,cpp]
|
|
----
|
|
printf("Number: %0-10f", 1.2); // Noncompliant: flag "0" is ignored because of "-"
|
|
----
|
|
+
|
|
When `0` is used, the number is right-aligned with leading ``0``s.
|
|
The flag `-` aligns the number to the left.
|
|
Consequently, zero `0` would be used when using both flags, thus making the `0` flag useless.
|
|
+
|
|
You should choose which flags make sense in your use case and remove the other.
|
|
|
|
* The formatting flags `␣` (space) and `+` are mutually exclusive:
|
|
+
|
|
[source,cpp]
|
|
----
|
|
printf("Number: % +f", 1.2); // Noncompliant: flag " " is ignored because of "+"
|
|
----
|
|
+
|
|
Both the space and the `+` flags change when the sign character is printed.
|
|
They are, therefore, incompatible with one another.
|
|
+
|
|
You should decide which one is appropriate in your case and remove the other.
|
|
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* {cpp} reference - https://en.cppreference.com/w/cpp/io/c/fprintf[`printf`]
|
|
* {cpp} reference - https://en.cppreference.com/w/cpp/utility/format/format[`std::format` from {cpp}20]
|
|
* {cpp} reference - https://en.cppreference.com/w/cpp/io/print[`std::print` from {cpp}23]
|
|
|
|
=== Standards
|
|
|
|
* https://wiki.sei.cmu.edu/confluence/x/J9YxBQ[CERT, FIO47-C.] - Use valid format strings
|
|
|
|
=== Related rules
|
|
|
|
* S6494 - {cpp} formatting functions should be used instead of C printf-like functions
|
|
|
|
* S2275 - Printf-style format strings should not lead to unexpected behavior at runtime
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
include::../comments-and-links.adoc[]
|
|
|
|
endif::env-github,rspecator-view[]
|