From f17ac57417530febd2c48bbb6c82004cb23d108c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Mar 2012 16:45:53 +0000 Subject: [PATCH] Return valid pointers from wxDateTime::ParseXXX() with non-wxString strings. The pointer returned by wxDateTime::ParseXXX() methods could point into a buffer of a temporary wxString created to wrap a char* or wchar_t* argument so dereferencing it was illegal. Fix this by defining separate overloads for char*/wchar_t* arguments returning pointers into the original string. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70996 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/datetime.h | 38 ++++++++++++ src/common/datetimefmt.cpp | 106 ++++++++++++++++++++++++++++++++ tests/datetime/datetimetest.cpp | 4 ++ 3 files changed, 148 insertions(+) diff --git a/include/wx/datetime.h b/include/wx/datetime.h index 1115e00f07..9deab532e1 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -1205,6 +1205,44 @@ public: : wxAnyStrPtr(); } + // In addition to wxAnyStrPtr versions above we also must provide the + // overloads for C strings as we must return a pointer into the original + // string and not inside a temporary wxString which would have been created + // if the overloads above were used. + // + // And then we also have to provide the overloads for wxCStrData, as usual. + wxAnyStrPtr ParseRfc822Date(const wxCStrData& date) + { return ParseRfc822Date(wxString(date)); } + const char* ParseRfc822Date(const char* date); + const wchar_t* ParseRfc822Date(const wchar_t* date); + + wxAnyStrPtr ParseFormat(const wxCStrData& date, + const wxString& format = wxDefaultDateTimeFormat, + const wxDateTime& dateDef = wxDefaultDateTime) + { return ParseFormat(wxString(date), format, dateDef); } + const char* ParseFormat(const char* date, + const wxString& format = wxDefaultDateTimeFormat, + const wxDateTime& dateDef = wxDefaultDateTime); + const wchar_t* ParseFormat(const wchar_t* date, + const wxString& format = wxDefaultDateTimeFormat, + const wxDateTime& dateDef = wxDefaultDateTime); + + wxAnyStrPtr ParseDateTime(const wxCStrData& datetime) + { return ParseDateTime(wxString(datetime)); } + const char* ParseDateTime(const char* datetime); + const wchar_t* ParseDateTime(const wchar_t* datetime); + + wxAnyStrPtr ParseDate(const wxCStrData& date) + { return ParseDate(wxString(date)); } + const char* ParseDate(const char* date); + const wchar_t* ParseDate(const wchar_t* date); + + wxAnyStrPtr ParseTime(const wxCStrData& time) + { return ParseTime(wxString(time)); } + const char* ParseTime(const char* time); + const wchar_t* ParseTime(const wchar_t* time); + + // implementation // ------------------------------------------------------------------------ diff --git a/src/common/datetimefmt.cpp b/src/common/datetimefmt.cpp index cfce31f86a..698749f2c9 100644 --- a/src/common/datetimefmt.cpp +++ b/src/common/datetimefmt.cpp @@ -935,6 +935,26 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end) return true; } +const char* wxDateTime::ParseRfc822Date(const char* date) +{ + wxString::const_iterator end; + wxString dateStr(date); + if ( !ParseRfc822Date(dateStr, &end) ) + return NULL; + + return date + dateStr.IterOffsetInMBStr(end); +} + +const wchar_t* wxDateTime::ParseRfc822Date(const wchar_t* date) +{ + wxString::const_iterator end; + wxString dateStr(date); + if ( !ParseRfc822Date(dateStr, &end) ) + return NULL; + + return date + (end - dateStr.begin()); +} + bool wxDateTime::ParseFormat(const wxString& date, const wxString& format, @@ -1569,6 +1589,32 @@ wxDateTime::ParseFormat(const wxString& date, return true; } +const char* +wxDateTime::ParseFormat(const char* date, + const wxString& format, + const wxDateTime& dateDef) +{ + wxString::const_iterator end; + wxString dateStr(date); + if ( !ParseFormat(dateStr, format, dateDef, &end) ) + return NULL; + + return date + dateStr.IterOffsetInMBStr(end); +} + +const wchar_t* +wxDateTime::ParseFormat(const wchar_t* date, + const wxString& format, + const wxDateTime& dateDef) +{ + wxString::const_iterator end; + wxString dateStr(date); + if ( !ParseFormat(dateStr, format, dateDef, &end) ) + return NULL; + + return date + (end - dateStr.begin()); +} + bool wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end) { @@ -1622,6 +1668,26 @@ wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end) return true; } +const char* wxDateTime::ParseDateTime(const char* date) +{ + wxString::const_iterator end; + wxString dateStr(date); + if ( !ParseDateTime(dateStr, &end) ) + return NULL; + + return date + dateStr.IterOffsetInMBStr(end); +} + +const wchar_t* wxDateTime::ParseDateTime(const wchar_t* date) +{ + wxString::const_iterator end; + wxString dateStr(date); + if ( !ParseDateTime(dateStr, &end) ) + return NULL; + + return date + (end - dateStr.begin()); +} + bool wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) { @@ -1979,6 +2045,26 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) return true; } +const char* wxDateTime::ParseDate(const char* date) +{ + wxString::const_iterator end; + wxString dateStr(date); + if ( !ParseDate(dateStr, &end) ) + return NULL; + + return date + dateStr.IterOffsetInMBStr(end); +} + +const wchar_t* wxDateTime::ParseDate(const wchar_t* date) +{ + wxString::const_iterator end; + wxString dateStr(date); + if ( !ParseDate(dateStr, &end) ) + return NULL; + + return date + (end - dateStr.begin()); +} + bool wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end) { @@ -2034,6 +2120,26 @@ wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end) return false; } +const char* wxDateTime::ParseTime(const char* date) +{ + wxString::const_iterator end; + wxString dateStr(date); + if ( !ParseTime(dateStr, &end) ) + return NULL; + + return date + dateStr.IterOffsetInMBStr(end); +} + +const wchar_t* wxDateTime::ParseTime(const wchar_t* date) +{ + wxString::const_iterator end; + wxString dateStr(date); + if ( !ParseTime(dateStr, &end) ) + return NULL; + + return date + (end - dateStr.begin()); +} + // ---------------------------------------------------------------------------- // Workdays and holidays support // ---------------------------------------------------------------------------- diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp index 65375c0896..3850715300 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -1043,6 +1043,10 @@ void DateTimeTestCase::TestDateParse() ); } } + + // Check that incomplete parse works correctly. + const char* p = dt.ParseFormat("2012-03-23 12:34:56", "%Y-%m-%d"); + CPPUNIT_ASSERT_EQUAL( " 12:34:56", wxString(p) ); } void DateTimeTestCase::TestDateParseISO() -- 2.45.2