According to the C Standard, subclause 6.4.5, paragraph 3 [ISO/IEC 9899:2011],:
A character string literal is a sequence of zero or more multibyte characters enclosed in double-quotes, as in
"xyz"
. A UTF−8 string literal is the same, except prefixed byu8
. A wide string literal is the same, except prefixed by the letterL
,u
, orU
.
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 terminating null character. String literals are usually referred to by a pointer to (or array of) characters. Ideally, they should be assigned only to pointers to (or arrays of) const char
or const wchar_t
. It is unspecified whether these arrays of string literals are distinct from each other. The behavior is undefined if a program attempts to modify any portion of a string literalsliteral. Modifying a string literal frequently results in an access violation because string literals are typically stored in read-only memory (see undefined behavior 33.)String literals are usually referred to by
Avoid assigning a string literal to a pointer to , or array of characters. Ideally, they should be assigned only to pointers to (or arrays of) const char
.When called with non-const
or casting a string literal to a pointer to non-const
. For the purposes of this rule, a pointer to (or array of) const characters must be treated as a string literal. Similarly, the return returned value from of the following library functions shall must be treated as a pointer to const
charactersstring literal if the first argument is a string literal:
strpbrk(), strchr(), strrchr(), strstr()
wcspbrk(), wcschr(), wcsrchr(), wcsstr()
memchr(), wmemchr()
Do not attempt to modify a string literal. Instead, use a named array of characters to create a modifiable copy of a string literal.
This rule is a specific instance of EXP40-C. Do not modify constant objects.
...
In this noncompliant code example, the char
pointer p
is initialized to the address of a string literal. Attempting to modify the string literal results in is undefined behavior:
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 see STR11-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 modified safely modified.
Code Block | ||||
---|---|---|---|---|
| ||||
char a[] = "string literal"; a[0] = 'S'; |
...
Compliant Solution (POSIX)
Instead This compliant solution uses a named array instead of passing a string literal, use a named array:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h> void func(void) { static char fname[] = "/tmp/edXXXXXX"; mkstemp(fname); } |
...
In this noncompliant example, the char *
result of the strrchr()
function is used to modify the object pointed to by pathname
. Because the pointer argument to strrchr()
points to a string literal, the effects of the modification are undefined.
...
This 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 to callers of get_dirname()
, a buffer and length for the directory name are passed into the function. It is insufficient to change pathname
to require a char *
instead of a const char *
because conforming compilers are not required to diagnose passing a string literal to a function accepting a char *
.
...
Modifying string literals can lead to abnormal program termination and possibly denial-of-service attacks.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
STR30-C | Low | Likely | Low | P9 | L2 |
...
...