diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-05-25 23:21:10 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-05-25 23:21:10 -0700 |
commit | a2279254bc56443ce4c9f0dd4cc51cf627332c4d (patch) | |
tree | d191fad80c880f1e4fe8ded972e5ea20142f4db7 /mpi | |
parent | 11b5c567124a61d8e8249a0fbcce47f2688573c6 (diff) | |
download | txr-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.c | 9 |
1 files changed, 6 insertions, 3 deletions
@@ -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); |