mirror of
https://github.com/stedolan/jq.git
synced 2024-05-11 05:55:39 +00:00
util.c: fix _WIN32 port of strptime (#3071)
In windows, time_t is a signed 32-bit integer type, so TIME_MAX needs to be declared as INT32_MAX instead of INT64_MAX. Also bump NetBSD's strptime to revision 1.65 from 1.63 to fix undefined behaviour (signed integer overflow) bugs. Related NetBSD problem report: https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58041 Noticed thanks to a compiler warning in the windows build CI. I declared the d variable as time_t instead of as unsigned to ensure that the signedness/size of TIME_MAX-d in the sse > TIME_MAX-d check is always correct, and to prevent -Wsign-compare warnings from triggering in the windows build.
This commit is contained in:
+36
-29
@@ -818,40 +818,47 @@ recurse:
|
||||
LEGAL_ALT(ALT_O);
|
||||
continue;
|
||||
|
||||
#ifndef TIME_MAX
|
||||
#define TIME_MAX INT64_MAX
|
||||
#endif
|
||||
case 's': /* seconds since the epoch */
|
||||
{
|
||||
time_t sse = 0;
|
||||
uint64_t rulim = TIME_MAX;
|
||||
|
||||
if (*bp < '0' || *bp > '9') {
|
||||
bp = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
sse *= 10;
|
||||
sse += *bp++ - '0';
|
||||
rulim /= 10;
|
||||
} while ((sse * 10 <= TIME_MAX) &&
|
||||
rulim && *bp >= '0' && *bp <= '9');
|
||||
|
||||
if (sse < 0 || (uint64_t)sse > TIME_MAX) {
|
||||
bp = NULL;
|
||||
continue;
|
||||
}
|
||||
case 's': { /* seconds since the epoch */
|
||||
#ifdef _WIN32
|
||||
if (localtime_s(tm, &sse) == 0)
|
||||
const time_t TIME_MAX = INT32_MAX;
|
||||
#else
|
||||
if (localtime_r(&sse, tm))
|
||||
const time_t TIME_MAX = INT64_MAX;
|
||||
#endif
|
||||
state |= S_YDAY | S_WDAY | S_MON | S_MDAY | S_YEAR;
|
||||
else
|
||||
bp = NULL;
|
||||
time_t sse;
|
||||
time_t d;
|
||||
|
||||
if (*bp < '0' || *bp > '9') {
|
||||
bp = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
sse = *bp++ - '0';
|
||||
while (*bp >= '0' && *bp <= '9') {
|
||||
d = *bp++ - '0';
|
||||
if (sse > TIME_MAX/10) {
|
||||
bp = NULL;
|
||||
break;
|
||||
}
|
||||
sse *= 10;
|
||||
if (sse > TIME_MAX - d) {
|
||||
bp = NULL;
|
||||
break;
|
||||
}
|
||||
sse += d;
|
||||
}
|
||||
if (bp == NULL)
|
||||
continue;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (localtime_s(tm, &sse))
|
||||
#else
|
||||
if (localtime_r(&sse, tm) == NULL)
|
||||
#endif
|
||||
bp = NULL;
|
||||
else
|
||||
state |= S_YDAY | S_WDAY | S_MON | S_MDAY | S_YEAR;
|
||||
continue;
|
||||
}
|
||||
|
||||
case 'U': /* The week of year, beginning on sunday. */
|
||||
case 'W': /* The week of year, beginning on monday. */
|
||||
|
||||
Reference in New Issue
Block a user