Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon, 25 Mar 2024 13:13:20 +0000
From: Alexander Weps <exander77@...me>
To: Rich Felker <dalias@...c.org>
Cc: musl@...ts.openwall.com
Subject: Re: Broken mktime calculations when crossing DST boundary

Have you read that e-mail? That case is addressed there as well...

So I am putting it here again, so you don't need to search for it:

> If you take your test program and switch it to initialize with
> tm_mday=31, then do -=1 instead of +=1, you'll find that it gives
> 2011-12-29 01:00:00 -10 as well, only now it seems like the correct,
> expected thing to happen. Any change to "fix" the case you're
> complaining about would necessarily break this case.

So (-day, +day):

Musl:
2011-12-31 01:00:00 +14
2011-12-29 01:00:00 -10
2011-12-29 01:00:00 -10

Glibc:
2012-01-01 01:00:00 +14
2011-12-31 01:00:00 +14
2012-01-01 01:00:00 +14

Seems like musl doesn't even interpret the initial struct tm correctly in that case. It is off by day.

Because December only had 30 days, 31s day after normalization is January 1st.

So no, musl is not correct, it is even more incorrect.

Jesus Christ.

AW

On Monday, March 25th, 2024 at 14:07, Rich Felker <dalias@...c.org> wrote:

> On Mon, Mar 25, 2024 at 12:55:28PM +0000, Alexander Weps wrote:
>
> > See below.
> >
> > AW
> >
> > On Monday, March 25th, 2024 at 13:21, Rich Felker dalias@...c.org wrote:
> >
> > > On Mon, Mar 25, 2024 at 11:52:00AM +0000, Alexander Weps wrote:
> > >
> > > > This is the simplest and most obvious example how broken the
> > > > calculation in musl is:
> > > >
> > > > void test10()
> > > > {
> > > > time_t t = 0;
> > > > struct tm tm = {0};
> > > > char buf[64];
> > > >
> > > > tm.tm_year = 2011 - 1900;
> > > > tm.tm_mon = 12 - 1;
> > > > tm.tm_mday = 29;
> > > > tm.tm_hour = 0;
> > > > tm.tm_min = 0;
> > > > tm.tm_sec = 0;
> > > > tm.tm_isdst = 0;
> > > >
> > > > strftime(buf, sizeof buf, "%F %T %Z", &tm);
> > > > printf("before: %s %ld %ld\n", buf, t, calc(&tm));
> > > >
> > > > t = mktime(&tm);
> > > >
> > > > strftime(buf, sizeof buf, "%F %T %Z", &tm);
> > > > printf("after1: %s %ld %ld\n", buf, t, calc(&tm));
> > > >
> > > > tm.tm_mday += 1;
> > > > t = mktime(&tm);
> > > >
> > > > strftime(buf, sizeof buf, "%F %T %Z", &tm);
> > > > printf("after2: %s %ld %ld\n", buf, t, calc(&tm));
> > > > }
> > > >
> > > > TZ=Pacific/Apia
> > > > Year is greater than 1970.
> > > >
> > > > Input:
> > > > 2011-12-29 01:00:00 -10
> > > >
> > > > Add a day:
> > > > tm.tm_mday += 1;
> > > > t = mktime(&tm);
> > > >
> > > > Output:
> > > > 2011-12-29 01:00:00 -10
> > > >
> > > > Musl cannot reliably increment date by a day. Incrementing struct tm
> > > > representing 2011-12-29 01:00:00 -10 by one day leads to the same
> > > > date.
> > > >
> > > > Causing a program to loop or stack overflow.
> > >
> > > I thought you had found a real bug here, and spent some time working
> > > out the math by hand on paper because local time is so headbangingly
> > > awful and confusing. In the end, the conclusion I'm left with is that
> > > it's working just as expected.
> >
> > It isn't.
> >
> > Output from musl:
> >
> > 2011-12-29 01:00:00 -10
> >
> > tm.tm_mday += 1;
> > t = mktime(&tm);
> >
> > 2011-12-29 01:00:00 -10 <-- date is the same after incrementing
> >
> > tm.tm_mday -= 1;
> > t = mktime(&tm);
>
>
> Read my mail again. I'm talking about starting from 2011-12-31 and
> decrementing.
>
> Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.