
In some cases, the `rule.adoc` at root of a rule is never included anywhere and thus is dead code. It's a maintenance cost by itself, but also it misses opportunities to inline code that seems used by two documents when in fact only one document is actually rendered. And this missed opportunity, in turn, stops us from applying the correct language tag on the code samples.
79 lines
3.0 KiB
Plaintext
79 lines
3.0 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Because ``++printf++``-style format strings are interpreted at runtime, rather than validated by the Java compiler, they can contain errors that lead to unexpected behavior or runtime errors. This rule statically validates the good behavior of ``++printf++``-style formats when calling the ``++format(...)++`` methods of ``++java.util.Formatter++``, ``++java.lang.String++``, ``++java.io.PrintStream++``, ``++MessageFormat++``, and ``++java.io.PrintWriter++`` classes and the ``++printf(...)++`` methods of ``++java.io.PrintStream++`` or ``++java.io.PrintWriter++`` classes.
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,java]
|
|
----
|
|
String.format("The value of my integer is %d", "Hello World"); // Noncompliant; an 'int' is expected rather than a String
|
|
String.format("Duke's Birthday year is %tX", c); //Noncompliant; X is not a supported time conversion character
|
|
String.format("Display %0$d and then %d", 1); //Noncompliant; arguments are numbered starting from 1
|
|
String.format("Not enough arguments %d and %d", 1); //Noncompliant; the second argument is missing
|
|
String.format("%< is equals to %d", 2); //Noncompliant; the argument index '<' refers to the previous format specifier but there isn't one
|
|
|
|
MessageFormat.format("Result {1}.", value); // Noncompliant; Not enough arguments. (first element is {0})
|
|
MessageFormat.format("Result {{0}.", value); // Noncompliant; Unbalanced number of curly brace (single curly braces should be escaped)
|
|
MessageFormat.format("Result ' {0}", value); // Noncompliant; Unbalanced number of quotes (single quote must be escaped)
|
|
|
|
java.util.logging.Logger logger;
|
|
logger.log(java.util.logging.Level.SEVERE, "Result {1}!", 14); // Noncompliant - Not enough arguments.
|
|
|
|
org.slf4j.Logger slf4jLog;
|
|
org.slf4j.Marker marker;
|
|
|
|
slf4jLog.debug(marker, "message {}"); // Noncompliant - Not enough arguments.
|
|
|
|
org.apache.logging.log4j.Logger log4jLog;
|
|
log4jLog.debug("message {}"); // Noncompliant - Not enough arguments.
|
|
----
|
|
|
|
|
|
=== Compliant solution
|
|
|
|
[source,java]
|
|
----
|
|
String.format("The value of my integer is %d", 3);
|
|
String.format("Duke's Birthday year is %tY", c);
|
|
String.format("Display %1$d and then %d", 1);
|
|
String.format("Not enough arguments %d and %d", 1, 2);
|
|
String.format("%d is equals to %<", 2);
|
|
|
|
MessageFormat.format("Result {0}.", value);
|
|
MessageFormat.format("Result {0} & {1}.", value, value);
|
|
MessageFormat.format("Result {0}.", myObject);
|
|
|
|
java.util.logging.Logger logger;
|
|
logger.log(java.util.logging.Level.SEVERE, "Result {1},{2}!", 14, 2);
|
|
|
|
org.slf4j.Logger slf4jLog;
|
|
org.slf4j.Marker marker;
|
|
|
|
slf4jLog.debug(marker, "message {}", 1);
|
|
|
|
org.apache.logging.log4j.Logger log4jLog;
|
|
log4jLog.debug("message {}", 1);
|
|
----
|
|
|
|
|
|
== Resources
|
|
|
|
* https://www.securecoding.cert.org/confluence/x/wQA1[CERT, FIO47-C.] - Use valid format strings
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
include::../message.adoc[]
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
include::../comments-and-links.adoc[]
|
|
|
|
endif::env-github,rspecator-view[]
|