chiark / gitweb /
Bug squashing.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 28 Jan 2006 19:03:25 +0000 (19:03 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 28 Jan 2006 19:03:25 +0000 (19:03 +0000)
  * Fix setting functions to check for null value (interpreted as property
    deletion) and raise an exception or do something else useful.

  * Fix conversion of read buffer to string so it returns the remainder
    rather than the whole thing.

  * Make conversions between MP and Python long work on PyObjects rather
    than PyLongObjects, to eliminate pointless type casts.

  * Fix primefield constructor argument parsing so that it doesn't crash!

  * Fix radix checking in MP conversions to exclude +/-1, and 0 for output.
    This turns into a little function now.

  * Do argument checking on Jacobi function.

buffer.c
catacomb-python.h
ec.c
field.c
group.c
mp.c
pgen.c
pubkey.c
rand.c

index 8e4ece55ffda821835914e8d071e59cd74b18d45..7456a3dad85c6404c234435ba82add4396840daa 100644 (file)
--- a/buffer.c
+++ b/buffer.c
@@ -83,7 +83,7 @@ static int rbuf_pysegcount(PyObject *me, int *nn)
   { if (nn) *nn = BSZ(BUF_B(me)); return (1); }
 
 static int rbuf_pyreadbuf(PyObject *me, int seg, void **q)
-  { assert(seg == 0); *q = BBASE(BUF_B(me)); return (BSZ(BUF_B(me))); }
+  { assert(seg == 0); *q = BCUR(BUF_B(me)); return (BLEFT(BUF_B(me))); }
 
 static PyObject *rbmeth_skip(PyObject *me, PyObject *arg)
 {
@@ -236,6 +236,7 @@ static PyObject *rbget_offset(PyObject *me, void *hunoz)
 static int rbset_offset(PyObject *me, PyObject *x, void *hunoz)
 {
   size_t n;
+  if (!x) NIERR("__del__");
   if (!convszt(x, &n)) goto end;
   if (n > BSZ(BUF_B(me))) VALERR("out of range");
   BCUR(BUF_B(me)) = BBASE(BUF_B(me)) + n;
index 286dd9ef03abd3e91d1295278a814c41689c4180..40ac758a9098e9b90effb2797724893caa7f60f0 100644 (file)
@@ -296,8 +296,8 @@ extern PyTypeObject *gf_pytype;
 #define MP_PYCHECK(o) PyObject_TypeCheck((o), mp_pytype)
 #define GF_PYCHECK(o) PyObject_TypeCheck((o), gf_pytype)
 
-extern mp *mp_frompylong(PyLongObject *);
-extern PyLongObject *mp_topylong(mp *);
+extern mp *mp_frompylong(PyObject *);
+extern PyObject *mp_topylong(mp *);
 extern mp *tomp(PyObject *);
 extern mp *getmp(PyObject *);
 extern int convmp(PyObject *, void *);
diff --git a/ec.c b/ec.c
index 685b4bf8dae9c636e593396b34cd449f5edab3da..a64ae45d4be526b6aa066afbebb160af01e64e45 100644 (file)
--- a/ec.c
+++ b/ec.c
@@ -507,7 +507,7 @@ static PyObject *ecpt_pylong(PyObject *me)
   PyObject *rc = 0;
   if (EC_ATINF(ECPT_P(me))) VALERR("point at infinity");
   getecptout(&p, me);
-  rc = (PyObject *)mp_topylong(p.x);
+  rc = mp_topylong(p.x);
 end:
   EC_DESTROY(&p);
   return (rc);
diff --git a/field.c b/field.c
index df6d4d43f6bd1531787e15b97fe74eddfac99041..bb99b77ffeb9e61325bc9f8a8d3b30529b0a9b1d 100644 (file)
--- a/field.c
+++ b/field.c
@@ -272,7 +272,7 @@ static PyObject *fe_pyint(PyObject *x)
 static PyObject *fe_pylong(PyObject *x)
 {
   mp *xx = F_OUT(FE_F(x), MP_NEW, FE_X(x));
-  PyObject *rc = (PyObject *)mp_topylong(xx);
+  PyObject *rc = mp_topylong(xx);
   MP_DROP(xx);
   return (rc);
 }
@@ -593,7 +593,7 @@ static PyObject *primefield_pynew(PyTypeObject *ty,
   field *f;
   char *kwlist[] = { "p", 0 };
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "O:primefield", kwlist,
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:primefield", kwlist,
                                   convmp, &xx))
     goto end;
   if ((f = field_prime(xx)) == 0)
diff --git a/group.c b/group.c
index dc72bc82798b5ae1f6930cc45f4b5e8a1bfbb492..76dde7766e4dc41b8c9aa47132978e77b701814c 100644 (file)
--- a/group.c
+++ b/group.c
@@ -165,7 +165,7 @@ static PyObject *meth__DHInfo_gendsa(PyObject *me,
     { "class", "pbits", "qbits", "seed", "event", "nsteps", 0 };
   PyObject *rc = 0;
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&s#|O&O&:generate", kwlist,
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&s#|O&O&:gendsa", kwlist,
                                   &me, convuint, &pl, convuint, &ql,
                                   &k, &ksz, convpgev, &evt,
                                   convuint, &steps))
@@ -656,7 +656,7 @@ static PyObject *ge_pylong(PyObject *me)
 
   if ((x = G_TOINT(GE_G(me), MP_NEW, GE_X(me))) == 0)
     TYERR("can't convert to integer");
-  rc = (PyObject *)mp_topylong(x);
+  rc = mp_topylong(x);
 end:
   mp_drop(x);
   return (rc);
diff --git a/mp.c b/mp.c
index 4c91865bdee3a526aa0e162100a262617ca50f29..0a0e206113edd7dbfebb4a982a150bce3e695a5c 100644 (file)
--- a/mp.c
+++ b/mp.c
 PyTypeObject *mp_pytype = 0;
 PyTypeObject *gf_pytype = 0;
 
-mp *mp_frompylong(PyLongObject *l)
+mp *mp_frompylong(PyObject *obj)
 {
   unsigned long bits;
+  PyLongObject *l = (PyLongObject *)obj;
   int sz;
   size_t w;
   mpd r = 0;
@@ -71,7 +72,7 @@ mp *mp_frompylong(PyLongObject *l)
   return (x);
 }
 
-PyLongObject *mp_topylong(mp *x)
+PyObject *mp_topylong(mp *x)
 {
   unsigned long bits = mp_bits(x);
   int sz = (bits + SHIFT - 1)/SHIFT;
@@ -83,7 +84,7 @@ PyLongObject *mp_topylong(mp *x)
 
   assert(MPW_BITS >= SHIFT);
   while (i < sz && p < x->vl) {
-    r |= *p << b;
+    r |= (mpd)*p++ << b;
     b += MPW_BITS;
     while (i < sz && b >= SHIFT) {
       l->ob_digit[i++] = r & MASK;
@@ -96,15 +97,13 @@ PyLongObject *mp_topylong(mp *x)
     r >>= SHIFT;
   }
   l->ob_size = (x->f & MP_NEG) ? -sz : sz;
-  return (l);
+  return ((PyObject *)l);
 }
 
 mp *mp_frompyobject(PyObject *o, int radix)
 {
   mp *x;
 
-  if ((x = tomp(o)) != 0)
-    return (x);
   if (PyString_Check(o)) {
     mptext_stringctx sc;
     mp *x;
@@ -115,6 +114,8 @@ mp *mp_frompyobject(PyObject *o, int radix)
     if (sc.buf < sc.lim) { MP_DROP(x); return (0); }
     return (x);
   }
+  if ((x = tomp(o)) != 0)
+    return (x);
   return (0);
 }
 
@@ -143,6 +144,13 @@ PyObject *mp_topystring(mp *x, int radix, const char *xpre,
   return (o);
 }
 
+static int good_radix_p(int r, int readp)
+{
+  return ((r >= -255 && r <= -2) ||
+         (readp && r == 0) ||
+         (r >= 2 && r <= 62));
+}
+
 PyObject *mp_pywrap(mp *x)
 {
   mp_pyobj *z = PyObject_New(mp_pyobj, mp_pytype);
@@ -214,7 +222,7 @@ mp *tomp(PyObject *o)
   } else if (PyInt_Check(o))
     return (mp_fromlong(MP_NEW, PyInt_AS_LONG(o)));
   else if ((l = PyNumber_Long(o)) != 0) {
-    x = mp_frompylong((PyLongObject *)l);
+    x = mp_frompylong(l);
     Py_DECREF(l);
     return (x);
   } else {
@@ -448,10 +456,10 @@ static PyObject *mp_pyint(PyObject *x)
   return (PyInt_FromLong(l));
 }
 static PyObject *mp_pylong(PyObject *x)
-  { return (PyObject *)mp_topylong(MP_X(x)); }
+  { return (mp_topylong(MP_X(x))); }
 static PyObject *mp_pyfloat(PyObject *x)
 {
-  PyObject *l = (PyObject *)mp_topylong(MP_X(x));
+  PyObject *l = mp_topylong(MP_X(x));
   double f = PyLong_AsDouble(l);
   Py_DECREF(l);
   return (PyFloat_FromDouble(f));
@@ -488,10 +496,10 @@ static PyObject *mp_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
   int radix = 0;
   char *kwlist[] = { "x", "radix", 0 };
 
-  if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|i:mp", kwlist, &x, &radix))
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|i:new", kwlist, &x, &radix))
     goto end;
   if (MP_PYCHECK(x)) RETURN_OBJ(x);
-  if (radix < -255 || radix > 62) VALERR("radix out of range");
+  if (!good_radix_p(radix, 1)) VALERR("bad radix");
   if ((z = mp_frompyobject(x, radix)) == 0) {
     PyErr_Format(PyExc_TypeError, "can't convert %.100s to mp",
                 x->ob_type->tp_name);
@@ -505,10 +513,9 @@ end:
 
 static long mp_pyhash(PyObject *me)
 {
-  long i = mp_tolong(MP_X(me));
-  if (i == -1)
-    i = -2;
-  return (i);
+  long h;
+  PyObject *l = mp_topylong(MP_X(me)); h = PyObject_Hash(l);
+  Py_DECREF(l); return (h);
 }
 
 static PyObject *mpmeth_jacobi(PyObject *me, PyObject *arg)
@@ -517,6 +524,8 @@ static PyObject *mpmeth_jacobi(PyObject *me, PyObject *arg)
   PyObject *z = 0;
 
   if (!PyArg_ParseTuple(arg, "O&:jacobi", convmp, &y)) goto end;
+  if (MP_NEGP(MP_X(me)) || MP_EVENP(MP_X(me)))
+    VALERR("must be positive and odd");
   z = PyInt_FromLong(mp_jacobi(y, MP_X(me)));
 end:
   if (y) MP_DROP(y);
@@ -622,8 +631,7 @@ static PyObject *mpmeth_tostring(PyObject *me, PyObject *arg, PyObject *kw)
   char *kwlist[] = { "radix", 0 };
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "|i:tostring", kwlist, &radix))
     goto end;
-  if (radix < -255 || radix > 62 || radix == -1 || radix == 0 || radix == 1)
-    VALERR("bad radix");
+  if (!good_radix_p(radix, 0)) VALERR("bad radix");
   return (mp_topystring(MP_X(me), radix, 0, 0, 0));
 end:
   return (0);
@@ -881,7 +889,7 @@ static PyObject *meth__MP_fromstring(PyObject *me,
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|i:fromstring",
                                   kwlist, &me, &p, &len, &r))
     goto end;
-  if (r < -255 || r > 62) VALERR("radix out of range");
+  if (!good_radix_p(r, 1)) VALERR("bad radix");
   sc.buf = p; sc.lim = p + len;
   if ((zz = mp_read(MP_NEW, r, &mptext_stringops, &sc)) == 0)
     SYNERR("bad integer");
@@ -1683,7 +1691,7 @@ static PyObject *gf_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|i:gf", kwlist, &x, &radix))
     goto end;
   if (GF_PYCHECK(x)) RETURN_OBJ(x);
-  if (radix < -255 || radix > 62) VALERR("radix out of range");
+  if (!good_radix_p(radix, 1)) VALERR("radix out of range");
   if ((z = mp_frompyobject(x, radix)) == 0) {
     PyErr_Format(PyExc_TypeError, "can't convert %.100s to gf",
                 x->ob_type->tp_name);
@@ -1950,7 +1958,7 @@ static PyObject *meth__GF_fromstring(PyObject *me,
   if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|i:fromstring",
                                   kwlist, &me, &p, &len, &r))
     goto end;
-  if (r < -255 || r > 62) VALERR("radix out of range");
+  if (!good_radix_p(r, 1)) VALERR("radix out of range");
   sc.buf = p; sc.lim = p + len;
   if ((zz = mp_read(MP_NEW, r, &mptext_stringops, &sc)) == 0 || MP_NEGP(zz))
     z = Py_BuildValue("(Os#)", Py_None, p, len);
diff --git a/pgen.c b/pgen.c
index 9ffd6fbc15c40aaf938d35af79f81397f34e4217..ae4dcc556ce85d50247ec6de5f7f3deece0f9a5b 100644 (file)
--- a/pgen.c
+++ b/pgen.c
@@ -129,7 +129,7 @@ end:
 }
 
 static PyObject *pfilt_pylong(PyObject *me)
