From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: from second.openwall.net (second.openwall.net [193.110.157.125]) by inbox.vuxu.org (Postfix) with SMTP id 3D91821376 for ; Wed, 27 Mar 2024 01:14:54 +0100 (CET) Received: (qmail 3393 invoked by uid 550); 27 Mar 2024 00:10:05 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 3359 invoked from network); 27 Mar 2024 00:10:04 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1711498480; x=1711757680; bh=T4VIP+lBW1YjsroMS5r5WNxIQxyWcNleosTCxLLsjjU=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=pPBiaCJZU0WuiPr1j2m/sm0S/a554X2LQL12EpUTBtGk6yOFDjmEsB8nqQYB6czLD bC+hY6dyo4qy6wg8m4vwL9BCPx8LhE5n40/Z/u102b+yYXwotm0/If15/R0irByWc2 AKsjZmEtscxyEsTVX/yjv2SICJCSaOS4LohEHYubswDly+36QZmUr5F0jpvDnTkjyA hYO1a4LbOcmMD9AZbl/j5Ws/4eOdolcJtPEY94DT09TKwE7WOQ6UV5kA4qGHULyDxY oC9/gv7nb0ds4Bhd4p5vOKqkYxCjIt7Stt0QOuwX+tGwWTTKVPd2+U0kja1T7b0CU8 wRNFXXdHEe8/Q== Date: Wed, 27 Mar 2024 00:14:23 +0000 To: musl@lists.openwall.com From: Alexander Weps Message-ID: In-Reply-To: References: <20240325122113.GB4163@brightrain.aerifal.cx> Feedback-ID: 20507743:user:proton MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [musl] Broken mktime calculations when crossing DST boundary See below. AW On Tuesday, March 26th, 2024 at 22:59, Thorsten Glaser wrote= : > Alexander Weps dixit: > > > > Not at all, glibc=E2=80=99s 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 repr= esented in epoch seconds. That is entirely compliant with POSIX and I would need to see some hard evi= dence 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 r= epresented, the function shall return the value (time_t)-1 [CX] [Option Sta= rt] 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 sh= all 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 sh= all 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 Ma= rked > https://austingroupbugs.net/view.php?id=3D1614 > > 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=E2=80=99s a bug in glibc. > > > I have to ask, but have you actually used mktime from the application e= nd? > > > 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 =E2=80=9Cmove on=E2=80=9D. With POSIX=E2=80=99 mktime interface, i= f 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 er= ror, but only EOVERFLOW is listed. > > > This is perfect example (TZ=3DPacific/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 som= e point: > > after2: 2011-12-29 00:00:00 -10 1325152800 > > after3: 2011-12-29 00:00:00 -10 1325152800 > > > That=E2=80=99s 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 =E2=80=9Csame time next day=E2=80=9D made by you is invalid. POS= IX > listed several examples (29=E1=B5=97=CA=B0 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=E2=80=99t > 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 > -- > =E2=80=9CHaving a smoking section in a restaurant is like having > a peeing section in a swimming pool.=E2=80=9D > -- Edward Burr