chiark / gitweb /
*.c: Separate string function calls according to text/binary usage.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 21 Oct 2019 01:38:59 +0000 (02:38 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 11 Apr 2020 11:44:21 +0000 (12:44 +0100)
Don't use the `PyString_...' functions directly.  Instead, define two
collections of macros `TEXT_...' and `BIN_...', which can be used on
text and binary strings respectively.  The two sets are slightly
different, because they've been designed to adapt to Python 3's
different interfaces.

There are no `PyString...' calls remaining outside of these macros.

15 files changed:
algorithms.c
bytestring.c
catacomb.c
ec.c
field.c
group.c
key.c
mp.c
passphrase.c
pgen.c
pubkey.c
pyke/pyke.c
pyke/pyke.h
rand.c
share.c

index babee57762d551f670d5181ecc8a51521dca698a..b48e46a28327a13cc7f06ce40bd2ba408853270e 100644 (file)
@@ -562,7 +562,7 @@ static void gcipher_pydealloc(PyObject *me)
 }
 
 static PyObject *gccget_name(PyObject *me, void *hunoz)
-  { return (PyString_FromString(GCCIPHER_CC(me)->name)); }
+  { return (TEXT_FROMSTR(GCCIPHER_CC(me)->name)); }
 
 static PyObject *gccget_keysz(PyObject *me, void *hunoz)
   { return (keysz_pywrap(GCCIPHER_CC(me)->keysz)); }
@@ -577,7 +577,7 @@ static PyObject *gcmeth_encrypt(PyObject *me, PyObject *arg)
 
   if (!PyArg_ParseTuple(arg, "O&:encrypt", convbin, &m)) return (0);
   rc = bytestring_pywrap(0, m.sz);
-  GC_ENCRYPT(GCIPHER_C(me), m.p, PyString_AS_STRING(rc), m.sz);
+  GC_ENCRYPT(GCIPHER_C(me), m.p, BIN_PTR(rc), m.sz);
   return (rc);
 }
 
@@ -589,7 +589,7 @@ static PyObject *gcmeth_enczero(PyObject *me, PyObject *arg)
 
   if (!PyArg_ParseTuple(arg, "i:enczero", &sz)) return (0);
   rc = bytestring_pywrap(0, sz);
-  p = PyString_AS_STRING(rc);
+  p = BIN_PTR(rc);
   memset(p, 0, sz);
   GC_ENCRYPT(GCIPHER_C(me), p, p, sz);
   return (rc);
@@ -602,7 +602,7 @@ static PyObject *gcmeth_decrypt(PyObject *me, PyObject *arg)
 
   if (!PyArg_ParseTuple(arg, "O&:decrypt", convbin, &c)) return (0);
   rc = bytestring_pywrap(0, c.sz);
-  GC_DECRYPT(GCIPHER_C(me), c.p, PyString_AS_STRING(rc), c.sz);
+  GC_DECRYPT(GCIPHER_C(me), c.p, BIN_PTR(rc), c.sz);
   return (rc);
 }
 
@@ -614,7 +614,7 @@ static PyObject *gcmeth_deczero(PyObject *me, PyObject *arg)
 
   if (!PyArg_ParseTuple(arg, "i:deczero", &sz)) return (0);
   rc = bytestring_pywrap(0, sz);
-  p = PyString_AS_STRING(rc);
+  p = BIN_PTR(rc);
   memset(p, 0, sz);
   GC_DECRYPT(GCIPHER_C(me), p, p, sz);
   return (rc);
@@ -902,8 +902,8 @@ static PyObject *gcaead_pywrap(gcaead *aec)
 
 #define MKTYPE(obj, thing, newfn, namefmt) do {                                \
   (obj) = newtype(gcaead_pytype, 0, 0);                                        \
-  (obj)->ty.ht_name = PyString_FromFormat(namefmt, aec->name);         \
-  (obj)->ty.ht_type.tp_name = PyString_AS_STRING((obj)->ty.ht_name);   \
+  (obj)->ty.ht_name = TEXT_FORMAT(namefmt, aec->name);                 \
+  (obj)->ty.ht_type.tp_name = TEXT_PTR((obj)->ty.ht_name);             \
   (obj)->ty.ht_type.tp_basicsize = sizeof(gaead##thing##_pyobj);       \
   (obj)->ty.ht_type.tp_base = gaead##thing##_pytype;                   \
   Py_INCREF(gaead##thing##_pytype);                                    \
@@ -931,7 +931,7 @@ static void gaeadkey_pydealloc(PyObject *me)
   { GAEAD_DESTROY(GAEADKEY_K(me)); Py_DECREF(Py_TYPE(me)); FREEOBJ(me); }
 
 static PyObject *gcaeget_name(PyObject *me, void *hunoz)
-  { return (PyString_FromString(GCAEAD_AEC(me)->name)); }
+  { return (TEXT_FROMSTR(GCAEAD_AEC(me)->name)); }
 
 static PyObject *gcaeget_keysz(PyObject *me, void *hunoz)
   { return (keysz_pywrap(GCAEAD_AEC(me)->keysz)); }
@@ -1367,7 +1367,7 @@ static PyObject *gaeemeth_done(PyObject *me, PyObject *arg, PyObject *kw)
   csz = ge->e->ops->c->bufsz; c = xmalloc(csz); buf_init(&b, c, csz);
   tag = bytestring_pywrap(0, tsz);
   err = GAEAD_DONE(ge->e, aad == Py_None ? 0 : GAEADAAD_A(aad), &b,
-                  PyString_AS_STRING(tag), tsz);
+                  BIN_PTR(tag), tsz);
   assert(!err); (void)err;
   buf_flip(&b); rc = Py_BuildValue("NN", bytestring_pywrapbuf(&b), tag);
 end:
@@ -1994,7 +1994,7 @@ static void ghash_pydealloc(PyObject *me)
 }
 
 static PyObject *gchget_name(PyObject *me, void *hunoz)
-  { return (PyString_FromString(GCHASH_CH(me)->name)); }
+  { return (TEXT_FROMSTR(GCHASH_CH(me)->name)); }
 
 static PyObject *gchget_hashsz(PyObject *me, void *hunoz)
   { return (PyInt_FromLong(GCHASH_CH(me)->hashsz)); }
@@ -2050,7 +2050,7 @@ static PyObject *ghmeth_done(PyObject *me)
   PyObject *rc;
   g = GH_COPY(GHASH_H(me));
   rc = bytestring_pywrap(0, g->ops->c->hashsz);
-  GH_DONE(g, PyString_AS_STRING(rc));
+  GH_DONE(g, BIN_PTR(rc));
   GH_DESTROY(g);
   return (rc);
 }
@@ -2253,8 +2253,8 @@ static PyObject *gmac_pywrap(PyObject *cobj, gmac *m)
   else Py_INCREF(cobj);
   g = newtype((PyTypeObject *)cobj, 0, 0);
   g->ty.ht_type.tp_basicsize = sizeof(ghash_pyobj);
-  g->ty.ht_name = PyString_FromFormat("%s(keyed)", m->ops->c->name);
-  g->ty.ht_type.tp_name = PyString_AS_STRING(g->ty.ht_name);
+  g->ty.ht_name = TEXT_FORMAT("%s(keyed)", m->ops->c->name);
+  g->ty.ht_type.tp_name = TEXT_PTR(g->ty.ht_name);
   g->ty.ht_type.tp_base = gmhash_pytype;
   Py_INCREF(gmac_pytype);
   g->ty.ht_type.tp_flags = (Py_TPFLAGS_DEFAULT |
@@ -2276,7 +2276,7 @@ static void gmac_pydealloc(PyObject *me)
 }
 
 static PyObject *gcmget_name(PyObject *me, void *hunoz)
-  { return (PyString_FromString(GCMAC_CM(me)->name)); }
+  { return (TEXT_FROMSTR(GCMAC_CM(me)->name)); }
 
 static PyObject *gcmget_keysz(PyObject *me, void *hunoz)
   { return (keysz_pywrap(GCMAC_CM(me)->keysz)); }
@@ -2490,9 +2490,9 @@ static PyObject *poly1305key_pynew(PyTypeObject *ty,
   if (keysz(k.sz, poly1305_keysz) != k.sz) VALERR("bad key length");
 
   pk = newtype(ty, 0, 0);
-  pk->ty.ht_name = PyString_FromString("poly1305(keyed)");
+  pk->ty.ht_name = TEXT_FROMSTR("poly1305(keyed)");
   pk->ty.ht_type.tp_basicsize = sizeof(poly1305hash_pyobj);
-  pk->ty.ht_type.tp_name = PyString_AS_STRING(pk->ty.ht_name);
+  pk->ty.ht_type.tp_name = TEXT_PTR(pk->ty.ht_name);
   pk->ty.ht_type.tp_base = poly1305hash_pytype;
   Py_INCREF(poly1305key_pytype);
   pk->ty.ht_type.tp_flags = (Py_TPFLAGS_DEFAULT |
@@ -2511,7 +2511,7 @@ end:
 }
 
 static PyObject *poly1305clsget_name(PyObject *me, void *hunoz)
-  { return (PyString_FromString("poly1305")); }
+  { return (TEXT_FROMSTR("poly1305")); }
 
 static PyObject *poly1305clsget_keysz(PyObject *me, void *hunoz)
   { return (keysz_pywrap(poly1305_keysz)); }
@@ -2600,7 +2600,7 @@ static PyObject *polymeth_done(PyObject *me)
   PyObject *rc;
   if (!(P1305_F(me) & f_mask)) VALERR("no mask");
   rc = bytestring_pywrap(0, POLY1305_TAGSZ);
-  poly1305_done(P1305_CTX(me), PyString_AS_STRING(rc));
+  poly1305_done(P1305_CTX(me), BIN_PTR(rc));
   return (rc);
 end:
   return (0);
@@ -2794,7 +2794,7 @@ static const PyTypeObject poly1305hash_pytype_skel = {
     if (n.sz != HDANCE##_INSZ) VALERR("bad input length");             \
     rc = bytestring_pywrap(0, HSALSA20_OUTSZ);                         \
     dance##_init(&dance, k.p, k.sz, 0);                                        \
-    hdance##_prf(&dance, n.p, PyString_AS_STRING(rc));                         \
+    hdance##_prf(&dance, n.p, BIN_PTR(rc));                            \
     return (rc);                                                       \
   end:                                                                 \
     return (0);                                                                \
@@ -2878,7 +2878,7 @@ static PyObject *kxvikmeth_extract(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "O&:extract", convuint, &n)) goto end;
   if (n > 200) VALERR("out of range");
   rc = bytestring_pywrap(0, n);
-  q = (octet *)PyString_AS_STRING(rc);
+  q = (octet *)BIN_PTR(rc);
   keccak1600_extract(&k->s, t, (n + 7)/8);
   i = 0;
   while (n > 8) { STORE64_L_(q, t[i]); i++; q += 8; n -= 8; }
@@ -3069,7 +3069,7 @@ static PyObject *shakemeth_done(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "O&:done", convszt, &n)) goto end;
   if (shake_check(me, 0)) goto end;
   rc = bytestring_pywrap(0, n);
-  shake_done(SHAKE_H(me), PyString_AS_STRING(rc), n);
+  shake_done(SHAKE_H(me), BIN_PTR(rc), n);
   SHAKE_ST(me) = -1;
 end:
   return (rc);
@@ -3093,7 +3093,7 @@ static PyObject *shakemeth_get(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "O&:get", convszt, &sz)) goto end;
   if (shake_check(me, 1)) goto end;
   rc = bytestring_pywrap(0, sz);
-  shake_get(SHAKE_H(me), PyString_AS_STRING(rc), sz);
+  shake_get(SHAKE_H(me), BIN_PTR(rc), sz);
 end:
   return (rc);
 }
@@ -3106,7 +3106,7 @@ static PyObject *shakemeth_mask(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "O&:mask", convbin, &in)) goto end;
   if (shake_check(me, 1)) goto end;
   rc = bytestring_pywrap(0, in.sz);
-  shake_mask(SHAKE_H(me), in.p, PyString_AS_STRING(rc), in.sz);
+  shake_mask(SHAKE_H(me), in.p, BIN_PTR(rc), in.sz);
 end:
   return (rc);
 }
@@ -3114,8 +3114,8 @@ end:
 static PyObject *shakeget_state(PyObject *me, void *hunoz)
 {
   int st = SHAKE_ST(me);
-  return (PyString_FromString(st == 0 ? "absorb" :
-                             st == 1 ? "squeeze" : "dead"));
+  return (TEXT_FROMSTR(st == 0 ? "absorb" :
+                      st == 1 ? "squeeze" : "dead"));
 }
 
 static const PyMemberDef shake_pymembers[] = {
@@ -3394,7 +3394,7 @@ static PyObject *gcprp_pywrap(const prpinfo *prp)
 }
 
 static PyObject *gcpget_name(PyObject *me, void *hunoz)
-  { return (PyString_FromString(GCPRP_PRP(me)->name)); }
+  { return (TEXT_FROMSTR(GCPRP_PRP(me)->name)); }
 static PyObject *gcpget_keysz(PyObject *me, void *hunoz)
   { return (keysz_pywrap(GCPRP_PRP(me)->keysz)); }
 static PyObject *gcpget_blksz(PyObject *me, void *hunoz)
@@ -3408,7 +3408,7 @@ static PyObject *gpmeth_encrypt(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "O&:encrypt", convbin, &m)) goto end;
   if (m.sz != GPRP_PRP(me)->blksz) VALERR("incorrect block length");
   rc = bytestring_pywrap(0, m.sz);
-  GPRP_PRP(me)->eblk(GPRP_CTX(me), m.p, PyString_AS_STRING(rc));
+  GPRP_PRP(me)->eblk(GPRP_CTX(me), m.p, BIN_PTR(rc));
 end:
   return (rc);
 }
@@ -3421,7 +3421,7 @@ static PyObject *gpmeth_decrypt(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "O&:decrypt", convbin, &c)) goto end;
   if (c.sz != GPRP_PRP(me)->blksz) VALERR("incorrect block length");
   rc = bytestring_pywrap(0, c.sz);
-  GPRP_PRP(me)->dblk(GPRP_CTX(me), c.p, PyString_AS_STRING(rc));
+  GPRP_PRP(me)->dblk(GPRP_CTX(me), c.p, BIN_PTR(rc));
 end:
   return (rc);
 }
index fdc6e50dfa86b4d8a78ab6fb09f911e28d471607..ced62b41784ca11da35e7ed6487082d95153d1c1 100644 (file)
@@ -36,8 +36,8 @@ static PyObject *empty, *bytev[256];
 
 static PyObject *allocate(PyTypeObject *ty, size_t n)
 {
-  PyStringObject *x;
-  x = (PyStringObject *)ty->tp_alloc(ty, n);
+  BINOBJ *x;
+  x = (BINOBJ *)ty->tp_alloc(ty, n);
   x->ob_sval[n] = 0;
 #if defined(CACHE_HASH) || PY_VERSION_HEX >= 0x02030000
   x->ob_shash = -1;
@@ -57,13 +57,13 @@ static PyObject *dowrap(PyTypeObject *ty, const void *p, size_t n)
       Py_INCREF(empty); return (empty);
     } else if (n == 1 && (ch = *(unsigned char *)p) < sizeof(bytev)) {
       if (!bytev[ch])
-       { bytev[ch] = allocate(ty, 1); *PyString_AS_STRING(bytev[ch]) = ch; }
+       { bytev[ch] = allocate(ty, 1); *BIN_PTR(bytev[ch]) = ch; }
       Py_INCREF(bytev[ch]); return (bytev[ch]);
     }
   }
 
   x = allocate(ty, n);
-  if (p) memcpy(PyString_AS_STRING(x), p, n);
+  if (p) memcpy(BIN_PTR(x), p, n);
   return (x);
 }
 
@@ -100,7 +100,7 @@ static PyObject *bymeth_zero(PyObject *me, PyObject *arg)
   PyObject *rc = 0;
   if (!PyArg_ParseTuple(arg, "O&:zero", convszt, &sz)) goto end;
   rc = bytestring_pywrap(0, sz);
-  memset(PyString_AS_STRING(rc), 0, sz);
+  memset(BIN_PTR(rc), 0, sz);
 end:
   return (rc);
 }
@@ -112,7 +112,7 @@ static PyObject *bytestring_pyrichcompare(PyObject *me,
   int b;
   Py_ssize_t minlen;
 
-  s0.p = PyString_AS_STRING(me); s0.sz = PyString_GET_SIZE(me);
+  s0.p = BIN_PTR(me); s0.sz = BIN_LEN(me);
   if (!convbin(you, &s1)) { PyErr_Clear(); RETURN_NOTIMPL; }
 
   switch (op) {
@@ -146,7 +146,7 @@ static PyObject *bytestring_pyconcat(PyObject *x, PyObject *y)
   if (!convbin(x, &xx) || !convbin(y, &yy)) goto end;
   zsz = (size_t)xx.sz + (size_t)yy.sz;
   if (xx.sz < 0 || yy.sz < 0 || zsz < xx.sz) VALERR("too long");
-  z = bytestring_pywrap(0, zsz); zp = PyString_AS_STRING(z);
+  z = bytestring_pywrap(0, zsz); zp = BIN_PTR(z);
   memcpy(zp, xx.p, xx.sz); memcpy(zp + xx.sz, yy.p, yy.sz);
 end:
   return (z);
@@ -157,10 +157,10 @@ static PyObject *bytestring_pyrepeat(PyObject *me, Py_ssize_t n)
   const unsigned char *xp; size_t xsz;
   PyObject *z = 0; char *zp; size_t zsz;
 
-  xp = (const unsigned char *)PyString_AS_STRING(me);
-  xsz = PyString_GET_SIZE(me);
+  xp = (const unsigned char *)BIN_PTR(me);
+  xsz = BIN_LEN(me);
   if (n < 0 || (n && xsz >= (size_t)-1/n)) VALERR("too long");
-  zsz = n*xsz; z = bytestring_pywrap(0, zsz); zp = PyString_AS_STRING(z);
+  zsz = n*xsz; z = bytestring_pywrap(0, zsz); zp = BIN_PTR(z);
   if (xsz == 1) memset(zp, *xp, zsz);
   else while (zsz) { memcpy(zp, xp, xsz); zp += xsz; zsz -= xsz; }
 end:
@@ -171,8 +171,8 @@ static PyObject *bytestring_pyitem(PyObject *me, Py_ssize_t i)
 {
   PyObject *rc = 0;
 
-  if (i < 0 || i >= PyString_GET_SIZE(me)) IXERR("out of range");
-  rc = bytestring_pywrap(PyString_AS_STRING(me) + i, 1);
+  if (i < 0 || i >= BIN_LEN(me)) IXERR("out of range");
+  rc = bytestring_pywrap(BIN_PTR(me) + i, 1);
 end:
   return (rc);
 }
@@ -180,7 +180,7 @@ end:
 static PyObject *bytestring_pyslice(PyObject *me, Py_ssize_t i, Py_ssize_t j)
 {
   PyObject *rc = 0;
-  size_t n = PyString_GET_SIZE(me);
+  size_t n = BIN_LEN(me);
 
   if (i < 0) i = 0;
   if (j < 0) j = 0;
@@ -188,7 +188,7 @@ static PyObject *bytestring_pyslice(PyObject *me, Py_ssize_t i, Py_ssize_t j)
   if (j < i) i = j = 0;
   if (i == 0 && j == n && Py_TYPE(me) == bytestring_pytype)
     { Py_INCREF(me); rc = me; goto end; }
-  rc = bytestring_pywrap(PyString_AS_STRING(me) + i, j - i);
+  rc = bytestring_pywrap(BIN_PTR(me) + i, j - i);
 end:
   return (rc);
 }
@@ -203,16 +203,16 @@ static PyObject *bytestring_pysubscript(PyObject *me, PyObject *ix)
   if (PyIndex_Check(ix)) {
     i = PyNumber_AsSsize_t(ix, PyExc_IndexError);
     if (i == -1 && PyErr_Occurred()) return (0);
-    if (i < 0) i += PyString_GET_SIZE(me);
+    if (i < 0) i += BIN_LEN(me);
     rc = bytestring_pyitem(me, i);
   } else if (PySlice_Check(ix)) {
-    if (PySlice_GetIndicesEx((PySliceObject *)ix, PyString_GET_SIZE(me),
+    if (PySlice_GetIndicesEx((PySliceObject *)ix, BIN_LEN(me),
                             &i, &j, &k, &n))
       return (0);
     if (k == 1) return bytestring_pyslice(me, i, j);
     rc = bytestring_pywrap(0, n);
-    p = (unsigned char *)PyString_AS_STRING(me) + i;
-    q = (unsigned char *)PyString_AS_STRING(rc);
+    p = (unsigned char *)BIN_PTR(me) + i;
+    q = (unsigned char *)BIN_PTR(rc);
     while (n--) { *q++ = *p; p += k; }
   } else
     TYERR("wanted integer or slice");
@@ -230,7 +230,7 @@ end:
     if (!convbin(x, &xx) || !convbin(y, &yy)) goto end;                        \
     if (xx.sz != yy.sz) VALERR("length mismatch");                     \
     rc = bytestring_pywrap(0, xx.sz);                                  \
-    xp = xx.p; yp = yy.p; zp = (unsigned char *)PyString_AS_STRING(rc);        \
+    xp = xx.p; yp = yy.p; zp = (unsigned char *)BIN_PTR(rc);           \
     for (i = xx.sz; i > 0; i--) *zp++ = *xp++ op *yp++;                        \
   end:                                                                 \
     return (rc);                                                       \
@@ -248,7 +248,7 @@ BINOP(xor, ^)
     PyObject *rc = 0;                                                  \
     if (!convbin(x, &xx)) goto end;                                    \
     rc = bytestring_pywrap(0, xx.sz);                                  \
-    xp = xx.p; zp = (unsigned char *)PyString_AS_STRING(rc);           \
+    xp = xx.p; zp = (unsigned char *)BIN_PTR(rc);                      \
     for (i = xx.sz; i > 0; i--) *zp++ = op *xp++;                      \
   end:                                                                 \
     return (rc);                                                       \
@@ -365,7 +365,7 @@ static const PyMethodDef methods[] = {
   { 0 }
 };
 
-#define string_pytype &PyString_Type
+#define string_pytype &BIN_TYPE
 void bytestring_pyinit(void)
 {
   INITTYPE(bytestring, string);
index 7d3cba7a8508a7873c9420db2c983e483f550cb0..c1e91ff4a4d9b7f0a7a437098e077eed083f5feb 100644 (file)
@@ -128,7 +128,7 @@ static void *thingtab_gmlookup(PyObject *me, PyObject *key, unsigned *f)
 {
   const char *p;
 
-  p = PyString_AsString(key); if (!p) return (0);
+  p = TEXT_STR(key); if (!p) return (0);
   return (sym_find(THINGTAB_T(me), p, -1, 0, f));
 }
 
@@ -139,7 +139,7 @@ static void *thingtab_gmiternext(PyObject *me, void *i)
   { sym_iter *it = i; void *e; SYM_NEXT(it, e); return (e); }
 
 static PyObject *thingtab_gmentrykey(PyObject *me, void *e)
-  { return (PyString_FromString(SYM_NAME(e))); }
+  { return (TEXT_FROMSTR(SYM_NAME(e))); }
 
 static PyObject *thingtab_gmentryvalue(PyObject *me, void *e)
   { PyObject *rc = THING_VAL(e); RETURN_OBJ(rc); }
@@ -325,7 +325,7 @@ EXPORT void init_base(void)
 {
   PyObject *mod;
 
-  modname = PyString_FromString("catacomb");
+  modname = TEXT_FROMSTR("catacomb");
   addmethods(methods);
   INIT_MODULES;
   INITTYPE(thingtab, root);
diff --git a/ec.c b/ec.c
index a67699e42dd8c5591a232b6601be696231ab087f..c9707b7b30b2af8d9806cf8ff28ed6a88d2b4a53 100644 (file)
--- a/ec.c
+++ b/ec.c
@@ -251,10 +251,10 @@ static PyObject *epmeth_tobuf(PyObject *me)
   else
     n = mp_octets(p.x) + mp_octets(p.y) + 6;
   rc = bytestring_pywrap(0, n);
-  buf_init(&b, PyString_AS_STRING(rc), n);
+  buf_init(&b, BIN_PTR(rc), n);
   buf_putec(&b, &p);
   assert(BOK(&b));
-  _PyString_Resize(&rc, BLEN(&b));
+  BIN_SETLEN(rc, BLEN(&b));
   EC_DESTROY(&p);
   return (rc);
 }
@@ -270,12 +270,12 @@ static PyObject *epmeth_toraw(PyObject *me)
 
   len = c->f->noctets * 2 + 1;
   rc = bytestring_pywrap(0, len);
-  p = PyString_AS_STRING(rc);
+  p = BIN_PTR(rc);
   buf_init(&b, p, len);
   EC_OUT(c, &pp, ECPT_P(me));
   ec_putraw(c, &b, &pp);
   EC_DESTROY(&pp);
-  _PyString_Resize(&rc, BLEN(&b));
+  BIN_SETLEN(rc, BLEN(&b));
   return (rc);
 }
 
@@ -295,7 +295,7 @@ static PyObject *epmeth_ec2osp(PyObject *me, PyObject *arg, PyObject *kw)
     return (0);
   len = c->f->noctets * 2 + 1;
   rc = bytestring_pywrap(0, len);
-  p = PyString_AS_STRING(rc);
+  p = BIN_PTR(rc);
   buf_init(&b, p, len);
   EC_OUT(c, &pp, ECPT_P(me));
   if (ec_ec2osp(c, f, &b, &pp)) {
@@ -303,7 +303,7 @@ static PyObject *epmeth_ec2osp(PyObject *me, PyObject *arg, PyObject *kw)
     VALERR("invalid flags");
   }
   EC_DESTROY(&pp);
-  _PyString_Resize(&rc, BLEN(&b));
+  BIN_SETLEN(rc, BLEN(&b));
 end:
   return (rc);
 }
@@ -516,8 +516,8 @@ static int ecptxl_1(ec_curve *c, ec *p, PyObject *x)
   else if (ECPT_PYCHECK(x)) {
     getecptout(p, x);
     goto fix;
-  } else if (PyString_Check(x)) {
-    qd.p = PyString_AS_STRING(x);
+  } else if (TEXT_CHECK(x)) {
+    qd.p = TEXT_PTR(x);
     qd.e = 0;
     if (!ec_ptparse(&qd, p))
       VALERR(qd.e);
@@ -1028,7 +1028,7 @@ end:
 }
 
 static PyObject *ecget_name(PyObject *me, void *hunoz)
-  { return (PyString_FromString(EC_NAME(ECCURVE_C(me)))); }
+  { return (TEXT_FROMSTR(EC_NAME(ECCURVE_C(me)))); }
 
 static PyObject *ecget_a(PyObject *me, void *hunoz)
   { return (fe_pywrap(ECCURVE_FOBJ(me), MP_COPY(ECCURVE_C(me)->a))); }
diff --git a/field.c b/field.c
index 8088d9f149fbe0f6e40b852b4c2b22ac6878d5a5..fa424df422235551726bfa22d58e6535fbf290b9 100644 (file)
--- a/field.c
+++ b/field.c
@@ -512,7 +512,7 @@ static PyObject *fget_noctets(PyObject *me, void *hunoz)
   { return (PyInt_FromLong(FIELD_F(me)->noctets)); }
 
 static PyObject *fget_name(PyObject *me, void *hunoz)
-  { return (PyString_FromString(F_NAME(FIELD_F(me)))); }
+  { return (TEXT_FROMSTR(F_NAME(FIELD_F(me)))); }
 
 static PyObject *fget_type(PyObject *me, void *hunoz)
   { return (PyInt_FromLong(F_TYPE(FIELD_F(me)))); }
diff --git a/group.c b/group.c
index 0feb109bd51e63fdc40968e0814fab170abb8265..b51cb6a4785e7efb9812ff0d87d02b92c035afee 100644 (file)
--- a/group.c
+++ b/group.c
@@ -493,6 +493,7 @@ static PyObject *ge_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
   ec p = EC_INIT;
   mp *y = 0;
   ge *xx = 0;
+  size_t n;
   mptext_stringctx sc;
 
   g = GROUP_G(ty);
@@ -507,9 +508,8 @@ static PyObject *ge_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
     if (G_FROMINT(g, xx, y))
       TYERR("can't convert from integer");
     MP_DROP(y);
-  } else if (PyString_Check(x)) {
-    sc.buf = PyString_AS_STRING(x);
-    sc.lim = sc.buf + PyString_GET_SIZE(x);
+  } else if (TEXT_CHECK(x)) {
+    TEXT_PTRLEN(x, sc.buf, n); sc.lim = sc.buf + n;
     if (G_READ(g, xx, &mptext_stringops, &sc) || sc.buf < sc.lim)
       VALERR("malformed group element string");
   } else
@@ -661,7 +661,7 @@ static PyObject *ge_pystr(PyObject *me)
   PyObject *rc;
 
   group_writedstr(GE_G(me), GE_X(me), &d);
-  rc = PyString_FromStringAndSize(d.buf, d.len);
+  rc = TEXT_FROMSTRLEN(d.buf, d.len);
   DDESTROY(&d);
   return (rc);
 }
@@ -746,10 +746,10 @@ static PyObject *gemeth_tobuf(PyObject *me)
 
   n = GE_G(me)->noctets + 4;
   rc = bytestring_pywrap(0, n);
-  buf_init(&b, PyString_AS_STRING(rc), n);
+  buf_init(&b, BIN_PTR(rc), n);
   G_TOBUF(GE_G(me), &b, GE_X(me));
   assert(BOK(&b));
-  _PyString_Resize(&rc, BLEN(&b));
+  BIN_SETLEN(rc, BLEN(&b));
   return (rc);
 }
 
@@ -761,10 +761,10 @@ static PyObject *gemeth_toraw(PyObject *me)
 
   n = GE_G(me)->noctets;
   rc = bytestring_pywrap(0, n);
-  buf_init(&b, PyString_AS_STRING(rc), n);
+  buf_init(&b, BIN_PTR(rc), n);
   G_TORAW(GE_G(me), &b, GE_X(me));
   assert(BOK(&b));
-  _PyString_Resize(&rc, BLEN(&b));
+  BIN_SETLEN(rc, BLEN(&b));
   return (rc);
 }
 
diff --git a/key.c b/key.c
index 368456ceb16a75dc6ad13e0452af1ffef11da02e..704466f318aa028b7e915e9c2432d109a3e356a1 100644 (file)
--- a/key.c
+++ b/key.c
@@ -51,7 +51,7 @@ static PyObject *kxmeth___init__(PyObject *me, PyObject *arg)
   if (PyObject_SetAttrString(me, "err", x)) goto end;
   Py_DECREF(x); x = 0;
 
-  x = PyString_FromString(key_strerror(err)); if (!x) goto end;
+  x = TEXT_FROMSTR(key_strerror(err)); if (!x) goto end;
   if (PyObject_SetAttrString(me, "errstring", x)) goto end;
   Py_DECREF(x); x = 0;
 
@@ -87,9 +87,9 @@ static PyObject *kxmeth___str__(PyObject *me, PyObject *arg)
   if (err >= 0 && err < N(tab)) errtag = tab[err];
   else errtag = "<unknown>";
   if ((x = PyObject_GetAttrString(me, "errstring")) == 0 ||
-      (errstr = PyString_AsString(x)) == 0)
+      (errstr = TEXT_STR(x)) == 0)
     goto done;
-  rc = PyString_FromFormat("%s (%ld): %s", errtag, -err, errstr);
+  rc = TEXT_FORMAT("%s (%ld): %s", errtag, -err, errstr);
 
 done:
   Py_XDECREF(x);
@@ -181,7 +181,7 @@ static int convfilter(PyObject *x, void *p)
   int err;
   int rc = 0;
 
-  if ((fs = PyString_AsString(x)) != 0) {
+  if ((fs = TEXT_STR(x)) != 0) {
     if ((err = key_readflags(fs, &end, &f->f, &f->m)) != 0)
       KEYERR(err);
     if (*end)
@@ -220,7 +220,7 @@ static int convflags(PyObject *x, void *p)
     return (1);
   else {
     PyErr_Clear();
-    if ((fs = PyString_AsString(x)) != 0) {
+    if ((fs = TEXT_STR(x)) != 0) {
       if ((err = key_readflags(fs, &end, f, 0)) != 0)
        KEYERR(err);
       if (*end)
@@ -261,7 +261,7 @@ static PyObject *kdmeth_writeflags(PyObject *me, PyObject *arg)
 
   if (!PyArg_ParseTuple(arg, "O&:key_writeflags", convuint, &f)) return (0);
   key_writeflags(f, &d);
-  rc = PyString_FromStringAndSize(d.buf, d.len);
+  rc = TEXT_FROMSTRLEN(d.buf, d.len);
   dstr_destroy(&d);
   return (rc);
 }
@@ -338,7 +338,7 @@ static PyObject *kdmeth_write(PyObject *me, PyObject *arg, PyObject *kw)
                                   convfilter, &f))
     return (0);
   key_write(KEYDATA_KD(me), &d, &f);
-  rc = PyString_FromStringAndSize(d.buf, d.len);
+  rc = TEXT_FROMSTRLEN(d.buf, d.len);
   dstr_destroy(&d);
   return (rc);
 }
@@ -795,7 +795,7 @@ end:
 }
 
 static PyObject *kdsget_str(PyObject *me, void *hunoz)
-  { return (PyString_FromString(KEYDATA_KD(me)->u.p)); }
+  { return (TEXT_FROMSTR(KEYDATA_KD(me)->u.p)); }
 
 static const PyGetSetDef keydatastr_pygetset[] = {
 #define GETSETNAME(op, name) kds##op##_##name
@@ -939,7 +939,7 @@ static void *keydatastruct_gmlookup(PyObject *me, PyObject *k, unsigned *f)
   key_struct *ks;
 
   assert((kd->e&KF_ENCMASK) == KENC_STRUCT);
-  if ((tag = PyString_AsString(k)) == 0) return (0);
+  if ((tag = TEXT_STR(k)) == 0) return (0);
   if (f) { key_split(&kd); KEYDATA_KD(me) = kd; }
   ks = sym_find(&kd->u.s, tag, -1, f ? sizeof(key_struct) : 0, f);
   if (ks && f && !*f) ks->k = 0;
@@ -958,7 +958,7 @@ static void *keydatastruct_gmiternext(PyObject *me, void *i)
   { return (sym_next(i)); }
 
 static PyObject *keydatastruct_gmentrykey(PyObject *me, void *e)
-  { key_struct *ks = e; return (PyString_FromString(SYM_NAME(ks))); }
+  { key_struct *ks = e; return (TEXT_FROMSTR(SYM_NAME(ks))); }
 
 static PyObject *keydatastruct_gmentryvalue(PyObject *me, void *e)
 {
@@ -1035,7 +1035,7 @@ static PyObject *keydatastruct_pynew(PyTypeObject *ty,
     if ((it = PyObject_GetIter(sub)) == 0)
       goto end;
     while ((name = PyIter_Next(it)) != 0) {
-      if ((p = PyString_AsString(name)) == 0 ||
+      if ((p = TEXT_STR(name)) == 0 ||
          (val = PyObject_GetItem(sub, name)) == 0)
        goto end;
       if (!KEYDATA_PYCHECK(val))
@@ -1119,7 +1119,7 @@ static const PyTypeObject keydatastruct_pytype_skel = {
 
 static void *keyattrs_gmlookup(PyObject *me, PyObject *k, unsigned *f)
 {
-  char *name = PyString_AsString(k);
+  char *name = TEXT_STR(k);
   key_attr *a = 0;
 
   if (!name) goto end;
@@ -1137,10 +1137,10 @@ static void *keyattrs_gmiternext(PyObject *me, void *i)
   { return (sym_next(i)); }
 
 static PyObject *keyattrs_gmentrykey(PyObject *me, void *e)
-  { return (PyString_FromString(SYM_NAME(e))); }
+  { return (TEXT_FROMSTR(SYM_NAME(e))); }
 
 static PyObject *keyattrs_gmentryvalue(PyObject *me, void *e)
-  { return (PyString_FromString(((key_attr *)e)->p)); }
+  { return (TEXT_FROMSTR(((key_attr *)e)->p)); }
 
 static int keyattrs_gmsetentry(PyObject *me, void *e, PyObject *val)
 {
@@ -1149,8 +1149,8 @@ static int keyattrs_gmsetentry(PyObject *me, void *e, PyObject *val)
   Py_ssize_t n;
   int rc = -1;
 
-  if (!PyString_Check(val)) TYERR("expected string");
-  p = PyString_AS_STRING(val); n = PyString_GET_SIZE(val);
+  if (!TEXT_CHECK(val)) TYERR("expected string");
+  TEXT_PTRLEN(val, p, n);
   if (n > 255) VALERR("attribute too long");
   if (memchr(p, 0, n)) VALERR("attribute must not contain nul");
   if (a->p) xfree(a->p);
@@ -1345,7 +1345,7 @@ static PyObject *kmeth_extract(PyObject *me, PyObject *arg, PyObject *kw)
                                   convfilter, &f) ||
       (fp = PyFile_AsFile(file)) == 0 ||
       (nameobj = PyFile_Name(file)) == 0 ||
-      (name = PyString_AsString(nameobj)) == 0)
+      (name = TEXT_STR(nameobj)) == 0)
     goto end;
   if (key_extract(KEY_KF(me), KEY_K(me), fp, &f))
     OSERR(name);
@@ -1372,7 +1372,7 @@ static PyObject *kget_id(PyObject *me, void *hunoz)
 static PyObject *kget_file(PyObject *me, void *hunoz)
   { RETURN_OBJ(KEY_KFOBJ(me)); }
 static PyObject *kget_type(PyObject *me, void *hunoz)
-  { return (PyString_FromString(KEY_K(me)->type)); }
+  { return (TEXT_FROMSTR(KEY_K(me)->type)); }
 static PyObject *kget_exptime(PyObject *me, void *hunoz)
   { return (getulong(KEY_K(me)->exp)); }
 static PyObject *kget_deltime(PyObject *me, void *hunoz)
@@ -1443,7 +1443,7 @@ static PyObject *kget_fulltag(PyObject *me, void *hunoz)
   PyObject *rc;
 
   key_fulltag(KEY_K(me), &d);
-  rc = PyString_FromStringAndSize(d.buf, d.len);
+  rc = TEXT_FROMSTRLEN(d.buf, d.len);
   dstr_destroy(&d);
   return (rc);
 }
@@ -1451,7 +1451,7 @@ static PyObject *kget_fulltag(PyObject *me, void *hunoz)
 static PyObject *kget_tag(PyObject *me, void *hunoz)
 {
   if (!KEY_K(me)->tag) RETURN_NONE;
-  return (PyString_FromString(KEY_K(me)->tag));
+  return (TEXT_FROMSTR(KEY_K(me)->tag));
 }
 static int kset_tag(PyObject *me, PyObject *x, void *hunoz)
 {
@@ -1459,7 +1459,7 @@ static int kset_tag(PyObject *me, PyObject *x, void *hunoz)
   char *tag;
 
   if (!x || x == Py_None) tag = 0;
-  else if ((tag = PyString_AsString(x)) == 0) goto end;
+  else if ((tag = TEXT_STR(x)) == 0) goto end;
   if ((err = key_settag(KEY_KF(me), KEY_K(me), tag)) != 0) KEYERR(err);
   return (0);
 end:
@@ -1469,7 +1469,7 @@ end:
 static PyObject *kget_comment(PyObject *me, void *hunoz)
 {
   if (!KEY_K(me)->c) RETURN_NONE;
-  return (PyString_FromString(KEY_K(me)->c));
+  return (TEXT_FROMSTR(KEY_K(me)->c));
 }
 static int kset_comment(PyObject *me, PyObject *x, void *hunoz)
 {
@@ -1477,7 +1477,7 @@ static int kset_comment(PyObject *me, PyObject *x, void *hunoz)
   char *c;
 
   if (!x || x == Py_None) c = 0;
-  else if ((c = PyString_AsString(x)) == 0) goto end;
+  else if ((c = TEXT_STR(x)) == 0) goto end;
   if ((err = key_setcomment(KEY_KF(me), KEY_K(me), c)) != 0) KEYERR(err);
   return (0);
 end:
@@ -1572,7 +1572,7 @@ static key *bytag(PyObject *me, PyObject *tagobj)
     k = key_byid(KEYFILE_KF(me), id);
   else {
     PyErr_Clear();
-    if ((tag = PyString_AsString(tagobj)) == 0)
+    if ((tag = TEXT_STR(tagobj)) == 0)
       goto end;
     k = key_bytag(KEYFILE_KF(me), tag);
   }
@@ -1704,7 +1704,7 @@ static PyObject *kfmeth_merge(PyObject *me, PyObject *arg, PyObject *kw)
   if ((fp = PyFile_AsFile(x)) == 0)
     goto end;
   x = PyFile_Name(x);
-  if ((name = PyString_AsString(x)) == 0)
+  if ((name = TEXT_STR(x)) == 0)
     goto end;
   rc = key_merge(KEYFILE_KF(me), name, fp, pythonreporter, &ri);
   if (ri.stop)
@@ -1806,7 +1806,7 @@ end:
 }
 
 static PyObject *kfget_name(PyObject *me, void *hunoz)
-  { return (PyString_FromString(KEYFILE_KF(me)->name)); }
+  { return (TEXT_FROMSTR(KEYFILE_KF(me)->name)); }
 static PyObject *kfget_modifiedp(PyObject *me, void *hunoz)
   { return (getbool(KEYFILE_KF(me)->f & KF_MODIFIED)); }
 static PyObject *kfget_writep(PyObject *me, void *hunoz)
diff --git a/mp.c b/mp.c
index 0da3a5ea464aef8ba07c3d8d04281b5de986de49..a664627de2def12a198bddf35994e85ff3cc9018 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -102,11 +102,11 @@ mp *mp_frompyobject(PyObject *o, int radix)
 {
   mp *x;
 
-  if (PyString_Check(o)) {
+  if (TEXT_CHECK(o)) {
     mptext_stringctx sc;
     mp *x;
-    sc.buf = PyString_AS_STRING(o);
-    sc.lim = sc.buf + PyString_GET_SIZE(o);
+    size_t sz;
+    TEXT_PTRLEN(o, sc.buf, sz); sc.lim = sc.buf + sz;
     x = mp_read(MP_NEW, radix, &mptext_stringops, &sc);
     if (!x) return (0);
     if (sc.buf < sc.lim) { MP_DROP(x); return (0); }
@@ -128,8 +128,7 @@ PyObject *mp_topystring(mp *x, int radix, const char *xpre,
   size_t postlen = post ? strlen(post) : 0;
   char *p;
   MP_COPY(x);
-  o = PyString_FromStringAndSize(0, len + 1 + xprelen + prelen + postlen);
-  p = PyString_AS_STRING(o);
+  TEXT_PREPAREWRITE(o, p, len + 1 + xprelen + prelen + postlen);
   sc.buf = p;
   if (xpre) { memcpy(sc.buf, xpre, xprelen); sc.buf += xprelen; }
   if (MP_NEGP(x)) { *sc.buf++ = '-'; x = mp_neg(x, x); }
@@ -138,7 +137,7 @@ PyObject *mp_topystring(mp *x, int radix, const char *xpre,
   mp_write(x, radix, &mptext_stringops, &sc);
   if (post) { memcpy(sc.buf, post, postlen); sc.buf += postlen; }
   MP_DROP(x);
-  _PyString_Resize(&o, sc.buf - p);
+  TEXT_DONEWRITE(o, sc.buf - p);
   return (o);
 }
 
@@ -709,7 +708,7 @@ end:
       if (!len) len = 1;                                               \
     }                                                                  \
     rc = bytestring_pywrap(0, len);                                    \
-    mp_##name(MP_X(me), PyString_AS_STRING(rc), len);                  \
+    mp_##name(MP_X(me), BIN_PTR(rc), len);                             \
   end:                                                                 \
     return (rc);                                                       \
   }
@@ -749,10 +748,10 @@ static PyObject *mpmeth_tobuf(PyObject *me)
   x = MP_X(me);
   n = mp_octets(x) + 3;
   rc = bytestring_pywrap(0, n);
-  buf_init(&b, PyString_AS_STRING(rc), n);
+  buf_init(&b, BIN_PTR(rc), n);
   buf_putmp(&b, x);
   assert(BOK(&b));
-  _PyString_Resize(&rc, BLEN(&b));
+  BIN_SETLEN(rc, BLEN(&b));
   return (rc);
 }
 
index 49bc7718f21da0aab542b48a0e101203b192cb9f..424bcc94bf5205176b1e89cab37d98d9033d6ac1 100644 (file)
@@ -92,7 +92,7 @@ static PyObject *pixmeth_read(PyObject *me, PyObject *arg, PyObject *kw)
   else if (r > 0)
     RETURN_NONE;
   else
-    rc = PyString_FromString(buf);
+    rc = BIN_FROMSTR(buf);
 end:
   return (rc);
 }
@@ -102,7 +102,7 @@ static PyObject *pixmeth_set(PyObject *me, PyObject *arg)
   char *tag;
   char *phrase;
 
-  if (!PyArg_ParseTuple(arg, "ss:set", &tag, &phrase))
+  if (!PyArg_ParseTuple(arg, "s"Y":set", &tag, &phrase))
     return (0);
   pixie_set(PIXIE_FD(me), tag, phrase);
   RETURN_ME;
@@ -195,7 +195,7 @@ static PyObject *meth_ppread(PyObject *me, PyObject *arg, PyObject *kw)
     goto end;
   if (passphrase_read(tag, f, buf, sizeof(buf)))
     SYSERR("passphrase read failed");
-  rc = PyString_FromString(buf);
+  rc = BIN_FROMSTR(buf);
 end:
   return (rc);
 }
@@ -220,7 +220,7 @@ static PyObject *meth_getpass(PyObject *me, PyObject *arg)
     goto end;
   if (pixie_getpass(prompt, buf, sizeof(buf)))
     OSERR(0);
-  rc = PyString_FromString(buf);
+  rc = BIN_FROMSTR(buf);
 end:
   return (rc);
 }
diff --git a/pgen.c b/pgen.c
index 5c8592f438b2d0843eba407793c38eaf27ac50d3..777ec32aeae1f482cee81adabae80cf0b868f2ad 100644 (file)
--- a/pgen.c
+++ b/pgen.c
@@ -419,7 +419,7 @@ static void pgevent_pydealloc(PyObject *me)
 } while (0)
 
 static PyObject *peget_name(PyObject *me, void *hunoz)
-  { PGEVENT_CHECK(me); return (PyString_FromString(PGEVENT_EV(me)->name)); }
+  { PGEVENT_CHECK(me); return (TEXT_FROMSTR(PGEVENT_EV(me)->name)); }
 
 static PyObject *peget_x(PyObject *me, void *hunoz)
   { PGEVENT_CHECK(me); return (mp_pywrap(MP_COPY(PGEVENT_EV(me)->m))); }
index 24552756411144cdb8f6c43d1c4c29cfca007f71..9ec115acc3584d6b2b7a39210b61a12d3b89586a 100644 (file)
--- a/pubkey.c
+++ b/pubkey.c
@@ -119,7 +119,7 @@ static PyObject *dsameth_endhash(PyObject *me, PyObject *arg)
   gdsa_endhash(DSA_D(me), h);
   h = GH_COPY(h);
   rc = bytestring_pywrap(0, GH_CLASS(h)->hashsz);
-  GH_DONE(h, PyString_AS_STRING(rc));
+  GH_DONE(h, BIN_PTR(rc));
   GH_DESTROY(h);
   return (rc);
 }
@@ -369,7 +369,7 @@ static PyObject *kcdsameth_endhash(PyObject *me, PyObject *arg)
   gkcdsa_endhash(DSA_D(me), h);
   h = GH_COPY(h);
   rc = bytestring_pywrap(0, GH_CLASS(h)->hashsz);
-  GH_DONE(h, PyString_AS_STRING(rc));
+  GH_DONE(h, BIN_PTR(rc));
   GH_DESTROY(h);
   return (rc);
 }
@@ -388,7 +388,7 @@ static PyObject *kcdsameth_sign(PyObject *me, PyObject *arg, PyObject *kw)
   if (h.sz != DSA_D(me)->h->hashsz)
     VALERR("bad message length (doesn't match hash size)");
   r = bytestring_pywrap(0, DSA_D(me)->h->hashsz);
-  s.r = (octet *)PyString_AS_STRING(r);
+  s.r = (octet *)BIN_PTR(r);
   gkcdsa_sign(DSA_D(me), &s, h.p, k);
   rc = Py_BuildValue("(ON)", r, mp_pywrap(s.s));
 end:
@@ -1156,7 +1156,7 @@ end:
     if (k.sz != X##_KEYSZ) VALERR("bad key length");                   \
     if (p.sz != X##_PUBSZ) VALERR("bad public length");                        \
     rc = bytestring_pywrap(0, X##_OUTSZ);                              \
-    x((octet *)PyString_AS_STRING(rc), k.p, p.p);                      \
+    x((octet *)BIN_PTR(rc), k.p, p.p);                                 \
     return (rc);                                                       \
   end:                                                                 \
     return (0);                                                                \
@@ -1179,7 +1179,7 @@ XDHS(DEFXDH)
     if (!PyArg_ParseTuple(arg, "O&:" #ed "_pubkey", convbin, &k))      \
       goto end;                                                                \
     rc = bytestring_pywrap(0, ED##_PUBSZ);                             \
-    ed##_pubkey((octet *)PyString_AS_STRING(rc), k.p, k.sz);           \
+    ed##_pubkey((octet *)BIN_PTR(rc), k.p, k.sz);                      \
     return (rc);                                                       \
   end:                                                                 \
     return (0);                                                                \
@@ -1207,7 +1207,7 @@ XDHS(DEFXDH)
     if (c.p && ph == -1) ph = 0;                                       \
     if (!p.p) { p.p = pp; ed##_pubkey(pp, k.p, k.sz); }                        \
     rc = bytestring_pywrap(0, ED##_SIGSZ);                             \
-    ed##sigver##_sign((octet *)PyString_AS_STRING(rc), k.p, k.sz,      \
+    ed##sigver##_sign((octet *)BIN_PTR(rc), k.p, k.sz,                 \
                      p.p, ph, c.p, c.sz, m.p, m.sz);                   \
     return (rc);                                                       \
   end:                                                                 \
index d874763b760f611e037b8ca653a215e96969e1be..cef4f822882d7036aaa1ce0dde7d067ba964be3d 100644 (file)
@@ -105,9 +105,9 @@ int convbin(PyObject *o, void *pp)
 {
   struct bin *r = pp;
 
-  if (PyString_Check(o)) {
-    r->p = PyString_AS_STRING(o);
-    r->sz = PyString_GET_SIZE(o);
+  if (BIN_CHECK(o)) {
+    r->p = BIN_PTR(o);
+    r->sz = BIN_LEN(o);
     return (1);
   }
   if (PyUnicode_Check(o)) {
@@ -143,7 +143,7 @@ void report_lost_exception_v(struct excinfo *exc,
   assert(!PyErr_Occurred());
 
   /* Format the explanation. */
-  if (why) whyobj = PyString_FromFormatV(why, ap);
+  if (why) whyobj = TEXT_VFORMAT(why, ap);
   else { whyobj = Py_None; Py_INCREF(whyobj); }
 
   /* Find our home module's `lostexchook' function.  This won't work if
@@ -172,8 +172,7 @@ ouch:
    * `sys.excepthook'.
    */
 sys:
-  PySys_WriteStderr("\n!!! LOST EXCEPTION: %s\n",
-                   PyString_AS_STRING(whyobj));
+  PySys_WriteStderr("\n!!! LOST EXCEPTION: %s\n", TEXT_PTR(whyobj));
   RESTORE_EXCINFO(exc);
   PyErr_Print();
   /* drop through... */
@@ -251,11 +250,13 @@ void *newtype(PyTypeObject *metaty,
   COPY(buffer);
 #undef COPY
   if (name)
-    ty->ht_name = PyString_FromString(name);
+    ty->ht_name = TEXT_FROMSTR(name);
   else if (ty->ht_type.tp_name)
-    ty->ht_name = PyString_FromString(ty->ht_type.tp_name);
+    ty->ht_name = TEXT_FROMSTR(ty->ht_type.tp_name);
+  else
+    ty->ht_name = 0;
   if (ty->ht_name)
-    ty->ht_type.tp_name = PyString_AS_STRING(ty->ht_name);
+    ty->ht_type.tp_name = TEXT_STR(ty->ht_name);
   ty->ht_slots = 0;
   (void)PyObject_INIT(&ty->ht_type, metaty);
   Py_INCREF(metaty);
@@ -304,11 +305,8 @@ PyObject *mkexc(PyObject *mod, PyObject *base,
     }
   }
 
-  if ((nameobj = PyString_FromFormat("%s.%s",
-                                    PyModule_GetName(mod),
-                                    name)) == 0 ||
-      (exc = PyErr_NewException(PyString_AS_STRING(nameobj),
-                               base, dict)) == 0)
+  if ((nameobj = TEXT_FORMAT("%s.%s", PyModule_GetName(mod), name)) == 0 ||
+      (exc = PyErr_NewException(TEXT_STR(nameobj), base, dict)) == 0)
     goto fail;
 
 done:
index 984b5d553a03e5161c13f46ba674734d4c7dc2ef..654f7517439ccef52003f3f9a809f9985af6f2a7 100644 (file)
@@ -89,6 +89,97 @@ PRIVATE_SYMBOLS;
   typedef long Py_hash_t;
 #endif
 
+/* Plain octet strings.  Python 2 calls these `str', while Python 3 calls
+ * them `bytes'.  We call them `bin' here, and define the following.
+ *
+ *   * `BINOBJ' is the C type of a `bin' object.
+ *   * `BIN_TYPE' is the Python `type' object for `bin'.
+ *   * `BIN_CHECK(OBJ)' is true if OBJ is a `bin' object.
+ *   * `BIN_PTR(OBJ)' points to the first octet of OBJ, without checking!
+ *   * `BIN_LEN(OBJ)' yields the length of OBJ in octets, without checking!
+ *   * `BIN_FROMSTR(STR)' makes a `bin' object from a null-terminated string.
+ *   * `BIN_FORMAT(FMT, ARGS...)' and `BIN_VFORMAT(FMT, AP)' make a `bin'
+ *     object from a `printf'-like format string and arguments.
+ *   * `BIN_PREPAREWRITE(OBJ, PTR, LEN)' prepares to make a `bin' object: it
+ *     sets PTR to point to a buffer of LEN bytes; call `BIN_DONEWRITE' when
+ *     finished.  The variable OBJ will eventually be the resulting object,
+ *     but until `BIN_DONEWRITE' is called, it may in fact be some different
+ *     object.
+ *   * `BIN_DONEWRITE(OBJ, LEN)' completes making a `bin' object: it adjusts
+ *     its length to be LEN, which must not be larger than the LEN given to
+ *     `BIN_PREPAREWRITE', and sets OBJ to point to the finished object.
+ *   * `BIN_SETLEN(OBJ, LEN)' adjusts the length of OBJ downwards to LEN,
+ *     without checking!
+ #   * `Y' is a format character for `PyArg_ParseTuple...' for retrieving a
+ *     null-terminated octet string from a `bin' object.
+ #   * `YN' is a format character for `PyArg_ParseTuple...' for retrieving an
+ *     octet string and length from any sort-of vaguely binary-ish object.
+ */
+#define BINOBJ PyStringObject
+#define BIN_TYPE PyString_Type
+#define BIN_CHECK(obj) PyString_Check(obj)
+#define BIN_PTR(obj) PyString_AS_STRING(obj)
+#define BIN_LEN(obj) PyString_GET_SIZE(obj)
+#define BIN_FROMSTR(str) PyString_FromString(str)
+#define BIN_FROMSTRLEN(str, len) PyString_FromStringAndSize(str, len)
+#define BIN_FORMAT PyString_FromFormat
+#define BIN_VFORMAT PyString_FromFormatV
+#define BIN_PREPAREWRITE(obj, ptr, sz) do {                            \
+  (obj) = PyString_FromStringAndSize(0, (sz));                         \
+  (ptr) = PyString_AS_STRING(obj);                                     \
+} while (0)
+#define BIN_DONEWRITE(obj, sz) do Py_SIZE(obj) = (sz); while (0)
+#define BIN_SETLEN(obj, len) do Py_SIZE(obj) = (len); while (0)
+#define Y "s"
+#define YN "s#"
+
+/* Text strings.  Both Python 2 and Python 3 call these `str', but they're
+ * very different because a Python 3 `str' is Unicode inside.  When dealing
+ * with Python 3 text, the data is UTF-8 encoded.  We call them `text' here,
+ * and define the following.
+ *
+ *   * `TEXTOBJ' is the C type of a `text' object.
+ *   * `TEXT_TYPE' is the Python `type' object for `text'.
+ *   * `TEXT_CHECK(OBJ)' is true if OBJ is a `text' object.
+ *   * `TEXT_STR(OBJ)' points to the first byte of a null-terminated string
+ *     OBJ, or is null.
+ *   * `TEXT_PTR(OBJ)' points to the first byte of OBJ, without checking!
+ *   * `TEXT_LEN(OBJ)' yields the length of OBJ in octets, without checking!
+ *   * `TEXT_FROMSTR(STR)' makes a `text' object from a null-terminated
+ *     string.
+ *   * `TEXT_FORMAT(FMT, ARGS...)' and `TEST_VFORMAT(FMT, AP)' make a `text'
+ *     object from a `printf'-like format string and arguments.
+ *   * `TEXT_PREPAREWRITE(OBJ, PTR, LEN)' prepares to make a `text' object:
+ *     it sets PTR to point to a buffer of LEN bytes; call `TEXT_DONEWRITE'
+ *     when finished.  The variable OBJ will eventually be the resulting
+ *     object, but until `TEXT_DONEWRITE' is called, it may in fact be some
+ *     different object.
+ *   * `TEXT_DONEWRITE(OBJ, LEN)' completes making a `text' object: it
+ *     adjusts its length to be LEN, which must not be larger than the LEN
+ *     given to `TEXT_PREPAREWRITE', and sets OBJ to point to the finished
+ *     object.
+ *
+ * (Use `s' and `s#' in `PyArg_ParseTuple...'.)
+ */
+#define TEXTOBJ PyStringObject
+#define TEXT_TYPE PyString_Type
+#define TEXT_CHECK(obj) PyString_Check(obj)
+#define TEXT_PTR(obj) PyString_AS_STRING(obj)
+#define TEXT_STR(obj) PyString_AsString(obj)
+#define TEXT_PTRLEN(obj, ptr, len) do {                                        \
+  (ptr) = PyString_AS_STRING(obj);                                     \
+  (len) = PyString_GET_SIZE(obj);                                      \
+} while (0)
+#define TEXT_FORMAT PyString_FromFormat
+#define TEXT_VFORMAT PyString_FromFormatV
+#define TEXT_PREPAREWRITE(obj, ptr, sz) do {                           \
+  (obj) = PyString_FromStringAndSize(0, (sz));                         \
+  (ptr) = PyString_AS_STRING(obj);                                     \
+} while (0)
+#define TEXT_DONEWRITE(obj, sz) do { Py_SIZE(obj) = (sz); } while (0)
+#define TEXT_FROMSTR(str) PyString_FromString(str)
+#define TEXT_FROMSTRLEN(str, len) PyString_FromStringAndSize(str, len)
+
 /*----- Utilities for returning values and exceptions ---------------------*/
 
 /* Returning values. */
