String literals are constant and should only be assigned to constant pointersthus should be protected by the const
qualification. This recommendation supports rule STR30-C.
Non-Compliant Code Example
The const
keyword is not included in this declarationIn the following non-compliant code, the const
keyword has been omitted.
Code Block | ||
---|---|---|
| ||
char *c = "Hello"; /* Bad: assigned to non-const */ c[3 |
Wiki Markup |
---|
If a statement such as {{c\[0\] = ' |
...
C'}} were placed following the above declaration, the code would likely still compile cleanly, but the result of the assignment is undefined as string literals are considered constant. |
Compliant Solution 1
In cases where the string referenced by c
is not meant to be modified, c
should be declared as a const
pointers,
preventing direct manipulation of the contents of the string literalsthis compliant solution, the characters referred to by the pointer c
are const
-qualified, meaning that any attempts to assign them to different values is an error.
Code Block | ||
---|---|---|
| ||
char const *c = "Hello"; /* Good */ //c[3] = 'a'; would cause a compile error |
Compliant Solution
...
2
In cases where the string referenced by c
is meant to be modified, use initialization instead of assignment. In this compliant solution, both c
is a and b
are modifiable char
arrays array which have has been initialized using the contents of the corresponding string literal.
Code Block | ||
---|---|---|
| ||
char ac[] = "abcHello"; |
This code is equivalent to:
...
bgColor | #ccccFF |
---|
Wiki Markup |
---|
Thus, a statement such as {{c\[0\ |
...
] = |
...
' |
...
C'}} is valid and will do what is expected. |
Non-Compliant Code Example 1
Although this code example is not compliant with the C99 Standard, it executes correctly if the contents of CMUfullname
are not modified.
Code Block | ||
---|---|---|
| ||
char *CMUfullname = "Carnegie Mellon University"; /* getGet school from user input and validate */ if (strcmp(school, "CMU")) { school = CMUfullname; } |
Non-Compliant Code Example 2
Adding in the const
keyword will likely generate a compiler warning, as the assignment of CMUfullname
to school
discards the const
qualifier. Any modifications to the contents of school
after this assignment will lead to errors.
Code Block | ||
---|---|---|
| ||
char const *CMUfullname = "Carnegie Mellon University"; /* getGet school from user input and validate */ if (strcmp(school, "CMU")) { school = CMUfullname; } |
Compliant Solution
The compliant solution uses the const
keyword to protect the string literal, as well as using strcpy()
to copy the value of CMUfullname
into school
, allowing future modification of school
.
Code Block | ||
---|---|---|
| ||
char const *CMUfullname = "Carnegie Mellon University"; /* getGet school from user input and validate */ if (strcmp(school, "CMU")) { //assuming school is properly allocated* Allocate correct amount of space for copy */ strcpy(school, CMUfullname); } |
Risk Assessment
Modifying string literals causes undefined behavior, resulting in abnormal program termination and denial-of-service vulnerabilities.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
STR05-A | 1 (low) | 3 (likely) | 2(medium) | P6 | L2 |
References:
Wiki Markup |
---|
[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0389.asc] \[[ISO/IEC 9899-1999:TC2|AA. C References#ISO/IEC 9899-1999TC2]\] Section 6.7.8, "Initialization" \[Lockheed Martin 2005\] Lockheed Martin. Joint Strike Fighter Air Vehicle C+\+ Coding Standards for the System Development and Demonstration Program. Document Number 2RDU00001, Rev C. December 2005. AV Rule 151.1 |