...
This specific noncompliant code example is from the Linux Kernel Mailing List archive site, although similar examples are common.
Code Block |
---|
|
int i;
ssize_t count = 0;
for (i = 0; i < 9; ++i) {
count += sprintf(
buf + count, "%02x ", ((u8 *)&slreg_num)[i]
);
}
count += sprintf(buf + count, "\n");
|
...
Wiki Markup |
---|
This compliant solution shows the redesigned API for {{sprintf()}} from the CERT managed string library \[[Burch 2006|AA. Bibliography#Burch06]\]. |
Code Block |
---|
|
errno_t sprintf_m(
string_m buf,
const string_m fmt,
int *count,
...
);
|
...
The previous code example can be amended as follows:
Code Block |
---|
|
int i;
rsize_t count = 0;
errno_t err;
for (i = 0; i < 9; ++i) {
err = sprintf_m(
buf + count, "%02x ", &count, ((u8 *)&slreg_num)[i]
);
if (err != 0) {
/* Handle print error */
}
}
err = sprintf_m(
buf + count, "%02x ", &count, ((u8 *)&slreg_num)[i]
);
if (err != 0) {
/* Handle print error */
}
|
...
The ssize_t
data type is designed as a "signed representation of size_t
." Consequently, it is often used as a return type for functions that can return an unsigned value upon success and a negative value upon error. For instance, the POSIX read()
function has the following signature:
Code Block |
---|
|
ssize_t read(int fildes, void *buf, size_t nbyte);
|
...
An alternative hypothetical signature for the read()
function would be
Code Block |
---|
|
errno_t read(int fildes, void *buf, size_t nbyte, size_t* rbytes);
|
...
In this noncompliant code example, the error handler returns normally, while the strcpy_s()
function's return value is not checked.
Code Block |
---|
|
constraint_handler_t handle_errors(void) {
constraint_handler_t data;
/* define what to do when error occurs */
return data;
}
/*...*/
set_constraint_handler(handle_errors);
/*...*/
/* Returns zero on success */
errno_t function(char *dst1){
char src1[100] = "hello";
strcpy_s(dst1, sizeof(dst1), src1);
/* At this point strcpy_s may have yielded an
error and handle_errors() might have returned */
/* ... */
return 0;
}
|
...
In this compliant solution, the error handler terminates the program, ensuring that strcpy_s()
never returns unless it fully succeeds.
Code Block |
---|
|
/*
* The abort_handler_s() function writes a message on the
* standard error stream and then calls the abort() function.
*/
set_constraint_handler(abort_handler_s);
/*...*/
/* Returns zero on success */
errno_t function(char *dst1){
char src1[100] = "hello";
strcpy_s(dst1, sizeof(dst1), src1);
/* Because abort_handler_s() never returns,
we only get here if strcpy_s() succeeds. */
/* ... */
return 0;
}
|
...