This is the mail archive of the
mailing list for the Cygwin project.
Invalid tm_zone from localtime() when TZ is not set
- From: KOBAYASHI Shinji <koba at jp dot fujitsu dot com>
- To: cygwin at cygwin dot com
- Date: Fri, 20 May 2016 13:22:31 +0900
- Subject: Invalid tm_zone from localtime() when TZ is not set
- Authentication-results: sourceware.org; auth=none
- References: <o8xeg8x7e2r dot wl-koba at jp dot fujitsu dot com> <932D033F-9DA4-4901-9158-328AA929FEC8 at etr-usa dot com>
>>>>> Warren Young wrote:
> How about you just give the line of code and explain what’s wrong with it? Then someone with checkin rights can reimplement your change from your prose description.
Thank you for your suggestion. So I try to describe the problem:
Current localtime() can return invalid tm_zone when used with
non-English Windows and the TZ environment variable is unset. This
leads to a failure of importing time module in Python 3:
% (unset TZ; python3 -c "import time")
Traceback (most recent call last):
File "<string>", line 1, in <module>
SystemError: initialization of time raised unreported exception
Although most users set the TZ environment variable, tox (>= 2.0)
drops most environment variables including TZ by default when invoking
test environments. So the users of tox on non-English Windows may
suffer from this problem.
localtime() calls tzsetwall() when TZ is not set. In tzsetwall(),
the StandardName and DaylightName member values retrieved by
GetTimeZoneInformation() are checked with isupper() and copied to the
char buffer used as the timezone name in tzparse(). However, the
type of these member values are wchar_t and isupper() is defined only
when isascii() is true. So it may happen that the char buffer
contains invalid characters as a result of implicit cast from wchar_t
The return value of isupper() for non-ascii characters depends on
other data, because an out of bounds access occurs for the small
(128 + 256) table used in isupper(). I confirmed the above error on
Japanese Windows with 64-bit Cygwin 2.5.0-1 and 2.5.1-1, but had no
problem with 64-bit Cygwin 2.4.1-1 nor with 32-bit Cygwins.
So, I propose to call isascii() to assure the wchar_t fits in the
range of ASCII before calling isupper().
I have considered some other methods:
1. Using iswupper() instead of isupper().
- Although this method is effective for Japanese environments, it
is not assured that the character iswupper() returns true fits in
the range of ASCII.
2. Add (char) cast to the argument of isupper().
- This method assures that the copied characters are uppercase
only. However, it may be different from original characters due
So I think that adding isascii() calls is better than these methods.
Problem reports: http://cygwin.com/problems.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple