...
The assert
macro expands to a void expression:
Code Block |
---|
#include <assert.h>
void assert(scalar expression);
|
...
In the following example, the test for integer wrap was omitted for the unsigned multiplication based on the assumption that MAX_TABLE_SIZE * sizeof(char *)
cannot exceed SIZE_MAX
. While Although we know this is true, it cannot do any harm to codify this assumption.
Code Block | ||||
---|---|---|---|---|
| ||||
assert(size <= SIZE_MAX/sizeof(char *));
table_size = size * sizeof(char *);
|
Assertions are primarily intended for use during debugging , and are generally turned off before code is deployed by defining the NDEBUG
macro (typically as a flag passed to the compiler). Consequently, assertions should be used to protect against incorrect programmer assumptions and not for runtime error checking.
...
- invalid user input (including command-line arguments and environment variables)
- file errors (for example, errors opening, reading or writing files)
- network errors (including network protocol errors)
- out-of-memory conditions (for example,
malloc()
or similar failures) - system resource exhaustion (for example, out-of-file descriptors, processes, threads)
- system call errors (for example, errors executing files, locking or unlocking mutexes)
- invalid permissions (for example, file, memory, user)
...
Code Block | ||||
---|---|---|---|---|
| ||||
if (size > SIZE_MAX / sizeof(char *)) {
fprintf(log_file, "%s: size %zu exceeds %zu bytes\n",
__FILE__, size, SIZE_MAX / sizeof(char *));
size = SIZE_MAX / sizeof(char *);
}
table_size = size * sizeof(char *);
|
...
Noncompliant Code Example (malloc()
)
The This noncompliant code example below uses the assert()
macro to verify that memory allocation succeeded. Because memory availability depends on the overall state of the system and can become exhausted at any point during a process lifetime, a robust program must be prepared to gracefully handle and recover from its exhaustion. Therefore, using the assert()
macro to verify that a memory allocation succeeded would be inappropriate because doing so might lead to an abrupt termination of the process, opening up the possibility of a denial-of-service attack. See also recommendation MEM11-C. Do not assume infinite heap space and rule MEM32-C. Detect and handle memory allocation errors.
Code Block | ||||
---|---|---|---|---|
| ||||
char *dupstring(const char *str) {
size_t len;
char *dup;
len = strlen(str);
dup = (char *)malloc(len + 1);
assert(NULL != dup);
memcpy(dup, str, len + 1);
return dup;
}
|
...
Compliant Solution (malloc()
)
The This compliant solution below demonstrates how to detect and handle possible memory exhaustion.
Code Block | ||||
---|---|---|---|---|
| ||||
char *dupstring(const char *str) {
size_t len;
char *dup;
len = strlen(str);
dup = (char*)malloc(len + 1);
/* detect and handle memory allocation error */
if (NULL == dup) {
return NULL;
}
memcpy(dup, str, len + 1);
return dup;
}
|
...
Tool | Version | Checker | Description | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Section | |
| ASSERT_SIDE_EFFECT | Section | Can detect the specific instance where assertion contains an operation/function call whichthat may have a side effect. |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
ERR00-C. Adopt and implement a consistent and comprehensive error-handling policy
CERT C++ Secure Coding Standard: MSC11-CPP. Incorporate diagnostic tests using assertions
...
2011 Section 7.2.1, "Program diagnostics"
...
assertion
...
...