upstream: rewrite convtime() to use a isdigit-scanner and

strtonum() instead of strange strtoul can might be fooled by garage
characters. passes regress/usr.bin/ssh/unittests/misc ok djm

OpenBSD-Commit-ID: 4b1ef826bb16047aea3f3bdcb385b72ffd450abc
This commit is contained in:
deraadt@openbsd.org 2024-04-02 09:52:14 +00:00 committed by Damien Miller
parent 8673137f78
commit 9f543d7022
No known key found for this signature in database
1 changed files with 36 additions and 22 deletions

58
misc.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.190 2024/03/04 02:16:11 djm Exp $ */ /* $OpenBSD: misc.c,v 1.191 2024/04/02 09:52:14 deraadt Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005-2020 Damien Miller. All rights reserved. * Copyright (c) 2005-2020 Damien Miller. All rights reserved.
@ -563,6 +563,14 @@ a2tun(const char *s, int *remote)
#define DAYS (HOURS * 24) #define DAYS (HOURS * 24)
#define WEEKS (DAYS * 7) #define WEEKS (DAYS * 7)
static char *
scandigits(char *s)
{
while (isdigit((unsigned char)*s))
s++;
return s;
}
/* /*
* Convert a time string into seconds; format is * Convert a time string into seconds; format is
* a sequence of: * a sequence of:
@ -587,28 +595,31 @@ a2tun(const char *s, int *remote)
int int
convtime(const char *s) convtime(const char *s)
{ {
long total, secs, multiplier; int secs, total = 0, multiplier;
const char *p; char *p, *os, *np, c;
char *endp; const char *errstr;
errno = 0; if (s == NULL || *s == '\0')
total = 0; return -1;
p = s; p = os = strdup(s); /* deal with const */
if (os == NULL)
if (p == NULL || *p == '\0')
return -1; return -1;
while (*p) { while (*p) {
secs = strtol(p, &endp, 10); np = scandigits(p);
if (p == endp || if (np) {
(errno == ERANGE && (secs == INT_MIN || secs == INT_MAX)) || c = *np;
secs < 0) *np = '\0';
return -1; }
secs = (int)strtonum(p, 0, INT_MAX, &errstr);
if (errstr)
goto fail;
*np = c;
multiplier = 1; multiplier = 1;
switch (*endp++) { switch (c) {
case '\0': case '\0':
endp--; np--; /* back up */
break; break;
case 's': case 's':
case 'S': case 'S':
@ -630,20 +641,23 @@ convtime(const char *s)
multiplier = WEEKS; multiplier = WEEKS;
break; break;
default: default:
return -1; goto fail;
} }
if (secs > INT_MAX / multiplier) if (secs > INT_MAX / multiplier)
return -1; goto fail;
secs *= multiplier; secs *= multiplier;
if (total > INT_MAX - secs) if (total > INT_MAX - secs)
return -1; goto fail;
total += secs; total += secs;
if (total < 0) if (total < 0)
return -1; goto fail;
p = endp; p = ++np;
} }
free(os);
return total; return total;
fail:
free(os);
return -1;
} }
#define TF_BUFS 8 #define TF_BUFS 8