diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze index 4bc146aa06f..a8bc752f1e9 100644 --- a/shell-completion/bash/systemd-analyze +++ b/shell-completion/bash/systemd-analyze @@ -41,7 +41,7 @@ _systemd_analyze() { ) local -A VERBS=( - [STANDALONE]='time blame plot dump unit-paths calendar' + [STANDALONE]='time blame plot dump unit-paths calendar timespan' [CRITICAL_CHAIN]='critical-chain' [DOT]='dot' [LOG_LEVEL]='log-level' diff --git a/src/basic/time-util.c b/src/basic/time-util.c index 9115c3bf272..4d297394e2a 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -1048,12 +1048,21 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) { something = true; + + k = ((usec_t) -1) / multiplier; + if ((usec_t) l + 1 >= k || (usec_t) z >= k) + return -ERANGE; + k = (usec_t) z * multiplier; for (; n > 0; n--) k /= 10; - r += (usec_t) l * multiplier + k; + k += (usec_t) l * multiplier; + if (k >= ((usec_t) -1) - r) + return -ERANGE; + + r += k; } *usec = r; @@ -1185,12 +1194,22 @@ int parse_nsec(const char *t, nsec_t *nsec) { for (i = 0; i < ELEMENTSOF(table); i++) if (startswith(e, table[i].suffix)) { - nsec_t k = (nsec_t) z * table[i].nsec; + nsec_t k; + + k = ((nsec_t) -1) / table[i].nsec; + if ((nsec_t) l + 1 >= k || (nsec_t) z >= k) + return -ERANGE; + + k = (nsec_t) z * table[i].nsec; for (; n > 0; n--) k /= 10; - r += (nsec_t) l * table[i].nsec + k; + k += (nsec_t) l * table[i].nsec; + if (k >= ((nsec_t) -1) - r) + return -ERANGE; + + r += k; p = e + strlen(table[i].suffix); something = true; diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c index 58c365df573..82a71d04788 100644 --- a/src/test/test-time-util.c +++ b/src/test/test-time-util.c @@ -94,6 +94,9 @@ static void test_parse_time(void) { assert_se(parse_time("5s", &u, USEC_PER_MSEC) >= 0); assert_se(u == 5 * USEC_PER_SEC); + + assert_se(parse_time("11111111111111y", &u, 1) == -ERANGE); + assert_se(parse_time("1.1111111111111y", &u, 1) == -ERANGE); } static void test_parse_nsec(void) { @@ -144,6 +147,8 @@ static void test_parse_nsec(void) { assert_se(parse_nsec("3.+1s", &u) < 0); assert_se(parse_nsec("3. 1s", &u) < 0); assert_se(parse_nsec("3.s", &u) < 0); + assert_se(parse_nsec("1111111111111y", &u) == -ERANGE); + assert_se(parse_nsec("1.111111111111y", &u) == -ERANGE); } static void test_format_timespan_one(usec_t x, usec_t accuracy) {