Fix out-of-bounds reads in ParseRfc822Date() with too short input

The implementation implicitly relies, in many places, on the assumption
that the input never ends prematurely. If it does, the iterator
pointing beyond the end of buffer is dereferenced, which is UB.

The solution used here is to append 32 zero bytes to the date string,
which hopefully keeps the code more readable than checking for the end
of string before each deference operation.

Add various syntactically invalid inputs to unit tests.

Closes #22185.
This commit is contained in:
Lauri Nurmi 2022-03-09 18:59:15 +02:00 committed by Vadim Zeitlin
parent 2362010a48
commit 8d9d2684ef
2 changed files with 56 additions and 2 deletions

View file

@ -743,8 +743,14 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const
// this function is "strict" by design - it must reject anything except true
// RFC822 time specs.
bool
wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
wxDateTime::ParseRfc822Date(const wxString& originalDate, wxString::const_iterator *end)
{
// This implementation implicitly relies on the assumption that the
// input never ends prematurely (all dereferencing of *p assumes that).
// To avoid iterating beyond the end of buffer, let us append 32 zero bytes
// to the date string (32 being the length of a typical RFC822 timestamp).
const wxString date(originalDate + wxString(32, '\0'));
const wxString::const_iterator pEnd = date.end();
wxString::const_iterator p = date.begin();
@ -953,7 +959,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
MakeFromUTC();
if ( end )
*end = p;
*end = originalDate.begin() + (p - date.begin());
return true;
}

View file

@ -1099,6 +1099,54 @@ void DateTimeTestCase::TestParseRFC822()
{ 0 },
false
},
{
"Sun, 01 Und 2008 16:30:10 +0200", // month: Undecimber
{ 0 },
false
},
{
"Sun, 01 Jun 2008 16:3:10 +0200", // missing digit
{ 0 },
false
},
{
"Sun 01 Jun 2008 16:39:10 +0200", // missing comma
{ 0 },
false
},
{
"Sat, 18 Dec 1999 10:48:30", // TZ missing
{ 0 },
false
},
{
"Sat, 18 Dec 1999", // time missing
{ 0 },
false
},
{
"Sat, 18 Dec 2", // most of year missing
{ 0 },
false
},
{
"Sun,", // missing date and time
{ 0 },
false
},
{
"", // empty input
{ 0 },
false
},
};
wxGCC_WARNING_RESTORE(missing-field-initializers)