mirror of
https://github.com/python/cpython
synced 2026-09-29 11:35:29 +03:00
Issue #22896: Avoid to use PyObject_AsCharBuffer(), PyObject_AsReadBuffer()
and PyObject_AsWriteBuffer().
This commit is contained in:
parent
b0ef78535a
commit
4fdb68491e
17 changed files with 327 additions and 335 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue