Module: wine Branch: master Commit: c8c3c4be914481d95a9c2790716b9d973e697b37 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c8c3c4be914481d95a9c279071...
Author: Owen Rudge orudge@codeweavers.com Date: Thu Mar 8 11:34:13 2012 +0000
comctl32/datetime: Check dates are within range in SetSystemTime.
---
dlls/comctl32/comctl32.h | 1 + dlls/comctl32/datetime.c | 46 +++++++++++++++++++++++++++++++++++++++- dlls/comctl32/monthcal.c | 2 +- dlls/comctl32/tests/datetime.c | 4 +- 4 files changed, 49 insertions(+), 4 deletions(-)
diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h index 7355e82..129ab0c 100644 --- a/dlls/comctl32/comctl32.h +++ b/dlls/comctl32/comctl32.h @@ -231,6 +231,7 @@ extern void UPDOWN_Unregister(void) DECLSPEC_HIDDEN;
int MONTHCAL_MonthLength(int month, int year) DECLSPEC_HIDDEN; int MONTHCAL_CalculateDayOfWeek(SYSTEMTIME *date, BOOL inplace) DECLSPEC_HIDDEN; +LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second) DECLSPEC_HIDDEN;
extern void THEMING_Initialize(void) DECLSPEC_HIDDEN; extern void THEMING_Uninitialize(void) DECLSPEC_HIDDEN; diff --git a/dlls/comctl32/datetime.c b/dlls/comctl32/datetime.c index 785769a..1443c35 100644 --- a/dlls/comctl32/datetime.c +++ b/dlls/comctl32/datetime.c @@ -138,6 +138,9 @@ static BOOL DATETIME_SendDateTimeChangeNotify (const DATETIME_INFO *infoPtr); static const WCHAR allowedformatchars[] = {'d', 'h', 'H', 'm', 'M', 's', 't', 'y', 'X', 0}; static const int maxrepetition [] = {4,2,2,2,4,2,2,4,-1};
+/* valid date limits */ +static const SYSTEMTIME max_allowed_date = { /* wYear */ 9999, /* wMonth */ 12, /* wDayOfWeek */ 0, /* wDay */ 31 }; +static const SYSTEMTIME min_allowed_date = { /* wYear */ 1752, /* wMonth */ 9, /* wDayOfWeek */ 0, /* wDay */ 14 };
static DWORD DATETIME_GetSystemTime (const DATETIME_INFO *infoPtr, SYSTEMTIME *systime) @@ -153,6 +156,43 @@ DATETIME_GetSystemTime (const DATETIME_INFO *infoPtr, SYSTEMTIME *systime) return GDT_VALID; }
+/* Checks value is within configured date range + * + * PARAMETERS + * + * [I] infoPtr : valid pointer to control data + * [I] date : pointer to valid date data to check + * + * RETURN VALUE + * + * TRUE - date within configured range + * FALSE - date is outside configured range + */ +static BOOL DATETIME_IsDateInValidRange(const DATETIME_INFO *infoPtr, const SYSTEMTIME *date) +{ + SYSTEMTIME range[2]; + DWORD limits; + + if ((MONTHCAL_CompareSystemTime(date, &max_allowed_date) == 1) || + (MONTHCAL_CompareSystemTime(date, &min_allowed_date) == -1)) + return FALSE; + + limits = SendMessageW (infoPtr->hMonthCal, MCM_GETRANGE, 0, (LPARAM) &range); + + if (limits & GDTR_MAX) + { + if (MONTHCAL_CompareSystemTime(date, &range[1]) == 1) + return FALSE; + } + + if (limits & GDTR_MIN) + { + if (MONTHCAL_CompareSystemTime(date, &range[0]) == -1) + return FALSE; + } + + return TRUE; +}
static BOOL DATETIME_SetSystemTime (DATETIME_INFO *infoPtr, DWORD flag, const SYSTEMTIME *systime) @@ -164,7 +204,7 @@ DATETIME_SetSystemTime (DATETIME_INFO *infoPtr, DWORD flag, const SYSTEMTIME *sy systime->wHour, systime->wMinute, systime->wSecond);
if (flag == GDT_VALID) { - if (systime->wYear < 1601 || systime->wYear > 30827 || + if (systime->wYear == 0 || systime->wMonth < 1 || systime->wMonth > 12 || systime->wDay < 1 || systime->wDay > MONTHCAL_MonthLength(systime->wMonth, systime->wYear) || @@ -175,6 +215,10 @@ DATETIME_SetSystemTime (DATETIME_INFO *infoPtr, DWORD flag, const SYSTEMTIME *sy ) return FALSE;
+ /* Windows returns true if the date is valid but outside the limits set */ + if (DATETIME_IsDateInValidRange(infoPtr, systime) == FALSE) + return TRUE; + infoPtr->dateValid = TRUE; infoPtr->date = *systime; /* always store a valid day of week */ diff --git a/dlls/comctl32/monthcal.c b/dlls/comctl32/monthcal.c index 1c9572b..a7722ee 100644 --- a/dlls/comctl32/monthcal.c +++ b/dlls/comctl32/monthcal.c @@ -296,7 +296,7 @@ static void MONTHCAL_CopyDate(const SYSTEMTIME *from, SYSTEMTIME *to) * * Note that no date validation performed, already validated values expected. */ -static LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second) +LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second) { FILETIME ft_first, ft_second;
diff --git a/dlls/comctl32/tests/datetime.c b/dlls/comctl32/tests/datetime.c index 8fb7d1f..24d339f 100644 --- a/dlls/comctl32/tests/datetime.c +++ b/dlls/comctl32/tests/datetime.c @@ -710,7 +710,7 @@ static void test_dtm_set_and_get_systemtime_with_limits(void) expect(1, r); r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]); ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r); - todo_wine expect_systime(&refSt, &getSt[0]); + expect_systime(&refSt, &getSt[0]);
fill_systime_struct(&st[0], 1977, 1, 0, 1, 0, 0, 0, 0);
@@ -718,7 +718,7 @@ static void test_dtm_set_and_get_systemtime_with_limits(void) expect(1, r); r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]); ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r); - todo_wine expect_systime(&refSt, &getSt[0]); + expect_systime(&refSt, &getSt[0]);
ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_systime_with_limits, "test_dtm_set_and_get_systime_with_limits", FALSE);