Re: Bug in UTC -> localtime conversion after 2038
Jeff Johnston via Newlib <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <CAOox84trYiOGQkCPkvfnm6JLrRkBX87Vvge95MVTJMcZyC2wSA@mail.gmail.com> |
Thanks Ivan. I added the patch manually as you didn't attach it, but made you the author. Patch applied. -- Jeff J. On Wed, Nov 4, 2020 at 11:21 AM Ivan Grokhotkov via Newlib < [email protected]> wrote: > > > > On 4 Nov 2020, at 12:36, Udo de Boer <[email protected]> wrote: > > > > [External: This email originated outside Espressif] > > > > Hi, > > > > UTC time to local timezone conversion did not work for years after 2038. > > Daylight saving in the timezone was not recognized. Tested on 32bit > > xtensa architecture with GCC 8.4 (esp32) and with 64bit time_t enabled. > > > > The struct tm is filled correct. So year, day etc are all filled with > > the correct values. But the tm.tm_isdst is 0 and no daylight saving is > > applied. > > > > It was caused by the following calculation in time/tzcalc_limits.c at > > line 68 > > > > /* store the change-over time in GMT form by adding offset */ > > tz->__tzrule[i].change = days * SECSPERDAY + > > tz->__tzrule[i].s + tz->__tzrule[i].offset; > > > > Here tz->__tzrule[i].change is a time_t (64bit). For some reason the > > compiler does the calculation in 32 bit. All variables used in the > > calculation are 32bit. > > > > I solved this locally by changing the lines to. > > > > /* store the change-over time in GMT form by adding offset */ > > tz->__tzrule[i].change = (time_t)days * SECSPERDAY + > > tz->__tzrule[i].s + tz->__tzrule[i].offset; > > > > Adding the cast time_t should not cause a problem when time_t is still > > 32bit. > > > > I don't know if this is correct solution. I also only needed this > > function. So more bugs like this could be hidden away in the time code. > > > > > > > > > > > > > > > > > Thank you for reporting and proposing the fix! > Espressif will include this into the next esp32 toolchain release. > > For the convenience of the maintainers, I’ve attached the patch below. > > > Best regards, > Ivan Grokhotkov > > > > From 782c19cd861479cf09a4e2ee27bb7fec1872c626 Mon Sep 17 00:00:00 2001 > From: Ivan Grokhotkov <[email protected]> > Date: Wed, 4 Nov 2020 16:49:51 +0100 > Subject: [PATCH] newlib: libc: fix 32-bit integer overflow when > calculating TZ > rules > > --- > newlib/libc/time/tzcalc_limits.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/newlib/libc/time/tzcalc_limits.c > b/newlib/libc/time/tzcalc_limits.c > index e0ea6549c..00044a5d3 100644 > --- a/newlib/libc/time/tzcalc_limits.c > +++ b/newlib/libc/time/tzcalc_limits.c > @@ -66,7 +66,7 @@ __tzcalc_limits (int year) > } > > /* store the change-over time in GMT form by adding offset */ > - tz->__tzrule[i].change = days * SECSPERDAY + > + tz->__tzrule[i].change = (time_t) days * SECSPERDAY + > tz->__tzrule[i].s + tz->__tzrule[i].offset; > } > > -- > 2.21.0 (Apple Git-122) > > > > > >