Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Tue, 26 Mar 2024 21:59:14 +0000 (UTC)
From: Thorsten Glaser <>
Subject: Re: Broken mktime calculations when crossing DST boundary

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.

>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.

>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).

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).

>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.

>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.)

  “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.