-  { return ((PyObject *)mp_topylong(PFILT_F(me)->m)); }
+  { return (mp_topylong(PFILT_F(me)->m)); }
 
 static PyObject *pfget_x(PyObject *me, void *hunoz)
   { return (mp_pywrap(MP_COPY(PFILT_F(me)->m))); }
index 9e5080671cb3aae03482b926ce828e944dbc9bea..735a2c01d771a80fe83ce3830e5f5065d2ca6ac4 100644 (file)
--- a/pubkey.c
+++ b/pubkey.c
@@ -670,7 +670,9 @@ static PyObject *rsaget_rng(PyObject *me, void *hunoz)
 static int rsaset_rng(PyObject *me, PyObject *val, void *hunoz)
 {
   int rc = -1;
-  if (val != Py_None && !GRAND_PYCHECK(val))
+  if (!val)
+    val = Py_None;
+  else if (val != Py_None && !GRAND_PYCHECK(val))
     TYERR("expected grand or None");
   Py_DECREF(RSA_RNG(me));
   RSA_RNG(me) = val;
diff --git a/rand.c b/rand.c
index a346e12a44fa026aee6128105bd8c61d6ca58563..d779846fa7d52d265dc282206e70d06c9f71cfe8 100644 (file)
--- a/rand.c
+++ b/rand.c
@@ -888,7 +888,7 @@ static PyObject *bbsget_x(PyObject *me, void *hunoz)
 
 static int bbsset_x(PyObject *me, PyObject *val, void *hunoz)
 {
-  mp *x = 0; grand *r = GRAND_R(me); int rc = -1;
+  mp *x = 0; grand *r = GRAND_R(me); int rc = -1; if (!x) NIERR("__del__");
   if ((x = getmp(val)) == 0) goto end; r->ops->misc(r, BBS_SET, x); rc = 0;
   end: mp_drop(x); return (rc);
 }