This is the mail archive of the
mailing list for the Cygwin project.
Re: Invalid tm_zone from localtime() when TZ is not set
- From: Csaba Raduly <rcsaba at gmail dot com>
- To: cygwin list <cygwin at cygwin dot com>
- Date: Fri, 20 May 2016 09:09:26 +0200
- Subject: Re: 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> <o8x8tz573zs dot wl-koba at jp dot fujitsu dot com>
On Fri, May 20, 2016 at 6:22 AM, KOBAYASHI Shinji wrote:
> 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.
If the type of those members is WCHAR then using isascii() /
isupper() on them is just plain wrong.
The correct function to use would be iswupper().
if (isupper(*src)) *dst++ = *src;
(where src is wchar_t* and dst is char*) assumes that the upper 8 bits
of *src are zero (or *src is -1).
If not, the behavior is at best implementation-defined (maybe even undefined).
> 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.
It is highly likely that if the argument of iswupper() does not fit
into ASCII then its result won't fit either.
> 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.
GCS a+ e++ d- C++ ULS$ L+$ !E- W++ P+++$ w++$ tv+ b++ DI D++ 5++
The Tao of math: The numbers you can count are not the real numbers.
Life is complex, with real and imaginary parts.
"Ok, it boots. Which means it must be bug-free and perfect. " -- Linus Torvalds
"People disagree with me. I just ignore them." -- Linus Torvalds
Problem reports: http://cygwin.com/problems.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple