roken: Test time add/sub overflow prot.

This commit is contained in:
Nicolas Williams
2022-02-15 17:38:35 -06:00
parent fe8d4f2883
commit 5682be7704
2 changed files with 123 additions and 1 deletions

View File

@@ -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

View File

@@ -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