Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 49fc8ec

Browse files
committed
Issue #18203: Add _PyMem_RawStrdup() and _PyMem_Strdup()
Replace strdup() with _PyMem_RawStrdup() or _PyMem_Strdup(), depending if the GIL is held or not.
1 parent 6f8eeee commit 49fc8ec

8 files changed

Lines changed: 64 additions & 29 deletions

File tree

Include/pymem.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ PyAPI_FUNC(void *) PyMem_Malloc(size_t size);
5858
PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size);
5959
PyAPI_FUNC(void) PyMem_Free(void *ptr);
6060

61+
PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str);
62+
PyAPI_FUNC(char *) _PyMem_Strdup(const char *str);
63+
6164
/* Macros. */
6265

6366
/* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL

Modules/_cursesmodule.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ PyCursesWindow_New(WINDOW *win, const char *encoding)
529529
wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
530530
if (wo == NULL) return NULL;
531531
wo->win = win;
532-
wo->encoding = strdup(encoding);
532+
wo->encoding = _PyMem_Strdup(encoding);
533533
if (wo->encoding == NULL) {
534534
Py_DECREF(wo);
535535
PyErr_NoMemory();
@@ -543,7 +543,7 @@ PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
543543
{
544544
if (wo->win != stdscr) delwin(wo->win);
545545
if (wo->encoding != NULL)
546-
free(wo->encoding);
546+
PyMem_Free(wo->encoding);
547547
PyObject_DEL(wo);
548548
}
549549

@@ -1938,13 +1938,13 @@ PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value)
19381938
ascii = PyUnicode_AsASCIIString(value);
19391939
if (ascii == NULL)
19401940
return -1;
1941-
encoding = strdup(PyBytes_AS_STRING(ascii));
1941+
encoding = _PyMem_Strdup(PyBytes_AS_STRING(ascii));
19421942
Py_DECREF(ascii);
19431943
if (encoding == NULL) {
19441944
PyErr_NoMemory();
19451945
return -1;
19461946
}
1947-
free(self->encoding);
1947+
PyMem_Free(self->encoding);
19481948
self->encoding = encoding;
19491949
return 0;
19501950
}

Modules/_pickle.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,8 +1213,8 @@ _Unpickler_SetInputEncoding(UnpicklerObject *self,
12131213
if (errors == NULL)
12141214
errors = "strict";
12151215

1216-
self->encoding = strdup(encoding);
1217-
self->errors = strdup(errors);
1216+
self->encoding = _PyMem_Strdup(encoding);
1217+
self->errors = _PyMem_Strdup(errors);
12181218
if (self->encoding == NULL || self->errors == NULL) {
12191219
PyErr_NoMemory();
12201220
return -1;
@@ -5590,8 +5590,8 @@ Unpickler_dealloc(UnpicklerObject *self)
55905590
_Unpickler_MemoCleanup(self);
55915591
PyMem_Free(self->marks);
55925592
PyMem_Free(self->input_line);
5593-
free(self->encoding);
5594-
free(self->errors);
5593+
PyMem_Free(self->encoding);
5594+
PyMem_Free(self->errors);
55955595

55965596
Py_TYPE(self)->tp_free((PyObject *)self);
55975597
}
@@ -5627,9 +5627,9 @@ Unpickler_clear(UnpicklerObject *self)
56275627
self->marks = NULL;
56285628
PyMem_Free(self->input_line);
56295629
self->input_line = NULL;
5630-
free(self->encoding);
5630+
PyMem_Free(self->encoding);
56315631
self->encoding = NULL;
5632-
free(self->errors);
5632+
PyMem_Free(self->errors);
56335633
self->errors = NULL;
56345634

56355635
return 0;

Modules/faulthandler.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ cancel_dump_traceback_later(void)
475475

476476
Py_CLEAR(thread.file);
477477
if (thread.header) {
478-
free(thread.header);
478+
PyMem_Free(thread.header);
479479
thread.header = NULL;
480480
}
481481
}
@@ -504,7 +504,7 @@ format_timeout(double timeout)
504504
"Timeout (%lu:%02lu:%02lu)!\n",
505505
hour, min, sec);
506506

507-
return strdup(buffer);
507+
return _PyMem_Strdup(buffer);
508508
}
509509

510510
static PyObject*
@@ -570,7 +570,7 @@ faulthandler_dump_traceback_later(PyObject *self,
570570
if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
571571
PyThread_release_lock(thread.running);
572572
Py_CLEAR(thread.file);
573-
free(header);
573+
PyMem_Free(header);
574574
thread.header = NULL;
575575
PyErr_SetString(PyExc_RuntimeError,
576576
"unable to start watchdog thread");
@@ -729,9 +729,10 @@ faulthandler_register_py(PyObject *self,
729729
return NULL;
730730

731731
if (user_signals == NULL) {
732-
user_signals = calloc(NSIG, sizeof(user_signal_t));
732+
user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
733733
if (user_signals == NULL)
734734
return PyErr_NoMemory();
735+
memset(user_signals, 0, NSIG * sizeof(user_signal_t));
735736
}
736737
user = &user_signals[signum];
737738

@@ -1136,7 +1137,7 @@ void _PyFaulthandler_Fini(void)
11361137
if (user_signals != NULL) {
11371138
for (signum=0; signum < NSIG; signum++)
11381139
faulthandler_unregister(&user_signals[signum], signum);
1139-
free(user_signals);
1140+
PyMem_Free(user_signals);
11401141
user_signals = NULL;
11411142
}
11421143
#endif

Modules/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ Py_Main(int argc, wchar_t **argv)
544544
Py_FatalError(
545545
"not enough memory to copy PYTHONWARNINGS");
546546
strcpy(buf, p);
547-
oldloc = strdup(setlocale(LC_ALL, NULL));
547+
oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
548548
setlocale(LC_ALL, "");
549549
for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) {
550550
#ifdef __APPLE__
@@ -562,7 +562,7 @@ Py_Main(int argc, wchar_t **argv)
562562
Py_DECREF(unicode);
563563
}
564564
setlocale(LC_ALL, oldloc);
565-
free(oldloc);
565+
PyMem_RawFree(oldloc);
566566
PyMem_RawFree(buf);
567567
}
568568
#endif

Modules/python.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ main(int argc, char **argv)
4343
fpsetmask(m & ~FP_X_OFL);
4444
#endif
4545

46-
oldloc = strdup(setlocale(LC_ALL, NULL));
46+
oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
4747
setlocale(LC_ALL, "");
4848
for (i = 0; i < argc; i++) {
4949
argv_copy[i] = _Py_char2wchar(argv[i], NULL);
5050
if (!argv_copy[i]) {
51-
free(oldloc);
51+
PyMem_RawFree(oldloc);
5252
fprintf(stderr, "Fatal Python error: "
5353
"unable to decode the command line argument #%i\n",
5454
i + 1);
@@ -59,7 +59,7 @@ main(int argc, char **argv)
5959
argv_copy2[argc] = argv_copy[argc] = NULL;
6060

6161
setlocale(LC_ALL, oldloc);
62-
free(oldloc);
62+
PyMem_RawFree(oldloc);
6363
res = Py_Main(argc, argv_copy);
6464
for (i = 0; i < argc; i++) {
6565
PyMem_RawFree(argv_copy2[i]);

Objects/obmalloc.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,34 @@ PyMem_Free(void *ptr)
294294
_PyMem.free(_PyMem.ctx, ptr);
295295
}
296296

297+
char *
298+
_PyMem_RawStrdup(const char *str)
299+
{
300+
size_t size;
301+
char *copy;
302+
303+
size = strlen(str) + 1;
304+
copy = PyMem_RawMalloc(size);
305+
if (copy == NULL)
306+
return NULL;
307+
memcpy(copy, str, size);
308+
return copy;
309+
}
310+
311+
char *
312+
_PyMem_Strdup(const char *str)
313+
{
314+
size_t size;
315+
char *copy;
316+
317+
size = strlen(str) + 1;
318+
copy = PyMem_Malloc(size);
319+
if (copy == NULL)
320+
return NULL;
321+
memcpy(copy, str, size);
322+
return copy;
323+
}
324+
297325
void *
298326
PyObject_Malloc(size_t size)
299327
{

Python/pythonrun.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ get_codec_name(const char *encoding)
174174
name_utf8 = _PyUnicode_AsString(name);
175175
if (name_utf8 == NULL)
176176
goto error;
177-
name_str = strdup(name_utf8);
177+
name_str = _PyMem_RawStrdup(name_utf8);
178178
Py_DECREF(name);
179179
if (name_str == NULL) {
180180
PyErr_NoMemory();
@@ -626,7 +626,7 @@ Py_Finalize(void)
626626

627627
/* reset file system default encoding */
628628
if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
629-
free((char*)Py_FileSystemDefaultEncoding);
629+
PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
630630
Py_FileSystemDefaultEncoding = NULL;
631631
}
632632

