From ed973feb5aff74a6732d53e6f7ff7988cf468afa Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 25 Mar 2009 11:51:37 +0000 Subject: [PATCH] fix dereferencing end() iterator in ParseFormat() and constructing out of bound iterator in ParseDate() (thanks to VC9 debug CRT for the warnings) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59839 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/datetimefmt.cpp | 67 +++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/src/common/datetimefmt.cpp b/src/common/datetimefmt.cpp index 2bd9b8b0c5..ece5bff59f 100644 --- a/src/common/datetimefmt.cpp +++ b/src/common/datetimefmt.cpp @@ -237,11 +237,12 @@ GetWeekDayFromName(const wxString& name, int flags, int lang) // scans all digits (but no more than len) and returns the resulting number bool GetNumericToken(size_t len, wxString::const_iterator& p, + const wxString::const_iterator& end, unsigned long *number) { size_t n = 1; wxString s; - while ( wxIsdigit(*p) ) + while ( p != end && wxIsdigit(*p) ) { s += *p++; @@ -253,10 +254,12 @@ bool GetNumericToken(size_t len, } // scans all alphabetic characters and returns the resulting string -wxString GetAlphaToken(wxString::const_iterator& p) +wxString +GetAlphaToken(wxString::const_iterator& p, + const wxString::const_iterator& end) { wxString s; - while ( wxIsalpha(*p) ) + while ( p != end && wxIsalpha(*p) ) { s += *p++; } @@ -1062,10 +1065,10 @@ bool wxDateTime::ParseFormat(const wxString& date, const wxString& format, const wxDateTime& dateDef, - wxString::const_iterator *end) + wxString::const_iterator *endParse) { wxCHECK_MSG( !format.empty(), false, "format can't be empty" ); - wxCHECK_MSG( end, false, "end iterator pointer must be specified" ); + wxCHECK_MSG( endParse, false, "end iterator pointer must be specified" ); wxString str; unsigned long num; @@ -1096,6 +1099,7 @@ wxDateTime::ParseFormat(const wxString& date, int year = 0; wxString::const_iterator input = date.begin(); + const wxString::const_iterator end = date.end(); for ( wxString::const_iterator fmt = format.begin(); fmt != format.end(); ++fmt ) { if ( *fmt != _T('%') ) @@ -1166,7 +1170,7 @@ wxDateTime::ParseFormat(const wxString& date, { wday = GetWeekDayFromName ( - GetAlphaToken(input), + GetAlphaToken(input, end), *fmt == 'a' ? Name_Abbr : Name_Full, DateLang_Local ); @@ -1184,7 +1188,7 @@ wxDateTime::ParseFormat(const wxString& date, { mon = GetMonthFromName ( - GetAlphaToken(input), + GetAlphaToken(input, end), *fmt == 'b' ? Name_Abbr : Name_Full, DateLang_Local ); @@ -1224,7 +1228,7 @@ wxDateTime::ParseFormat(const wxString& date, const wxDateTime dt = ParseFormatAt ( input, - date.end(), + end, wxS("%a %b %d %H:%M:%S %Y"), wxS("%x %X"), wxS("%X %x") @@ -1249,7 +1253,7 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('d'): // day of a month (01-31) - if ( !GetNumericToken(width, input, &num) || + if ( !GetNumericToken(width, input, end, &num) || (num > 31) || (num < 1) ) { // no match @@ -1263,7 +1267,7 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('H'): // hour in 24h format (00-23) - if ( !GetNumericToken(width, input, &num) || (num > 23) ) + if ( !GetNumericToken(width, input, end, &num) || (num > 23) ) { // no match return false; @@ -1274,7 +1278,8 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('I'): // hour in 12h format (01-12) - if ( !GetNumericToken(width, input, &num) || !num || (num > 12) ) + if ( !GetNumericToken(width, input, end, &num) || + !num || (num > 12) ) { // no match return false; @@ -1286,7 +1291,8 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('j'): // day of the year - if ( !GetNumericToken(width, input, &num) || !num || (num > 366) ) + if ( !GetNumericToken(width, input, end, &num) || + !num || (num > 366) ) { // no match return false; @@ -1297,7 +1303,7 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('l'): // milliseconds (0-999) - if ( !GetNumericToken(width, input, &num) ) + if ( !GetNumericToken(width, input, end, &num) ) return false; haveMsec = true; @@ -1305,7 +1311,8 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('m'): // month as a number (01-12) - if ( !GetNumericToken(width, input, &num) || !num || (num > 12) ) + if ( !GetNumericToken(width, input, end, &num) || + !num || (num > 12) ) { // no match return false; @@ -1316,7 +1323,8 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('M'): // minute as a decimal number (00-59) - if ( !GetNumericToken(width, input, &num) || (num > 59) ) + if ( !GetNumericToken(width, input, end, &num) || + (num > 59) ) { // no match return false; @@ -1328,7 +1336,7 @@ wxDateTime::ParseFormat(const wxString& date, case _T('p'): // AM or PM string { - wxString am, pm, token = GetAlphaToken(input); + wxString am, pm, token = GetAlphaToken(input, end); // some locales have empty AM/PM tokens and thus when formatting // dates with the %p specifier nothing is generated; when trying to @@ -1355,7 +1363,7 @@ wxDateTime::ParseFormat(const wxString& date, case _T('r'): // time as %I:%M:%S %p { wxDateTime dt; - if ( !dt.ParseFormat(wxString(input, date.end()), + if ( !dt.ParseFormat(wxString(input, end), wxS("%I:%M:%S %p"), &input) ) return false; @@ -1371,7 +1379,7 @@ wxDateTime::ParseFormat(const wxString& date, case _T('R'): // time as %H:%M { const wxDateTime - dt = ParseFormatAt(input, date.end(), wxS("%H:%M")); + dt = ParseFormatAt(input, end, wxS("%H:%M")); if ( !dt.IsValid() ) return false; @@ -1385,7 +1393,8 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('S'): // second as a decimal number (00-61) - if ( !GetNumericToken(width, input, &num) || (num > 61) ) + if ( !GetNumericToken(width, input, end, &num) || + (num > 61) ) { // no match return false; @@ -1398,7 +1407,7 @@ wxDateTime::ParseFormat(const wxString& date, case _T('T'): // time as %H:%M:%S { const wxDateTime - dt = ParseFormatAt(input, date.end(), wxS("%H:%M:%S")); + dt = ParseFormatAt(input, end, wxS("%H:%M:%S")); if ( !dt.IsValid() ) return false; @@ -1414,7 +1423,8 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('w'): // weekday as a number (0-6), Sunday = 0 - if ( !GetNumericToken(width, input, &num) || (wday > 6) ) + if ( !GetNumericToken(width, input, end, &num) || + (wday > 6) ) { // no match return false; @@ -1470,7 +1480,7 @@ wxDateTime::ParseFormat(const wxString& date, } const wxDateTime - dt = ParseFormatAt(input, date.end(), + dt = ParseFormatAt(input, end, fmtDate, fmtDateAlt); if ( !dt.IsValid() ) return false; @@ -1511,7 +1521,7 @@ wxDateTime::ParseFormat(const wxString& date, // fails, as "%I:%M:%S %p" - this should catch the most // common cases const wxDateTime - dt = ParseFormatAt(input, date.end(), "%T", "%r"); + dt = ParseFormatAt(input, end, "%T", "%r"); if ( !dt.IsValid() ) return false; @@ -1528,7 +1538,8 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('y'): // year without century (00-99) - if ( !GetNumericToken(width, input, &num) || (num > 99) ) + if ( !GetNumericToken(width, input, end, &num) || + (num > 99) ) { // no match return false; @@ -1542,7 +1553,7 @@ wxDateTime::ParseFormat(const wxString& date, break; case _T('Y'): // year with century - if ( !GetNumericToken(width, input, &num) ) + if ( !GetNumericToken(width, input, end, &num) ) { // no match return false; @@ -1659,7 +1670,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( haveWDay && GetWeekDay() != wday ) return false; - *end = input; + *endParse = input; return true; } @@ -1745,11 +1756,15 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) { wxTRANSLATE("tomorrow"), 1 }, }; + const size_t lenRest = date.end() - p; for ( size_t n = 0; n < WXSIZEOF(literalDates); n++ ) { const wxString dateStr = wxGetTranslation(literalDates[n].str); size_t len = dateStr.length(); + if ( len > lenRest ) + continue; + const wxString::const_iterator pEnd = p + len; if ( wxString(p, pEnd).CmpNoCase(dateStr) == 0 ) {