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="768bef08-2d13-4b10-b3f4-d22920997e7c"><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++; |
...
Noncompliant Code Example
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.
Risk Assessment
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 |
|---|
Detectable | Repairable | Priority | Level |
|---|---|---|---|
PRE07-C |
Low | Unlikely |
Yes |
No | P2 | L3 |
Automated Detection
| Tool | Version | Checker | Description | ||
|---|---|---|---|---|---|
| Astrée |
|
GCC provides a -Wtrigraphs option that warns when trigraphs are used. GCC also provides a --no-trigraph option that is enabled by default.
The LDRA tool suite V 7.6.0 can detect violations of this recommendation.
| 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-A. Enclose header files in an inclusion guard 01. Preprocessor (PRE)