Properly handle *snprintf() errors
authorLaslo Hunhold <dev@frign.de>
Thu, 17 May 2018 21:23:28 +0000 (23:23 +0200)
committerAaron Marcher <me@drkhsh.at>
Thu, 17 May 2018 21:26:56 +0000 (23:26 +0200)
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.

slstatus.c
util.c

index e8d367bb33480bd884a5ac589d26b81e95386003..35bdcd6372002008f8731dde2bc5364d7cdc327b 100644 (file)
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#include <errno.h>
 #include <locale.h>
 #include <signal.h>
 #include <stdio.h>
@@ -53,7 +54,7 @@ main(int argc, char *argv[])
        struct sigaction act;
        struct timespec start, current, diff, intspec, wait;
        size_t i, len;
-       int sflag;
+       int sflag, ret;
        char status[MAXLEN];
 
        sflag = 0;
@@ -88,12 +89,16 @@ main(int argc, char *argv[])
                for (i = len = 0; i < LEN(args); i++) {
                        const char * res = args[i].func(args[i].args);
                        res = (res == NULL) ? unknown_str : res;
-                       len += snprintf(status + len, sizeof(status) - len,
-                                       args[i].fmt, res);
-
-                       if (len >= sizeof(status)) {
-                               status[sizeof(status) - 1] = '\0';
+                       if ((ret = snprintf(status + len, sizeof(status) - len,
+                                           args[i].fmt, res)) < 0) {
+                               fprintf(stderr, "snprintf: %s\n",
+                                       strerror(errno));
+                               break;
+                       } else if ((size_t)ret >= sizeof(status) - len) {
+                               fprintf(stderr, "snprintf: Output truncated\n");
+                               break;
                        }
+                       len += ret;
                }
 
                if (sflag) {
diff --git a/util.c b/util.c
index 8808abad671efa18fb41b8f327c9ca18537f07a7..6113049cdcae1f987e700ceaf8e826bb2549f7c9 100644 (file)
--- a/util.c
+++ b/util.c
@@ -10,15 +10,15 @@ const char *
 bprintf(const char *fmt, ...)
 {
        va_list ap;
-       size_t len;
+       int ret;
 
        va_start(ap, fmt);
-       len = vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
-       va_end(ap);
-
-       if (len >= sizeof(buf)) {
-               buf[sizeof(buf)-1] = '\0';
+       if ((ret = vsnprintf(buf, sizeof(buf), fmt, ap)) < 0) {
+               fprintf(stderr, "vsnprintf: %s\n", strerror(errno));
+       } else if ((size_t)ret >= sizeof(buf)) {
+               fprintf(stderr, "vsnprintf: Output truncated\n");
        }
+       va_end(ap);
 
        return buf;
 }