rspec/rules/S3457/cfamily/rule.adoc
2023-10-23 16:28:04 +02:00

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[]