]> granicus.if.org Git - python/commitdiff
Issue #18203: Add _PyMem_RawStrdup() and _PyMem_Strdup()
authorVictor Stinner <victor.stinner@gmail.com>
Sun, 7 Jul 2013 21:30:24 +0000 (23:30 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Sun, 7 Jul 2013 21:30:24 +0000 (23:30 +0200)
Replace strdup() with _PyMem_RawStrdup() or _PyMem_Strdup(), depending if the
GIL is held or not.

Include/pymem.h
Modules/_cursesmodule.c
Modules/_pickle.c
Modules/faulthandler.c
Modules/main.c
Modules/python.c
Objects/obmalloc.c
Python/pythonrun.c

index 58c52425b467a35e36f558034e5e45008a0609d6..83f1537f3f55128cd6157c7d68417eb761fe30c6 100644 (file)
@@ -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_Free(void *ptr);
 
+PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str);
+PyAPI_FUNC(char *) _PyMem_Strdup(const char *str);
+
 /* Macros. */
 
 /* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL
index fbe18f6e06b9b8edb7ef0fead895ba008b50d65b..5d1489852d94617d2e1d5db6d0394926c1d01eea 100644 (file)
@@ -529,7 +529,7 @@ PyCursesWindow_New(WINDOW *win, const char *encoding)
     wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
     if (wo == NULL) return NULL;
     wo->win = win;
-    wo->encoding = strdup(encoding);
+    wo->encoding = _PyMem_Strdup(encoding);
     if (wo->encoding == NULL) {
         Py_DECREF(wo);
         PyErr_NoMemory();
@@ -543,7 +543,7 @@ PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
 {
     if (wo->win != stdscr) delwin(wo->win);
     if (wo->encoding != NULL)
-        free(wo->encoding);
+        PyMem_Free(wo->encoding);
     PyObject_DEL(wo);
 }
 
@@ -1938,13 +1938,13 @@ PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value)
     ascii = PyUnicode_AsASCIIString(value);
     if (ascii == NULL)
         return -1;
-    encoding = strdup(PyBytes_AS_STRING(ascii));
+    encoding = _PyMem_Strdup(PyBytes_AS_STRING(ascii));
     Py_DECREF(ascii);
     if (encoding == NULL) {
         PyErr_NoMemory();
         return -1;
     }
-    free(self->encoding);
+    PyMem_Free(self->encoding);
     self->encoding = encoding;
     return 0;
 }
index 5b30931310838628e9fb1baf0c73172d7416e5d3..72bd7fce65513201bb640d3413ec8cc6f4060b50 100644 (file)
@@ -1213,8 +1213,8 @@ _Unpickler_SetInputEncoding(UnpicklerObject *self,
     if (errors == NULL)
         errors = "strict";
 
-    self->encoding = strdup(encoding);
-    self->errors = strdup(errors);
+    self->encoding = _PyMem_Strdup(encoding);
+    self->errors = _PyMem_Strdup(errors);
     if (self->encoding == NULL || self->errors == NULL) {
         PyErr_NoMemory();
         return -1;
@@ -5590,8 +5590,8 @@ Unpickler_dealloc(UnpicklerObject *self)
     _Unpickler_MemoCleanup(self);
     PyMem_Free(self->marks);
     PyMem_Free(self->input_line);
-    free(self->encoding);
-    free(self->errors);
+    PyMem_Free(self->encoding);
+    PyMem_Free(self->errors);
 
     Py_TYPE(self)->tp_free((PyObject *)self);
 }
@@ -5627,9 +5627,9 @@ Unpickler_clear(UnpicklerObject *self)
     self->marks = NULL;
     PyMem_Free(self->input_line);
     self->input_line = NULL;
-    free(self->encoding);
+    PyMem_Free(self->encoding);
     self->encoding = NULL;
-    free(self->errors);
+    PyMem_Free(self->errors);
     self->errors = NULL;
 
     return 0;
index 686a45a145c5d2f3060ef60a17d2c5a1dede572b..172945d1a40746b4ebfff37b99e81a1d3b254e59 100644 (file)
@@ -475,7 +475,7 @@ cancel_dump_traceback_later(void)
 
     Py_CLEAR(thread.file);
     if (thread.header) {
-        free(thread.header);
+        PyMem_Free(thread.header);
         thread.header = NULL;
     }
 }
@@ -504,7 +504,7 @@ format_timeout(double timeout)
                       "Timeout (%lu:%02lu:%02lu)!\n",
                       hour, min, sec);
 
-    return strdup(buffer);
+    return _PyMem_Strdup(buffer);
 }
 
 static PyObject*
@@ -570,7 +570,7 @@ faulthandler_dump_traceback_later(PyObject *self,
     if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
         PyThread_release_lock(thread.running);
         Py_CLEAR(thread.file);
-        free(header);
+        PyMem_Free(header);
         thread.header = NULL;
         PyErr_SetString(PyExc_RuntimeError,
                         "unable to start watchdog thread");
@@ -729,9 +729,10 @@ faulthandler_register_py(PyObject *self,
         return 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)
             return PyErr_NoMemory();
+        memset(user_signals, 0, NSIG * sizeof(user_signal_t));
     }
     user = &user_signals[signum];
 
@@ -1136,7 +1137,7 @@ void _PyFaulthandler_Fini(void)
     if (user_signals != NULL) {
         for (signum=0; signum < NSIG; signum++)
             faulthandler_unregister(&user_signals[signum], signum);
-        free(user_signals);
+        PyMem_Free(user_signals);
         user_signals = NULL;
     }
 #endif
index 2bafbfda586edc7dc2c00d4edff5b3a57f459c4b..af0d7f40641f7117da878385a9698b9ee276fcd6 100644 (file)
@@ -544,7 +544,7 @@ Py_Main(int argc, wchar_t **argv)
             Py_FatalError(
                "not enough memory to copy PYTHONWARNINGS");
         strcpy(buf, p);
-        oldloc = strdup(setlocale(LC_ALL, NULL));
+        oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
         setlocale(LC_ALL, "");
         for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) {
 #ifdef __APPLE__
@@ -562,7 +562,7 @@ Py_Main(int argc, wchar_t **argv)
             Py_DECREF(unicode);
         }
         setlocale(LC_ALL, oldloc);
-        free(oldloc);
+        PyMem_RawFree(oldloc);
         PyMem_RawFree(buf);
     }
 #endif
index aaa7fcff22b613a4d850062f20c96c76100e4c08..0ad1130f1991b848b3695e81d8070665707a5a52 100644 (file)
@@ -43,12 +43,12 @@ main(int argc, char **argv)
     fpsetmask(m & ~FP_X_OFL);
 #endif
 
-    oldloc = strdup(setlocale(LC_ALL, NULL));
+    oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
     setlocale(LC_ALL, "");
     for (i = 0; i < argc; i++) {
         argv_copy[i] = _Py_char2wchar(argv[i], NULL);
         if (!argv_copy[i]) {
-            free(oldloc);
+            PyMem_RawFree(oldloc);
             fprintf(stderr, "Fatal Python error: "
                             "unable to decode the command line argument #%i\n",
                             i + 1);
@@ -59,7 +59,7 @@ main(int argc, char **argv)
     argv_copy2[argc] = argv_copy[argc] = NULL;
 
     setlocale(LC_ALL, oldloc);
-    free(oldloc);
+    PyMem_RawFree(oldloc);
     res = Py_Main(argc, argv_copy);
     for (i = 0; i < argc; i++) {
         PyMem_RawFree(argv_copy2[i]);
index 97a137db37300435fa376d58caef369ddcb35d0f..8e25229e09f6c5823fd2d297dc8995a75f4b415e 100644 (file)
@@ -294,6 +294,34 @@ PyMem_Free(void *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 *
 PyObject_Malloc(size_t size)
 {
index 94175be87e95476d43a2c78eed8d17a14eb07a23..d95a09d4a7e8e3dc4286e921f3b3ce0b699135fc 100644 (file)
@@ -174,7 +174,7 @@ get_codec_name(const char *encoding)
     name_utf8 = _PyUnicode_AsString(name);
     if (name_utf8 == NULL)
         goto error;
-    name_str = strdup(name_utf8);
+    name_str = _PyMem_RawStrdup(name_utf8);
     Py_DECREF(name);
     if (name_str == NULL) {
         PyErr_NoMemory();
@@ -626,7 +626,7 @@ Py_Finalize(void)
 
     /* reset file system default encoding */
     if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
