use wxStrnlen() and add NULL-checks in wxMsgCatalogFile::FillHash for safer handling of corrupted MO files (closes #3151)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58106 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Francesco Montorsi
2009-01-14 19:26:14 +00:00
parent 16d4ffde1e
commit f00204d341
2 changed files with 25 additions and 8 deletions

View File

@@ -234,7 +234,8 @@ bool MyApp::OnInit()
wxLocale::AddCatalogLookupPathPrefix(wxT(".")); wxLocale::AddCatalogLookupPathPrefix(wxT("."));
// Initialize the catalogs we'll be using // Initialize the catalogs we'll be using
m_locale.AddCatalog(wxT("internat")); if (!m_locale.AddCatalog(wxT("internat")))
wxLogError(_("Couldn't find/load the 'internat' catalog."));
// this catalog is installed in standard location on Linux systems and // this catalog is installed in standard location on Linux systems and
// shows that you may make use of the standard message catalogs as well // shows that you may make use of the standard message catalogs as well

View File

@@ -868,6 +868,9 @@ wxPluralFormsCalculator* wxPluralFormsCalculator::make(const char* s)
// wxMsgCatalogFile corresponds to one disk-file message catalog. // wxMsgCatalogFile corresponds to one disk-file message catalog.
// //
// This is a "low-level" class and is used only by wxMsgCatalog // This is a "low-level" class and is used only by wxMsgCatalog
// NOTE: for the documentation of the binary catalog (.MO) files refer to
// the GNU gettext manual:
// http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxString, wxMessagesHash); WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxString, wxMessagesHash);
@@ -881,12 +884,12 @@ public:
// load the catalog from disk (szDirPrefix corresponds to language) // load the catalog from disk (szDirPrefix corresponds to language)
bool Load(const wxString& szDirPrefix, const wxString& szName, bool Load(const wxString& szDirPrefix, const wxString& szName,
wxPluralFormsCalculatorPtr& rPluralFormsCalculator); wxPluralFormsCalculatorPtr& rPluralFormsCalculator);
// fills the hash with string-translation pairs // fills the hash with string-translation pairs
void FillHash(wxMessagesHash& hash, bool FillHash(wxMessagesHash& hash,
const wxString& msgIdCharset, const wxString& msgIdCharset,
bool convertEncoding) const; bool convertEncoding) const;
// return the charset of the strings in this catalog or empty string if // return the charset of the strings in this catalog or empty string if
// none/unknown // none/unknown
@@ -1356,7 +1359,7 @@ bool wxMsgCatalogFile::Load(const wxString& szDirPrefix, const wxString& szName,
return true; return true;
} }
void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool wxMsgCatalogFile::FillHash(wxMessagesHash& hash,
const wxString& msgIdCharset, const wxString& msgIdCharset,
bool convertEncoding) const bool convertEncoding) const
{ {
@@ -1444,6 +1447,8 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash,
for (size_t32 i = 0; i < m_numStrings; i++) for (size_t32 i = 0; i < m_numStrings; i++)
{ {
const char *data = StringAtOfs(m_pOrigTable, i); const char *data = StringAtOfs(m_pOrigTable, i);
if (!data)
return false; // may happen for invalid MO files
wxString msgid; wxString msgid;
#if wxUSE_UNICODE #if wxUSE_UNICODE
@@ -1458,6 +1463,9 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash,
#endif // wxUSE_UNICODE #endif // wxUSE_UNICODE
data = StringAtOfs(m_pTransTable, i); data = StringAtOfs(m_pTransTable, i);
if (!data)
return false; // may happen for invalid MO files
size_t length = Swap(m_pTransTable[i].nLen); size_t length = Swap(m_pTransTable[i].nLen);
size_t offset = 0; size_t offset = 0;
size_t index = 0; size_t index = 0;
@@ -1488,7 +1496,12 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash,
} }
// skip this string // skip this string
offset += strlen(str) + 1; // IMPORTANT: accesses to the 'data' pointer are valid only for
// the first 'length+1' bytes (GNU specs says that the
// final NUL is not counted in length); using wxStrnlen()
// we make sure we don't access memory beyond the valid range
// (which otherwise may happen for invalid MO files):
offset += wxStrnlen(str, length - offset) + 1;
++index; ++index;
} }
} }
@@ -1497,6 +1510,8 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash,
delete sourceConv; delete sourceConv;
delete inputConvPtr; delete inputConvPtr;
#endif // wxUSE_WCHAR_T #endif // wxUSE_WCHAR_T
return true;
} }
@@ -1531,7 +1546,8 @@ bool wxMsgCatalog::Load(const wxString& dirPrefix, const wxString& name,
if ( !file.Load(dirPrefix, name, m_pluralFormsCalculator) ) if ( !file.Load(dirPrefix, name, m_pluralFormsCalculator) )
return false; return false;
file.FillHash(m_messages, msgIdCharset, bConvertEncoding); if ( !file.FillHash(m_messages, msgIdCharset, bConvertEncoding) )
return false;
#if !wxUSE_UNICODE #if !wxUSE_UNICODE
// we should use a conversion compatible with the message catalog encoding // we should use a conversion compatible with the message catalog encoding