From c3da9cfae1f6b26eab07f90467f125dc8d174950 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 23 Jun 2021 12:53:37 +0300 Subject: [PATCH] [3.9] bpo-44482: Fix very unlikely resource leak in glob in non-CPython implementations (GH-26843). (cherry picked from commit 5c7940257e1f611e7284fd504887bd29a63d0a94) Co-authored-by: Serhiy Storchaka --- Lib/glob.py | 9 +++++++-- .../Library/2021-06-22-08-43-04.bpo-44482.U9GznK.rst | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-06-22-08-43-04.bpo-44482.U9GznK.rst diff --git a/Lib/glob.py b/Lib/glob.py index 0dd2f8be6610945..123706113095156 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -1,5 +1,6 @@ """Filename globbing utility.""" +import contextlib import os import re import fnmatch @@ -79,7 +80,7 @@ def _iglob(pathname, recursive, dironly): # takes a literal basename (so it only has to check for its existence). def _glob1(dirname, pattern, dironly): - names = list(_iterdir(dirname, dironly)) + names = _listdir(dirname, dironly) if not _ishidden(pattern): names = (x for x in names if not _ishidden(x)) return fnmatch.filter(names, pattern) @@ -130,9 +131,13 @@ def _iterdir(dirname, dironly): except OSError: return +def _listdir(dirname, dironly): + with contextlib.closing(_iterdir(dirname, dironly)) as it: + return list(it) + # Recursively yields relative pathnames inside a literal directory. def _rlistdir(dirname, dironly): - names = list(_iterdir(dirname, dironly)) + names = _listdir(dirname, dironly) for x in names: if not _ishidden(x): yield x diff --git a/Misc/NEWS.d/next/Library/2021-06-22-08-43-04.bpo-44482.U9GznK.rst b/Misc/NEWS.d/next/Library/2021-06-22-08-43-04.bpo-44482.U9GznK.rst new file mode 100644 index 000000000000000..d05fe908e3eba38 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-06-22-08-43-04.bpo-44482.U9GznK.rst @@ -0,0 +1,2 @@ +Fix very unlikely resource leak in :mod:`glob` in alternate Python +implementations.