...
In this compliant solution, the result of realloc()
is assigned to the temporary pointer q
and validated before it is assigned to the original pointer p
.:
Code Block | ||||
---|---|---|---|---|
| ||||
void *p; void *q; size_t new_size= /* nonzero size */; q = realloc(p, new_size); if (q == NULL) { /* Handle error */ } else { p = q; } |
...
In the following noncompliant code example, snprinf()
is assumed to succeed. However, if the call fails (for example, because of insufficient memory, as described in GNU libc bug 441945), the subsequent call to log_message()
is likely to result in undefined behavior since because the character buffer is not initialized and need not be null-terminated.
...
When the length of the formatted string is unbounded, it is best to invoke the function twice, once with a NULL
buffer to determine the size of output, then dynamically allocate a buffer of sufficient size, and finally call snprintf()
again to format the output into the dynamically allocated buffer. Even with this approach the success of all calls still needs to be tested, and any errors still need to be appropriately handled. A possible optimization is to first attempt to format the string into a reasonably small buffer allocated on the stack and only when the buffer turns out to be too small allocate one of a sufficient size dynamically. This approach is shown in the following compliant solution.:
Code Block | ||||
---|---|---|---|---|
| ||||
void f(int i, int width, int prec) { char buffer[20]; char *buf = buffer; int n = sizeof buffer; const char fmt[] = "i = %*.*i"; n = snprintf(buf, n, fmt, width, prec, i); if (n < 0) { /* Handle snprintf() error */ strcpy(buffer, "unknown error"); goto write_log; } if (n < sizeof buffer) goto write_log; buf = (char*)malloc(n + 1); if (NULL == buf) { /* Handle malloc() error */ strcpy(buffer, "unknown error"); goto write_log; } n = snprintf(buf, n, fmt, width, prec, i); if (n < 0) { /* Handle snprintf() error */ strcpy(buffer, "unknown error"); } write_log: log_message(buf); if (buf != buffer) free(buf); } |
...
A compliant solution avoids assuming that fmemopen()
and open_memstream()
succeed regardless of its arguments and tests the return value of the function before using the file pointers in
and out
.:
Code Block | ||||
---|---|---|---|---|
| ||||
int main(int argc, char *argv[]) { FILE *out; FILE *in; if (argc != 2) { /* Handle error */ } in = fmemopen(argv[1], strlen(argv[1]), "r"); if (in == NULL){ /* Handle error */ } /* Use in */ out = open_memstream(&ptr, &size); if (out == NULL){ /* Handle error */ } /* Use out */ } |
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Compass/ROSE | Can detect violations of this recommendation when checking for violations of EXP12-C. Do not ignore values returned by functions and EXP34-C. Do not dereference null pointers. | ||||||||
| CHECKED_RETURN | Finds inconsistencies in how function call return values are handled. Coverity Prevent cannot discover all violations of this recommendation, so further verification is necessary. | |||||||
Fortify SCA | 5.0 |
| |||||||
| 80 D | Partially implemented. | |||||||
PRQA QA-C |
| 3200 | Partially implemented. |
Related Coding Practices
Coding Practice | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
medium | unlikely | medium | P2 | L3 | |
low | probable | high | P2 | L3 | |
FLP32-C. Prevent or detect domain and range errors in math functions | medium | probable | medium | P8 | L2 |
high | likely | medium | P18 | L1 | |
medium | probable | high | P4 | L3 | |
FIO33-C. Detect and handle input output errors resulting in undefined behavior | high | probable | medium | P12 | L1 |
low | unlikely | medium | P2 | L3 | |
ERR00-C. Adopt and implement a consistent and comprehensive error-handling policy | medium | probable | high | P4 | L3 |
low | unlikely | high | P1 | L3 | |
medium | probable | high | P4 | L3 | |
API04-C. Provide a consistent and usable error-checking mechanism | medium | unlikely | medium | P2 | L3 |
low | likely | medium | P6 | L2 | |
low | likely | medium | P6 | L2 |
...