X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/737c443bd16aa48366e941b886e6a3e8630bab85..6c2cd2a2116c5eff1646e0acb7cad2c887300300:/src/msw/debughlp.cpp diff --git a/src/msw/debughlp.cpp b/src/msw/debughlp.cpp index 3752aa10b2..d2ddec0146 100644 --- a/src/msw/debughlp.cpp +++ b/src/msw/debughlp.cpp @@ -25,7 +25,15 @@ #include "wx/msw/debughlp.h" -#if wxUSE_DBGHELP +#if wxUSE_DBGHELP && wxUSE_DYNLIB_CLASS + +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + +// to prevent recursion which could result from corrupted data we limit +// ourselves to that many levels of embedded fields inside structs +static const unsigned MAX_DUMP_DEPTH = 20; // ---------------------------------------------------------------------------- // globals @@ -137,7 +145,7 @@ const wxString& wxDbgHelpDLL::GetErrorMessage() void wxDbgHelpDLL::LogError(const wxChar *func) { ::OutputDebugString(wxString::Format(_T("dbghelp: %s() failed: %s\r\n"), - func, wxSysErrorMsg(::GetLastError()))); + func, wxSysErrorMsg(::GetLastError())).wx_str()); } // ---------------------------------------------------------------------------- @@ -286,7 +294,7 @@ wxDbgHelpDLL::DumpField(PSYMBOL_INFO pSym, void *pVariable, unsigned level) wxString s; // avoid infinite recursion - if ( level > 100 ) + if ( level > MAX_DUMP_DEPTH ) { return s; } @@ -383,17 +391,35 @@ wxDbgHelpDLL::DumpUDT(PSYMBOL_INFO pSym, void *pVariable, unsigned level) s.reserve(512); s = GetSymbolName(pSym); -#if !wxUSE_STL +#if !wxUSE_STD_STRING // special handling for ubiquitous wxString: although the code below works // for it as well, it shows the wxStringBase class and takes 4 lines // instead of only one as this branch if ( s == _T("wxString") ) { wxString *ps = (wxString *)pVariable; - s << _T("(\"") << *ps << _T(")\""); + + // we can't just dump wxString directly as it could be corrupted or + // invalid and it could also be locked for writing (i.e. if we're + // between GetWriteBuf() and UngetWriteBuf() calls) and assert when we + // try to access it contents using public methods, so instead use our + // knowledge of its internals + const wxChar *p = NULL; + if ( !::IsBadReadPtr(ps, sizeof(wxString)) ) + { + p = ps->data(); + wxStringData *data = (wxStringData *)p - 1; + if ( ::IsBadReadPtr(data, sizeof(wxStringData)) || + ::IsBadReadPtr(p, sizeof(wxChar *)*data->nAllocLength) ) + { + p = NULL; // don't touch this pointer with 10 feet pole + } + } + + s << _T("(\"") << (p ? p : _T("???")) << _T(")\""); } else // any other UDT -#endif // !wxUSE_STL +#endif // !wxUSE_STD_STRING { // Determine how many children this type has. DWORD dwChildrenCount = 0;