roken: Test time add/sub overflow prot.
This commit is contained in:
@@ -21,7 +21,7 @@ AM_CPPFLAGS += -I$(DBHEADER)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
bin_PROGRAMS = rkvis rkbase32 rkbase64
|
bin_PROGRAMS = rkvis rkbase32 rkbase64
|
||||||
noinst_PROGRAMS = snprintf-test resolve-test rkpty test-detach test-auxval rtbl
|
noinst_PROGRAMS = snprintf-test resolve-test rkpty test-detach test-auxval rtbl timeval
|
||||||
|
|
||||||
CHECK_LOCAL = snprintf-test resolve-test rkpty make-roken
|
CHECK_LOCAL = snprintf-test resolve-test rkpty make-roken
|
||||||
|
|
||||||
@@ -40,6 +40,7 @@ check_PROGRAMS = \
|
|||||||
parse_time-test \
|
parse_time-test \
|
||||||
snprintf-test \
|
snprintf-test \
|
||||||
strpftime-test \
|
strpftime-test \
|
||||||
|
timeval \
|
||||||
tsearch-test
|
tsearch-test
|
||||||
|
|
||||||
TESTS = $(check_PROGRAMS)
|
TESTS = $(check_PROGRAMS)
|
||||||
@@ -89,6 +90,9 @@ else
|
|||||||
vis_h = vis.h
|
vis_h = vis.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
timeval_SOURCES = timeval.c
|
||||||
|
timeval_CPPFLAGS = -DTEST
|
||||||
|
|
||||||
rkvis_SOURCES = vis.c $(vis_h) vis-extras.h
|
rkvis_SOURCES = vis.c $(vis_h) vis-extras.h
|
||||||
rkvis_CPPFLAGS = -DTEST
|
rkvis_CPPFLAGS = -DTEST
|
||||||
|
|
||||||
|
@@ -172,3 +172,121 @@ timevalsub(struct timeval *t1, const struct timeval *t2)
|
|||||||
t1->tv_usec -= t2->tv_usec;
|
t1->tv_usec -= t2->tv_usec;
|
||||||
timevalfix(t1);
|
timevalfix(t1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
time_t t, delta, r;
|
||||||
|
int e = 0;
|
||||||
|
|
||||||
|
if (argc == 0)
|
||||||
|
return 0; /* Apparently POSIX and Linux allow this case */
|
||||||
|
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
|
||||||
|
while (argc > 0) {
|
||||||
|
int64_t n;
|
||||||
|
time_t a;
|
||||||
|
char *ends;
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
errx(1, "Usage: [TIME +|- DELTA [== TIME]]");
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = strtoll(argv[0], &ends, 0);
|
||||||
|
if (errno)
|
||||||
|
err(1, "Time value is invalid");
|
||||||
|
if (*ends != '\0')
|
||||||
|
errx(1, "Time value is invalid");
|
||||||
|
t = n;
|
||||||
|
|
||||||
|
n = strtoll(argv[2], &ends, 0);
|
||||||
|
if (errno)
|
||||||
|
err(1, "Delta value is invalid");
|
||||||
|
if (*ends != '\0')
|
||||||
|
errx(1, "Delta value is invalid");
|
||||||
|
delta = n;
|
||||||
|
|
||||||
|
if (argv[1][0] == '+' && argv[1][1] == '\0')
|
||||||
|
r = rk_time_add(t, delta);
|
||||||
|
else if (argv[1][0] == '-' && argv[1][1] == '\0')
|
||||||
|
r = rk_time_sub(t, delta);
|
||||||
|
else
|
||||||
|
errx(1, "Operator must be a + or a - arithmetic operator");
|
||||||
|
|
||||||
|
if (delta == 0 && r != t) {
|
||||||
|
warnx("%s %s %s != %s!", argv[0], argv[1], argv[2], argv[0]);
|
||||||
|
e = 1;
|
||||||
|
}
|
||||||
|
if (t == 0 && r != delta) {
|
||||||
|
warnx("%s %s %s != %s!", argv[0], argv[1], argv[2], argv[2]);
|
||||||
|
e = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > 4 && strcmp(argv[3], "==") == 0) {
|
||||||
|
n = strtoll(argv[4], &ends, 0);
|
||||||
|
if (errno)
|
||||||
|
err(1, "Time value is invalid");
|
||||||
|
if (*ends != '\0')
|
||||||
|
errx(1, "Time value is invalid");
|
||||||
|
a = n;
|
||||||
|
if (a != r) {
|
||||||
|
warnx("%s %s %s != %s!", argv[0], argv[1], argv[2], argv[4]);
|
||||||
|
e = 1;
|
||||||
|
}
|
||||||
|
argc -= 5;
|
||||||
|
argv += 5;
|
||||||
|
} else {
|
||||||
|
#ifdef TIME_T_SIGNED
|
||||||
|
printf("%s %s %s == %lld\n", argv[0], argv[1], argv[2],
|
||||||
|
(long long)r);
|
||||||
|
#else
|
||||||
|
printf("%s %s %s == %llu\n", argv[0], argv[1], argv[2],
|
||||||
|
(unsigned long long)r);
|
||||||
|
#endif
|
||||||
|
argc -= 3;
|
||||||
|
argv += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK(e) do { if (!(e)) errx(1, "Expression not true: " #e "!"); } while (0)
|
||||||
|
#ifdef TIME_T_SIGNED
|
||||||
|
#if SIZEOF_TIME_T == 4
|
||||||
|
CHECK(rk_time_add(INT32_MIN, -1) == INT32_MIN);
|
||||||
|
CHECK(rk_time_sub(INT32_MIN, 1) == INT32_MIN);
|
||||||
|
CHECK(rk_time_sub(-1, INT32_MAX) == INT32_MIN);
|
||||||
|
CHECK(rk_time_add(INT32_MAX, 0) == INT32_MAX);
|
||||||
|
CHECK(rk_time_add(INT32_MAX, 1) == INT32_MAX);
|
||||||
|
CHECK(rk_time_add(1, INT32_MAX) == INT32_MAX);
|
||||||
|
CHECK(rk_time_add(0, INT32_MAX) == INT32_MAX);
|
||||||
|
#elif SIZEOF_TIME_T == 8
|
||||||
|
CHECK(rk_time_add(INT64_MIN, -1) == INT64_MIN);
|
||||||
|
CHECK(rk_time_sub(INT64_MIN, 1) == INT64_MIN);
|
||||||
|
CHECK(rk_time_sub(-1, INT64_MAX) == INT64_MIN);
|
||||||
|
CHECK(rk_time_add(INT64_MAX, 0) == INT64_MAX);
|
||||||
|
CHECK(rk_time_add(INT64_MAX, 1) == INT64_MAX);
|
||||||
|
CHECK(rk_time_add(1, INT64_MAX) == INT64_MAX);
|
||||||
|
CHECK(rk_time_add(0, INT64_MAX) == INT64_MAX);
|
||||||
|
#endif
|
||||||
|
CHECK(rk_time_add(0, -1) == -1);
|
||||||
|
CHECK(rk_time_sub(0, 1) == -1);
|
||||||
|
#else
|
||||||
|
#if SIZEOF_TIME_T == 4
|
||||||
|
CHECK(rk_time_add(UINT32_MAX, 0) == UINT32_MAX);
|
||||||
|
CHECK(rk_time_add(UINT32_MAX, 1) == UINT32_MAX);
|
||||||
|
CHECK(rk_time_add(1, UINT32_MAX) == UINT32_MAX);
|
||||||
|
CHECK(rk_time_add(0, UINT32_MAX) == UINT32_MAX);
|
||||||
|
#elif SIZEOF_TIME_T == 8
|
||||||
|
CHECK(rk_time_add(UINT64_MAX, 0) == UINT64_MAX);
|
||||||
|
CHECK(rk_time_add(UINT64_MAX, 1) == UINT64_MAX);
|
||||||
|
CHECK(rk_time_add(1, UINT64_MAX) == UINT64_MAX);
|
||||||
|
CHECK(rk_time_add(0, UINT64_MAX) == UINT64_MAX);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
CHECK(rk_time_add(0, 1) == 1);
|
||||||
|
CHECK(rk_time_add(1, 0) == 1);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Reference in New Issue
Block a user