The tests cause 1-word over-reads in nn_divapprox_classical_preinv_c.
diff --git a/nn_quadratic.c b/nn_quadratic.c
index 9a71d5e..2a5c63c 100644
--- a/nn_quadratic.c
+++ b/nn_quadratic.c
@@ -312,6 +312,9 @@ word_t nn_divapprox_classical_preinv_c(nn_t q, nn_t a, len_t m, nn_src_t d,
word_t cy = 0, d1 = d[n - 1];
len_t s = m - n + 1;
+ nn_t orig_a = a;
+ nn_src_t orig_d = d;
+
ASSERT(q != a);
ASSERT(q != d);
ASSERT(a != d);
@@ -352,7 +355,16 @@ word_t nn_divapprox_classical_preinv_c(nn_t q, nn_t a, len_t m, nn_src_t d,
a--;
/* rare case where truncation ruins normalisation */
if (ci > d[s] || (ci == d[s] && nn_cmp_m(a - s + 1, d, s) >= 0))
+ {
+ // word_t xxx = (a-s)+1 + s+1 - (orig_a + m);
+ // if(xxx > 0 && xxx < 9999)
+ // printf(">>>%zx\n", xxx); // xxx should never be positive... but is sometimes 1.
+
+ // These asserts are the conditions for the nn_sub_m in _nn_divapprox_helper *not* accessing OOB
+ ASSERT(orig_a <= (a-s)+1 && (a-s)+1 + s+1 <= orig_a + m); // The second clause here is violated.
+ ASSERT(orig_d <= d && d + s+1 <= orig_d + n);
return _nn_divapprox_helper(q, a - s, d, s);
+ }
divapprox21_preinv2(q[s - 1], ci, a[0], dinv);
The tests cause 1-word over-reads in nn_divapprox_classical_preinv_c.
The following patch makes this condition visible:
(Not sure what the fix is; reading math code is hard.)