Merge branch '1.3.x'
authorMark Wooding <mdw@distorted.org.uk>
Wed, 27 Nov 2019 15:12:23 +0000 (15:12 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 27 Nov 2019 15:12:23 +0000 (15:12 +0000)
* 1.3.x: (101 commits)
  rand.c: Show keyword argument as optional.
  mp.c: Fix punctuation error in docstrings.
  t/t-*.py: Use the `WriteBuffer.contents' property.
  t/t-bytes.py: Check that indexing, slicing, etc. return `C.ByteString'.
  t/t-algorithms.py: Add a simple test for `Keccak1600.copy'.
  t/t-algorithms.py: Add tests for other HSalsa20 and HChaCha key sizes.
  t/t-algorithms.py: Add AEAD tests.
  t/t-algorithms.py: Add tests for the new `KeySZ.pad' method.
  catacomb/__init__.py (KeySZRange.pad): Return correct value.
  algorithms.c: Propagate `AEADF_NOAAD' to `aad' objects.
  algorithms.c (AEADAAD.copy): Propagate the hashed length to the copy.
  t/: Add a test suite.
  ec.c: Don't lose error status when constructing points from a sequence.
  ec.c: Free partially constructed points coordinatewise.
  *.c: Be more careful about `PySequence_Size'.
  key.c: Reformat the rest of the `KeyError' constructor.
  key.c: Parse `KeyError' constructor arguments by hand.
  catacomb-python.h: Add a macro for raising `OverflowError'.
  key.c: Collect `KeyError' argument count as a separate step.
  key.c: Use tuple functions on `KeyError' argument tuple.
  ...

1  2 
catacomb-python.h
catacomb.c

diff --combined catacomb-python.h
  #include <catacomb/share.h>
  #include <catacomb/gfshare.h>
  
 +/*----- Other preliminaries -----------------------------------------------*/
 +
 +#define GOBBLE_SEMI extern int notexist
 +#if defined(__GNUC__) && defined(__ELF__)
 +#  define PRIVATE_SYMBOLS _Pragma("GCC visibility push(hidden)") GOBBLE_SEMI
 +#  define PUBLIC_SYMBOLS _Pragma("GCC visibility pop") GOBBLE_SEMI
 +#  define EXPORT __attribute__((__visibility__("default")))
 +#else
 +#  define PRIVATE_SYMBOLS GOBBLE_SEMI
 +#  define PUBLIC_SYMBOLS GOBBLE_SEMI
 +#  define EXPORT
 +#endif
 +
 +PRIVATE_SYMBOLS;
 +
  /*----- Utility macros ----------------------------------------------------*/
  
  #define RETURN_OBJ(obj) do { Py_INCREF(obj); return (obj); } while (0)
    goto end;                                                           \
  } while (0)
  #define VALERR(str) EXCERR(PyExc_ValueError, str)
+ #define OVFERR(str) EXCERR(PyExc_OverflowError, str)
  #define TYERR(str) EXCERR(PyExc_TypeError, str)
  #define IXERR(str) EXCERR(PyExc_IndexError, str)
  #define ZDIVERR(str) EXCERR(PyExc_ZeroDivisionError, str)
    PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);                        \
    goto end;                                                           \
  } while (0)
- #define PGENERR do { pgenerr(); goto end; } while (0)
+ #define PGENERR(exc) do { pgenerr(exc); goto end; } while (0)
  
  #define CONVFUNC(ty, cty, ext)                                                \
    int conv##ty(PyObject *o, void *p)                                  \
  } while (0)
  #define INITTYPE(ty, base) INITTYPE_META(ty, base, type)
  
- #define INSERT(name, ob) do {                                         \
+ extern PyObject *home_module;
+ #define INSERT(name, ob) do { \
    PyObject *_o = (PyObject *)(ob);                                    \
    Py_INCREF(_o);                                                      \
    PyModule_AddObject(mod, name, _o);                                  \
@@@ -250,7 -238,8 +253,8 @@@ MODULES(DO
  
  #define KWLIST (/*unconst*/ char **)kwlist
  
- struct nameval { const char *name; unsigned long value; };
+ struct nameval { const char *name; unsigned f; unsigned long value; };
+ #define CF_SIGNED 1u
  extern void setconstants(PyObject *, const struct nameval *);
  
  extern PyObject *mexp_common(PyObject *, PyObject *, size_t,
@@@ -274,7 -263,34 +278,34 @@@ extern PyObject *getulong(unsigned long
  extern PyObject *getk64(kludge64);
  extern void *newtype(PyTypeObject *, const PyTypeObject *, const char *);
  
+ struct excinfo { PyObject *ty, *val, *tb; };
+ #define EXCINFO_INIT { 0, 0, 0 }
  extern PyObject *mkexc(PyObject *, PyObject *, const char *, PyMethodDef *);
+ #define INIT_EXCINFO(exc) do {                                                \
+   struct excinfo *_exc = (exc); _exc->ty = _exc->val = _exc->tb = 0;  \
+ } while (0)
+ #define RELEASE_EXCINFO(exc) do {                                     \
+   struct excinfo *_exc = (exc);                                               \
+   Py_XDECREF(_exc->ty);        _exc->ty  = 0;                                 \
+   Py_XDECREF(_exc->val); _exc->val = 0;                                       \
+   Py_XDECREF(_exc->tb);        _exc->tb  = 0;                                 \
+ } while (0)
+ #define STASH_EXCINFO(exc) do {                                               \
+   struct excinfo *_exc = (exc);                                               \
+   PyErr_Fetch(&_exc->ty, &_exc->val, &_exc->tb);                      \
+   PyErr_NormalizeException(&_exc->ty, &_exc->val, &_exc->tb);         \
+ } while (0)
+ #define RESTORE_EXCINFO(exc) do {                                     \
+   struct excinfo *_exc = (exc);                                               \
+   PyErr_Restore(_exc->ty, _exc->val, _exc->tb);                               \
+   _exc->ty = _exc->val = _exc->tb = 0;                                        \
+ } while (0)
+ extern void report_lost_exception(struct excinfo *, const char *, ...);
+ extern void report_lost_exception_v(struct excinfo *, const char *, va_list);
+ extern void stash_exception(struct excinfo *, const char *, ...);
+ extern void restore_exception(struct excinfo *, const char *, ...);
  extern void typeready(PyTypeObject *);
  extern PyTypeObject *inittype(PyTypeObject *, PyTypeObject *);
  extern void addmethods(const PyMethodDef *);
