chiark / gitweb /
rand.c: Careful range checking on `block' and `mp'.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 12 Sep 2016 21:26:09 +0000 (22:26 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 13 May 2017 14:38:22 +0000 (15:38 +0100)
  * For `mp', don't allow the `or' mask to be wider than the requested
    result.

  * For `range', insist that the limit is strictly positive, so that the
    output range is actually inhabited.

These parallel currently unreleased fixes to the underlying library,
which are required for things to work properly; so bump the dependency.

debian/control
rand.c

index c52c8d8ca272bf42e315450dc509b19193e207b2..444feba7e87eca68a2d944bbcfa2e1e65c84f92a 100644 (file)
@@ -5,7 +5,7 @@ XS-Python-Version: >= 2.6, << 2.8
 Maintainer: Mark Wooding <mdw@distorted.org.uk>
 Build-Depends: debhelper (>= 9), pkg-config,
        python, python2.6-dev, python2.7-dev,
-       mlib-dev (>= 2.2.2.1), catacomb-dev (>= 2.2.0)
+       mlib-dev (>= 2.2.2.1), catacomb-dev (>= 2.2.5+14)
 Standards-Version: 3.8.0
 
 Package: python-catacomb
diff --git a/rand.c b/rand.c
index 6e1d05efcb4ae5edd6822cac0f74cbc5f2751f33..4fcb15502b4a62554bd54f72f88816eff7f1c16a 100644 (file)
--- a/rand.c
+++ b/rand.c
@@ -90,20 +90,20 @@ static PyObject *grmeth_range(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "O:range", &m)) return (0);
   if (PyInt_Check(m)) {
     long mm = PyInt_AS_LONG(m);
-    if (mm < 0)
-      goto negative;
+    if (mm <= 0)
+      goto notpos;
     if (mm <= 0xffffffff)
       return (PyInt_FromLong(grand_range(GRAND_R(me), mm)));
   }
   if ((x = getmp(m)) == 0)
     goto end;
-  if (MP_NEGP(x))
-    goto negative;
+  if (!MP_POSP(x))
+    goto notpos;
   y = mprand_range(MP_NEW, x, GRAND_R(me), 0);
   MP_DROP(x);
   return (mp_pywrap(y));
-negative:
-  TYERR("range must be nonnegative");
+notpos:
+  VALERR("range must be strictly positive");
 end:
   if (x) MP_DROP(x);
   return (0);
@@ -112,12 +112,13 @@ end:
 static PyObject *grmeth_mp(PyObject *me, PyObject *arg, PyObject *kw)
 {
   size_t l;
-  mpw o;
+  mpw o = 0;
   char *kwlist[] = { "bits", "or", 0 };
 
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:mp", kwlist,
                                   convszt, &l, convmpw, &o))
     goto end;
+  if (l < MPW_BITS && (o >> l)) VALERR("or mask too large");
   return (mp_pywrap(mprand(MP_NEW, l, GRAND_R(me), o)));
 end:
   return (0);