diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-06-18 07:56:04 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-06-18 10:14:34 -0700 |
commit | b97ffb72390bb8da611bf201bf4052d9ee8e850e (patch) | |
tree | 4ff9b8531d9fe3e6acaa0fe56d1e0d9666207e6b /mpi | |
parent | cf5f21c8e7c54f0053c223e9ae6490b71d7314d3 (diff) | |
download | txr-b97ffb72390bb8da611bf201bf4052d9ee8e850e.tar.gz txr-b97ffb72390bb8da611bf201bf4052d9ee8e850e.tar.bz2 txr-b97ffb72390bb8da611bf201bf4052d9ee8e850e.zip |
mpi: avoid OOB pointer decr in two descending loops.
* mpi.c (s_mp_cmp): Rewrite loop as a for with
a bottom test, and the increments in the usual place.
ap and bp aren't decremented if the index is zero.
Ironic to fix this, given that we march through the
stack in the garbage collector.
(s_mp_ispow2): Similar restructuring, with an additional
guard around ix being set up to descend from the
second-to-last digit.
Diffstat (limited to 'mpi')
-rw-r--r-- | mpi/mpi.c | 22 |
1 files changed, 12 insertions, 10 deletions
@@ -3824,13 +3824,13 @@ int s_mp_cmp(mp_int *a, mp_int *b) mp_size ix = ua - 1; mp_digit *ap = DIGITS(a) + ix, *bp = DIGITS(b) + ix; - while (ix < MP_SIZE_MAX) { + for (;; ix--, ap--, bp--) { if (*ap > *bp) return MP_GT; else if (*ap < *bp) return MP_LT; - - --ap; --bp; --ix; + if (ix == 0) + break; } return MP_EQ; @@ -3871,14 +3871,16 @@ mp_size s_mp_ispow2(mp_int *v) extra = s_highest_bit(d) - 1; - ix = uv - 2; - dp = DIGITS(v) + ix; - - while (ix < MP_SIZE_MAX - 1) { - if (*dp) - return MP_SIZE_MAX; /* not a power of two */ + if (uv >= 2) { + ix = uv - 2; + dp = DIGITS(v) + ix; - --dp; --ix; + for (;; ix--, dp--) { + if (*dp) + return MP_SIZE_MAX; /* not a power of two */ + if (ix == 0) + break; + } } return ((uv - 1) * DIGIT_BIT) + extra; |