...
- It does not make sense to think of array sizes in bytes in all cases; for example, in the case of an array of integers.
- If the size in bytes of the array is required, it can be derived from the number of elements in the array.
- It is better not to add to the cognitive load of the function user and probably easier for by requiring the user to think of calculate the size in bytes of the array in terms of its elements.
In most cases, the distinction between the number of elements and number of bytes is moot: There is a clear mapping between the two, and it is easier to think in terms of number of elements anyway. Unfortunately, this issue can become muddled when working with multibyte strings as the logical entity being manipulated differs from that of the type being used to implement it. Here, it is important to remember that the type of the array is a character and not a multibyte character. Accordingly, the number of elements in the array is represented as a number of characters.
...
It is not necessary to go beyond the standard C library to find examples that violate this recommendation, because the C language often prioritizes performance at the expense of robustness. The following are two examples from C99 §7.21 of the C standard.
Code Block | ||
---|---|---|
| ||
char *strncpy(char * restrict s1, const char * restrict s2, size_t n); char *strncat(char * restrict s1, const char * restrict s2, size_t n); |
The problem with these functions is twofoldThese functions have two problems. First, there is no indication of the size of the first array, s1
. ThusAs a result, it is not possible to discern within the function how large s1
is and how many elements may be written into it. Second, while it appears that a size is supplied for s2
is supplied, this is, in fact, , the size_t
paramenter n
actually gives the number of elements to copy. ThusConsequently, there is no guarantee that the elements being copied are members of way for either function to determine the size of the array s2
.
Compliant Solution
The above C99 strncpy()
strncat()
functions could be improved by adding element count parameters as follows:
Code Block | ||
---|---|---|
| ||
char *strncpy(char * restrict s1, size_t s1count, const char * restrict s2, size_t s2count, size_t n);
char *strncat(char * restrict s1, size_t s1count, const char * restrict s2, size_t s2count, size_t n);
|
Note that for strncpy()
, it makes sense to maintain the n
parameter as the caller may only wish to copy a subset of The n
parameter is used to specify a number of elements to copy that is less than the total number of elements . For strncat()
, the n
parameter is no longer requiredin the source string.
Compliant Solution (TR24731TR 24731-1)
TR24731TR 24731-1, which will be an appendix in C1x, prescribes the addition of "secure" versions of the noncompliant examples provided aboveC1X, defines bounds-checking versions of standard C library string handling functions.
Code Block | ||
---|---|---|
| ||
errno_t strncpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2, rsize_t n); errno_t strcat_s(char * restrict s1, rsize_t s1max, const char * restrict s2); |
...