diff options
author | Jakob Kaivo <jkk@ung.org> | 2024-02-02 13:22:25 -0500 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2024-02-02 13:22:25 -0500 |
commit | 68467da17d576a17e4ff96c60f581561ac0bbe88 (patch) | |
tree | abd46d060469cd4438634c5c4ff660d2b1771c2c | |
parent | 8a620a7c60e5745f5f38aaa1547a66a2d0dc9926 (diff) |
check for invalid integer conversions
-rw-r--r-- | src/inttypes/imaxabs.c | 2 | ||||
-rw-r--r-- | src/inttypes/imaxdiv.c | 4 | ||||
-rw-r--r-- | src/stdlib/_strtoi.h | 1 | ||||
-rw-r--r-- | src/stdlib/abs.c | 5 | ||||
-rw-r--r-- | src/stdlib/div.c | 6 | ||||
-rw-r--r-- | src/stdlib/labs.c | 4 | ||||
-rw-r--r-- | src/stdlib/ldiv.c | 6 | ||||
-rw-r--r-- | src/stdlib/llabs.c | 4 | ||||
-rw-r--r-- | src/stdlib/lldiv.c | 6 |
9 files changed, 34 insertions, 4 deletions
diff --git a/src/inttypes/imaxabs.c b/src/inttypes/imaxabs.c index 9a49cfc9..04cb0440 100644 --- a/src/inttypes/imaxabs.c +++ b/src/inttypes/imaxabs.c @@ -8,7 +8,7 @@ intmax_t imaxabs(intmax_t j) SIGNAL_SAFE(0); if (j == INTMAX_MIN) { - /* undefined behavior */ + UNDEFINED("In call to imaxabs(): The absoluate value of INTMAX_MIN is not representable as an intmax_t"); return INTMAX_MIN; } diff --git a/src/inttypes/imaxdiv.c b/src/inttypes/imaxdiv.c index 7600cfab..c007f762 100644 --- a/src/inttypes/imaxdiv.c +++ b/src/inttypes/imaxdiv.c @@ -7,6 +7,10 @@ imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom) { SIGNAL_SAFE(0); + if ((denom == 0) || (numer == INTMAX_MIN && denom == -1)) { + UNDEFINED("In call to imaxdiv(): The result of %jd / %jd is not representable as an intmax_t", numer, denom); + } + imaxdiv_t r; r.quot = numer / denom; r.rem = numer % denom; diff --git a/src/stdlib/_strtoi.h b/src/stdlib/_strtoi.h index dc160aeb..194e0c8f 100644 --- a/src/stdlib/_strtoi.h +++ b/src/stdlib/_strtoi.h @@ -106,6 +106,7 @@ if (ret > max / base) { overflow = 1; + UNDEFINED("In call to %s(): %s (base %d) is not representable", __func__, start, base); } else { ret = (ret * base) + n; } diff --git a/src/stdlib/abs.c b/src/stdlib/abs.c index 74455c59..3cdd2762 100644 --- a/src/stdlib/abs.c +++ b/src/stdlib/abs.c @@ -9,12 +9,15 @@ int abs(int j) SIGNAL_SAFE(0); if (j == INT_MIN) { - /* undefined behavior */ + UNDEFINED("In call to abs(): The absolute value of INT_MIN is not representable as an int"); + return INT_MIN; } return j < 0 ? -j : j; } +CHECK_1(int, 0, abs, int) + /*** computes the absolute value of ARGUMENT(j). ***/ diff --git a/src/stdlib/div.c b/src/stdlib/div.c index 3cb2df78..ab267a53 100644 --- a/src/stdlib/div.c +++ b/src/stdlib/div.c @@ -1,3 +1,4 @@ +#include <limits.h> #include <stdlib.h> #include "_stdlib.h" @@ -8,12 +9,17 @@ div_t div(int numer, int denom) div_t d; SIGNAL_SAFE(0); + if ((denom == 0) || (numer == INT_MIN && denom == -1)) { + UNDEFINED("In call to div(): The result of %d / %d is not representable as an int", numer, denom); + } d.quot = numer / denom; d.rem = numer % denom; return d; } +CHECK_2(div_t, {0}, div, int, int) + /*** computes both the quotient and remainder of ARGUMENT(numer) divided by ARGUMENT(denom). diff --git a/src/stdlib/labs.c b/src/stdlib/labs.c index 692fd8d0..55df7727 100644 --- a/src/stdlib/labs.c +++ b/src/stdlib/labs.c @@ -9,13 +9,15 @@ long int labs(long int j) SIGNAL_SAFE(0); if (j == LONG_MIN) { - /* undefined */ + UNDEFINED("In call to labs(): The absolute value of LONG_MIN is not representable as a long int"); return LONG_MIN; } return j < 0 ? -j : j; } +CHECK_1(long int, 0, labs, long int) + /*** computes the absolute value of ARGUMENT(j). ***/ diff --git a/src/stdlib/ldiv.c b/src/stdlib/ldiv.c index dc236d10..0b7f0167 100644 --- a/src/stdlib/ldiv.c +++ b/src/stdlib/ldiv.c @@ -1,3 +1,4 @@ +#include <limits.h> #include <stdlib.h> #include "_stdlib.h" @@ -8,12 +9,17 @@ ldiv_t ldiv(long int numer, long int denom) ldiv_t d; SIGNAL_SAFE(0); + if ((denom == 0) || (numer == LONG_MIN && denom == -1)) { + UNDEFINED("In call to ldiv(): The result of %ld / %ld is not representable as a long int", numer, denom); + } d.quot = numer / denom; d.rem = numer % denom; return d; } +CHECK_2(ldiv_t, {0}, ldiv, long int, long int) + /*** computes both the quotient and remainder of ARGUMENT(numer) divided by ARGUMENT(denom). diff --git a/src/stdlib/llabs.c b/src/stdlib/llabs.c index e60e34b5..3af9bcce 100644 --- a/src/stdlib/llabs.c +++ b/src/stdlib/llabs.c @@ -9,13 +9,15 @@ long long int llabs(long long int j) SIGNAL_SAFE(0); if (j == LLONG_MIN) { - /* undefined */ + UNDEFINED("In call to llabs(): The absolute value of LLONG_MIN is not representable as a long long int"); return LLONG_MIN; } return j < 0 ? -j : j; } +CHECK_1(long long int, 0, llabs, long long int) + /*** computes the absolute value of ARGUMENT(j). ***/ diff --git a/src/stdlib/lldiv.c b/src/stdlib/lldiv.c index 6a8e6fd5..42a5cab6 100644 --- a/src/stdlib/lldiv.c +++ b/src/stdlib/lldiv.c @@ -1,3 +1,4 @@ +#include <limits.h> #include <stdlib.h> #include "_stdlib.h" @@ -6,6 +7,9 @@ lldiv_t lldiv(long long int numer, long long int denom) { SIGNAL_SAFE(0); + if ((denom == 0) || (numer == LLONG_MIN && denom == -1)) { + UNDEFINED("In call to lldiv(): The result of %lld / %lld is not representable as a long long int", numer, denom); + } lldiv_t d; d.quot = numer / denom; @@ -13,6 +17,8 @@ lldiv_t lldiv(long long int numer, long long int denom) return d; } +CHECK_2(lldiv_t, {0}, lldiv, long long int, long long int) + /*** computes both the quotient and remainder of ARGUMENT(numer) divided by ARGUMENT(denom). |