summaryrefslogtreecommitdiff
path: root/src/time
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-10-08 23:30:42 +0000
committerRich Felker <dalias@aerifal.cx>2015-10-08 23:30:42 +0000
commitc82d3bada30cb27e14abda7859da5d2e784830ff (patch)
tree080b81ab7a2c1036c37bb07b46886c40c961fd52 /src/time
parent7b9f57f207b51132f188f750161953b7baf32154 (diff)
downloadmusl-c82d3bada30cb27e14abda7859da5d2e784830ff.tar.gz
fix integer overflows in time_t/struct tm conversion code
as found and reported by Brian Mastenbrook, the expressions 400*qc_cycles and years+100 in __secs_to_tm were both subject to integer overflow for extreme values of the input t. this patch by Szabolcs Nagy fixes the code by switching to larger types, and matches the original intent I had in mind when writing this code.
Diffstat (limited to 'src/time')
-rw-r--r--src/time/__secs_to_tm.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/time/__secs_to_tm.c b/src/time/__secs_to_tm.c
index f3c1cf92..3a3123a1 100644
--- a/src/time/__secs_to_tm.c
+++ b/src/time/__secs_to_tm.c
@@ -10,10 +10,10 @@
int __secs_to_tm(long long t, struct tm *tm)
{
- long long days, secs;
+ long long days, secs, years;
int remdays, remsecs, remyears;
int qc_cycles, c_cycles, q_cycles;
- int years, months;
+ int months;
int wday, yday, leap;
static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
@@ -55,7 +55,7 @@ int __secs_to_tm(long long t, struct tm *tm)
yday = remdays + 31 + 28 + leap;
if (yday >= 365+leap) yday -= 365+leap;
- years = remyears + 4*q_cycles + 100*c_cycles + 400*qc_cycles;
+ years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles;
for (months=0; days_in_month[months] <= remdays; months++)
remdays -= days_in_month[months];