From: Jacob Czekalla jczekalla@codeweavers.com
Order of day or month and time or year needs to be considered. --- dlls/wininet/internet.c | 132 ++++++++++++++++++++++++++++------------ 1 file changed, 94 insertions(+), 38 deletions(-)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 17a7ce9385e..1ba6579e6fb 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -3960,6 +3960,71 @@ BOOL WINAPI InternetTimeToSystemTimeA( LPCSTR string, SYSTEMTIME* time, DWORD re return ret; }
+static inline int calc_month(SYSTEMTIME* time, const WCHAR **s, WCHAR *end) +{ + if (**s == '\0') return TRUE; + time->wMonth = 0; + if (iswalpha(**s)) + { + if ((*s)[1] == '\0' || (*s)[2] == '\0') return TRUE; + for (int i = 0; i < 12; i++) + { + if (!wcsnicmp(WININET_month[i], *s, 3)) + { + time->wMonth = i + 1; + *s += 3; + break; + } + } + } + else if (is_time_digit(**s)) + { + time->wMonth = wcstol(*s, &end, 10); + *s = end; + } + if (time->wMonth == 0) return TRUE; + return FALSE; +} + +static inline void calc_day(SYSTEMTIME* time, const WCHAR **s, WCHAR *end) +{ + time->wDay = wcstol( *s, &end, 10 ); + *s = end; +} + +static inline int calc_time(SYSTEMTIME* time, const WCHAR **s, WCHAR *end) +{ + if (**s == '\0') return TRUE; + time->wHour = wcstol( *s, &end, 10 ); + *s = end; + + while (**s && !is_time_digit(**s)) (*s)++; + if (**s == '\0') return TRUE; + time->wMinute = wcstol( *s, &end, 10 ); + *s = end; + + while (**s && !is_time_digit(**s)) (*s)++; + if (**s == '\0') return TRUE; + time->wSecond = wcstol( *s, &end, 10 ); + *s = end; + + time->wMilliseconds = 0; + return FALSE; +} + +static inline void calc_year(SYSTEMTIME* time, const WCHAR **s, WCHAR *end) +{ + time->wYear = wcstol( *s, &end, 10 ); + *s = end; +} + +static inline int is_time(const WCHAR *s) +{ + if (s[1] == L':' || s[2] == L':') + return 1; + return 0; +} + /*********************************************************************** * InternetTimeToSystemTimeW (WININET.@) */ @@ -3968,6 +4033,7 @@ BOOL WINAPI InternetTimeToSystemTimeW( LPCWSTR string, SYSTEMTIME* time, DWORD r unsigned int i; const WCHAR *s = string; WCHAR *end; + int got_day = 0, got_time = 0;
TRACE( "%s %p 0x%08lx\n", debugstr_w(string), time, reserved );
@@ -3992,6 +4058,7 @@ BOOL WINAPI InternetTimeToSystemTimeW( LPCWSTR string, SYSTEMTIME* time, DWORD r if (!wcsnicmp(WININET_wkday[i], s, 3)) { time->wDayOfWeek = i; + s += 3; break; } } @@ -4003,54 +4070,43 @@ BOOL WINAPI InternetTimeToSystemTimeW( LPCWSTR string, SYSTEMTIME* time, DWORD r } if (time->wDayOfWeek > 6) return TRUE;
- while (*s && !is_time_digit(*s)) s++; - time->wDay = wcstol( s, &end, 10 ); - s = end; - while (*s && !iswalpha(*s) && !is_time_digit(*s)) s++; - if (*s == '\0') return TRUE; - time->wMonth = 0; - - if (iswalpha(*s)) + if (is_time_digit(*s)) { - if (s[1] == '\0' || s[2] == '\0') return TRUE; - for (i = 0; i < 12; i++) - { - if (!wcsnicmp(WININET_month[i], s, 3)) - { - time->wMonth = i + 1; - break; - } - } + calc_day(time, &s, end); + got_day = 1; + }else + { + if (calc_month(time, &s, end)) + return TRUE; } - else if (is_time_digit(*s)) + while (*s && !iswalpha(*s) && !is_time_digit(*s)) s++; + if (got_day) { - time->wMonth = wcstol(s, &end, 10); - s = end; + if (calc_month(time, &s, end)) + return TRUE; } - if (time->wMonth == 0) return TRUE; - - while (*s && !is_time_digit(*s)) s++; - if (*s == '\0') return TRUE; - time->wYear = wcstol( s, &end, 10 ); - s = end; - - while (*s && !is_time_digit(*s)) s++; - if (*s == '\0') return TRUE; - time->wHour = wcstol( s, &end, 10 ); - s = end; + else + calc_day(time, &s, end);
while (*s && !is_time_digit(*s)) s++; if (*s == '\0') return TRUE; - time->wMinute = wcstol( s, &end, 10 ); - s = end; - + if (is_time(s)) + { + if (calc_time(time, &s, end)) + return TRUE; + got_time = 1; + }else + calc_year(time, &s, end); while (*s && !is_time_digit(*s)) s++; if (*s == '\0') return TRUE; - time->wSecond = wcstol( s, &end, 10 ); - s = end; - - time->wMilliseconds = 0; + if (got_time) + calc_year(time, &s, end); + else + { + if (calc_time(time, &s, end)) + return TRUE; + } return TRUE; }