mirror of https://github.com/python/cpython
gh-106084: Remove _PySequence_BytesToCharpArray() function (#106088)
Remove private _PySequence_BytesToCharpArray() and _Py_FreeCharPArray() functions from the public C API: move these functions from Objects/abstract.c to Modules/_posixsubprocess.c.
This commit is contained in:
parent
00e75a3372
commit
7ca871634e
|
@ -171,10 +171,6 @@ PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
|
PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
|
||||||
|
|
||||||
PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self);
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
|
|
||||||
|
|
||||||
/* For internal use by buffer API functions */
|
/* For internal use by buffer API functions */
|
||||||
PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
|
PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
|
||||||
const Py_ssize_t *shape);
|
const Py_ssize_t *shape);
|
||||||
|
|
|
@ -182,6 +182,88 @@ _is_fd_in_sorted_fd_sequence(int fd, int *fd_sequence,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
static void _Py_FreeCharPArray(char *const array[]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flatten a sequence of bytes() objects into a C array of
|
||||||
|
* NULL terminated string pointers with a NULL char* terminating the array.
|
||||||
|
* (ie: an argv or env list)
|
||||||
|
*
|
||||||
|
* Memory allocated for the returned list is allocated using PyMem_Malloc()
|
||||||
|
* and MUST be freed by _Py_FreeCharPArray().
|
||||||
|
*/
|
||||||
|
static char *const *
|
||||||
|
_PySequence_BytesToCharpArray(PyObject* self)
|
||||||
|
{
|
||||||
|
char **array;
|
||||||
|
Py_ssize_t i, argc;
|
||||||
|
PyObject *item = NULL;
|
||||||
|
Py_ssize_t size;
|
||||||
|
|
||||||
|
argc = PySequence_Size(self);
|
||||||
|
if (argc == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
assert(argc >= 0);
|
||||||
|
|
||||||
|
if ((size_t)argc > (PY_SSIZE_T_MAX-sizeof(char *)) / sizeof(char *)) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
array = PyMem_Malloc((argc + 1) * sizeof(char *));
|
||||||
|
if (array == NULL) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < argc; ++i) {
|
||||||
|
char *data;
|
||||||
|
item = PySequence_GetItem(self, i);
|
||||||
|
if (item == NULL) {
|
||||||
|
/* NULL terminate before freeing. */
|
||||||
|
array[i] = NULL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
/* check for embedded null bytes */
|
||||||
|
if (PyBytes_AsStringAndSize(item, &data, NULL) < 0) {
|
||||||
|
/* NULL terminate before freeing. */
|
||||||
|
array[i] = NULL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
size = PyBytes_GET_SIZE(item) + 1;
|
||||||
|
array[i] = PyMem_Malloc(size);
|
||||||
|
if (!array[i]) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
memcpy(array[i], data, size);
|
||||||
|
Py_DECREF(item);
|
||||||
|
}
|
||||||
|
array[argc] = NULL;
|
||||||
|
|
||||||
|
return array;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
Py_XDECREF(item);
|
||||||
|
_Py_FreeCharPArray(array);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Free's a NULL terminated char** array of C strings. */
|
||||||
|
static void
|
||||||
|
_Py_FreeCharPArray(char *const array[])
|
||||||
|
{
|
||||||
|
Py_ssize_t i;
|
||||||
|
for (i = 0; array[i] != NULL; ++i) {
|
||||||
|
PyMem_Free(array[i]);
|
||||||
|
}
|
||||||
|
PyMem_Free((void*)array);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do all the Python C API calls in the parent process to turn the pass_fds
|
* Do all the Python C API calls in the parent process to turn the pass_fds
|
||||||
* "py_fds_to_keep" tuple into a C array. The caller owns allocation and
|
* "py_fds_to_keep" tuple into a C array. The caller owns allocation and
|
||||||
|
|
|
@ -2906,80 +2906,3 @@ PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result)
|
||||||
}
|
}
|
||||||
return PYGEN_ERROR;
|
return PYGEN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Flatten a sequence of bytes() objects into a C array of
|
|
||||||
* NULL terminated string pointers with a NULL char* terminating the array.
|
|
||||||
* (ie: an argv or env list)
|
|
||||||
*
|
|
||||||
* Memory allocated for the returned list is allocated using PyMem_Malloc()
|
|
||||||
* and MUST be freed by _Py_FreeCharPArray().
|
|
||||||
*/
|
|
||||||
char *const *
|
|
||||||
_PySequence_BytesToCharpArray(PyObject* self)
|
|
||||||
{
|
|
||||||
char **array;
|
|
||||||
Py_ssize_t i, argc;
|
|
||||||
PyObject *item = NULL;
|
|
||||||
Py_ssize_t size;
|
|
||||||
|
|
||||||
argc = PySequence_Size(self);
|
|
||||||
if (argc == -1)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
assert(argc >= 0);
|
|
||||||
|
|
||||||
if ((size_t)argc > (PY_SSIZE_T_MAX-sizeof(char *)) / sizeof(char *)) {
|
|
||||||
PyErr_NoMemory();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
array = PyMem_Malloc((argc + 1) * sizeof(char *));
|
|
||||||
if (array == NULL) {
|
|
||||||
PyErr_NoMemory();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
for (i = 0; i < argc; ++i) {
|
|
||||||
char *data;
|
|
||||||
item = PySequence_GetItem(self, i);
|
|
||||||
if (item == NULL) {
|
|
||||||
/* NULL terminate before freeing. */
|
|
||||||
array[i] = NULL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* check for embedded null bytes */
|
|
||||||
if (PyBytes_AsStringAndSize(item, &data, NULL) < 0) {
|
|
||||||
/* NULL terminate before freeing. */
|
|
||||||
array[i] = NULL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
size = PyBytes_GET_SIZE(item) + 1;
|
|
||||||
array[i] = PyMem_Malloc(size);
|
|
||||||
if (!array[i]) {
|
|
||||||
PyErr_NoMemory();
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
memcpy(array[i], data, size);
|
|
||||||
Py_DECREF(item);
|
|
||||||
}
|
|
||||||
array[argc] = NULL;
|
|
||||||
|
|
||||||
return array;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
Py_XDECREF(item);
|
|
||||||
_Py_FreeCharPArray(array);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Free's a NULL terminated char** array of C strings. */
|
|
||||||
void
|
|
||||||
_Py_FreeCharPArray(char *const array[])
|
|
||||||
{
|
|
||||||
Py_ssize_t i;
|
|
||||||
for (i = 0; array[i] != NULL; ++i) {
|
|
||||||
PyMem_Free(array[i]);
|
|
||||||
}
|
|
||||||
PyMem_Free((void*)array);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue