...
At compile time, string literals are used to create an array of static storage duration of sufficient length to contain the character sequence and a null-termination character. It is unspecified whether these arrays are distinct. The behavior is undefined if a program attempts to modify string literals but frequently results in an access violation because string literals are typically stored in read-only memory. See also undefined behavior 30 33 of Annex J of C99C11.
Do not attempt to modify a string literal. Use a named array of characters to obtain a modifiable string.
...
Code Block | ||||
---|---|---|---|---|
| ||||
char *p = "string literal";
p[0] = 'S';
|
...
As an array initializer, a string literal specifies the initial values of characters in an array, as well as the size of the array. (See rule STR36-C. Do not specify the bound of a character array initialized with a string literal.) This code creates a copy of the string literal in the space allocated to the character array a
. The string stored in a
can be safely modified.
Code Block | ||||
---|---|---|---|---|
| ||||
char a[] = "string literal";
a[0] = 'S';
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
char *fname;
fname = mkstemp("/tmp/edXXXXXX");
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
static char fname[] = "/tmp/edXXXXXX";
mkstemp(fname);
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
const char* get_dirname(const char* pathname) {
char* slash;
slash = strrchr(pathname, '/');
if (slash)
*slash = '\0'; /* undefined behavior */
return pathname;
}
int main() {
puts(get_dirname(__FILE__));
return 0;
}
|
...
A compliant solution avoids modifying a const object, even if it is possible to obtain a non-const pointer to such an object by calling a standard C library function, such as strrchr()
. To reduce the risk of callers of get_dirname()
passing constant objects to the function, the argument is declared to be a non-const pointer. While converting a string literal to non-const char*
is permitted by the language, conforming compilers could issue a diagnostic for such code. See also recommendation EXP05-C. Do not cast away a const qualification.
Code Block | ||||
---|---|---|---|---|
| ||||
char* get_dirname(char* pathname) {
char* slash;
slash = strrchr(pathname, '/');
if (slash)
*slash = '\0';
return pathname;
}
int main() {
char pathname[] = __FILE__;
/* calling get_dirname(__FILE__) may be diagnosed */
puts(get_dirname(pathname));
return 0;
}
|
...
Tool | Version | Checker | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Section |
| section157 S | sectionPartially | Implemented sectionimplemented. | |||||||||||
Splint |
|
| section|||||||||||||
Compass/ROSE | |||||||||||||||
Section | Can detect simple violations of this rule. |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...
CERT C++ Secure Coding Standard: STR30-CPP. Do not attempt to modify string literals
ISO/IEC 9899:19992011 Section 6.4.5, "String literals"
ISO/IEC TR 17961 (Draft) Modifying string literals [strmod]
Bibliography
[Summit 1995] comp.lang.c FAQ list - , Question 1.32
[Plum 1991] Topic 1.26, "strings - string literals"
...