Properly handle *snprintf() errors
Posix guarantees that the resulting string is null-terminated, even if we have an overflow. Instead of doing what has already been done, properly warn when there has been an error or overflow, so the user can do something about it.
This commit is contained in:
parent
b759662983
commit
c83b388a3f
17
slstatus.c
17
slstatus.c
@ -1,4 +1,5 @@
|
|||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
#include <errno.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -53,7 +54,7 @@ main(int argc, char *argv[])
|
|||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
struct timespec start, current, diff, intspec, wait;
|
struct timespec start, current, diff, intspec, wait;
|
||||||
size_t i, len;
|
size_t i, len;
|
||||||
int sflag;
|
int sflag, ret;
|
||||||
char status[MAXLEN];
|
char status[MAXLEN];
|
||||||
|
|
||||||
sflag = 0;
|
sflag = 0;
|
||||||
@ -88,12 +89,16 @@ main(int argc, char *argv[])
|
|||||||
for (i = len = 0; i < LEN(args); i++) {
|
for (i = len = 0; i < LEN(args); i++) {
|
||||||
const char * res = args[i].func(args[i].args);
|
const char * res = args[i].func(args[i].args);
|
||||||
res = (res == NULL) ? unknown_str : res;
|
res = (res == NULL) ? unknown_str : res;
|
||||||
len += snprintf(status + len, sizeof(status) - len,
|
if ((ret = snprintf(status + len, sizeof(status) - len,
|
||||||
args[i].fmt, res);
|
args[i].fmt, res)) < 0) {
|
||||||
|
fprintf(stderr, "snprintf: %s\n",
|
||||||
if (len >= sizeof(status)) {
|
strerror(errno));
|
||||||
status[sizeof(status) - 1] = '\0';
|
break;
|
||||||
|
} else if ((size_t)ret >= sizeof(status) - len) {
|
||||||
|
fprintf(stderr, "snprintf: Output truncated\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
len += ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sflag) {
|
if (sflag) {
|
||||||
|
12
util.c
12
util.c
@ -10,15 +10,15 @@ const char *
|
|||||||
bprintf(const char *fmt, ...)
|
bprintf(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
size_t len;
|
int ret;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
len = vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
|
if ((ret = vsnprintf(buf, sizeof(buf), fmt, ap)) < 0) {
|
||||||
va_end(ap);
|
fprintf(stderr, "vsnprintf: %s\n", strerror(errno));
|
||||||
|
} else if ((size_t)ret >= sizeof(buf)) {
|
||||||
if (len >= sizeof(buf)) {
|
fprintf(stderr, "vsnprintf: Output truncated\n");
|
||||||
buf[sizeof(buf)-1] = '\0';
|
|
||||||
}
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user