-
-
Notifications
You must be signed in to change notification settings - Fork 32.7k
[memory leak]bpo-16322, bpo-27426: Fix time zone names encoding issues in Windows #3740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…). Related changes in tmtotuple() and time.gmtime()
Modules/timemodule.c
Outdated
@@ -109,6 +109,20 @@ win_perf_counter(_Py_clock_info_t *info) | |||
} | |||
return PyFloat_FromDouble(diff / (double)cpu_frequency); | |||
} | |||
|
|||
// Function to get time zone name with Windows API | |||
static void get_windows_zone(wchar_t *out) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move "static void" on a separate line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Modules/timemodule.c
Outdated
TIME_ZONE_INFORMATION tzi; | ||
DWORD tzid = GetTimeZoneInformation(&tzi); | ||
|
||
if (tzid < 2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't be better to use named constants? TIME_ZONE_ID_STANDARD, TIME_ZONE_ID_DAYLIGHT, etc.
Handle error (TIME_ZONE_ID_INVALID).
Modules/timemodule.c
Outdated
@@ -622,27 +656,27 @@ time_strftime(PyObject *self, PyObject *args) | |||
fmt = PyBytes_AS_STRING(format); | |||
#endif | |||
|
|||
#if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME) | |||
#if defined(MS_WINDOWS) && defined(HAVE_WCSFTIME) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What abut the case defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@serhiy-storchaka If I'm not mistaken, this case is possible only when we undefine HAVE_WCSFTIME somewhere. Do you mean we should have special code for this case?
Now I just returned this block to state before switching from wcsftime to strftime.
Modules/timemodule.c
Outdated
|
||
//Replace %Z with time zone name | ||
if (count) { | ||
size_t l = wcslen(fmt) + (len_zone - 2) * count + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check for integer overflow.
if (len_zone - 2 > (Py_SSIZE_MAX/sizeof(time_char) - 1 - wcslen(fmt)) / count) {
// raise MemoryError
}
Modules/timemodule.c
Outdated
|
||
// Count the number of %Z occurences | ||
ins = fmt; | ||
for (count = 0; tmp = wcsstr(ins, L"%Z"); ++count) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use the same variable for ins
and tmp
here.
Modules/timemodule.c
Outdated
wrong encoding of time zone names.*/ | ||
#ifdef MS_WINDOWS | ||
TIME_ZONE_INFORMATION tzi; | ||
GetTimeZoneInformation(&tzi); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle error (TIME_ZONE_ID_INVALID).
Is DaylightName
initialized properly if GetTimeZoneInformation() != TIME_ZONE_ID_DAYLIGHT
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think so. TIME_ZONE_INFORMATION
structure get all members if GetTimeZoneInformation()
succeeds. On my system GetTimeZoneInformation() == TIME_ZONE_ID_UNKNOWN
, i.e. daylight saving time is not used, but both names initialized properly. However, DaylightName
and StandardName
can be empty.
Modules/timemodule.c
Outdated
/* check that the format string contains only valid directives */ | ||
for (outbuf = strchr(fmt, '%'); | ||
for (outbuf = wcschr(fmt, L'%'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loops for Windows, AIX and Solaris are too similar. Can they be merged?
Modules/timemodule.c
Outdated
while (count--) { | ||
ins = wcsstr(fmt, L"%Z"); | ||
len_copy = ins - fmt; | ||
if (wcsncmp(ins - 1, L"%", 1) == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the format starts with a "%Z", ins == fmt
and ins - 1
is outside of a buffer.
If "%Z" follows a double "%" ("%%%Z"), it is copied as is.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase And if you don't make the requested changes, you will be put in the comfy chair! |
I didn't expect the Spanish Inquisition! |
Nobody expects the Spanish Inquisition! @serhiy-storchaka: please review the changes made to this pull request. |
Oops... Fix of memory leak needed.
|
Use Windows APIs to avoid wrong encoding of time zone names: bpo-16322 and bpo-27426.
Switch back to using wcsftime because:
https://bugs.python.org/issue16322