Two consecutive question marks signify the start of a trigraph sequence. According to the C99 Standard \[C Standard, subclause 5.2.1.1 [ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\]:2011], Wiki Markup
All occurrences in a source file of the following sequences of three characters (that is, trigraph sequences) are replaced with the corresponding single character.
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="1b49c3e6-da37-47b0-9b80-fbe8590e6283"><ac:plain-text-body><![CDATA[
??=
#
??)
]
??!
|
??(
[
??'
^
??>
}
]]></ac:plain-text-body></ac:structured-macro>
??/
\
??<
{
??-
~
Noncompliant Code Example
In this noncompliant code example, a++
is not executed , because the trigraph sequence ??/
is replaced by \
, logically putting a++
on the same line as the comment.:
Code Block | ||||
---|---|---|---|---|
| ||||
// whatWhat is the value of a now??/ a++; |
Compliant Solution
The following This compliant solution eliminates the accidental introduction of the trigraph by separating the ?'squestion marks:
Code Block | ||||
---|---|---|---|---|
| ||||
// whatWhat is the value of a now? ?/ a++; |
...
This noncompliant code example includes the trigraph sequence ??!
, which is replaced by the character |
.:
Code Block | ||||
---|---|---|---|---|
| ||||
size_t i; = /* assignmentSome ofinitial ivalue */; if (i > 9000) { if (puts("Over 9000!??!") == EOF) { /* Handle Errorerror */ } } |
This example prints Over 9000!|
if a C99C-compliant compiler is used.
Compliant Solution
The This compliant solution uses string concatenation to concatenate the two question marks; otherwise, they are interpreted as beginning a trigraph sequence.:
Code Block | ||||
---|---|---|---|---|
| ||||
size_t i = /* Some initial value */; /* assignmentAssignment of i */ if (i > 9000) { if (puts("Over 9000!?""?!") == EOF) { /* Handle Errorerror */ } } |
The above code This code prints Over 9000!??!
, as intended.
...
Inadvertent trigraphs can result in unexpected behavior. Some compilers provide options to warn when trigraphs are encountered , or to disable trigraph expansion. Use the warning options, and ensure your code compiles cleanly. (see See MSC00-C. Compile cleanly at high warning levels.).
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
PRE07-C |
Low |
Unlikely |
Medium | P2 | L3 |
Automated Detection
The LDRA tool suite V 7.6.0 can detect violations of this recommendation.
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| trigraph | Fully checked | ||||||
Axivion Bauhaus Suite |
| CertC-PRE07 | |||||||
| CC2.PRE07 | Fully implemented | |||||||
GCC |
| Can detect violation of this recommendation when the | |||||||
Helix QAC |
| C3601 | |||||||
LDRA tool suite |
| 81 S | Fully implemented | ||||||
Parasoft C/C++test |
| CERT_C-PRE07-a | Trigraphs shall not be used | ||||||
PC-lint Plus |
| 584, 854, 9060 | Fully supported | ||||||
Polyspace Bug Finder |
| CERT C: Rec. PRE07-C | Checks for use of trigraphs (rec. fully covered) | ||||||
RuleChecker |
| trigraph | Fully checked | ||||||
SonarQube C/C++ Plugin |
| TrigraphUsage |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
...
Related Guidelines
SEI CERT C++ Coding Standard | VOID PRE07-CPP. Avoid using repeated question marks |
MISRA C:2012 | Rule 4.2 (advisory) |
Bibliography
[ISO/IEC 9899:2011] | Subclause 5.2.1.1, |
...
"Trigraph Sequences" |
...
sequences" \[[MISRA 04|AA. C References#MISRA 04]\] Rule 4.2PRE06-C. Enclose header files in an inclusion guard 01. Preprocessor (PRE)