-        free((char*)Py_FileSystemDefaultEncoding);
+        PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
         Py_FileSystemDefaultEncoding = NULL;
     }
 
@@ -1081,7 +1081,11 @@ initstdio(void)
     encoding = Py_GETENV("PYTHONIOENCODING");
     errors = NULL;
     if (encoding) {
-        encoding = strdup(encoding);
+        encoding = _PyMem_Strdup(encoding);
+        if (encoding == NULL) {
+            PyErr_NoMemory();
+            goto error;
+        }
         errors = strchr(encoding, ':');
         if (errors) {
             *errors = '\0';
@@ -1140,10 +1144,10 @@ initstdio(void)
        when import.c tries to write to stderr in verbose mode. */
     encoding_attr = PyObject_GetAttrString(std, "encoding");
     if (encoding_attr != NULL) {
-        const char * encoding;
-        encoding = _PyUnicode_AsString(encoding_attr);
-        if (encoding != NULL) {
-            PyObject *codec_info = _PyCodec_Lookup(encoding);
+        const char * std_encoding;
+        std_encoding = _PyUnicode_AsString(encoding_attr);
+        if (std_encoding != NULL) {
+            PyObject *codec_info = _PyCodec_Lookup(std_encoding);
             Py_XDECREF(codec_info);
         }
         Py_DECREF(encoding_attr);
@@ -1160,8 +1164,7 @@ initstdio(void)
         status = -1;
     }
 
-    if (encoding)
-        free(encoding);
+    PyMem_Free(encoding);
     Py_XDECREF(bimod);
     Py_XDECREF(iomod);
     return status;