diff --git a/libcxx/include/locale b/libcxx/include/locale --- a/libcxx/include/locale +++ b/libcxx/include/locale @@ -1925,7 +1925,7 @@ const ctype& __ct) const { int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1; - if (!(__err & ios_base::failbit) && __t <= 11) + if (!(__err & ios_base::failbit) && 0 <= __t && __t <= 11) __m = __t; else __err |= ios_base::failbit; diff --git a/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp b/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp --- a/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp @@ -104,5 +104,57 @@ assert(t.tm_year == 109); assert(err == std::ios_base::eofbit); } + // Months must be > 0 and <= 12. + { + const my_facet f(LOCALE_en_US_UTF_8, 1); + const char in[] = "00/21/2022"; + err = std::ios_base::goodbit; + t = std::tm(); + I i = f.get_date(I(in), I(in+sizeof(in)/sizeof(in[0])-1), ios, err, &t); +#if _LIBCPP_VERSION + // libc++ points to the '/' after the month. + assert(base(i) == in+2); +#else + // libstdc++ points to the second character. + assert(base(i) == in+1); +#endif + // tm is not modified. + assert(t.tm_mon == 0); + assert(t.tm_mday == 0); + assert(t.tm_year == 0); + assert(err == std::ios_base::failbit); + } + { + const my_facet f(LOCALE_en_US_UTF_8, 1); + const char in[] = "13/21/2022"; + err = std::ios_base::goodbit; + t = std::tm(); + I i = f.get_date(I(in), I(in+sizeof(in)/sizeof(in[0])-1), ios, err, &t); +#if _LIBCPP_VERSION + // libc++ points to the '/' after the month. + assert(base(i) == in+2); +#else + // libstdc++ points to the second character. + assert(base(i) == in+1); +#endif + assert(base(i) == in+2); + assert(t.tm_mon == 0); + assert(t.tm_mday == 0); + assert(t.tm_year == 0); + assert(err == std::ios_base::failbit); + } + // Leading zero is allowed. + { + const my_facet f(LOCALE_en_US_UTF_8, 1); + const char in[] = "03/21/2022"; + err = std::ios_base::goodbit; + t = std::tm(); + I i = f.get_date(I(in), I(in+sizeof(in)/sizeof(in[0])-1), ios, err, &t); + assert(base(i) == in+sizeof(in)/sizeof(in[0])-1); + assert(t.tm_mon == 2); + assert(t.tm_mday == 21); + assert(t.tm_year == 122); + assert(err == std::ios_base::eofbit); + } return 0; }