diff -u M2Crypto/SWIG/_lib.h M2Crypto-0.21.1/SWIG/_lib.h --- M2Crypto/SWIG/_lib.h 2011-01-19 19:56:37.622364336 +0100 +++ M2Crypto-0.21.1/SWIG/_lib.h 2011-05-10 20:14:38.593211256 +0200 @@ -7,6 +7,16 @@ #define PY_SSIZE_T_MIN INT_MIN #endif +#if PY_VERSION_HEX < 0x02060000 +struct Py_buffer /* Only a subset */ +{ + void *buf; + Py_ssize_t len; +}; + +#define PyBUF_CONTIG_RO 0 +#endif /* PY_VERSION_HEX < 0x02060000 */ + typedef struct _blob { unsigned char *data; int len; @@ -20,6 +30,10 @@ int *buffer_len); static int m2_PyString_AsStringAndSizeInt(PyObject *obj, char **s, int *len); +/* Always use these two together, to correctly handle non-memoryview objects. */ +static int m2_PyObject_GetBufferInt(PyObject *obj, Py_buffer *view, int flags); +static void m2_PyBuffer_Release(PyObject *obj, Py_buffer *view); + void gen_callback(int p, int n, void *arg); int passphrase_callback(char *buf, int num, int v, void *userdata); diff -u M2Crypto/SWIG/_lib.i M2Crypto-0.21.1/SWIG/_lib.i --- M2Crypto/SWIG/_lib.i 2011-01-19 19:49:21.537145465 +0100 +++ M2Crypto-0.21.1/SWIG/_lib.i 2011-05-10 20:19:10.924328007 +0200 @@ -47,9 +47,36 @@ /* Python helpers. */ %} +%ignore PyObject_CheckBuffer; +%ignore PyObject_GetBuffer; +%ignore PyBuffer_Release; %ignore m2_PyObject_AsReadBufferInt; +%ignore m2_PyObject_GetBufferInt; +%ignore m2_PyBuffer_Release; %ignore m2_PyString_AsStringAndSizeInt; %{ + +#if PY_VERSION_HEX < 0x02060000 +static int PyObject_CheckBuffer(PyObject *obj) +{ + (void)obj; + return 0; +} + +static int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) +{ + (void)obj; + (void)view; + (void)flags; + return -1; +} + +static void PyBuffer_Release(Py_buffer *view) +{ + (void)view; +} +#endif /* PY_VERSION_HEX < 0x02060000 */ + static int m2_PyObject_AsReadBufferInt(PyObject *obj, const void **buffer, int *buffer_len) @@ -68,6 +95,37 @@ return 0; } +static int m2_PyObject_GetBufferInt(PyObject *obj, Py_buffer *view, int flags) +{ + int ret; + + if (PyObject_CheckBuffer(obj)) + ret = PyObject_GetBuffer(obj, view, flags); + else { + const void *buf; + + ret = PyObject_AsReadBuffer(obj, &buf, &view->len); + if (ret == 0) + view->buf = (void *)buf; + } + if (ret) + return ret; + if (view->len > INT_MAX) { + PyErr_SetString(PyExc_ValueError, "object too large"); + m2_PyBuffer_Release(obj, view); + return -1; + } + + return 0; +} + +static void m2_PyBuffer_Release(PyObject *obj, Py_buffer *view) +{ + if (PyObject_CheckBuffer(obj)) + PyBuffer_Release(view); + /* else do nothing, view->buf comes from PyObject_AsReadBuffer */ +} + static int m2_PyString_AsStringAndSizeInt(PyObject *obj, char **s, int *len) { diff -u M2Crypto/SWIG/_ssl.i M2Crypto-0.21.1/SWIG/_ssl.i --- M2Crypto/SWIG/_ssl.i 2011-01-19 19:56:51.957338576 +0100 +++ M2Crypto-0.21.1/SWIG/_ssl.i 2011-05-10 19:58:26.779904541 +0200 @@ -700,12 +700,12 @@ } int ssl_write(SSL *ssl, PyObject *blob, double timeout) { - const void *buf; - int len, r, ssl_err, ret; + Py_buffer buf; + int r, ssl_err, ret; struct timeval tv; - if (m2_PyObject_AsReadBufferInt(blob, &buf, &len) == -1) { + if (m2_PyObject_GetBufferInt(blob, &buf, PyBUF_CONTIG_RO) == -1) { return -1; } @@ -713,7 +713,7 @@ gettimeofday(&tv, NULL); again: Py_BEGIN_ALLOW_THREADS - r = SSL_write(ssl, buf, len); + r = SSL_write(ssl, buf.buf, buf.len); ssl_err = SSL_get_error(ssl, r); Py_END_ALLOW_THREADS @@ -741,22 +741,22 @@ ret = -1; } - + m2_PyBuffer_Release(blob, &buf); return ret; } int ssl_write_nbio(SSL *ssl, PyObject *blob) { - const void *buf; - int len, r, err, ret; + Py_buffer buf; + int r, err, ret; - if (m2_PyObject_AsReadBufferInt(blob, &buf, &len) == -1) { + if (m2_PyObject_GetBufferInt(blob, &buf, PyBUF_CONTIG_RO) == -1) { return -1; } Py_BEGIN_ALLOW_THREADS - r = SSL_write(ssl, buf, len); + r = SSL_write(ssl, buf.buf, buf.len); Py_END_ALLOW_THREADS @@ -785,7 +785,7 @@ ret = -1; } - + m2_PyBuffer_Release(blob, &buf); return ret; }