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="c7613a4a-0416-4a86-addd-73e8ebeb69b2"><ac:plain-text-body><![CDATA[
??=
#
??)
]
??!
|]]></ac:plain-text-body></ac:structured-macro>
??(
[
??'
^
??>
}
??/
\
??<
{
??-
~
...
Noncompliant Code Example
In this non-compliant 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 non-compliant 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 error */ } } |
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 error */ } } |
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-AC. 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 |
| trigraph | Fully checked | ||||||
| Axivion Bauhaus Suite |
| CertC-PRE07 | |||||||
GCC provides a -Wtrigraphs option that warns when trigraphs are used. GCC also provides a --no-trigraph option that is enabled by default.
...
| 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
...
...
| 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) PRE08-A. Guarantee that header file names are unique