summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2022-07-07 10:40:26 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2022-07-07 10:40:26 +0000
commit4830b6f9f5344c8ce04b073e7209b04599f8a01a (patch)
treec1a1a17bd47e8b0c7690dd619b5ce7ebe59a9cfc
parent2f1169179b84735300e41378dbcc1531660ccb72 (diff)
Handle strange format strings better.
Make sure that the allocated buffers are not zero sized even for an empty format string. Also do not call strftime if the buffer is empty. The return value of strftime does not distinguish between an empty format string and an overflow of the output buffer. Finally auto scale the size of the outbuf in case strftime fails. Some format specifiers expand to 25 and more chars so it is hard to guess in advance what size is required. This may waste some memory but it keeps the code as simple as possible. OK tb@
-rw-r--r--usr.bin/ts/ts.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/usr.bin/ts/ts.c b/usr.bin/ts/ts.c
index 5bb55939f3f..ccfe21f8b17 100644
--- a/usr.bin/ts/ts.c
+++ b/usr.bin/ts/ts.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ts.c,v 1.7 2022/07/06 07:59:03 claudio Exp $ */
+/* $OpenBSD: ts.c,v 1.8 2022/07/07 10:40:25 claudio Exp $ */
/*
* Copyright (c) 2022 Job Snijders <job@openbsd.org>
* Copyright (c) 2022 Claudio Jeker <claudio@openbsd.org>
@@ -31,6 +31,7 @@ static char *format = "%b %d %H:%M:%S";
static char *buf;
static char *outbuf;
static size_t bufsize;
+static size_t obsize;
static void fmtfmt(const struct timespec *);
static void __dead usage(void);
@@ -77,14 +78,14 @@ main(int argc, char *argv[])
if (argc == 1)
format = *argv;
- bufsize = strlen(format);
+ bufsize = strlen(format) + 1;
if (bufsize > SIZE_MAX / 10)
errx(1, "format string too big");
-
bufsize *= 10;
+ obsize = bufsize;
if ((buf = calloc(1, bufsize)) == NULL)
err(1, NULL);
- if ((outbuf = calloc(1, bufsize)) == NULL)
+ if ((outbuf = calloc(1, obsize)) == NULL)
err(1, NULL);
/* force UTC for interval calculations */
@@ -165,9 +166,14 @@ fmtfmt(const struct timespec *ts)
}
} while (*f != '\0');
- if (strftime(outbuf, bufsize, buf, tm) == 0)
- errx(1, "strftime");
-
+ *outbuf = '\0';
+ if (*buf != '\0') {
+ while (strftime(outbuf, obsize, buf, tm) == 0) {
+ if ((outbuf = reallocarray(outbuf, 2, obsize)) == NULL)
+ err(1, NULL);
+ obsize *= 2;
+ }
+ }
fprintf(stdout, "%s ", outbuf);
if (ferror(stdout))
exit(1);