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]\]:9899: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="33973d7b-4ba3-4e94-852e-1ad90ac26a2e"><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 question 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.
Implementation Details
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 MSC00-AC. Compile cleanly at high warning levels.)
...
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
PRE07- |
1 (low)
1 (unlikely)
2 (medium)
P2
C | Low | Unlikely | Medium | P2 | L3 |
Automated Detection
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" \[Wikipedia\] ["C Trigraphs"|http://en.wikipedia.org/wiki/C_trigraph]PRE06-A. Enclose header file in an inclusion guard 01. Preprocessor (PRE) PRE08-A. Guarantee that header filenames are unique