[Python-bugs-list] [ python-Bugs-533234 ] tm_isdst > 1 Passed to strftime.

noreply@sourceforge.net noreply@sourceforge.net
Fri, 22 Mar 2002 19:27:37 -0800


Bugs item #533234, was opened at 2002-03-21 13:33
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=533234&group_id=5470

Category: Python Library
Group: Python 2.2.1 candidate
>Status: Closed
Resolution: Fixed
Priority: 5
Submitted By: Ralph Corderoy (ralph)
Assigned to: Skip Montanaro (montanaro)
Summary: tm_isdst > 1 Passed to strftime.

Initial Comment:
README says

    On some Linux systems (those that are not yet
    using glibc 6), test_strftime fails due to a
    non-standard implementation of strftime() in the C
    library. Please ignore this, or upgrade to glibc
    version 6.

I find test_calendar fails.  As this is before
test_strftime I didn't find the above message for a
while.  I'd guess test_calendar is failing because of
the strftime problem.  Can README be updated to
suggest test_calendar may fail as well for the same
reason.

    % uname -a
    Linux anon 2.0.36 #1 Tue Dec 29 13:11:13 EST 1998 
        i586 unknown
    % ldd /usr/local/src/Python-2.2.1c1/python
        libdl.so.2 => /lib/libdl.so.2
        libpthread.so.0 => /lib/libpthread.so.0
        libutil.so.1 => /lib/libutil.so.1
        libm.so.6 => /lib/libm.so.6 
        libc.so.6 => /lib/libc.so.6
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2
    % rpm -qf /lib/libc.so.6
    glibc-2.0.7-29


----------------------------------------------------------------------

>Comment By: Tim Peters (tim_one)
Date: 2002-03-22 22:27

Message:
Logged In: YES 
user_id=31435

Fixed again, by being duller instead of cleverer, in

Lib/calendar.py; new revision: 1.27
Lib/test/test_calendar.py; new revision: 1.3

----------------------------------------------------------------------

Comment By: Ralph Corderoy (ralph)
Date: 2002-03-22 19:01

Message:
Logged In: YES 
user_id=911

Although I agree passing a tuple stuff full of
co-incidental numbers isn't great, unfortunately, the
suggestion of (2001, 1, i+1, 12, 0, 0, i, i+1, 0) is
definitely wrong.

I think it should be (2001, item, 1, 12, 0, 0, item,
1, 0) and have attached calendar.patch which is
against latest CVS.

I'd guess that it was originally (item,) * 9 so
_localized_name could be used for anything.  It only
ended up being used for week and month names so item
should only appear twice in the tuple.

Also, Tim's suggestion made every month name the same,
e.g. `January'.  Plus it added one to item for the
month, yet the original just used plain item.

I've altered test_calendar.py to check that one week
day name doesn't match another, and the same for month
names.  But I've not written Python before so please
check carefully.

Lastly, _localized_name looks well dodgy to me.  It
only takes a len yet week day names are zero-based and
month names one-based!  Observe.

>>> ','.join(day_name[:])
'Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday'
>>> ','.join(day_abbr[:])
'Mon,Tue,Wed,Thu,Fri,Sat,Sun'

They seem fine.

>>> ','.join(month_name[:])
'Dec,January,February,March,April,May,June,July,August,
    September,October,November,December'
>>> ','.join(month_abbr[:])
'Saturday,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'

But accessing an invalid index 0 happens to give a
random string on this system, but could easily core
dump on another.

It seems _localized_name needs knowledge of the
minimum legal index too.  How well that maps onto the
Pythonic `negative index is relative to end' I don't
know.


----------------------------------------------------------------------

Comment By: Skip Montanaro (montanaro)
Date: 2002-03-22 13:36

Message:
Logged In: YES 
user_id=44345

reclosing - thanks for the better fix (v. 1.26)


----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2002-03-22 13:23

Message:
Logged In: YES 
user_id=31435

I'm reopening this:  passing a vector of nonsense to 
strftime seems likely to break again somewhere else.  2001 
started on a Monday, so I'd rather we passed

(2001, 1, i+1, 12, 0, 0, i, i+1, 0)

Then all the fields are consistent with each other, and 
only a terribly broken strftime() could fail.

----------------------------------------------------------------------

Comment By: Skip Montanaro (montanaro)
Date: 2002-03-22 13:08

Message:
Logged In: YES 
user_id=44345

fixed in calendar.py v. 1.25

bugfix candidate.


----------------------------------------------------------------------

Comment By: Ralph Corderoy (ralph)
Date: 2002-03-22 11:53

Message:
Logged In: YES 
user_id=911

Yep, passing a tm_isdst of 0 or -1 works fine.

----------------------------------------------------------------------

Comment By: Skip Montanaro (montanaro)
Date: 2002-03-22 10:29

Message:
Logged In: YES 
user_id=44345

Ralph,

Thanks, that helps a lot.  Can you try changing the
strftime link in calendar.py:_localized_name to

return strftime(self.format, 
(item,)*8+(0,)).capitalize()

and let me know if that cures the problem?


----------------------------------------------------------------------

Comment By: Ralph Corderoy (ralph)
Date: 2002-03-22 07:04

Message:
Logged In: YES 
user_id=911

PS.  Presumably, your Mandrake glibc doesn't use tm_isdst
without checking its value first?

----------------------------------------------------------------------

Comment By: Ralph Corderoy (ralph)
Date: 2002-03-22 06:57

Message:
Logged In: YES 
user_id=911

Ah, OK, I see I do have glibc 6.  I thought it was a
big jump from 2.0.7 to 6.x.x  :-)

I've tracked the SIGSEGV down further.  In
test_calendar.py there's

    self.assertEqual(len([d for d in calendar.day_abbr]), 7)

This SEGVs when d = 2.  For d of 0 and 1 it correctly
retrieves "Mon", "Tue".

calendar.py does

    return strftime(self.format, (item,)*9).capitalize()

constructing a struct tm structure on the fly with
that tuple.  Unfortunately, glibc's time/strftime.c
uses tm_isdst as an index into an array.

    # if HAVE_TZSET
      tzset ();
    # endif

      if (!(zone && *zone) && tp->tm_isdst >= 0)
        zone = tzname[tp->tm_isdst];

On this system tzname is really __tzname.

    (gdb) p __tzname
    $2 = {0x400d91d1 "GMT", 0x400d91cd "BST"}

Boom!

Elsewhere, glibc checks that tm_isdst is 0 or 1 before 
using it as an index, so this is probably a glibc bug.  
However, it makes little sense to pass in a value of 
tm_isdst that happens to match the day of the week so
I'd suggest passing in -1 instead since values < 0 are
used to indicate `unknown'.

If calendar.py doesn't change then README still needs
to say that test_calendar and test_strftime fail in
this situation.


----------------------------------------------------------------------

Comment By: Skip Montanaro (montanaro)
Date: 2002-03-21 13:51

Message:
Logged In: YES 
user_id=44345

It's not clear to me that the README warning here is
correct.  I believe you *are* running glibc 6.  (Note
the '6' in libc.so.6.)  I have similar version numbers on
my Mandrake system which does have glibc 6.


----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=533234&group_id=5470