diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c index fe9e10f9679..d31a501567b 100644 --- a/libc/tzcode/strptime.c +++ b/libc/tzcode/strptime.c @@ -1,4 +1,4 @@ -/* $OpenBSD: strptime.c,v 1.30 2019/05/12 12:49:52 schwarze Exp $ */ +/* $OpenBSD: strptime.c,v 1.31 2023/03/02 16:21:51 millert Exp $ */ /* $NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $ */ /*- * Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc. @@ -29,8 +29,10 @@ */ #include +#include +#include #include -#include +#include #include #include @@ -43,6 +45,8 @@ // Android: this code is not pointer-sign clean. #pragma clang diagnostic ignored "-Wpointer-sign" #pragma clang diagnostic ignored "-Wunused-function" +// Android: clang thinks people don't know && has higher precedence than ||. +#pragma clang diagnostic ignored "-Wlogical-op-parentheses" #define _ctloc(x) (_CurrentTimeLocale->x) @@ -78,8 +82,8 @@ static const int mon_lengths[2][MONSPERYEAR] = { { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; -static int _conv_num64(const unsigned char **, int64_t *, int64_t, int64_t); static int _conv_num(const unsigned char **, int *, int, int); +static int epoch_to_tm(const unsigned char **, struct tm *); static int leaps_thru_end_of(const int y); static char *_strptime(const char *, const char *, struct tm *, int); static const u_char *_find_string(const u_char *, int *, const char * const *, @@ -351,27 +355,10 @@ again: switch (c = *fmt++) { if (!(_conv_num(&bp, &tm->tm_sec, 0, 60))) return (NULL); break; - case 's': /* Seconds since epoch */ - { - // Android change based on FreeBSD's implementation. - int saved_errno = errno; - errno = 0; - const unsigned char* old_bp = bp; - long n = strtol((const char*) bp, (char**) &bp, 10); - errno = saved_errno; - time_t t = n; - if (bp == old_bp || errno == ERANGE || - ((long) t) != n) return NULL; - - if (localtime_r(&t, tm) == NULL) return NULL; - - //int64_t i64; - //if (!(_conv_num64(&bp, &i64, 0, INT64_MAX))) - // return (NULL); - //if (!gmtime_r(&i64, tm)) - // return (NULL); - fields = 0xffff; /* everything */ - } + case 's': /* Seconds since epoch. */ + if (!(epoch_to_tm(&bp, tm))) + return (NULL); + fields = 0xffff; /* everything */ break; case 'U': /* The week of year, beginning on sunday. */ case 'W': /* The week of year, beginning on monday. */ @@ -635,26 +622,27 @@ _conv_num(const unsigned char **buf, int *dest, int llim, int ulim) } static int -_conv_num64(const unsigned char **buf, int64_t *dest, int64_t llim, int64_t ulim) +epoch_to_tm(const unsigned char **buf, struct tm *tm) { - int result = 0; - int64_t rulim = ulim; - - if (**buf < '0' || **buf > '9') - return (0); - - /* we use rulim to break out of the loop when we run out of digits */ - do { - result *= 10; - result += *(*buf)++ - '0'; - rulim /= 10; - } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9'); - - if (result < llim || result > ulim) - return (0); - - *dest = result; - return (1); + int saved_errno = errno; + int ret = 0; + time_t secs; + char *ep; + + errno = 0; + secs = strtoll(*buf, &ep, 10); + if (*buf == (unsigned char *)ep) + goto done; + if (secs < 0 || + secs == LLONG_MAX && errno == ERANGE) + goto done; + if (localtime_r(&secs, tm) == NULL) + goto done; + ret = 1; +done: + *buf = ep; + errno = saved_errno; + return (ret); } static const u_char * diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h index 823f2a9b113..f8530457c77 100644 --- a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h +++ b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h @@ -26,7 +26,7 @@ THIS SOFTWARE. ****************************************************************/ -/* This is a variation on dtoa.c that converts arbitary binary +/* This is a variation on dtoa.c that converts arbitrary binary floating-point formats to and from decimal notation. It uses double-precision arithmetic internally, so there are still various #ifdefs that adapt the calculations to the native diff --git a/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c index da68b904286..3577fc91a53 100644 --- a/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c +++ b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: setvbuf.c,v 1.14 2016/09/21 04:38:56 guenther Exp $ */ +/* $OpenBSD: setvbuf.c,v 1.15 2022/09/28 16:44:14 gnezdo Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -31,6 +31,7 @@ * SUCH DAMAGE. */ +#include #include #include #include "local.h" @@ -52,7 +53,7 @@ setvbuf(FILE *fp, char *buf, int mode, size_t size) * when setting _IONBF. */ if (mode != _IONBF) - if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0) + if ((mode != _IOFBF && mode != _IOLBF) || size > INT_MAX) return (EOF); /* diff --git a/libc/upstream-openbsd/lib/libc/stdlib/div.c b/libc/upstream-openbsd/lib/libc/stdlib/div.c index beaa428c7a8..5e6164f0bb4 100644 --- a/libc/upstream-openbsd/lib/libc/stdlib/div.c +++ b/libc/upstream-openbsd/lib/libc/stdlib/div.c @@ -1,4 +1,4 @@ -/* $OpenBSD: div.c,v 1.6 2015/09/13 08:31:47 guenther Exp $ */ +/* $OpenBSD: div.c,v 1.7 2022/12/27 17:10:06 jmc Exp $ */ /* * Copyright (c) 1990 Regents of the University of California. * All rights reserved. @@ -46,7 +46,7 @@ div(int num, int denom) * words, we should always truncate the quotient towards * 0, never -infinity. * - * Machine division and remainer may work either way when + * Machine division and remainder may work either way when * one or both of n or d is negative. If only one is * negative and r.quot has been truncated towards -inf, * r.rem will have the same sign as denom and the opposite diff --git a/libc/upstream-openbsd/lib/libc/stdlib/setenv.c b/libc/upstream-openbsd/lib/libc/stdlib/setenv.c index 15c550ba30b..fc8e5b677f9 100644 --- a/libc/upstream-openbsd/lib/libc/stdlib/setenv.c +++ b/libc/upstream-openbsd/lib/libc/stdlib/setenv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: setenv.c,v 1.19 2016/09/21 04:38:56 guenther Exp $ */ +/* $OpenBSD: setenv.c,v 1.20 2022/08/08 22:40:03 millert Exp $ */ /* * Copyright (c) 1987 Regents of the University of California. * All rights reserved. @@ -48,9 +48,10 @@ putenv(char *str) for (cp = str; *cp && *cp != '='; ++cp) ; - if (*cp != '=') { + if (cp == str || *cp != '=') { + /* '=' is the first character of string or is missing. */ errno = EINVAL; - return (-1); /* missing `=' in string */ + return (-1); } if (__findenv(str, (int)(cp - str), &offset) != NULL) {