Skip to content

nn_divapprox_classical_preinv_c sometimes over-reads input a #19

@percontation

Description

@percontation

The tests cause 1-word over-reads in nn_divapprox_classical_preinv_c.

The following patch makes this condition visible:

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);

(Not sure what the fix is; reading math code is hard.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions