From b4a76e3fe8499cb3a1145f3aaab0a6fb2e7c9246 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Jun 2010 00:06:11 +0200 Subject: [PATCH] Issue #8991: convertbuffer() rejects discontigious buffers. --- Misc/NEWS | 2 ++ Python/getargs.c | 34 +++++++++++----------------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 6855696..9e24399 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,8 @@ What's New in Python 3.2 Alpha 1? Core and Builtins ----------------- +- Issue #8991: convertbuffer() rejects discontigious buffers. + - Issue #8592: PyArg_Parse*() functions raise a TypeError for "y", "u" and "Z" formats if the string contains a null byte/character. Write unit tests for string formats. diff --git a/Python/getargs.c b/Python/getargs.c index 20f4814..8171377 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -863,7 +863,8 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, return converterr(CONV_UNICODE, arg, msgbuf, bufsize); PyBuffer_FillInfo(p, arg, - PyBytes_AS_STRING(uarg), PyBytes_GET_SIZE(uarg), + PyBytes_AS_STRING(uarg), + PyBytes_GET_SIZE(uarg), 1, 0); } else { /* any buffer-like object */ @@ -1328,13 +1329,15 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, PyErr_Clear(); return converterr("read-write buffer", arg, msgbuf, bufsize); } + if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) { + PyBuffer_Release((Py_buffer*)p); + return converterr("contiguous buffer", arg, msgbuf, bufsize); + } if (addcleanup(p, freelist, cleanup_buffer)) { return converterr( "(cleanup problem)", arg, msgbuf, bufsize); } - if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) - return converterr("contiguous buffer", arg, msgbuf, bufsize); break; } @@ -1380,42 +1383,27 @@ convertbuffer(PyObject *arg, void **p, char **errmsg) *errmsg = NULL; *p = NULL; - if (pb == NULL || - pb->bf_getbuffer == NULL || - pb->bf_releasebuffer != NULL) { - *errmsg = "bytes or read-only buffer"; + if (pb != NULL && pb->bf_releasebuffer != NULL) { + *errmsg = "read-only pinned buffer"; return -1; } - - if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0) { - *errmsg = "bytes or single-segment read-only buffer"; + if (getbuffer(arg, &view, errmsg) < 0) return -1; - } count = view.len; *p = view.buf; PyBuffer_Release(&view); return count; } -/* XXX for 3.x, getbuffer and convertbuffer can probably - be merged again. */ static int getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) { - PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; - if (pb == NULL) { + if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) { *errmsg = "bytes or buffer"; return -1; } - if (pb->bf_getbuffer == NULL) { - *errmsg = "convertible to a buffer"; - return -1; - } - if (PyObject_GetBuffer(arg, view, 0) < 0) { - *errmsg = "convertible to a buffer"; - return -1; - } if (!PyBuffer_IsContiguous(view, 'C')) { + PyBuffer_Release(&view); *errmsg = "contiguous buffer"; return -1; } -- 1.6.2.5