Commits

Aleš Erjavec committed e4175f3

Fix a memory leak in 'getFileSystemEncoding'

The string returned by a call to sys.getfilesystemencoding was never decrefed.

Changed the function signature to return a std::string.

  • Participants
  • Parent commits a93bccd

Comments (0)

Files changed (2)

File source/orange/lib_io.cpp

 PyObject *encodeStatus(const vector<pair<int, int> > &metaStatus);
 
 
-/* Same as sys.getfilesystemencoding()
- * (the returned pointer points to a PyString_Object internal buffer
- * and should not be modified).
- */
-char* getFileSystemEncoding()
+/* Same as sys.getfilesystemencoding() */
+
+std::string getFileSystemEncoding()
 {
-    PyObject *fsencoding = PySys_GetObject("getfilesystemencoding"); // Borrowed ref
-    fsencoding = PyObject_CallObject(fsencoding, NULL); // This should be a string.
+    char name[] = "getfilesystemencoding";
+    PyObject *fsencoding = PySys_GetObject(name); // Borrowed ref
+    fsencoding = PyObject_CallObject(fsencoding, NULL); // This should return a string.
     assert(PyString_Check(fsencoding));
-    return PyString_AsString(fsencoding);
+    std::string encoding(PyString_AsString(fsencoding));
+    Py_DECREF(fsencoding);
+    return encoding;
 }
 
 /* ************ FILE EXAMPLE GENERATORS ************ */
 
     if (!PyArg_ParseTuple(args, "sO&", &filename, pt_ExampleGenerator, &gen))
     {
-        char *encoding = getFileSystemEncoding();
-        if (!PyArg_ParseTuple(args, "esO&", encoding, &filename, pt_ExampleGenerator, &gen))
+        std::string encoding = getFileSystemEncoding();
+        if (!PyArg_ParseTuple(args, "esO&", encoding.c_str(), &filename, pt_ExampleGenerator, &gen))
             PYERROR(PyExc_TypeError, "string and example generator expected", PYNULL);
         PyErr_Clear();
         free_filename = true;
 
     if (!PyArg_ParseTuple(args, "sO&:saveBasket", &filename, pt_ExampleGenerator, &gen))
     {
-      char *encoding = getFileSystemEncoding();
-      if (!PyArg_ParseTuple(args, "esO&:saveBasket", encoding, &filename, pt_ExampleGenerator, &gen))
+      std::string encoding = getFileSystemEncoding();
+      if (!PyArg_ParseTuple(args, "esO&:saveBasket", encoding.c_str(), &filename, pt_ExampleGenerator, &gen))
           return PYNULL;
       PyErr_Clear();
       free_filename = true;

File source/orange/lib_kernel.cpp

 
 
 const char *getExtension(const char *name);
-char *getFileSystemEncoding(); // defined in lib_io.cpp
+std::string getFileSystemEncoding(); // defined in lib_io.cpp
 
 PyObject *saveTabDelimited(PyObject *, PyObject *args, PyObject *keyws);
 PyObject *saveC45(PyObject *, PyObject *args);
   if (!PyArg_ParseTuple(args, "s:ExampleGenerator.save", &filename))
   {
       // Try again, this time with the fs encoding.
-      char *encoding = getFileSystemEncoding();
-      if (!PyArg_ParseTuple(args, "es:ExampleGenerator.save", encoding, &filename))
+      std::string encoding = getFileSystemEncoding();
+      if (!PyArg_ParseTuple(args, "es:ExampleGenerator.save", encoding.c_str(), &filename))
           return PYNULL;
       free_filename = true;
       PyErr_Clear();
 PyObject *ExampleTable_new(PyTypeObject *type, PyObject *argstuple, PyObject *keywords) BASED_ON(ExampleGenerator - Orange.data.Table, "(filename | domain[, examples] | examples)")
 {
   PyTRY
-
     char *filename = NULL;
     if (PyArg_ParseTuple(argstuple, "s", &filename))
         return loadDataFromFile(type, filename, argstuple, keywords, false);
     /*For a case where the unicode can't be converted to a default
      * encoding (on most platforms this is ASCII)
      */
-    char * coding = getFileSystemEncoding();
-    if (PyArg_ParseTuple(argstuple, "es", coding, &filename))
+    std::string coding = getFileSystemEncoding();
+    if (PyArg_ParseTuple(argstuple, "es", coding.c_str(), &filename))
     {
         PyObject *rval = loadDataFromFile(type, filename, argstuple, keywords, false);
         PyMem_Free(filename);