summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2024-02-02 13:22:25 -0500
committerJakob Kaivo <jkk@ung.org>2024-02-02 13:22:25 -0500
commit68467da17d576a17e4ff96c60f581561ac0bbe88 (patch)
treeabd46d060469cd4438634c5c4ff660d2b1771c2c
parent8a620a7c60e5745f5f38aaa1547a66a2d0dc9926 (diff)
check for invalid integer conversions
-rw-r--r--src/inttypes/imaxabs.c2
-rw-r--r--src/inttypes/imaxdiv.c4
-rw-r--r--src/stdlib/_strtoi.h1
-rw-r--r--src/stdlib/abs.c5
-rw-r--r--src/stdlib/div.c6
-rw-r--r--src/stdlib/labs.c4
-rw-r--r--src/stdlib/ldiv.c6
-rw-r--r--src/stdlib/llabs.c4
-rw-r--r--src/stdlib/lldiv.c6
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).