瀏覽代碼

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.
Laslo Hunhold 7 年之前
父節點
當前提交
c83b388a3f
共有 2 個文件被更改,包括 17 次插入12 次删除
  1. 11 6
      slstatus.c
  2. 6 6
      util.c

+ 11 - 6
slstatus.c

@@ -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) {

+ 6 - 6
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;
 }