@@ -1081,7 +1081,11 @@ initstdio(void)
10811081
encoding = Py_GETENV("PYTHONIOENCODING");
10821082
errors = NULL;
10831083
if (encoding) {
1084-
encoding = strdup(encoding);
1084+
encoding = _PyMem_Strdup(encoding);
1085+
if (encoding == NULL) {
1086+
PyErr_NoMemory();
1087+
goto error;
1088+
}
10851089
errors = strchr(encoding, ':');
10861090
if (errors) {
10871091
*errors = '\0';
@@ -1140,10 +1144,10 @@ initstdio(void)
11401144
when import.c tries to write to stderr in verbose mode. */
11411145
encoding_attr = PyObject_GetAttrString(std, "encoding");
11421146
if (encoding_attr != NULL) {
1143-
const char * encoding;
1144-
encoding = _PyUnicode_AsString(encoding_attr);
1145-
if (encoding != NULL) {
1146-
PyObject *codec_info = _PyCodec_Lookup(encoding);
1147+
const char * std_encoding;
1148+
std_encoding = _PyUnicode_AsString(encoding_attr);
1149+
if (std_encoding != NULL) {
1150+
PyObject *codec_info = _PyCodec_Lookup(std_encoding);
11471151
Py_XDECREF(codec_info);
11481152
}
11491153
Py_DECREF(encoding_attr);
@@ -1160,8 +1164,7 @@ initstdio(void)
11601164
status = -1;
11611165
}
11621166

1163-
if (encoding)
1164-
free(encoding);
1167+
PyMem_Free(encoding);
11651168
Py_XDECREF(bimod);
11661169
Py_XDECREF(iomod);
11671170
return status;

0 commit comments

Comments
 (0)