calendarspec: improve overflow handling
Check if the parsed seconds value fits in an integer *after* multiplying by USEC_PER_SEC, otherwise a large value can trigger modulo by zero during normalization.
This commit is contained in:
parent
9f702d00d6
commit
c0aebb4b3b
|
@ -20,6 +20,7 @@
|
|||
#include <alloca.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -96,7 +97,7 @@ static void normalize_chain(CalendarComponent **c) {
|
|||
* While we're counting the chain, also normalize `stop`
|
||||
* so the length of the range is a multiple of `repeat`
|
||||
*/
|
||||
if (i->stop > i->start)
|
||||
if (i->stop > i->start && i->repeat > 0)
|
||||
i->stop -= (i->stop - i->start) % i->repeat;
|
||||
|
||||
}
|
||||
|
@ -487,7 +488,7 @@ static int parse_weekdays(const char **p, CalendarSpec *c) {
|
|||
}
|
||||
}
|
||||
|
||||
static int parse_component_decimal(const char **p, bool usec, unsigned long *res) {
|
||||
static int parse_component_decimal(const char **p, bool usec, int *res) {
|
||||
unsigned long value;
|
||||
const char *e = NULL;
|
||||
char *ee = NULL;
|
||||
|
@ -502,8 +503,6 @@ static int parse_component_decimal(const char **p, bool usec, unsigned long *res
|
|||
return -errno;
|
||||
if (ee == *p)
|
||||
return -EINVAL;
|
||||
if ((unsigned long) (int) value != value)
|
||||
return -ERANGE;
|
||||
e = ee;
|
||||
|
||||
if (usec) {
|
||||
|
@ -530,6 +529,9 @@ static int parse_component_decimal(const char **p, bool usec, unsigned long *res
|
|||
}
|
||||
|
||||
finish:
|
||||
if (value > INT_MAX)
|
||||
return -ERANGE;
|
||||
|
||||
*p = e;
|
||||
*res = value;
|
||||
|
||||
|
@ -556,9 +558,8 @@ static int const_chain(int value, CalendarComponent **c) {
|
|||
}
|
||||
|
||||
static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
|
||||
unsigned long start, stop = -1, repeat = 0;
|
||||
int r, start, stop = -1, repeat = 0;
|
||||
CalendarComponent *cc;
|
||||
int r;
|
||||
const char *e;
|
||||
|
||||
assert(p);
|
||||
|
|
|
@ -238,6 +238,8 @@ int main(int argc, char* argv[]) {
|
|||
assert_se(calendar_spec_from_string("*:05..10/6", &c) < 0);
|
||||
assert_se(calendar_spec_from_string("20/4:00", &c) < 0);
|
||||
assert_se(calendar_spec_from_string("00:00/60", &c) < 0);
|
||||
assert_se(calendar_spec_from_string("00:00:2300", &c) < 0);
|
||||
assert_se(calendar_spec_from_string("00:00:18446744073709551615", &c) < 0);
|
||||
|
||||
test_timestamp();
|
||||
test_hourly_bug_4031();
|
||||
|
|
Loading…
Reference in a new issue