Package: wxwidgets2.6 Version: 2.6.3.2.1.5 Severity: wishlist
A bug was reported in scorched3d in Ubuntu (https://bugs.launchpad.net/ubuntu/+source/gaphor/+bug/35375) that caused a crash on startup. This was traced to unsafe handling of unicode characters in wxGetUserName(). A patch was made in CVS to the 2.8 trunk to address this. Attached is a backport of that patch to wxwidgets2.6. I have only tested this patch with scorched3d, but after application, scorched3d no longer segfaulted on start, and worked properly. No recompile of scorched3d was required, so I presume that the ABI was preserved. Note that the diff is fairly ugly. It needs to be applied from within the pacakge directory with patch -p4 < M35375.wx25.patch. My apologies for this. -- Emmet HIKORY
diff -Nru /tmp/lH6F7ooV9n/wxwidgets2.6-2.6.3.2.1.5ubuntu6/include/wx/strconv.h /tmp/rLVQvKyeIa/wxwidgets2.6-2.6.3.2.1.5ubuntu7/include/wx/strconv.h --- /tmp/lH6F7ooV9n/wxwidgets2.6-2.6.3.2.1.5ubuntu6/include/wx/strconv.h 2006-05-01 13:38:40.000000000 +0900 +++ /tmp/rLVQvKyeIa/wxwidgets2.6-2.6.3.2.1.5ubuntu7/include/wx/strconv.h 2007-04-28 13:38:47.000000000 +0900 @@ -339,10 +339,14 @@ #if wxUSE_UNICODE #define wxConvertWX2MB(s) wxConvCurrent->cWX2MB(s) #define wxConvertMB2WX(s) wxConvCurrent->cMB2WX(s) + wxWCharBuffer wxSafeConvertMB2WX(const char *s); + wxCharBuffer wxSafeConvertWX2MB(const wchar_t *ws); #else // ANSI // no conversions to do #define wxConvertWX2MB(s) (s) #define wxConvertMB2WX(s) (s) + #define wxSafeConvertMB2WX(s) (s) + #define wxSafeConvertWX2MB(s) (s) #endif // Unicode/ANSI #endif diff -Nru /tmp/lH6F7ooV9n/wxwidgets2.6-2.6.3.2.1.5ubuntu6/src/common/strconv.cpp /tmp/rLVQvKyeIa/wxwidgets2.6-2.6.3.2.1.5ubuntu7/src/common/strconv.cpp --- /tmp/lH6F7ooV9n/wxwidgets2.6-2.6.3.2.1.5ubuntu6/src/common/strconv.cpp 2006-05-01 13:38:40.000000000 +0900 +++ /tmp/rLVQvKyeIa/wxwidgets2.6-2.6.3.2.1.5ubuntu7/src/common/strconv.cpp 2007-04-28 13:40:09.000000000 +0900 @@ -2831,6 +2831,35 @@ wxConvLibcObj; #endif +#if wxUSE_UNICODE + +wxWCharBuffer wxSafeConvertMB2WX(const char *s) +{ + if ( !s ) + return wxWCharBuffer(); + + wxWCharBuffer wbuf(wxConvLibc.cMB2WX(s)); + if ( !wbuf ) + wbuf = wxConvUTF8.cMB2WX(s); + if ( !wbuf ) + wbuf = wxConvISO8859_1.cMB2WX(s); + + return wbuf; +} + +wxCharBuffer wxSafeConvertWX2MB(const wchar_t *ws) +{ + if ( !ws ) + return wxCharBuffer(); + + wxCharBuffer buf(wxConvLibc.cWX2MB(ws)); + if ( !buf ) + buf = wxMBConvUTF8(wxMBConvUTF8::MAP_INVALID_UTF8_TO_OCTAL).cWX2MB(ws); + + return buf; +} + +#endif // wxUSE_UNICODE #else // !wxUSE_WCHAR_T diff -Nru /tmp/lH6F7ooV9n/wxwidgets2.6-2.6.3.2.1.5ubuntu6/src/unix/utilsunx.cpp /tmp/rLVQvKyeIa/wxwidgets2.6-2.6.3.2.1.5ubuntu7/src/unix/utilsunx.cpp --- /tmp/lH6F7ooV9n/wxwidgets2.6-2.6.3.2.1.5ubuntu6/src/unix/utilsunx.cpp 2006-05-01 13:38:40.000000000 +0900 +++ /tmp/rLVQvKyeIa/wxwidgets2.6-2.6.3.2.1.5ubuntu7/src/unix/utilsunx.cpp 2007-04-28 13:38:31.000000000 +0900 @@ -477,7 +477,7 @@ while (argv[mb_argc]) { - wxWX2MBbuf mb_arg = wxConvertWX2MB(argv[mb_argc]); + wxWX2MBbuf mb_arg = wxSafeConvertWX2MB(argv[mb_argc]); mb_argv[mb_argc] = strdup(mb_arg); mb_argc++; } @@ -728,7 +728,7 @@ } if ((ptr = wxGetenv(wxT("USER"))) != NULL || (ptr = wxGetenv(wxT("LOGNAME"))) != NULL) { - who = getpwnam(wxConvertWX2MB(ptr)); + who = getpwnam(wxSafeConvertWX2MB(ptr)); } // We now make sure the the user exists! @@ -742,7 +742,7 @@ who = getpwnam (user.mb_str()); } - return wxConvertMB2WX(who ? who->pw_dir : 0); + return wxSafeConvertMB2WX(who ? who->pw_dir : 0); } // ---------------------------------------------------------------------------- @@ -764,7 +764,7 @@ bool ok = uname(&uts) != -1; if ( ok ) { - wxStrncpy(buf, wxConvertMB2WX(uts.nodename), sz - 1); + wxStrncpy(buf, wxSafeConvertMB2WX(uts.nodename), sz - 1); buf[sz] = wxT('\0'); } #elif defined(HAVE_GETHOSTNAME) @@ -810,7 +810,7 @@ { if ( !wxStrchr(buf, wxT('.')) ) { - struct hostent *host = gethostbyname(wxConvertWX2MB(buf)); + struct hostent *host = gethostbyname(wxSafeConvertWX2MB(buf)); if ( !host ) { wxLogSysError(_("Cannot get the official hostname")); @@ -820,7 +820,7 @@ else { // the canonical name - wxStrncpy(buf, wxConvertMB2WX(host->h_name), sz); + wxStrncpy(buf, wxSafeConvertMB2WX(host->h_name), sz); } } //else: it's already a FQDN (BSD behaves this way) @@ -836,7 +836,7 @@ *buf = wxT('\0'); if ((who = getpwuid(getuid ())) != NULL) { - wxStrncpy (buf, wxConvertMB2WX(who->pw_name), sz - 1); + wxStrncpy (buf, wxSafeConvertMB2WX(who->pw_name), sz - 1); return true; } @@ -855,9 +855,9 @@ char *comma = strchr(who->pw_gecos, ','); if (comma) *comma = '\0'; // cut off non-name comment fields - wxStrncpy (buf, wxConvertMB2WX(who->pw_gecos), sz - 1); + wxStrncpy (buf, wxSafeConvertMB2WX(who->pw_gecos), sz - 1); #else // !HAVE_PW_GECOS - wxStrncpy (buf, wxConvertMB2WX(who->pw_name), sz - 1); + wxStrncpy (buf, wxSafeConvertMB2WX(who->pw_name), sz - 1); #endif // HAVE_PW_GECOS/!HAVE_PW_GECOS return true; }