From 69c928ef472f89987f95e2fa798e2ba2d23eaf31 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 11 Mar 2007 23:38:42 +0000 Subject: [PATCH] added wxSafeConvertMB2WX/WX2MB() and use them when interfacing with C functions which crash if we pass them NULL pointers git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44771 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 4 ++++ include/wx/strconv.h | 15 +++++++++++++++ src/common/strconv.cpp | 34 ++++++++++++++++++++++++++++++++-- src/palmos/utils.cpp | 2 +- src/unix/utilsunx.cpp | 27 +++++++++++++-------------- 5 files changed, 65 insertions(+), 17 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index f9fea6f423..e6b69a5b93 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -70,6 +70,10 @@ All: - Fixed Base64 computation in wxHTTP (p_michalczyk) - Fix handling of wxSOCKET_REUSEADDR in wxDatagramSocket (troelsk) +Unix Ports: + +- Fixed crash in wxGetUserName() in Unicode build + wxMSW - Fix lack of spin control update event when control lost focus. diff --git a/include/wx/strconv.h b/include/wx/strconv.h index ba28c8a81a..4e4afff9dc 100644 --- a/include/wx/strconv.h +++ b/include/wx/strconv.h @@ -521,10 +521,25 @@ extern WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvCurrent; #if wxUSE_UNICODE #define wxConvertWX2MB(s) wxConvCurrent->cWX2MB(s) #define wxConvertMB2WX(s) wxConvCurrent->cMB2WX(s) + + // these functions should be used when the conversions really, really have + // to succeed (usually because we pass their results to a standard C + // function which would crash if we passed NULL to it), so these functions + // always return a valid pointer if their argument is non-NULL + + // this function safety is achieved by trying wxConvLibc first, wxConvUTF8 + // next if it fails and, finally, wxConvISO8859_1 which always succeeds + extern WXDLLIMPEXP_BASE wxWCharBuffer wxSafeConvertMB2WX(const char *s); + + // this function uses wxConvLibc and wxConvUTF8(MAP_INVALID_UTF8_TO_OCTAL) + // if it fails + extern WXDLLIMPEXP_BASE 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 // _WX_STRCONV_H_ diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index bd0a0926c3..e515024035 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -3650,9 +3650,39 @@ WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvFileName = & #else wxConvUTF8Obj; #endif -#else +#else // !__WXOSX__ wxConvLibcObj; -#endif +#endif // __WXOSX__/!__WXOSX__ + +#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 --git a/src/palmos/utils.cpp b/src/palmos/utils.cpp index 81db337f9b..f9f5806ec8 100644 --- a/src/palmos/utils.cpp +++ b/src/palmos/utils.cpp @@ -90,7 +90,7 @@ bool wxGetUserName(wxChar *buf, int maxSize) return false; } - wxStrncpy (buf, wxConvertMB2WX(id), maxSize - 1); + wxStrncpy (buf, wxSafeConvertMB2WX(id), maxSize - 1); // free the buffer MemPtrUnlock(id); diff --git a/src/unix/utilsunx.cpp b/src/unix/utilsunx.cpp index 3688288505..73148ac613 100644 --- a/src/unix/utilsunx.cpp +++ b/src/unix/utilsunx.cpp @@ -473,7 +473,7 @@ long wxExecute(wxChar **argv, int flags, wxProcess *process) 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++; } @@ -722,7 +722,7 @@ char *wxGetUserHome( const wxString &user ) } 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! @@ -736,7 +736,7 @@ char *wxGetUserHome( const wxString &user ) who = getpwnam (user.mb_str()); } - return wxConvertMB2WX(who ? who->pw_dir : 0); + return wxSafeConvertMB2WX(who ? who->pw_dir : 0); } // ---------------------------------------------------------------------------- @@ -787,7 +787,7 @@ static bool wxGetHostNameInternal(wxChar *buf, int sz) 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) @@ -795,7 +795,7 @@ static bool wxGetHostNameInternal(wxChar *buf, int sz) bool ok = gethostname(cbuf, sz) != -1; if ( ok ) { - wxStrncpy(buf, wxConvertMB2WX(cbuf), sz - 1); + wxStrncpy(buf, wxSafeConvertMB2WX(cbuf), sz - 1); buf[sz] = wxT('\0'); } #else // no uname, no gethostname @@ -839,7 +839,7 @@ bool wxGetFullHostName(wxChar *buf, int sz) { if ( !wxStrchr(buf, wxT('.')) ) { - struct hostent *host = gethostbyname(wxConvertWX2MB(buf)); + struct hostent *host = gethostbyname(wxSafeConvertWX2MB(buf)); if ( !host ) { wxLogSysError(_("Cannot get the official hostname")); @@ -849,7 +849,7 @@ bool wxGetFullHostName(wxChar *buf, int sz) 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) @@ -865,7 +865,7 @@ bool wxGetUserId(wxChar *buf, int sz) *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; } @@ -874,24 +874,23 @@ bool wxGetUserId(wxChar *buf, int sz) bool wxGetUserName(wxChar *buf, int sz) { +#ifdef HAVE_PW_GECOS struct passwd *who; *buf = wxT('\0'); if ((who = getpwuid (getuid ())) != NULL) { - // pw_gecos field in struct passwd is not standard -#ifdef HAVE_PW_GECOS char *comma = strchr(who->pw_gecos, ','); if (comma) *comma = '\0'; // cut off non-name comment fields - wxStrncpy (buf, wxConvertMB2WX(who->pw_gecos), sz - 1); -#else // !HAVE_PW_GECOS - wxStrncpy (buf, wxConvertMB2WX(who->pw_name), sz - 1); -#endif // HAVE_PW_GECOS/!HAVE_PW_GECOS + wxStrncpy (buf, wxSafeConvertMB2WX(who->pw_gecos), sz - 1); return true; } return false; +#else // !HAVE_PW_GECOS + return wxGetUserId(buf, sz); +#endif // HAVE_PW_GECOS/!HAVE_PW_GECOS } bool wxIsPlatform64Bit() -- 2.45.2