summaryrefslogtreecommitdiffstats
path: root/mpi
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-05-25 23:21:10 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-05-25 23:21:10 -0700
commita2279254bc56443ce4c9f0dd4cc51cf627332c4d (patch)
treed191fad80c880f1e4fe8ded972e5ea20142f4db7 /mpi
parent11b5c567124a61d8e8249a0fbcce47f2688573c6 (diff)
downloadtxr-a2279254bc56443ce4c9f0dd4cc51cf627332c4d.tar.gz
txr-a2279254bc56443ce4c9f0dd4cc51cf627332c4d.tar.bz2
txr-a2279254bc56443ce4c9f0dd4cc51cf627332c4d.zip
mpi: avoid additive inverse of most negative integer.
* mpi.c (mp_set_int, mp_set_intptr, mp_set_double_intptr): When the signed input is negative, do not simply calculate its inverse with unary minus, because it could be the most negative value that has no additive inverse. Instead, convert to unsigned first, then apply the unary minus to the unsigned type, which calculates the two's complement.
Diffstat (limited to 'mpi')
-rw-r--r--mpi/mpi.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/mpi/mpi.c b/mpi/mpi.c
index 5befd2b3..52525762 100644
--- a/mpi/mpi.c
+++ b/mpi/mpi.c
@@ -364,7 +364,8 @@ void mp_set(mp_int *mp, mp_digit d)
mp_err mp_set_int(mp_int *mp, long z)
{
mp_size ix;
- unsigned long v = abs(z);
+ unsigned long w = z;
+ unsigned long v = z >= 0 ? w : -w;
mp_err res;
ARGCHK(mp != NULL, MP_BADARG);
@@ -422,7 +423,8 @@ mp_err mp_set_uintptr(mp_int *mp, uint_ptr_t z)
mp_err mp_set_intptr(mp_int *mp, int_ptr_t z)
{
- int_ptr_t v = z > 0 ? z : -z;
+ uint_ptr_t w = z;
+ uint_ptr_t v = z >= 0 ? w : -w;
mp_err err = mp_set_uintptr(mp, v);
if (err == MP_OKAY && z < 0)
@@ -496,7 +498,8 @@ int mp_in_uintptr_range(mp_int *mp)
mp_err mp_set_double_intptr(mp_int *mp, double_intptr_t z)
{
mp_size ix, shift;
- double_intptr_t v = z > 0 ? z : -z;
+ double_uintptr_t w = z;
+ double_uintptr_t v = z >= 0 ? w : -w;
const mp_size nd = (sizeof v + sizeof (mp_digit) - 1) / sizeof (mp_digit);
ARGCHK(mp != NULL, MP_BADARG);