]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-142776: Ensure fp file descriptor is closed on all code paths in import.c (GH...
authorstratakis <cstratak@redhat.com>
Fri, 19 Dec 2025 18:14:52 +0000 (19:14 +0100)
committerGitHub <noreply@github.com>
Fri, 19 Dec 2025 18:14:52 +0000 (10:14 -0800)
Misc/NEWS.d/next/Core_and_Builtins/2025-12-18-01-00-14.gh-issue-142776.ACaoeP.rst [new file with mode: 0644]
Python/import.c

diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-18-01-00-14.gh-issue-142776.ACaoeP.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-18-01-00-14.gh-issue-142776.ACaoeP.rst
new file mode 100644 (file)
index 0000000..3039b04
--- /dev/null
@@ -0,0 +1 @@
+Fix a file descriptor leak in import.c
index db433dbc971d76d3f70b88036e4337a67c964448..466c5868ab7ee8166efea8fafeff04e7e3e31508 100644 (file)
@@ -4762,6 +4762,7 @@ static PyObject *
 _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
 /*[clinic end generated code: output=83249b827a4fde77 input=c31b954f4cf4e09d]*/
 {
+    FILE *fp = NULL;
     PyObject *mod = NULL;
     PyThreadState *tstate = _PyThreadState_GET();
 
@@ -4804,16 +4805,12 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
     /* We would move this (and the fclose() below) into
      * _PyImport_GetModuleExportHooks(), but it isn't clear if the intervening
      * code relies on fp still being open. */
-    FILE *fp;
     if (file != NULL) {
         fp = Py_fopen(info.filename, "r");
         if (fp == NULL) {
             goto finally;
         }
     }
-    else {
-        fp = NULL;
-    }
 
     PyModInitFunction p0 = NULL;
     PyModExportFunction ex0 = NULL;
@@ -4822,7 +4819,7 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
         mod = import_run_modexport(tstate, ex0, &info, spec);
         // Modules created from slots handle GIL enablement (Py_mod_gil slot)
         // when they're created.
-        goto cleanup;
+        goto finally;
     }
     if (p0 == NULL) {
         goto finally;
@@ -4845,13 +4842,10 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
     }
 #endif
 
-cleanup:
-    // XXX Shouldn't this happen in the error cases too (i.e. in "finally")?
-    if (fp) {
+finally:
+    if (fp != NULL) {
         fclose(fp);
     }
-
-finally:
     _Py_ext_module_loader_info_clear(&info);
     return mod;
 }