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
This commit is contained in:
Vadim Zeitlin 2007-03-11 23:38:42 +00:00
parent fe295b0d3e
commit 69c928ef47
5 changed files with 65 additions and 17 deletions

View File

@ -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.

View File

@ -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_

View File

@ -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

View File

@ -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);

View File

@ -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()