...
The following noncompliant code overflows its buffer if msg
is too long, and has undefined behavior if msg
is a null pointer.
Code Block | ||||
---|---|---|---|---|
| ||||
void complain(const char *msg) { static const char prefix[] = "Error: "; static const char suffix[] = "\n"; char buf[BUFSIZ]; strcpy(buf, prefix); strcat(buf, msg); strcat(buf, suffix); fputs(buf, stderr); } |
...
The following compliant solution will not overflow its buffer.
Code Block | ||||
---|---|---|---|---|
| ||||
void complain(const char *msg) { errno_t err; static const char prefix[] = "Error: "; static const char suffix[] = "\n"; char buf[BUFSIZ]; err = strcpy_s(buf, sizeof(buf), prefix); if (err != 0) { /* handle error */ } err = strcat_s(buf, sizeof(buf), msg); if (err != 0) { /* handle error */ } err = strcat_s(buf, sizeof(buf), suffix); if (err != 0) { /* handle error */ } fputs(buf, stderr); } |
...
The following compliant solution performs some of the checking at compile time using a static assertion. (See recommendation DCL03-C. Use a static assertion to test the value of a constant expression.)
Code Block | ||||
---|---|---|---|---|
| ||||
void complain(const char *msg) { errno_t err; static const char prefix[] = "Error: "; static const char suffix[] = "\n"; char buf[BUFSIZ]; /* Ensure that more than one character * is available for msg. */ static_assert(sizeof(buf) > sizeof(prefix) + sizeof(suffix), "Buffer for complain() is too small"); strcpy(buf, prefix); err = strcat_s(buf, sizeof(buf), msg); if (err != 0) { /* handle error */ } err = strcat_s(buf, sizeof(buf), suffix); if (err != 0) { /* handle error */ } fputs(buf, stderr); } |
...