Owen Rudge : comctl32/datetime: Check dates are within range in SetSystemTime.

Alexandre Julliard julliard at winehq.org
Mon Mar 12 11:59:57 CDT 2012


Module: wine
Branch: master
Commit: c8c3c4be914481d95a9c2790716b9d973e697b37
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c8c3c4be914481d95a9c2790716b9d973e697b37

Author: Owen Rudge <orudge at 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);
 




More information about the wine-cvs mailing list