Issue #22896: Avoid to use PyObject_AsCharBuffer(), PyObject_AsReadBuffer()

and PyObject_AsWriteBuffer().
This commit is contained in:
Serhiy Storchaka 2015-02-03 01:21:08 +02:00
parent b0ef78535a
commit 4fdb68491e
17 changed files with 327 additions and 335 deletions

View file

@ -284,8 +284,6 @@ unicode_internal_decode(PyObject *self,
{
PyObject *obj;
const char *errors = NULL;
const char *data;
Py_ssize_t size;
if (!PyArg_ParseTuple(args, "O|z:unicode_internal_decode",
&obj, &errors))
@ -298,11 +296,16 @@ unicode_internal_decode(PyObject *self,
return codec_tuple(obj, PyUnicode_GET_LENGTH(obj));
}
else {
if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))
Py_buffer view;
PyObject *result;
if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0)
return NULL;
return codec_tuple(_PyUnicode_DecodeUnicodeInternal(data, size, errors),
size);
result = codec_tuple(
_PyUnicode_DecodeUnicodeInternal(view.buf, view.len, errors),
view.len);
PyBuffer_Release(&view);
return result;
}
}
@ -727,8 +730,6 @@ unicode_internal_encode(PyObject *self,
{
PyObject *obj;
const char *errors = NULL;
const char *data;
Py_ssize_t len, size;
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"unicode_internal codec has been deprecated",
@ -741,6 +742,7 @@ unicode_internal_encode(PyObject *self,
if (PyUnicode_Check(obj)) {
Py_UNICODE *u;
Py_ssize_t len, size;
if (PyUnicode_READY(obj) < 0)
return NULL;
@ -755,9 +757,13 @@ unicode_internal_encode(PyObject *self,
PyUnicode_GET_LENGTH(obj));
}
else {
if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))
Py_buffer view;
PyObject *result;
if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0)
return NULL;
return codec_tuple(PyBytes_FromStringAndSize(data, size), size);
result = codec_tuple(PyBytes_FromStringAndSize(view.buf, view.len), view.len);
PyBuffer_Release(&view);
return result;
}
}

View file

@ -463,39 +463,45 @@ KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep);
static PyObject *
CDataType_from_buffer(PyObject *type, PyObject *args)
{
void *buffer;
Py_ssize_t buffer_len;
Py_buffer buffer;
Py_ssize_t offset = 0;
PyObject *obj, *result;
PyObject *result, *mv;
StgDictObject *dict = PyType_stgdict(type);
assert (dict);
if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset))
return NULL;
if (-1 == PyObject_AsWriteBuffer(obj, &buffer, &buffer_len))
if (!PyArg_ParseTuple(args, "w*|n:from_buffer", &buffer, &offset))
return NULL;
if (offset < 0) {
PyErr_SetString(PyExc_ValueError,
"offset cannot be negative");
PyBuffer_Release(&buffer);
return NULL;
}
if (dict->size > buffer_len - offset) {
if (dict->size > buffer.len - offset) {
PyErr_Format(PyExc_ValueError,
"Buffer size too small (%zd instead of at least %zd bytes)",
buffer_len, dict->size + offset);
buffer.len, dict->size + offset);
PyBuffer_Release(&buffer);
return NULL;
}
result = PyCData_AtAddress(type, (char *)buffer + offset);
if (result == NULL)
return NULL;
Py_INCREF(obj);
if (-1 == KeepRef((CDataObject *)result, -1, obj)) {
result = PyCData_AtAddress(type, (char *)buffer.buf + offset);
if (result == NULL) {
PyBuffer_Release(&buffer);
return NULL;
}
mv = PyMemoryView_FromBuffer(&buffer);
if (mv == NULL) {
PyBuffer_Release(&buffer);
return NULL;
}
/* Hack the memoryview so that it will release the buffer. */
((PyMemoryViewObject *)mv)->mbuf->master.obj = buffer.obj;
((PyMemoryViewObject *)mv)->view.obj = buffer.obj;
if (-1 == KeepRef((CDataObject *)result, -1, mv))
result = NULL;
return result;
}
@ -508,37 +514,36 @@ GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
static PyObject *
CDataType_from_buffer_copy(PyObject *type, PyObject *args)
{
const void *buffer;
Py_ssize_t buffer_len;
Py_buffer buffer;
Py_ssize_t offset = 0;
PyObject *obj, *result;
PyObject *result;
StgDictObject *dict = PyType_stgdict(type);
assert (dict);
if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset))
return NULL;
if (-1 == PyObject_AsReadBuffer(obj, (const void**)&buffer, &buffer_len))
if (!PyArg_ParseTuple(args, "y*|n:from_buffer", &buffer, &offset))
return NULL;
if (offset < 0) {
PyErr_SetString(PyExc_ValueError,
"offset cannot be negative");
PyBuffer_Release(&buffer);
return NULL;
}
if (dict->size > buffer_len - offset) {
if (dict->size > buffer.len - offset) {
PyErr_Format(PyExc_ValueError,
"Buffer size too small (%zd instead of at least %zd bytes)",
buffer_len, dict->size + offset);
buffer.len, dict->size + offset);
PyBuffer_Release(&buffer);
return NULL;
}
result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL);
if (result == NULL)
return NULL;
memcpy(((CDataObject *)result)->b_ptr,
(char *)buffer+offset, dict->size);
if (result != NULL) {
memcpy(((CDataObject *)result)->b_ptr,
(char *)buffer.buf + offset, dict->size);
}
PyBuffer_Release(&buffer);
return result;
}

