Issue #18203: Add _PyMem_RawStrdup() and _PyMem_Strdup()
Replace strdup() with _PyMem_RawStrdup() or _PyMem_Strdup(), depending if the GIL is held or not.
This commit is contained in:
parent
6f8eeee7b9
commit
49fc8ece81
|
@ -58,6 +58,9 @@ PyAPI_FUNC(void *) PyMem_Malloc(size_t size);
|
||||||
PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size);
|
PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size);
|
||||||
PyAPI_FUNC(void) PyMem_Free(void *ptr);
|
PyAPI_FUNC(void) PyMem_Free(void *ptr);
|
||||||
|
|
||||||
|
PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str);
|
||||||
|
PyAPI_FUNC(char *) _PyMem_Strdup(const char *str);
|
||||||
|
|
||||||
/* Macros. */
|
/* Macros. */
|
||||||
|
|
||||||
/* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL
|
/* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL
|
||||||
|
|
|
@ -529,7 +529,7 @@ PyCursesWindow_New(WINDOW *win, const char *encoding)
|
||||||
wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
|
wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
|
||||||
if (wo == NULL) return NULL;
|
if (wo == NULL) return NULL;
|
||||||
wo->win = win;
|
wo->win = win;
|
||||||
wo->encoding = strdup(encoding);
|
wo->encoding = _PyMem_Strdup(encoding);
|
||||||
if (wo->encoding == NULL) {
|
if (wo->encoding == NULL) {
|
||||||
Py_DECREF(wo);
|
Py_DECREF(wo);
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
|
@ -543,7 +543,7 @@ PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
|
||||||
{
|
{
|
||||||
if (wo->win != stdscr) delwin(wo->win);
|
if (wo->win != stdscr) delwin(wo->win);
|
||||||
if (wo->encoding != NULL)
|
if (wo->encoding != NULL)
|
||||||
free(wo->encoding);
|
PyMem_Free(wo->encoding);
|
||||||
PyObject_DEL(wo);
|
PyObject_DEL(wo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1938,13 +1938,13 @@ PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value)
|
||||||
ascii = PyUnicode_AsASCIIString(value);
|
ascii = PyUnicode_AsASCIIString(value);
|
||||||
if (ascii == NULL)
|
if (ascii == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
encoding = strdup(PyBytes_AS_STRING(ascii));
|
encoding = _PyMem_Strdup(PyBytes_AS_STRING(ascii));
|
||||||
Py_DECREF(ascii);
|
Py_DECREF(ascii);
|
||||||
if (encoding == NULL) {
|
if (encoding == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
free(self->encoding);
|
PyMem_Free(self->encoding);
|
||||||
self->encoding = encoding;
|
self->encoding = encoding;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1213,8 +1213,8 @@ _Unpickler_SetInputEncoding(UnpicklerObject *self,
|
||||||
if (errors == NULL)
|
if (errors == NULL)
|
||||||
errors = "strict";
|
errors = "strict";
|
||||||
|
|
||||||
self->encoding = strdup(encoding);
|
self->encoding = _PyMem_Strdup(encoding);
|
||||||
self->errors = strdup(errors);
|
self->errors = _PyMem_Strdup(errors);
|
||||||
if (self->encoding == NULL || self->errors == NULL) {
|
if (self->encoding == NULL || self->errors == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -5590,8 +5590,8 @@ Unpickler_dealloc(UnpicklerObject *self)
|
||||||
_Unpickler_MemoCleanup(self);
|
_Unpickler_MemoCleanup(self);
|
||||||
PyMem_Free(self->marks);
|
PyMem_Free(self->marks);
|
||||||
PyMem_Free(self->input_line);
|
PyMem_Free(self->input_line);
|
||||||
free(self->encoding);
|
PyMem_Free(self->encoding);
|
||||||
free(self->errors);
|
PyMem_Free(self->errors);
|
||||||
|
|
||||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||||
}
|
}
|
||||||
|
@ -5627,9 +5627,9 @@ Unpickler_clear(UnpicklerObject *self)
|
||||||
self->marks = NULL;
|
self->marks = NULL;
|
||||||
PyMem_Free(self->input_line);
|
PyMem_Free(self->input_line);
|
||||||
self->input_line = NULL;
|
self->input_line = NULL;
|
||||||
free(self->encoding);
|
PyMem_Free(self->encoding);
|
||||||
self->encoding = NULL;
|
self->encoding = NULL;
|
||||||
free(self->errors);
|
PyMem_Free(self->errors);
|
||||||
self->errors = NULL;
|
self->errors = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -475,7 +475,7 @@ cancel_dump_traceback_later(void)
|
||||||
|
|
||||||
Py_CLEAR(thread.file);
|
Py_CLEAR(thread.file);
|
||||||
if (thread.header) {
|
if (thread.header) {
|
||||||
free(thread.header);
|
PyMem_Free(thread.header);
|
||||||
thread.header = NULL;
|
thread.header = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -504,7 +504,7 @@ format_timeout(double timeout)
|
||||||
"Timeout (%lu:%02lu:%02lu)!\n",
|
"Timeout (%lu:%02lu:%02lu)!\n",
|
||||||
hour, min, sec);
|
hour, min, sec);
|
||||||
|
|
||||||
return strdup(buffer);
|
return _PyMem_Strdup(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
|
@ -570,7 +570,7 @@ faulthandler_dump_traceback_later(PyObject *self,
|
||||||
if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
|
if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
|
||||||
PyThread_release_lock(thread.running);
|
PyThread_release_lock(thread.running);
|
||||||
Py_CLEAR(thread.file);
|
Py_CLEAR(thread.file);
|
||||||
free(header);
|
PyMem_Free(header);
|
||||||
thread.header = NULL;
|
thread.header = NULL;
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
"unable to start watchdog thread");
|
"unable to start watchdog thread");
|
||||||
|
@ -729,9 +729,10 @@ faulthandler_register_py(PyObject *self,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (user_signals == NULL) {
|
if (user_signals == NULL) {
|
||||||
user_signals = calloc(NSIG, sizeof(user_signal_t));
|
user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
|
||||||
if (user_signals == NULL)
|
if (user_signals == NULL)
|
||||||
return PyErr_NoMemory();
|
return PyErr_NoMemory();
|
||||||
|
memset(user_signals, 0, NSIG * sizeof(user_signal_t));
|
||||||
}
|
}
|
||||||
user = &user_signals[signum];
|
user = &user_signals[signum];
|
||||||
|
|
||||||
|
@ -1136,7 +1137,7 @@ void _PyFaulthandler_Fini(void)
|
||||||
if (user_signals != NULL) {
|
if (user_signals != NULL) {
|
||||||
for (signum=0; signum < NSIG; signum++)
|
for (signum=0; signum < NSIG; signum++)
|
||||||
faulthandler_unregister(&user_signals[signum], signum);
|
faulthandler_unregister(&user_signals[signum], signum);
|
||||||
free(user_signals);
|
PyMem_Free(user_signals);
|
||||||
user_signals = NULL;
|
user_signals = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -544,7 +544,7 @@ Py_Main(int argc, wchar_t **argv)
|
||||||
Py_FatalError(
|
Py_FatalError(
|
||||||
"not enough memory to copy PYTHONWARNINGS");
|
"not enough memory to copy PYTHONWARNINGS");
|
||||||
strcpy(buf, p);
|
strcpy(buf, p);
|
||||||
oldloc = strdup(setlocale(LC_ALL, NULL));
|
oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) {
|
for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -562,7 +562,7 @@ Py_Main(int argc, wchar_t **argv)
|
||||||
Py_DECREF(unicode);
|
Py_DECREF(unicode);
|
||||||
}
|
}
|
||||||
setlocale(LC_ALL, oldloc);
|
setlocale(LC_ALL, oldloc);
|
||||||
free(oldloc);
|
PyMem_RawFree(oldloc);
|
||||||
PyMem_RawFree(buf);
|
PyMem_RawFree(buf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -43,12 +43,12 @@ main(int argc, char **argv)
|
||||||
fpsetmask(m & ~FP_X_OFL);
|
fpsetmask(m & ~FP_X_OFL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
oldloc = strdup(setlocale(LC_ALL, NULL));
|
oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
argv_copy[i] = _Py_char2wchar(argv[i], NULL);
|
argv_copy[i] = _Py_char2wchar(argv[i], NULL);
|
||||||
if (!argv_copy[i]) {
|
if (!argv_copy[i]) {
|
||||||
free(oldloc);
|
PyMem_RawFree(oldloc);
|
||||||
fprintf(stderr, "Fatal Python error: "
|
fprintf(stderr, "Fatal Python error: "
|
||||||
"unable to decode the command line argument #%i\n",
|
"unable to decode the command line argument #%i\n",
|
||||||
i + 1);
|
i + 1);
|
||||||
|
@ -59,7 +59,7 @@ main(int argc, char **argv)
|
||||||
argv_copy2[argc] = argv_copy[argc] = NULL;
|
argv_copy2[argc] = argv_copy[argc] = NULL;
|
||||||
|
|
||||||
setlocale(LC_ALL, oldloc);
|
setlocale(LC_ALL, oldloc);
|
||||||
free(oldloc);
|
PyMem_RawFree(oldloc);
|
||||||
res = Py_Main(argc, argv_copy);
|
res = Py_Main(argc, argv_copy);
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
PyMem_RawFree(argv_copy2[i]);
|
PyMem_RawFree(argv_copy2[i]);
|
||||||
|
|
|
@ -294,6 +294,34 @@ PyMem_Free(void *ptr)
|
||||||
_PyMem.free(_PyMem.ctx, ptr);
|
_PyMem.free(_PyMem.ctx, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
_PyMem_RawStrdup(const char *str)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
char *copy;
|
||||||
|
|
||||||
|
size = strlen(str) + 1;
|
||||||
|
copy = PyMem_RawMalloc(size);
|
||||||
|
if (copy == NULL)
|
||||||
|
return NULL;
|
||||||
|
memcpy(copy, str, size);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
_PyMem_Strdup(const char *str)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
char *copy;
|
||||||
|
|
||||||
|
size = strlen(str) + 1;
|
||||||
|
copy = PyMem_Malloc(size);
|
||||||
|
if (copy == NULL)
|
||||||
|
return NULL;
|
||||||
|
memcpy(copy, str, size);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
PyObject_Malloc(size_t size)
|
PyObject_Malloc(size_t size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -174,7 +174,7 @@ get_codec_name(const char *encoding)
|
||||||
name_utf8 = _PyUnicode_AsString(name);
|
name_utf8 = _PyUnicode_AsString(name);
|
||||||
if (name_utf8 == NULL)
|
if (name_utf8 == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
name_str = strdup(name_utf8);
|
name_str = _PyMem_RawStrdup(name_utf8);
|
||||||
Py_DECREF(name);
|
Py_DECREF(name);
|
||||||
if (name_str == NULL) {
|
if (name_str == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
|
@ -626,7 +626,7 @@ Py_Finalize(void)
|
||||||
|
|
||||||
/* reset file system default encoding */
|
/* reset file system default encoding */
|
||||||
if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
|
if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
|
||||||
free((char*)Py_FileSystemDefaultEncoding);
|
PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
|
||||||
Py_FileSystemDefaultEncoding = NULL;
|
Py_FileSystemDefaultEncoding = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,7 +1081,11 @@ initstdio(void)
|
||||||
encoding = Py_GETENV("PYTHONIOENCODING");
|
encoding = Py_GETENV("PYTHONIOENCODING");
|
||||||
errors = NULL;
|
errors = NULL;
|
||||||
if (encoding) {
|
if (encoding) {
|
||||||
encoding = strdup(encoding);
|
encoding = _PyMem_Strdup(encoding);
|
||||||
|
if (encoding == NULL) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
errors = strchr(encoding, ':');
|
errors = strchr(encoding, ':');
|
||||||
if (errors) {
|
if (errors) {
|
||||||
*errors = '\0';
|
*errors = '\0';
|
||||||
|
@ -1140,10 +1144,10 @@ initstdio(void)
|
||||||
when import.c tries to write to stderr in verbose mode. */
|
when import.c tries to write to stderr in verbose mode. */
|
||||||
encoding_attr = PyObject_GetAttrString(std, "encoding");
|
encoding_attr = PyObject_GetAttrString(std, "encoding");
|
||||||
if (encoding_attr != NULL) {
|
if (encoding_attr != NULL) {
|
||||||
const char * encoding;
|
const char * std_encoding;
|
||||||
encoding = _PyUnicode_AsString(encoding_attr);
|
std_encoding = _PyUnicode_AsString(encoding_attr);
|
||||||
if (encoding != NULL) {
|
if (std_encoding != NULL) {
|
||||||
PyObject *codec_info = _PyCodec_Lookup(encoding);
|
PyObject *codec_info = _PyCodec_Lookup(std_encoding);
|
||||||
Py_XDECREF(codec_info);
|
Py_XDECREF(codec_info);
|
||||||
}
|
}
|
||||||
Py_DECREF(encoding_attr);
|
Py_DECREF(encoding_attr);
|
||||||
|
@ -1160,8 +1164,7 @@ initstdio(void)
|
||||||
status = -1;
|
status = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encoding)
|
PyMem_Free(encoding);
|
||||||
free(encoding);
|
|
||||||
Py_XDECREF(bimod);
|
Py_XDECREF(bimod);
|
||||||
Py_XDECREF(iomod);
|
Py_XDECREF(iomod);
|
||||||
return status;
|
return status;
|
||||||
|
|
Loading…
Reference in New Issue