Submitter: Clive H Pygott
Submission Date: 2014-03-11
Subject: CSCR error in 5.21 example
Summary
The (cut-down) requirement for rule 5.21 is:
A call to a standard memory allocation function is presumed to be intended for type T * when it appears in any of the following contexts
A call to a standard memory allocation function taking a size integer argument n and presumed to be intended for type T * shall be
diagnosed when n < sizeof(T).
{malloc is identified as a standard memory allocation function}
The example for 5.21 is:
wchar_t *f1(void) {
const wchar_t *p = L"Hello, World!";
const size_t n = sizeof(p) * (wcslen(p) + 1);
wchar_t *q = (wchar_t *)malloc(n); // diagnostic required
/* ... */
return q;
}
Why is a diagnostic required on the malloc statement? On my machine
Indeed, the only values of n that would require a diagnostic are 0 and 1.
I think the original intent was to make q smaller than 28 (the space required for 14 wide characters), then copy p to q (buffer overrun),
but this rule doesn’t actually address that and the copy isn’t included in the example. That is, I think the original example was to be
of the form:
This does have an issue - buffer overrun, but still doesn’t violate 5.21 as currently stated (14 is still >= 2).
I think the reason 5.21 got changed was either:
wchar_t *f2(void) {
const wchar_t *p = L"Hello, World!";
const size_t n = /*sizeof(p) * */ (wcslen(p) + 1); /* NB n == 14 */
wchar_t *q = (wchar_t *)malloc(n);
wcscpy(q, p);
return q;
}
Suggested Technical Corrigendum
Either 5.21 needs a different example, such as :
struct S1 { int x, y, z;}; /* sizeof(S1) is 12 */
struct S1 *copyS1(const struct S1 s) {
struct S1 *q = (struct S1 *)malloc(8); /* Diagnostic required */
*q = s;
return q;
}
or the rule needs to be changed to reflect that the allocated memory is in effect an array of size n/sizeof(T),
and that it shouldn’t be indexed beyond that size (including by copy functions such as wcscpy etc. - this caveat may also need to be added to 5.22)
I'd favour changing the example