[libcxx-commits] [PATCH] D124175: [libcxx] Reject month 0 in get_date/__get_month

David Spickett via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Thu Apr 21 07:27:42 PDT 2022


DavidSpickett created this revision.
Herald added a project: All.
DavidSpickett requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

This fixes #47663.

Months in dates should be >= 1 and <= 12.
We parse up to two digits then minus one, because
we want to store this as "months since January"
(0-11).

However we didn't check that the result of that
was not -1. For example if you had (MM/DD/YYYY)
00/21/2022.

Added tests for:

- Failing if month is 0
- Failing if month is 12
- Allowing a leading zero in month e.g. "01"


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D124175

Files:
  libcxx/include/locale
  libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp


Index: libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp
===================================================================
--- libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp
+++ libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp
@@ -103,5 +103,47 @@
         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);
+        // We consume the first two chars checking the month.
+        assert(base(i) == in+2);
+        // 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[] = "12/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+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;
 }
Index: libcxx/include/locale
===================================================================
--- libcxx/include/locale
+++ libcxx/include/locale
@@ -1925,7 +1925,7 @@
                                               const ctype<char_type>& __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;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124175.424200.patch
Type: text/x-patch
Size: 2475 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220421/afbf72ca/attachment.bin>


More information about the libcxx-commits mailing list