@@ -326,7 +417,7 @@ extern PyTypeObject *inittype(const PyTypeObject */*skel*/,
 /*----- Populating modules ------------------------------------------------*/
 
 extern PyObject *modname;
-  /* The overall module name.  Set this with `PyString_FromString'. */
+  /* The overall module name.  Set this with `TEXT_FROMSTR'. */
 
 extern PyObject *home_module;
   /* The overall module object. */
diff --git a/rand.c b/rand.c
index 069c351a945fb8511f41a70f55925cf200f89976..675bf7012fdd3bb81cd4488abc3a531bed368553 100644 (file)
--- a/rand.c
+++ b/rand.c
@@ -146,7 +146,7 @@ static PyObject *grmeth_block(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "O&:block", convulong, &n)) goto end;
   if (grand_check(me)) return (0);
   rc = bytestring_pywrap(0, n);
-  grand_fill(GRAND_R(me), PyString_AS_STRING(rc), n);
+  grand_fill(GRAND_R(me), BIN_PTR(rc), n);
 end:
   return (rc);
 }
@@ -239,7 +239,7 @@ static PyObject *grmeth_mask(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "O&:mask", convbin, &in)) return (0);
   if (grand_check(me)) return (0);
   rc = bytestring_pywrap(0, in.sz);
