Hello,
Issue persists on current SVN.
wx 2.8.10 Valgrind 3.5.0 traces (plus some program log output):
after COPTime_HumanReadable2wxDateTime: <0x1dc61460> time "0084-08-07 00:00:00 <C8>S<C6>]?aE<B4>HwE<9E>^F^W<C8>^S<C6>^]3?a^ET<C6>]\inE"
==14317== Conditional jump or move depends on uninitialised value(s ) ==14317== at 0x5D70CAC: strftime_l (in /lib/libc-2.5.so) ==14317== by 0x5D6F81E: strftime (in /lib/libc-2.5.so) ==14317== by 0x62CC511: CallStrftime(char const*, tm const*) (datetime.cpp:456) ==14317== by 0x62D1DEF: wxDateTime::Format(char const*, wxDateTime::TimeZone const&) const (datetime.cpp:2660) ==14317== by 0x561396C: COPTime_DumpTime(wxDateTime const&, char const*) (cop_time.cpp:344) ==14317== by 0x5613F32: COPTime_HumanReadable2wxDateTime(wxDateTime&, int, int, int, int, int, int, int) (cop_time.cpp:520)
==14317== Use of uninitialised value of size 4 ==14317== at 0x5D70CB8: strftime_l (in /lib/libc-2.5.so) ==14317== by 0x5D6F81E: strftime (in /lib/libc-2.5.so) ==14317== by 0x62CC511: CallStrftime(char const*, tm const*) (datetime.cpp:456) ==14317== by 0x62D1DEF: wxDateTime::Format(char const*, wxDateTime::TimeZone const&) const (datetime.cpp:2660) ==14317== by 0x561396C: COPTime_DumpTime(wxDateTime const&, char const*) (cop_time.cpp:344) ==14317== by 0x5613F32: COPTime_HumanReadable2wxDateTime(wxDateTime&, int, int, int, int, int, int, int) (cop_time.cpp:520)
Happens due to src/common/datetime.cpp/wxDateTime::Format() doing:
// used for calls to strftime() when we only deal with time struct tm tmTimeOnly; tmTimeOnly.tm_hour = tm.hour; tmTimeOnly.tm_min = tm.min; tmTimeOnly.tm_sec = tm.sec; tmTimeOnly.tm_wday = 0; tmTimeOnly.tm_yday = 0; tmTimeOnly.tm_mday = 1; // any date will do tmTimeOnly.tm_mon = 0; tmTimeOnly.tm_year = 76; tmTimeOnly.tm_isdst = 0; // no DST, we adjust for tz ourselves
and _NOT_ doing any memset() (bad, BAAD) on the stack-local, UNINITIALIZED struct (memset() should _always_ be done regardless of whether we "know" that we properly assigned all members of struct tm, since we _cannot_ know this in wx code since struct tm is very system-specific) and then not initializing the tm_zone member (const char *) to any useful value either, before calling
#ifdef HAVE_STRFTIME
res += CallStrftime(_T("%Z"), &tmTimeOnly);
#endif
Result is a nice _very_ long garbage string (log output above), dangerously close to risking an application-side buffer overflow in case the wxDateTime::Format() caller is daring enough to copy the result to a fixed-size-calculated (say 10 time + 10 date + 10 time zone chars == 30 chars) char buffer.
Once the tmTimeOnly has been fixed to have a memset(), there's still the issue of a non-working %Z zone string processing: there's still a NULL string instead of useful zone name input.
Thanks!