View file

@ -437,17 +437,18 @@ PyDoc_STRVAR(readinto_doc,
"is set not to block as has no data to read.");
static PyObject *
bytesio_readinto(bytesio *self, PyObject *buffer)
bytesio_readinto(bytesio *self, PyObject *arg)
{
void *raw_buffer;
Py_buffer buffer;
Py_ssize_t len, n;
CHECK_CLOSED(self);
if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1)
if (!PyArg_Parse(arg, "w*", &buffer))
return NULL;
/* adjust invalid sizes */
len = buffer.len;
n = self->string_size - self->pos;
if (len > n) {
len = n;
@ -455,10 +456,11 @@ bytesio_readinto(bytesio *self, PyObject *buffer)
len = 0;
}
memcpy(raw_buffer, self->buf + self->pos, len);
memcpy(buffer.buf, self->buf + self->pos, len);
assert(self->pos + len < PY_SSIZE_T_MAX);
assert(len >= 0);
self->pos += len;
PyBuffer_Release(&buffer);
return PyLong_FromSsize_t(len);
}

View file

@ -522,19 +522,20 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val)
return -1;
sqlite3_result_text(context, str, -1, SQLITE_TRANSIENT);
} else if (PyObject_CheckBuffer(py_val)) {
const char* buffer;
Py_ssize_t buflen;
if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) {
Py_buffer view;
if (PyObject_GetBuffer(py_val, &view, PyBUF_SIMPLE) != 0) {
PyErr_SetString(PyExc_ValueError,
"could not convert BLOB to buffer");
return -1;
}
if (buflen > INT_MAX) {
if (view.len > INT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"BLOB longer than INT_MAX bytes");
PyBuffer_Release(&view);
return -1;
}
sqlite3_result_blob(context, buffer, (int)buflen, SQLITE_TRANSIENT);
sqlite3_result_blob(context, view.buf, (int)view.len, SQLITE_TRANSIENT);
PyBuffer_Release(&view);
} else {
return -1;
}

View file

@ -94,7 +94,6 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter)
{
int rc = SQLITE_OK;
const char* buffer;
char* string;
Py_ssize_t buflen;
parameter_type paramtype;
@ -145,18 +144,22 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec
}
rc = sqlite3_bind_text(self->st, pos, string, (int)buflen, SQLITE_TRANSIENT);
break;
case TYPE_BUFFER:
if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) != 0) {
case TYPE_BUFFER: {
Py_buffer view;
if (PyObject_GetBuffer(parameter, &view, PyBUF_SIMPLE) != 0) {
PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
return -1;
}
if (buflen > INT_MAX) {
if (view.len > INT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"BLOB longer than INT_MAX bytes");
PyBuffer_Release(&view);
return -1;
}
rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT);
rc = sqlite3_bind_blob(self->st, pos, view.buf, (int)view.len, SQLITE_TRANSIENT);
PyBuffer_Release(&view);
break;
}
case TYPE_UNKNOWN:
rc = -1;
}

View file

@ -1842,8 +1842,8 @@ static PyObject *
s_pack_into(PyObject *self, PyObject *args)
{
PyStructObject *soself;
char *buffer;
Py_ssize_t buffer_len, offset;
Py_buffer buffer;
Py_ssize_t offset;
/* Validate arguments. +1 is for the first arg as buffer. */
soself = (PyStructObject *)self;
@ -1868,34 +1868,37 @@ s_pack_into(PyObject *self, PyObject *args)
}
/* Extract a writable memory buffer from the first argument */
if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
(void**)&buffer, &buffer_len) == -1 ) {
if (!PyArg_Parse(PyTuple_GET_ITEM(args, 0), "w*", &buffer))
return NULL;
}
assert( buffer_len >= 0 );
assert(buffer.len >= 0);
/* Extract the offset from the first argument */
offset = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 1), PyExc_IndexError);
if (offset == -1 && PyErr_Occurred())
if (offset == -1 && PyErr_Occurred()) {
PyBuffer_Release(&buffer);
return NULL;
}
/* Support negative offsets. */
if (offset < 0)
offset += buffer_len;
offset += buffer.len;
/* Check boundaries */
if (offset < 0 || (buffer_len - offset) < soself->s_size) {
if (offset < 0 || (buffer.len - offset) < soself->s_size) {
PyErr_Format(StructError,
"pack_into requires a buffer of at least %zd bytes",
soself->s_size);
PyBuffer_Release(&buffer);
return NULL;
}
/* Call the guts */
if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
PyBuffer_Release(&buffer);
return NULL;
}
PyBuffer_Release(&buffer);
Py_RETURN_NONE;
}