-  q = (octet *)PyString_AS_STRING(rc);
+  q = (octet *)BIN_PTR(rc);
   GR_FILL(r, q, in.sz);
   p = in.p; n = in.sz; while (n--) *q++ ^= *p++;
   return (rc);
@@ -253,7 +253,7 @@ static void grand_pydealloc(PyObject *me)
 }
 
 static PyObject *grget_name(PyObject *me, void *hunoz)
-  { return (grand_check(me) ? 0 : PyString_FromString(GRAND_R(me)->ops->name)); }
+  { return (grand_check(me) ? 0 : TEXT_FROMSTR(GRAND_R(me)->ops->name)); }
 
 static PyObject *grget_cryptop(PyObject *me, void *hunoz)
   { return (grand_check(me) ? 0 : getbool(GRAND_R(me)->ops->f & GRAND_CRYPTO)); }
@@ -731,7 +731,7 @@ static PyObject *gccrand_pywrap(const gccrand_info *info)
 }
 
 static PyObject *gccrget_name(PyObject *me, void *hunoz)
-  { return (PyString_FromString(GCCRAND_INFO(me)->name)); }
+  { return (TEXT_FROMSTR(GCCRAND_INFO(me)->name)); }
 static PyObject *gccrget_keysz(PyObject *me, void *hunoz)
   { return (keysz_pywrap(GCCRAND_INFO(me)->keysz)); }
 
