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
This commit is contained in:
parent
b33e98f0bd
commit
ed973feb5a
@ -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 )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user