This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Invalid tm_zone from localtime() when TZ is not set

>>>>>	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
to char.

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
     to casting.

So I think that adding isascii() calls is better than these methods.



Problem reports:
Unsubscribe info:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]