time.mktime memory access violation bug

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


On Thu, 20 Nov 2003 21:01:18 +0100, Peter Otten <__peter__ at web.de> wrote:

>Bengt Richter wrote:
>
>>  Python 2.3.2 (#49, Oct  2 2003, 20:02:00) [MSC v.1200 32 bit (Intel)] on
>>  win32 Type "help", "copyright", "credits" or "license" for more
>>  information.
>>  >>> import time
>>  >>> time.mktime((1969, 12, 31, 17, 0, 0, 0, 0, 0))
>>  3600.0
>>  >>> time.mktime((1969, 12, 31, 17, 0, 0, 0, 0, 1))
>>  0.0
>>  >>> time.mktime((1969, 12, 31, 16, 0, 0, 0, 0, 1))
>>  [crash with popup]
>
>More data points:
>
>import time
>n = 1000000
>for i in range(-n, n):
>    lt = time.localtime(i)
>    try:
>        time.mktime(lt)
>    except OverflowError:
>        print "Cannot cope with %r %r" % (i, lt)
>
>Python 2.3.2 (#1, Oct 21 2003, 10:03:19)
>[GCC 3.2] on linux2
>Type "help", "copyright", "credits" or "license" for more information.
>>>> import check_mktime
>Cannot cope with -1 (1970, 1, 1, 0, 59, 59, 3, 1, 0)
>>>>
>
>Now omitting localtime():
>
>>>> time.mktime((1970, 1, 1, 0, 59, 59, 3, 1, 0))
>Traceback (most recent call last):
>  File "<stdin>", line 1, in ?
>OverflowError: mktime argument out of range
>>>>
>
>So, on Linux:
>
>- times < 0 seem to be OK.
>- but -1 is used (abused?) as an error value
>
>Attempts to provoke an OverflowError with the above technique for the lower
>limit failed due to the following behaviour of localtime():
>
>>>> time.localtime(-3600*24*365*80)
>(1901, 12, 13, 21, 45, 52, 4, 347, 0)
>
>I. e. always the same for low values, so, "guessing" the lower limit:
>
>>>> time.localtime(-2**31)
>(1901, 12, 13, 21, 45, 52, 4, 347, 0)
>>>> time.localtime(-2**31+1)
>(1901, 12, 13, 21, 45, 53, 4, 347, 0)
>>>> time.localtime(-2**31+2)
>(1901, 12, 13, 21, 45, 54, 4, 347, 0)
>>>>
>
>But mktime() seems OK:
>
>>>> time.mktime((1901, 12, 13, 21, 45, 51, 4, 347, 0))
>Traceback (most recent call last):
>  File "<stdin>", line 1, in ?
>OverflowError: mktime argument out of range
>>>>
>
>Conclusion: The fatal error is probably due to NT's mktime() implementation.
>Times before (1901, ...) should raise an Overflow error. I don't like the
>-1 special value, but I am not sure how the error value of the underlying C
>library and one second before the Unix epoch could be disambiguated.
>
What does the following sequence do on your machine? Your tests did not apparently
exercise the daylight savings time path involved in my crash. 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)

BTW, I wonder if mktime does anything with those zeroes that I supplied at [6:8]
Hm, well,
 >>> time.mktime(time.localtime(0)[:-1]+(1,))
crashes too, so probably that's not involved.

No time to pursue this in the code, sorry ...

Regards,
Bengt Richter




More information about the Python-list mailing list