time.mktime memory access violation bug

Bengt Richter bokr at oz.net
Thu Nov 20 22:07:46 EST 2003


On Thu, 20 Nov 2003 23:54:24 +0100, Peter Otten <__peter__ at web.de> wrote:

>Bengt Richter wrote:
>
>> What does the following sequence do on your machine? Your tests did not
>> apparently exercise the daylight savings time path involved in my crash.
>
>My (tacit, sorry) assumption was that setting daylight savings to 1 would
>subtract 3600s from the Unix epoch, making it a negative value and thus
>provoke the crash. But that was wrong:
>
>>>> def d(t):
>...     tpl = time.localtime(t)
>...     return time.mktime(tpl[:-3] + (0, 0, 0)) - time.mktime(tpl[:-3] +
>(0, 0, 1))
>...
>>>> d(0)
>0.0
>
>With an arbitrary summer time:
>
>>>> d(962924461)
>3600.0
>>>>
>
>> E.g.,
>> 
>>  >>> import time
>>  >>> time.localtime(0)
>>  (1969, 12, 31, 16, 0, 0, 2, 365, 0)
>>  >>> time.mktime(time.localtime(0))
>>  0.0
>>  >>> time.mktime(time.localtime(0)[:6]+(0,0,1))
>> 
>> (my NT4 crashes here)
>> 
>
>For completeness:
>
>>>> time.localtime(0)
>(1970, 1, 1, 1, 0, 0, 3, 1, 0)
>>>> time.mktime(time.localtime(0))
>0.0
>>>> time.mktime(time.localtime(0)[:6] + (0, 0, 1))
>0.0
>>>>
>
>From the docs I would expect that such a "smart" behaviour would require a
>DST flag of -1.
Agreed.

>
>Looking at the two zero times (UTC + x vs UTC - x hours) I wonder if an NT
>machine on this side of the zero meridian would encounter the same
>problems.
I suspect so. I think it is in the mktime.c of the MS library:
>
I suspect that "can't get NULL" is wrong in this snippet from D:\VC98\CRT\SRC\MKTIME.C
when passed the zero epoch, because the associated localtime doesn't handle negative epoch time.

====

            /*
             * Convert this second count back into a time block structure.
             * If localtime returns NULL, return an error.
             */
            if ( (tbtemp = localtime(&tmptm1)) == NULL )
                goto err_mktime;

            /*
             * Now must compensate for DST. The ANSI rules are to use the
             * passed-in tm_isdst flag if it is non-negative. Otherwise,
             * compute if DST applies. Recall that tbtemp has the time without
             * DST compensation, but has set tm_isdst correctly.
             */
            if ( (tb->tm_isdst > 0) || ((tb->tm_isdst < 0) &&
              (tbtemp->tm_isdst > 0)) ) {
                tmptm1 += _dstbias;
                tbtemp = localtime(&tmptm1);    /* reconvert, can't get NULL */
            }

====
I think it dies a little later on
    *tb = *tbtemp;
... stepping through disassembly of optimized code with no source except the separate file
to infer what is going on ;-/

This is from MSVC++6.0 BTW, which UIAM windows python 2.3.2 still was compiled with(?)

What is Python policy when a vendor lib module causes a bug?

Regards,
Bengt Richter




More information about the Python-list mailing list