Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 27 Mar 2024 00:14:23 +0000
From: Alexander Weps <exander77@...me>
To: musl@...ts.openwall.com
Subject: Re: Broken mktime calculations when crossing DST boundary

See below.

AW


On Tuesday, March 26th, 2024 at 22:59, Thorsten Glaser <tg@...bsd.de> wrote:

> Alexander Weps dixit:
>
> > > Not at all, glibc’s mktime just throws the towel with
> > > EOVERFLOW saying that the requested time does not exist.
> >
> > How is this not compliant with POSIX?
>
>
> POSIX indicates that this is valid only if the date is not
> representable in time_t, and it has different handling for
> dates that fall into gaps, see the other mails from me, as
> well as below.
>

I think you confuse two things here:

1. mktime returning -1
2. mktime setting errno to EOVERFLOW

The 2. maybe debatable in obscure circles, but that's entirely unrelated.

But mktime can return -1 if and when it deems that struct tm cannot be represented in epoch seconds.

That is entirely compliant with POSIX and I would need to see some hard evidence for it not being the case.

>From Issue 7:

> RETURN VALUE
>
>     The mktime() function shall return the specified time since the Epoch encoded as a value of type time_t. If the time since the Epoch cannot be represented, the function shall return the value (time_t)-1 [CX] [Option Start]  and set errno to indicate the error. [Option End]
>
> ERRORS
>
>     The mktime() function shall fail if:
>
>     [EOVERFLOW]
>         [CX] [Option Start] The result cannot be represented. [Option End]


First and foremost mktime may fail and when it fails it returns -1.

Issue 6: If the time since the Epoch cannot be represented, the function shall return the value (time_t)-1 and may set errno to indicate the error.
Isuse 7: If the time since the Epoch cannot be represented, the function shall return the value (time_t)-1 and set errno to indicate the error.

Only errno offered is EOVERFLOW.
So I interpret it that since Issue 7, the correct behavior is to set errno to EOVERFLOW.

Also from:
Minutes of the 27th July 2023 Teleconference    Austin-1332 Page 1 of 1
Submitted by Andrew Josey, The Open Group.         28th July 2023

> Bug 1614: XSH 3/mktime does not specify EINVAL and should  Accepted as Marked
> https://austingroupbugs.net/view.php?id=1614
>
> An interpretation is required.
>
> Interpretation response:
> The standard clearly states that when an unsuccessful call to
> mktime() returns (time_t)-1 it sets errno to [EOVERFLOW], and
> conforming implementations must conform to this.
>
> Rationale:
>
> The RETURN VALUE section on the mktime() page states:
>     If the time since the Epoch cannot be represented, the function
>     shall return the value (time_t)-1 [CX]and set errno to indicate
>     the error[/CX].
>
> This requires that errno is set to indicate "the error", and the
> beginning of the sentence states the nature of the error condition
> to which "the error" refers: the time since the Epoch (i.e. the
> integer value to be returned) cannot be represented. The ERRORS
> section requires that the error number [EOVERFLOW] is used for this
> condition.
>
> Thus the standard requires that errno is set to [EOVERFLOW] when
> an unsuccessful call to mktime() returns (time_t)-1 and an
> implementation that sets it to [EINVAL] does not conform.
>
> The mktime() function does not have any way to indicate to the
> caller that an error other than [EOVERFLOW] occurred.

> > This is perfectly valid behavior, that is both expected and can be
> > handled in code easily.
>
>
> No, it’s a bug in glibc.
>
> > I have to ask, but have you actually used mktime from the application end?
>
>
> Of course.
>
> > I am not sure what you mean by correct. Struct tm is neither correct
> > nor incorrect. It can be in three states:
> > 1) Set by user.
> > 2) Normalized by mktime.
> > 3) Not fully normalized by mktime.
>
>
> Huh? No.

Then explain what is incorrect struct tm.

>
> > If I get -1, I know the struct tm does not represent valid time_t and I
> > handle it and move on.
>
>
> Define “move on”. With POSIX’ mktime interface, if you get -1 and
> EOVERFLOW, then moving further into the same direction will never
> give you not -1 again, because -1 is what you get when your tm_year
> was too far out of the representation (e.g. 2039 on a system with
> a 32-bit time_t).

Not true as shown above.

>
> EOVERFLOW means that the time cannot be represented in time_t, not
> that the time cannot be represented in struct tm. And for these
> gaps, the time_t values are consecutive (1325239199/1325239200).

No, return value -1 means that the time cannot represented as epoch seconds (for any number of reasons).

Required errno is Issue 7 change that should be used to indicate type of error, but only EOVERFLOW is listed.

>
> > This is perfect example (TZ=Pacific/Apia):
> >
> > before: 2011-12-31 00:00:00 +14 0
> > after1: 2011-12-31 00:00:00 +14 1325239200
> > after1: 2011-12-30 00:00:00 +14 -1
>
>
> No, this cannot give -1 per POSIX.

Not true as shown above.

>
> > Musl instead of giving sane results starts running in the circle at some point:
> > after2: 2011-12-29 00:00:00 -10 1325152800
> > after3: 2011-12-29 00:00:00 -10 1325152800
>
>
> That’s because it does this correctly.
>
> > Doesn't work, this will not give the same time next day, this fails on
> > STD/DST changes.
> >
> > Because same time next day is not always 86400 apart.
>
>
> I know. But the basic assumption that there even is such a
> thing as “same time next day” made by you is invalid. POSIX
> listed several examples (29ᵗʰ February next year as well as
> gaps in timezone offsets).
>
> One thing you can do is to add 86400, localtime(), then check
> that at least tm_mday, tm_hour and tm_min (Issue 8d4, line
> 48052) are what you expect, and handle cases where they aren’t
> manually. But having added 86400, you have two starting points
> from which to manually approach this (the original value and
> the newer value). (Perhaps a location could even skip more than
> 24 hours in a discontinuity.)
>
> bye,
> //mirabilos
> --
> “Having a smoking section in a restaurant is like having
> a peeing section in a swimming pool.”
> -- Edward Burr

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.