Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcrt/time.c | 27 ++++++++++++++------------- dlls/ucrtbase/tests/misc.c | 12 ++++++------ 2 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index 4248fe4f85..8534738406 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -1190,6 +1190,7 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, { MSVCRT_size_t ret, tmp; BOOL alternate; + int year = mstm ? mstm->tm_year + 1900 : -1;
if(!str || !format) { if(str && max) @@ -1272,8 +1273,9 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, break; #if _MSVCR_VER>=140 case 'C': - tmp = (1900+mstm->tm_year)/100; - if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 2, 0, 99)) + if(!MSVCRT_CHECK_PMT(year>=0 && year<=9999)) + goto einval_error; + if(!strftime_int(str, &ret, max, year/100, alternate ? 0 : 2, 0, 99)) return 0; break; #endif @@ -1283,6 +1285,8 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, break; #if _MSVCR_VER>=140 case 'D': + if(!MSVCRT_CHECK_PMT(year>=0 && year<=9999)) + goto einval_error; if(!strftime_int(str, &ret, max, mstm->tm_mon+1, alternate ? 0 : 2, 1, 12)) return 0; if(ret < max) @@ -1291,7 +1295,7 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, return 0; if(ret < max) str[ret++] = '/'; - if(!strftime_int(str, &ret, max, mstm->tm_year%100, alternate ? 0 : 2, 0, 99)) + if(!strftime_int(str, &ret, max, year%100, alternate ? 0 : 2, 0, 99)) return 0; break; case 'e': @@ -1301,8 +1305,7 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, str[ret-2] = ' '; break; case 'F': - tmp = 1900+mstm->tm_year; - if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 4, 0, 9999)) + if(!strftime_int(str, &ret, max, year, alternate ? 0 : 4, 0, 9999)) return 0; if(ret < max) str[ret++] = '-'; @@ -1315,7 +1318,7 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, break; case 'g': case 'G': - tmp = 1900 + mstm->tm_year; + tmp = year; if (mstm->tm_yday - (mstm->tm_wday ? mstm->tm_wday : 7) + 4 < 0) tmp--; else if(mstm->tm_yday - (mstm->tm_wday ? mstm->tm_wday : 7) + 5 > 365 + IsLeapYear(tmp)) @@ -1409,18 +1412,16 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, break; case 'y': #if _MSVCR_VER>=140 - if(!MSVCRT_CHECK_PMT(mstm->tm_year>=-1900 && mstm->tm_year<=8099)) - goto einval_error; - tmp = (mstm->tm_year+1900)%100; + if(!MSVCRT_CHECK_PMT(year>=0 && year<=9999)) #else - tmp = mstm->tm_year%100; + if(!MSVCRT_CHECK_PMT(year>=1900)) #endif - if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 2, 0, 99)) + goto einval_error; + if(!strftime_int(str, &ret, max, year%100, alternate ? 0 : 2, 0, 99)) return 0; break; case 'Y': - tmp = 1900+mstm->tm_year; - if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 4, 0, 9999)) + if(!strftime_int(str, &ret, max, year, alternate ? 0 : 4, 0, 9999)) return 0; break; case 'z': diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index debf0b87a0..9c5045b66a 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -930,23 +930,23 @@ static void test_strftime(void) BOOL todo; BOOL todo_handler; } tests[] = { - {"%C", "", { 0, 0, 0, 1, 0, -2000, 4, 0, 0 }, FALSE, TRUE}, - {"%C", "", { 0, 0, 0, 1, 0, -1901, 4, 0, 0 }, TRUE}, + {"%C", "", { 0, 0, 0, 1, 0, -2000, 4, 0, 0 }}, + {"%C", "", { 0, 0, 0, 1, 0, -1901, 4, 0, 0 }}, {"%C", "00", { 0, 0, 0, 1, 0, -1900, 4, 0, 0 }}, {"%C", "18", { 0, 0, 0, 1, 0, -1, 4, 0, 0 }}, {"%C", "19", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%C", "99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }}, - {"%C", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }, FALSE, TRUE}, + {"%C", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }}, {"%d", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }, TRUE}, {"%d", "01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%d", "31", { 0, 0, 0, 31, 0, 70, 4, 0, 0 }}, {"%d", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }, FALSE, TRUE}, - {"%D", "", { 0, 0, 0, 1, 0, -1901, 4, 0, 0 }, FALSE, TRUE}, + {"%D", "", { 0, 0, 0, 1, 0, -1901, 4, 0, 0 }}, {"%D", "01/01/00", { 0, 0, 0, 1, 0, -1900, 4, 0, 0 }}, - {"%D", "01/01/99", { 0, 0, 0, 1, 0, -1, 4, 0, 0 }, TRUE}, + {"%D", "01/01/99", { 0, 0, 0, 1, 0, -1, 4, 0, 0 }}, {"%D", "01/01/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%D", "01/01/99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }}, - {"%D", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }, TRUE}, + {"%D", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }}, {"%#D", "1/1/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%e", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }, TRUE}, {"%e", " 1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcrt/time.c | 12 +++++++++--- dlls/ucrtbase/tests/misc.c | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index 8534738406..802032d79e 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -54,6 +54,12 @@ static const int MonthLengths[2][12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
+#if _MSVCR_VER>=140 +static const int MAX_SECONDS = 60; +#else +static const int MAX_SECONDS = 59; +#endif + static inline BOOL IsLeapYear(int Year) { return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0); @@ -1141,7 +1147,7 @@ static inline BOOL strftime_format(STRFTIME_CHAR *str, MSVCRT_size_t *pos, MSVCR if(count > 2) ret = strftime_nstr(str, pos, max, format, count-2); if(ret) - ret = strftime_int(str, pos, max, mstm->tm_sec, count == 1 ? 0 : 2, 0, 59); + ret = strftime_int(str, pos, max, mstm->tm_sec, count == 1 ? 0 : 2, 0, MAX_SECONDS); break; case 'a': case 'A': @@ -1381,7 +1387,7 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, break; #endif case 'S': - if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, 59)) + if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, MAX_SECONDS)) return 0; break; #if _MSVCR_VER>=140 @@ -1397,7 +1403,7 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, return 0; if(ret < max) str[ret++] = ':'; - if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, 59)) + if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, MAX_SECONDS)) return 0; break; case 'u': diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 9c5045b66a..154781dd33 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -1004,7 +1004,7 @@ static void test_strftime(void) {"%#x", "", { 0, 0, 0, 30, 12, 70, 4, 0, 0 }}, {"%X", "00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%X", "14:00:00", { 0, 0, 14, 1, 0, 70, 4, 0, 0 }}, - {"%X", "23:59:60", { 60, 59, 23, 1, 0, 70, 4, 0, 0 }, TRUE}, + {"%X", "23:59:60", { 60, 59, 23, 1, 0, 70, 4, 0, 0 }}, };
const struct {
Signed-off-by: Piotr Caban piotr@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcrt/time.c | 10 +++++----- dlls/ucrtbase/tests/misc.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index 802032d79e..288b4d5cda 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -1052,7 +1052,7 @@ static inline BOOL strftime_format(STRFTIME_CHAR *str, MSVCRT_size_t *pos, MSVCR switch(count) { case 1: case 2: - ret = strftime_int(str, pos, max, mstm->tm_mday, count==1 ? 0 : 2, 0, 31); + ret = strftime_int(str, pos, max, mstm->tm_mday, count==1 ? 0 : 2, 1, 31); break; case 3: ret = strftime_str(str, pos, max, STRFTIME_TD(time_data, short_wday)[mstm->tm_wday]); @@ -1286,7 +1286,7 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, break; #endif case 'd': - if(!strftime_int(str, &ret, max, mstm->tm_mday, alternate ? 0 : 2, 0, 31)) + if(!strftime_int(str, &ret, max, mstm->tm_mday, alternate ? 0 : 2, 1, 31)) return 0; break; #if _MSVCR_VER>=140 @@ -1297,7 +1297,7 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, return 0; if(ret < max) str[ret++] = '/'; - if(!strftime_int(str, &ret, max, mstm->tm_mday, alternate ? 0 : 2, 0, 31)) + if(!strftime_int(str, &ret, max, mstm->tm_mday, alternate ? 0 : 2, 1, 31)) return 0; if(ret < max) str[ret++] = '/'; @@ -1305,7 +1305,7 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, return 0; break; case 'e': - if(!strftime_int(str, &ret, max, mstm->tm_mday, alternate ? 0 : 2, 0, 31)) + if(!strftime_int(str, &ret, max, mstm->tm_mday, alternate ? 0 : 2, 1, 31)) return 0; if(!alternate && str[ret-2] == '0') str[ret-2] = ' '; @@ -1319,7 +1319,7 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, return 0; if(ret < max) str[ret++] = '-'; - if(!strftime_int(str, &ret, max, mstm->tm_mday, alternate ? 0 : 2, 0, 31)) + if(!strftime_int(str, &ret, max, mstm->tm_mday, alternate ? 0 : 2, 1, 31)) return 0; break; case 'g': diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 154781dd33..6700b4bdf1 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -937,7 +937,7 @@ static void test_strftime(void) {"%C", "19", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%C", "99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }}, {"%C", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }}, - {"%d", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }, TRUE}, + {"%d", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }, FALSE, TRUE}, {"%d", "01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%d", "31", { 0, 0, 0, 31, 0, 70, 4, 0, 0 }}, {"%d", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }, FALSE, TRUE}, @@ -948,7 +948,7 @@ static void test_strftime(void) {"%D", "01/01/99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }}, {"%D", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }}, {"%#D", "1/1/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, - {"%e", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }, TRUE}, + {"%e", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }, FALSE, TRUE}, {"%e", " 1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%e", "31", { 0, 0, 0, 31, 0, 70, 4, 0, 0 }}, {"%e", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }, FALSE, TRUE},
Signed-off-by: Piotr Caban piotr@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcrt/time.c | 10 ++++------ dlls/ucrtbase/tests/misc.c | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index 288b4d5cda..127a2164b8 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -1344,12 +1344,10 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, return 0; break; case 'I': - tmp = mstm->tm_hour; - if(tmp > 12) - tmp -= 12; - else if(!tmp) - tmp = 12; - if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 2, 1, 12)) + if(!MSVCRT_CHECK_PMT(mstm->tm_hour>=0 && mstm->tm_hour<=23)) + goto einval_error; + if(!strftime_int(str, &ret, max, (mstm->tm_hour + 11) % 12 + 1, + alternate ? 0 : 2, 1, 12)) return 0; break; case 'j': diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 6700b4bdf1..c242546a80 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -965,14 +965,14 @@ static void test_strftime(void) {"%u", "6", { 0, 0, 0, 1, 0, 117, 6, 0, 0 }}, {"%u", "", { 0, 0, 0, 1, 0, 117, 7, 0, 0 }, TRUE}, {"%h", "Jan", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, - {"%I", "", { 0, 0, -1, 1, 0, 70, 4, 0, 0 }, FALSE, TRUE}, + {"%I", "", { 0, 0, -1, 1, 0, 70, 4, 0, 0 }}, {"%I", "12", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%I", "01", { 0, 0, 1, 1, 0, 70, 4, 0, 0 }}, {"%I", "11", { 0, 0, 11, 1, 0, 70, 4, 0, 0 }}, {"%I", "12", { 0, 0, 12, 1, 0, 70, 4, 0, 0 }}, {"%I", "01", { 0, 0, 13, 1, 0, 70, 4, 0, 0 }}, {"%I", "11", { 0, 0, 23, 1, 0, 70, 4, 0, 0 }}, - {"%I", "", { 0, 0, 24, 1, 0, 70, 4, 0, 0 }, TRUE}, + {"%I", "", { 0, 0, 24, 1, 0, 70, 4, 0, 0 }}, {"%n", "\n", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%r", "12:00:00 AM", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }, TRUE}, {"%r", "02:00:00 PM", { 0, 0, 14, 1, 0, 121, 6, 0, 0 }, TRUE},
Signed-off-by: Piotr Caban piotr@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcrt/time.c | 2 ++ dlls/ucrtbase/tests/misc.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index 127a2164b8..84e725747f 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -1405,6 +1405,8 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, return 0; break; case 'u': + if(!MSVCRT_CHECK_PMT(mstm->tm_wday>=0 && mstm->tm_wday<=6)) + goto einval_error; tmp = mstm->tm_wday ? mstm->tm_wday : 7; if(!strftime_int(str, &ret, max, tmp, 0, 1, 7)) return 0; diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index c242546a80..93a78a5de7 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -959,11 +959,11 @@ static void test_strftime(void) {"%#R", "0:0", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%T", "00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%#T", "0:0:0", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, - {"%u", "", { 0, 0, 0, 1, 0, 117, -1, 0, 0 }, FALSE, TRUE}, + {"%u", "", { 0, 0, 0, 1, 0, 117, -1, 0, 0 }}, {"%u", "7", { 0, 0, 0, 1, 0, 117, 0, 0, 0 }}, {"%u", "1", { 0, 0, 0, 1, 0, 117, 1, 0, 0 }}, {"%u", "6", { 0, 0, 0, 1, 0, 117, 6, 0, 0 }}, - {"%u", "", { 0, 0, 0, 1, 0, 117, 7, 0, 0 }, TRUE}, + {"%u", "", { 0, 0, 0, 1, 0, 117, 7, 0, 0 }}, {"%h", "Jan", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%I", "", { 0, 0, -1, 1, 0, 70, 4, 0, 0 }}, {"%I", "12", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
Signed-off-by: Piotr Caban piotr@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcrt/time.c | 2 +- dlls/ucrtbase/tests/misc.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index 84e725747f..ec8f45d140 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -998,7 +998,7 @@ static inline BOOL strftime_int(STRFTIME_CHAR *str, MSVCRT_size_t *pos, MSVCRT_s
if(src<l || src>h) { *str = 0; - *MSVCRT__errno() = MSVCRT_EINVAL; + MSVCRT_INVALID_PMT("Invalid value", MSVCRT_EINVAL); return FALSE; }
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 93a78a5de7..6314662eac 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -937,10 +937,10 @@ static void test_strftime(void) {"%C", "19", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%C", "99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }}, {"%C", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }}, - {"%d", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }, FALSE, TRUE}, + {"%d", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }}, {"%d", "01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%d", "31", { 0, 0, 0, 31, 0, 70, 4, 0, 0 }}, - {"%d", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }, FALSE, TRUE}, + {"%d", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }}, {"%D", "", { 0, 0, 0, 1, 0, -1901, 4, 0, 0 }}, {"%D", "01/01/00", { 0, 0, 0, 1, 0, -1900, 4, 0, 0 }}, {"%D", "01/01/99", { 0, 0, 0, 1, 0, -1, 4, 0, 0 }}, @@ -948,10 +948,10 @@ static void test_strftime(void) {"%D", "01/01/99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }}, {"%D", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }}, {"%#D", "1/1/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, - {"%e", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }, FALSE, TRUE}, + {"%e", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }}, {"%e", " 1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%e", "31", { 0, 0, 0, 31, 0, 70, 4, 0, 0 }}, - {"%e", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }, FALSE, TRUE}, + {"%e", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }}, {"%#e", "1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%F", "1970-01-01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%#F", "1970-1-1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
Hi Jeff,
On 11/22/19 1:28 AM, Jeff Smith wrote:
if(src<l || src>h) { *str = 0;
*MSVCRT__errno() = MSVCRT_EINVAL;
MSVCRT_INVALID_PMT("Invalid value", MSVCRT_EINVAL); return FALSE; }
Please change it to if(!MSVCRT_CHECK_PMT(src>=l && src<=h)).
Could you please also move it earlier in the series? It makes some other changes not needed (e.g. patch 5/7 is not needed).
Thanks, Piotr
On 11/22/19 1:35 PM, Piotr Caban wrote:
Hi Jeff,
On 11/22/19 1:28 AM, Jeff Smith wrote:
if(src<l || src>h) { *str = 0; - *MSVCRT__errno() = MSVCRT_EINVAL; + MSVCRT_INVALID_PMT("Invalid value", MSVCRT_EINVAL); return FALSE; }
Please change it to if(!MSVCRT_CHECK_PMT(src>=l && src<=h)).
Could you please also move it earlier in the series? It makes some other changes not needed (e.g. patch 5/7 is not needed).
The patch 5/7 will still be needed, sorry for that. Please only change the if condition.
Thanks, Piotr
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcrt/time.c | 35 +++++++++++++++++++++++++++-------- dlls/ucrtbase/tests/misc.c | 4 ++-- 2 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index ec8f45d140..93700e3048 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -1195,6 +1195,8 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, MSVCRT___lc_time_data *time_data, MSVCRT__locale_t loc) { MSVCRT_size_t ret, tmp; + MSVCRT_pthreadlocinfo locinfo; + BOOL time_data_from_param = (time_data) ? TRUE : FALSE; BOOL alternate; int year = mstm ? mstm->tm_year + 1900 : -1;
@@ -1205,8 +1207,9 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max, return 0; }
+ locinfo = loc ? loc->locinfo : get_locinfo(); if(!time_data) - time_data = loc ? loc->locinfo->lc_time_curr : get_locinfo()->lc_time_curr; + time_data = locinfo->lc_time_curr;
for(ret=0; *format && ret<max; format++) { if(*format != '%') { @@ -1233,13 +1236,29 @@ static MSVCRT_size_t strftime_impl(STRFTIME_CHAR *str, MSVCRT_size_t max,
switch(*format) { case 'c': - if(!strftime_format(str, &ret, max, mstm, time_data, - alternate ? STRFTIME_TD(time_data, date) : STRFTIME_TD(time_data, short_date))) - return 0; - if(ret < max) - str[ret++] = ' '; - if(!strftime_format(str, &ret, max, mstm, time_data, STRFTIME_TD(time_data, time))) - return 0; +#if _MSVCR_VER>=140 + if(!strcmp(locinfo->lc_category[MSVCRT_LC_TIME].locale, "C") && + !time_data_from_param && !alternate) + { + static const WCHAR date_format[] = { 'd','d','d',' ','M','M','M',' ','d','d', + ' ','H','H',':','m','m',':','s','s',' ','y','y','y','y',0 }; + MSVCRT_size_t day_offset = ret + 8; + if(!strftime_format(str, &ret, max, mstm, time_data, date_format)) + return 0; + if(str[day_offset] == '0') + str[day_offset] = ' '; + } + else +#endif + { + if(!strftime_format(str, &ret, max, mstm, time_data, + alternate ? STRFTIME_TD(time_data, date) : STRFTIME_TD(time_data, short_date))) + return 0; + if(ret < max) + str[ret++] = ' '; + if(!strftime_format(str, &ret, max, mstm, time_data, STRFTIME_TD(time_data, time))) + return 0; + } break; case 'x': if(!strftime_format(str, &ret, max, mstm, time_data, diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 6314662eac..9598333fc8 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -992,8 +992,8 @@ static void test_strftime(void) {"%g", "72", { 0, 0, 0, 3, 0, 72, 1, 2, 0 }}, {"%G", "1971", { 0, 0, 0, 2, 0, 72, 0, 1, 0 }}, {"%G", "1972", { 0, 0, 0, 3, 0, 72, 1, 2, 0 }}, - {"%c", "Thu Jan 1 00:00:00 1970", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }, TRUE}, - {"%c", "Thu Feb 30 00:00:00 1970", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }, TRUE}, + {"%c", "Thu Jan 1 00:00:00 1970", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%c", "Thu Feb 30 00:00:00 1970", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, {"%#c", "Thursday, January 01, 1970 00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%#c", "Thursday, February 30, 1970 00:00:00", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, {"%x", "01/01/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
Hi Jeff,
On 11/22/19 1:28 AM, Jeff Smith wrote:
- BOOL time_data_from_param = (time_data) ? TRUE : FALSE;
time_data_from_param is not used if MSVCR_VER != 140. Also a quick testing shows that it's still not correct. Probably we should find a better way of recognizing lc_time_curr from C locale.
+#if _MSVCR_VER>=140
if(!strcmp(locinfo->lc_category[MSVCRT_LC_TIME].locale, "C") &&
!time_data_from_param && !alternate)
{
static const WCHAR date_format[] = { 'd','d','d',' ','M','M','M',' ','d','d',
' ','H','H',':','m','m',':','s','s',' ','y','y','y','y',0 };
MSVCRT_size_t day_offset = ret + 8;
if(!strftime_format(str, &ret, max, mstm, time_data, date_format))
return 0;
if(str[day_offset] == '0')
str[day_offset] = ' ';
Is it the same as calling following code? static const WCHAR date_format[] = {'a',' ','b',' ','e',' ','T',' ','Y'}; tmp = strftime_impl(str+ret, max-ret, date_format, mstm, time_data, loc); if (!tmp) goto einval_error; ret += tmp;
It will remove the need to manipulate the function output.
Thanks, Piotr