On Mon, 18 Jul 2005 17:34:55 +0200, Campo Weijerman <[EMAIL PROTECTED]> wrote:

> > +    /* This edge case is to workaround the undefined behaviour, where the
> > +     * TIMEZONE makes the time go beyond the defined range.
> > +     * gmtime (0x7fffffff) => 2038-01-19 03:14:07
> > +     * If there is a negative offset in TZ, like MET-1METDST, some broken
> > +     * implementations of localtime () (like AIX 5.2) barf with bogus
> > +     * return values:
> > +     * 0x7fffffff gmtime               2038-01-19 03:14:07
> > +     * 0x7fffffff localtime            1901-12-13 21:45:51
> > +     * 0x7fffffff mylocaltime          2038-01-19 04:14:07
> > +     * 0x3c19137f gmtime               2001-12-13 20:45:51
> > +     * 0x3c19137f localtime            2001-12-13 21:45:51
> > +     * 0x3c19137f mylocaltime          2001-12-13 21:45:51
> > +     * Given that legal timezones are typically between GMT-12 and GMT+12
> > +     * we turn back the clock 23 hours before calling the localtime
> > +     * function, and add those to the return value. This will never cause
> > +     * day wrapping problems, since the edge case is Jan *19*
> > +     */
> > +    T = *tp - 82800; /* 23 hour. allows up to GMT-23 */
> > +    P = localtime (&T);
> > +    P->tm_hour += 23;
> > +    if (P->tm_hour >= 24) {
> > +       P->tm_hour -= 24;
> > +       P->tm_mday++;
> > +    }
> 
> Well, it's not nice, but I suppose it should fix the boundary case.
> However, I think you should also increment these other fields along
> with tm_mday:
> 
> int tm_wday;    /* Day of week (Sunday = 0) */
> int tm_yday;    /* Day of year (0 - 365) */

Both done now in #25173

> I'm not fond of this sort of struct tm manipulation.  It's easy to
> get wrong, and then you have just replaced a known bug by an unknown
> one.  Luckily,  2038-01-19 is supposed to be on a Tuesday, and we
> are sufficiently far away from the boundaries of the week, month, and
> year...  Until someone starts using TZ=CUT-50, say :-(

As the surrounding comments already said.

By the time this workaround should be a problem, we are all on 64, 128 or
even 256 bit machines
As you can see, the bug is already safe for 64bit values, since the
workaround only acts in a small window:

+    if (!tp || *tp < 0x7fff573f || *tp >= 0x80000000)
+       return (localtime (tp));

-- 
H.Merijn Brand        Amsterdam Perl Mongers (http://amsterdam.pm.org/)
using Perl 5.6.2, 5.8.0, 5.8.5, & 5.9.2  on HP-UX 10.20, 11.00 & 11.11,
 AIX 4.3 & 5.2, SuSE 9.2 & 9.3, and Cygwin. http://www.cmve.net/~merijn
Smoking perl: http://www.test-smoke.org,    perl QA: http://qa.perl.org
 reports  to: [EMAIL PROTECTED],                perl-qa@perl.org

Reply via email to