-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
Closed
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
LeakSanitizer detects memory leaks in the readline module when running test_audit
.
Affected Code
Four functions in Modules/readline.c
:
- line 298:
PyUnicode_FSConverter
callLines 278 to 316 in b2f9fb9
/* Exported function to load a readline history file */ /*[clinic input] @critical_section readline.read_history_file filename as filename_obj: object = None / Load a readline history file. The default filename is ~/.history. [clinic start generated code]*/ static PyObject * readline_read_history_file_impl(PyObject *module, PyObject *filename_obj) /*[clinic end generated code: output=66a951836fb54fbb input=5d86fd7813172a67]*/ { PyObject *filename_bytes; if (filename_obj != Py_None) { if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) return NULL; if (PySys_Audit("open", "OCi", filename_obj, 'r', 0) < 0) { return NULL; } errno = read_history(PyBytes_AS_STRING(filename_bytes)); Py_DECREF(filename_bytes); } else { /* Use the documented default filename here, * even though readline expands it different internally. */ if (PySys_Audit("open", "sCi", "~/.history", 'r', 0) < 0) { return NULL; } errno = read_history(NULL); } if (errno) return PyErr_SetFromErrno(PyExc_OSError); Py_RETURN_NONE; } - line 342:
PyUnicode_FSConverter
callLines 320 to 366 in b2f9fb9
/* Exported function to save a readline history file */ /*[clinic input] @critical_section readline.write_history_file filename as filename_obj: object = None / Save a readline history file. The default filename is ~/.history. [clinic start generated code]*/ static PyObject * readline_write_history_file_impl(PyObject *module, PyObject *filename_obj) /*[clinic end generated code: output=fbcad13d8ef59ae6 input=34aaada95120cfaa]*/ { PyObject *filename_bytes; const char *filename; int err; if (filename_obj != Py_None) { if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) return NULL; filename = PyBytes_AS_STRING(filename_bytes); if (PySys_Audit("open", "OCi", filename_obj, 'w', 0) < 0) { return NULL; } } else { filename_bytes = NULL; filename = NULL; /* Use the documented default filename here, * even though readline expands it different internally. */ if (PySys_Audit("open", "sCi", "~/.history", 'w', 0) < 0) { return NULL; } } errno = err = write_history(filename); int history_length = FT_ATOMIC_LOAD_INT_RELAXED(_history_length); if (!err && history_length >= 0) history_truncate_file(filename, history_length); Py_XDECREF(filename_bytes); errno = err; if (errno) return PyErr_SetFromErrno(PyExc_OSError); Py_RETURN_NONE; } - line 399:
PyUnicode_FSConverter
callLines 371 to 424 in b2f9fb9
/*[clinic input] @critical_section readline.append_history_file nelements: int filename as filename_obj: object = None / Append the last nelements items of the history list to file. The default filename is ~/.history. [clinic start generated code]*/ static PyObject * readline_append_history_file_impl(PyObject *module, int nelements, PyObject *filename_obj) /*[clinic end generated code: output=5df06fc9da56e4e4 input=78a6061a8d3a0275]*/ { if (nelements < 0) { PyErr_SetString(PyExc_ValueError, "nelements must be positive"); return NULL; } PyObject *filename_bytes; const char *filename; int err; if (filename_obj != Py_None) { if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) return NULL; filename = PyBytes_AS_STRING(filename_bytes); if (PySys_Audit("open", "OCi", filename_obj, 'a', 0) < 0) { return NULL; } } else { filename_bytes = NULL; filename = NULL; /* Use the documented default filename here, * even though readline expands it different internally. */ if (PySys_Audit("open", "sCi", "~/.history", 'a', 0) < 0) { return NULL; } } errno = err = append_history( nelements - libedit_append_replace_history_offset, filename); int history_length = FT_ATOMIC_LOAD_INT_RELAXED(_history_length); if (!err && history_length >= 0) history_truncate_file(filename, history_length); Py_XDECREF(filename_bytes); errno = err; if (errno) return PyErr_SetFromErrno(PyExc_OSError); Py_RETURN_NONE; } - line 255:
PyUnicode_FSConverter
callLines 237 to 276 in b2f9fb9
/*[clinic input] @critical_section readline.read_init_file filename as filename_obj: object = None / Execute a readline initialization file. The default filename is the last filename used. [clinic start generated code]*/ static PyObject * readline_read_init_file_impl(PyObject *module, PyObject *filename_obj) /*[clinic end generated code: output=8e059b676142831e input=62b767adfab6cc15]*/ { PyObject *filename_bytes; if (filename_obj != Py_None) { if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) return NULL; if (PySys_Audit("open", "OCi", filename_obj, 'r', 0) < 0) { return NULL; } errno = rl_read_init_file(PyBytes_AS_STRING(filename_bytes)); Py_DECREF(filename_bytes); } else { /* We have the choice to either try to exactly reproduce the * logic to find the filename, ignore it, or provide a dummy value. * In contract to the history file manipulations, there's no * clear default to choose. */ if (PySys_Audit("open", "sCi", "<readline_init_file>", 'r', 0) < 0) { return NULL; } errno = rl_read_init_file(NULL); } if (errno) return PyErr_SetFromErrno(PyExc_OSError); disable_bracketed_paste(); Py_RETURN_NONE; }
Steps to Reproduce
Build:
CC=clang CXX=clang++ ./configure --disable-optimizations --with-pydebug --with-address-sanitizer && make -j$(nproc)
Run:
./python -X dev -X showrefcount -m test test_audit -j0
Result
LeakSanitizer reports 4 memory leaks of 75 bytes each (300 bytes total). Full logs attached as .log files.
Summary from LeakSanitizer:
SUMMARY: AddressSanitizer: 300 byte(s) leaked in 4 allocation(s).
All leaks originate from PyUnicode_FSConverter
calls in the affected functions.
CPython versions tested on:
3.14, 3.15, CPython main branch
Operating systems tested on:
Linux
Linked PRs
Metadata
Metadata
Assignees
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error