summaryrefslogtreecommitdiff
path: root/date.c
diff options
context:
space:
mode:
Diffstat (limited to 'date.c')
-rw-r--r--date.c44
1 files changed, 22 insertions, 22 deletions
diff --git a/date.c b/date.c
index 4e4b355af03f..11c5e5fe8d49 100644
--- a/date.c
+++ b/date.c
@@ -42,7 +42,7 @@ static void display(const char *, time_t);
static void dogmt(void);
static void errensure(void);
static void timeout(FILE *, const char *, const struct tm *);
-static _Noreturn void usage(void);
+static ATTRIBUTE_NORETURN void usage(void);
int
main(const int argc, char *argv[])
@@ -117,14 +117,19 @@ dogmt(void)
static char ** fakeenv;
if (fakeenv == NULL) {
- register int from;
- register int to;
- register int n;
static char tzeutc0[] = "TZ=UTC0";
+ ptrdiff_t from, to, n;
for (n = 0; environ[n] != NULL; ++n)
continue;
- fakeenv = malloc((n + 2) * sizeof *fakeenv);
+#if defined ckd_add && defined ckd_mul
+ if (!ckd_add(&n, n, 2) && !ckd_mul(&n, n, sizeof *fakeenv)
+ && n <= SIZE_MAX)
+ fakeenv = malloc(n);
+#else
+ if (n <= min(PTRDIFF_MAX, SIZE_MAX) / sizeof *fakeenv - 2)
+ fakeenv = malloc((n + 2) * sizeof *fakeenv);
+#endif
if (fakeenv == NULL) {
fprintf(stderr, _("date: Memory exhausted\n"));
errensure();
@@ -183,33 +188,28 @@ display(char const *format, time_t now)
static void
timeout(FILE *fp, char const *format, struct tm const *tmp)
{
- char * cp;
- size_t result;
- size_t size;
- struct tm tm;
- int INCR = 1024;
+ char *cp = NULL;
+ ptrdiff_t result;
+ ptrdiff_t size = 1024 / 2;
- if (!tmp) {
- fprintf(stderr, _("date: error: time out of range\n"));
- errensure();
- return;
- }
- tm = *tmp;
- tmp = &tm;
- size = INCR;
- cp = malloc(size);
for ( ; ; ) {
- if (cp == NULL) {
+#ifdef ckd_mul
+ bool bigger = !ckd_mul(&size, size, 2) && size <= SIZE_MAX;
+#else
+ bool bigger = (size <= min(PTRDIFF_MAX, SIZE_MAX) / 2
+ && (size *= 2, true));
+#endif
+ char *newcp = bigger ? realloc(cp, size) : NULL;
+ if (!newcp) {
fprintf(stderr,
_("date: error: can't get memory\n"));
errensure();
exit(retval);
}
+ cp = newcp;
result = strftime(cp, size, format, tmp);
if (result != 0)
break;
- size += INCR;
- cp = realloc(cp, size);
}
fwrite(cp + 1, 1, result - 1, fp);
free(cp);