X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Ftime.c;h=e66a9cba8438746722ff43e9eecdc9a721095205;hb=6c4f87e411aa5375eaea5a5909a5c610e38c7e70;hp=57e14b66c6d5be590ba2218e49a8a4b29c5a685f;hpb=8f2cb7ab26b9c720c24cdeffb624bfe0c2352353;p=oweals%2Fbusybox.git diff --git a/libbb/time.c b/libbb/time.c index 57e14b66c..e66a9cba8 100644 --- a/libbb/time.c +++ b/libbb/time.c @@ -23,14 +23,16 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) if (sscanf(date_str, "%u:%u%c", &ptm->tm_hour, &ptm->tm_min, - &end) >= 2) { + &end) >= 2 + ) { /* no adjustments needed */ } else /* mm.dd-HH:MM */ if (sscanf(date_str, "%u.%u-%u:%u%c", &ptm->tm_mon, &ptm->tm_mday, &ptm->tm_hour, &ptm->tm_min, - &end) >= 4) { + &end) >= 4 + ) { /* Adjust month from 1-12 to 0-11 */ ptm->tm_mon -= 1; } else @@ -38,15 +40,13 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) if (sscanf(date_str, "%u.%u.%u-%u:%u%c", &ptm->tm_year, &ptm->tm_mon, &ptm->tm_mday, &ptm->tm_hour, &ptm->tm_min, - &end) >= 5) { - ptm->tm_year -= 1900; /* Adjust years */ - ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ - } else + &end) >= 5 /* yyyy-mm-dd HH:MM */ - if (sscanf(date_str, "%u-%u-%u %u:%u%c", &ptm->tm_year, + || sscanf(date_str, "%u-%u-%u %u:%u%c", &ptm->tm_year, &ptm->tm_mon, &ptm->tm_mday, &ptm->tm_hour, &ptm->tm_min, - &end) >= 5) { + &end) >= 5 + ) { ptm->tm_year -= 1900; /* Adjust years */ ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ } else @@ -58,7 +58,6 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) return; /* don't fall through to end == ":" check */ } else #endif -//TODO: coreutils 6.9 also accepts "yyyy-mm-dd HH" (no minutes) { bb_error_msg_and_die(bb_msg_invalid_date, date_str); } @@ -68,7 +67,29 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) end = '\0'; /* else end != NUL and we error out */ } - } else if (date_str[0] == '@') { + } else + if (strchr(date_str, '-') + /* Why strchr('-') check? + * sscanf below will trash ptm->tm_year, this breaks + * if parse_str is "10101010" (iow, "MMddhhmm" form) + * because we destroy year. Do these sscanf + * only if we saw a dash in parse_str. + */ + /* yyyy-mm-dd HH */ + && (sscanf(date_str, "%u-%u-%u %u%c", &ptm->tm_year, + &ptm->tm_mon, &ptm->tm_mday, + &ptm->tm_hour, + &end) >= 4 + /* yyyy-mm-dd */ + || sscanf(date_str, "%u-%u-%u%c", &ptm->tm_year, + &ptm->tm_mon, &ptm->tm_mday, + &end) >= 3 + ) + ) { + ptm->tm_year -= 1900; /* Adjust years */ + ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ + } else + if (date_str[0] == '@') { time_t t = bb_strtol(date_str + 1, NULL, 10); if (!errno) { struct tm *lt = localtime(&t); @@ -163,8 +184,10 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) ptm->tm_year -= 1900; /* Adjust years */ ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ } else { + err: bb_error_msg_and_die(bb_msg_invalid_date, date_str); } + ptm->tm_sec = 0; /* assume zero if [.SS] is not given */ if (end == '.') { /* xxx.SS */ if (sscanf(strchr(date_str, '.') + 1, "%u%c", @@ -172,6 +195,19 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) end = '\0'; /* else end != NUL and we error out */ } + /* Users were confused by "date -s 20180923" + * working (not in the way they were expecting). + * It was interpreted as MMDDhhmm, and not bothered by + * "month #20" in the least. Prevent such cases: + */ + if (ptm->tm_sec > 60 /* allow "23:60" leap second */ + || ptm->tm_min > 59 + || ptm->tm_hour > 23 + || ptm->tm_mday > 31 + || ptm->tm_mon > 11 /* month# is 0..11, not 1..12 */ + ) { + goto err; + } } if (end != '\0') { bb_error_msg_and_die(bb_msg_invalid_date, date_str); @@ -217,12 +253,10 @@ char* FAST_FUNC strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) #define CLOCK_MONOTONIC 1 #endif -/* libc has incredibly messy way of doing this, - * typically requiring -lrt. We just skip all this mess */ static void get_mono(struct timespec *ts) { - if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, ts)) - bb_error_msg_and_die("clock_gettime(MONOTONIC) failed"); + if (clock_gettime(CLOCK_MONOTONIC, ts)) + bb_simple_error_msg_and_die("clock_gettime(MONOTONIC) failed"); } unsigned long long FAST_FUNC monotonic_ns(void) {