@@@ -343,6 -359,7 +374,7 @@@ extern mp *getgf(PyObject *)
  extern int convgf(PyObject *, void *);
  extern PyObject *mp_pywrap(mp *);
  extern PyObject *gf_pywrap(mp *);
+ extern long mphash(mp *);
  extern mp *mp_frompyobject(PyObject *, int);
  extern PyObject *mp_topystring(mp *, int,
                               const char *, const char *, const char *);
@@@ -361,7 -378,6 +393,6 @@@ extern PyTypeObject *fe_pytype
  #define FE_FOBJ(o) ((PyObject *)(o)->ob_type)
  #define FE_X(o) (((fe_pyobj *)(o))->x)
  extern PyObject *fe_pywrap(PyObject *, mp *);
- extern mp *getfe(field *, PyObject *);
  
  typedef struct fe_pyobj {
    PyObject_HEAD
@@@ -715,9 -731,15 +746,15 @@@ extern PyTypeObject *pgev_pytype
  #define PGEV_PYCHECK(o) PyObject_TypeCheck(o, pgev_pytype)
  #define PGEV_PG(o) (&((pgev_pyobj *)(o))->pg)
  
+ typedef struct pypgev {
+   pgev ev;
+   PyObject *obj;
+   struct excinfo *exc;
+ } pypgev;
  extern int convpgev(PyObject *, void *);
- extern void droppgev(pgev *);
- extern void pgenerr(void);
+ extern void droppgev(pypgev *);
+ extern void pgenerr(struct excinfo *exc);
  
  /*----- That's all, folks -------------------------------------------------*/
  
diff --combined catacomb.c
  /*----- Main code ---------------------------------------------------------*/
  
  static const struct nameval consts[] = {
- #define C(x) { #x, x }
+ #define CF(f, x) { #x, f, x }
+ #define C(x) { #x, (x) >= 0 ? 0 : CF_SIGNED, x }
    C(FTY_PRIME), C(FTY_BINARY),
    C(PGEN_PASS), C(PGEN_FAIL), C(PGEN_BEGIN), C(PGEN_TRY), C(PGEN_DONE),
    C(PGEN_ABORT),
    C(MPW_MAX),
+   C(RAND_IBITS),
    C(PMODE_READ), C(PMODE_VERIFY),
    C(KOPEN_READ), C(KOPEN_WRITE), C(KOPEN_NOFILE),
-   C(KEXP_FOREVER), C(KEXP_EXPIRE),
+   CF(0, KEXP_FOREVER), CF(0, KEXP_EXPIRE),
    C(KF_ENCMASK), C(KENC_BINARY), C(KENC_MP), C(KENC_STRUCT),
      C(KENC_ENCRYPT), C(KENC_STRING), C(KENC_EC),
    C(KF_CATMASK), C(KCAT_SYMM), C(KCAT_PRIV), C(KCAT_PUB), C(KCAT_SHARE),
@@@ -56,6 -58,7 +58,7 @@@
    KEY_ERRORS(ENTRY)
  #undef ENTRY
  #undef C
+ #undef CF
    { 0 }
  };
  
@@@ -75,7 -78,8 +78,8 @@@ PyObject *mexp_common(PyObject *me, PyO
      arg = PyTuple_GetItem(arg, 0);
    Py_INCREF(arg);
    if (!PySequence_Check(arg)) TYERR("not a sequence");
-   n = PySequence_Size(arg); if (!n) { z = id(me); goto end; }
+   n = PySequence_Size(arg); if (n < 0) goto end;
+   if (!n) { z = id(me); goto end; }
    x = PySequence_GetItem(arg, 0);
    if (PySequence_Check(x))
      flat = 0;
@@@ -140,7 -144,7 +144,7 @@@ static PyObject *meth__ego(PyObject *me
    char *argv0;
    if (!PyArg_ParseTuple(arg, "s:_ego", &argv0))
      return (0);
 -  if (strcmp(QUIS, "<UNNAMED>") == 0)
 +  if (STRCMP(QUIS, ==, "<UNNAMED>"))
      ego(argv0);
    RETURN_NONE;
  }
@@@ -160,14 -164,14 +164,14 @@@ static void init_random(void
  
    if (!Py_HashRandomizationFlag) return;
    seed = getenv("PYTHONHASHSEED");
 -  if (!seed || strcmp(seed, "random") == 0) r = GR_WORD(&rand_global);
 +  if (!seed || STRCMP(seed, ==, "random")) r = GR_WORD(&rand_global);
    else r = strtoul(seed, 0, 0);
    if (!r) r = 0xe011f220; /* zero doesn't work well */
    unihash_setkey(&unihash_global, r);
  #endif
  }
  
 -void init_base(void)
 +EXPORT void init_base(void)
  {
    PyObject *mod;
    addmethods(methods);