The code below with "If format didn't already specify seconds, grab seconds" detects whether the format contains seconds by relying on the index of the format (with an i>2 predicate). However, the format "%a %b %e %H:%M:%S %Z %Y" does not end with seconds, so we shouldn't parse fraction of seconds here. On the other hand, the format "%H:%M:%S" ends with seconds, so we should parse fraction of seconds there.
Add a test for it; the test uses a >60 number for fraction of seconds to trigger the bug before the fix. Without the fix, "12:34:56.777" are recognized as "12:34:77", which is an invalid time. Fixes: d1a446687a9c ("xparsedate: support default date(1) output format.") --- lib/xwrap.c | 3 ++- tests/date.test | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/xwrap.c b/lib/xwrap.c index d07f355a..e5b35bb7 100644 --- a/lib/xwrap.c +++ b/lib/xwrap.c @@ -1025,8 +1025,9 @@ void xparsedate(char *str, time_t *t, unsigned *nano, int endian) // Formats with seconds come first. Posix can't agree on whether 12 digits // has year before (touch -t) or year after (date), so support both. char *s = str, *p, *oldtz = 0, *formats[] = {"%Y-%m-%d %T", "%Y-%m-%dT%T", + "%H:%M:%S", "%a %b %e %H:%M:%S %Z %Y", // date(1) output format in POSIX/C locale. - "%H:%M:%S", "%Y-%m-%d %H:%M", "%Y-%m-%d", "%H:%M", "%m%d%H%M", + "%Y-%m-%d %H:%M", "%Y-%m-%d", "%H:%M", "%m%d%H%M", endian ? "%m%d%H%M%y" : "%y%m%d%H%M", endian ? "%m%d%H%M%C%y" : "%C%y%m%d%H%M"}; diff --git a/tests/date.test b/tests/date.test index 9777edb3..3ec2659e 100644 --- a/tests/date.test +++ b/tests/date.test @@ -42,6 +42,9 @@ testing "Unix time missing @" "TZ=$tz date 1438053157 2>/dev/null || echo no" \ testing "-d 12:34" 'TZ=UTC date -d 12:34 | grep -q " 12:34:00 UTC $this_year" && echo OK' "OK\n" "" "" testing "-d 12:34:56" 'TZ=UTC date -d 12:34:56 | grep -q " 12:34:56 UTC $this_year" && echo OK' "OK\n" "" "" +# Test fraction +testing "-d 12:34:56.777" 'date -d 12:34:56.777 +%H:%M:%S.%3N | grep -q "12:34:56.777" && echo OK' "OK\n" "" "" + # Test the %N extension to srtftime(3) format strings. testing "%N" "touch -d 2012-01-23T12:34:56.123456789 f && date -r f +%Y%m%d-%H%M%S.%N" "20120123-123456.123456789\n" "" "" testing "%1N" "touch -d 2012-01-23T12:34:56.123456789 f && date -r f +%Y%m%d-%H%M%S.%1N" "20120123-123456.1\n" "" "" -- 2.46.0.662.g92d0881bb0-goog _______________________________________________ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net