@@ -1135,7 +1135,7 @@ static PyObject *drget_seed(PyObject *me, void *hunoz)
   grand *r = GRAND_R(me);
   int n = r->ops->misc(r, DSARAND_SEEDSZ);
   PyObject *rc = bytestring_pywrap(0, n);
-  r->ops->misc(r, DSARAND_GETSEED, PyString_AS_STRING(rc));
+  r->ops->misc(r, DSARAND_GETSEED, BIN_PTR(rc));
   return (rc);
 }
 
diff --git a/share.c b/share.c
index eadaa482e843b36b0e5535ab93cc6721b599294b..30bff92c812363af57976455f437eef6ac890eb2 100644 (file)
--- a/share.c
+++ b/share.c
@@ -137,7 +137,7 @@ static PyObject *gfsmeth_get(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "O&:get", convuint, &i)) goto end;
   if (i >= 255) VALERR("index must be < 255");
   rc = bytestring_pywrap(0, GFSHARE_S(me)->sz);
-  gfshare_get(GFSHARE_S(me), i, PyString_AS_STRING(rc));
+  gfshare_get(GFSHARE_S(me), i, BIN_PTR(rc));
 end:
   return (rc);
 }
@@ -246,7 +246,7 @@ static PyObject *gfsmeth_combine(PyObject *me)
   PyObject *rc = 0;
   if (GFSHARE_S(me)->i < GFSHARE_S(me)->t) VALERR("not enough shares yet");
   rc = bytestring_pywrap(0, GFSHARE_S(me)->sz);
-  gfshare_combine(GFSHARE_S(me), PyString_AS_STRING(rc));
+  gfshare_combine(GFSHARE_S(me), BIN_PTR(rc));
 end:
   return (rc);
 }