summaryrefslogtreecommitdiffstats
path: root/mpi/mpi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-18 07:56:04 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-18 07:56:04 -0700
commit4f1be55004386216d5acdf8aac51c1b8e9ef5813 (patch)
tree4ff9b8531d9fe3e6acaa0fe56d1e0d9666207e6b /mpi/mpi.c
parent84905b35bfbb7d886978d6ec078e6bec014a3ef9 (diff)
downloadtxr-4f1be55004386216d5acdf8aac51c1b8e9ef5813.tar.gz
txr-4f1be55004386216d5acdf8aac51c1b8e9ef5813.tar.bz2
txr-4f1be55004386216d5acdf8aac51c1b8e9ef5813.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/mpi.c')
-rw-r--r--mpi/mpi.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/mpi/mpi.c b/mpi/mpi.c
index e4122001..46ec3ddc 100644
--- a/mpi/mpi.c
+++ b/mpi/mpi.c
@@ -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;