From 2ec562f15a095c23bc7c16199ea7428007b7b8ec Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 24 Nov 2019 15:11:46 +0000 Subject: [PATCH] catacomb.c, util.c: Publish negative constants correctly. The various `KERR_...' constants and `PGEN_ABORT' are canonically negative integers, but weren't published correctly. Add a flags word to `struct nameval' to identify constants which should really be signed, and some fancy footwork to convert unsigned integers back to negative values without upsetting C. Adjust the `C' macro to spot negative constants and mark them specially. Not all is well. In particular, the `KEXP_...' constants should /not/ be published as signed values, even if `time_t' is signed on the target platform, because the Python bindings handle them exclusively as `unsigned long' values. To make this work, also introduce `CF' which allows us to set the flags explicitly, and use it for `KEXP_...'. --- catacomb-python.h | 3 ++- catacomb.c | 6 ++++-- util.c | 12 ++++++------ 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/catacomb-python.h b/catacomb-python.h index c272b53..b1120fa 100644 --- a/catacomb-python.h +++ b/catacomb-python.h @@ -233,7 +233,8 @@ MODULES(DO) return (d); \ } -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, diff --git a/catacomb.c b/catacomb.c index d7b3dc7..daa404a 100644 --- a/catacomb.c +++ b/catacomb.c @@ -31,7 +31,8 @@ /*----- 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), @@ -39,7 +40,7 @@ static const struct nameval consts[] = { 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), @@ -55,6 +56,7 @@ static const struct nameval consts[] = { KEY_ERRORS(ENTRY) #undef ENTRY #undef C +#undef CF { 0 } }; diff --git a/util.c b/util.c index d613a7a..9332c8b 100644 --- a/util.c +++ b/util.c @@ -280,14 +280,14 @@ PyTypeObject *inittype(PyTypeObject *tyskel, PyTypeObject *meta) void setconstants(PyObject *mod, const struct nameval *c) { PyObject *x; + unsigned long u; while (c->name) { - if (c->value > LONG_MAX) - x = PyLong_FromUnsignedLong(c->value); - else - x = PyInt_FromLong(c->value); - PyModule_AddObject(mod, (/*unconst*/ char *)c->name, x); - c++; + u = c->value; + if (u <= LONG_MAX) x = PyInt_FromLong(u); + else if (c->f&CF_SIGNED) x = PyInt_FromLong(-1 - (long)(ULONG_MAX - u)); + else x = PyLong_FromUnsignedLong(u); + PyModule_AddObject(mod, (/*unconst*/ char *)c->name, x); c++; } } -- 2.11.0