[Python-checkins] bpo-35474: Fix mimetypes.guess_all_extensions() potentially mutating list (GH-28286) (GH-28289)
ambv
webhook-mailer at python.org
Mon Sep 13 13:24:34 EDT 2021
https://github.com/python/cpython/commit/06c26f4d2909eae196ac81c9ed9b41e747e42685
commit: 06c26f4d2909eae196ac81c9ed9b41e747e42685
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: ambv <lukasz at langa.pl>
date: 2021-09-13T19:24:29+02:00
summary:
bpo-35474: Fix mimetypes.guess_all_extensions() potentially mutating list (GH-28286) (GH-28289)
* Calling guess_all_extensions() with strict=False potentially
mutated types_map_inv.
* Mutating the result of guess_all_extensions() mutated types_map_inv.
(cherry picked from commit 97ea18ecede8bfd33d5ab2dd0e7e2aada2051111)
Co-authored-by: Serhiy Storchaka <storchaka at gmail.com>
files:
A Misc/NEWS.d/next/Library/2021-09-11-10-45-12.bpo-35474.tEY3SD.rst
M Lib/mimetypes.py
M Lib/test/test_mimetypes.py
diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py
index 1e83131d05b1c..c389685c08f6f 100644
--- a/Lib/mimetypes.py
+++ b/Lib/mimetypes.py
@@ -175,7 +175,7 @@ def guess_all_extensions(self, type, strict=True):
but non-standard types.
"""
type = type.lower()
- extensions = self.types_map_inv[True].get(type, [])
+ extensions = list(self.types_map_inv[True].get(type, []))
if not strict:
for ext in self.types_map_inv[False].get(type, []):
if ext not in extensions:
diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py
index fb9cb04452c30..4098a22644092 100644
--- a/Lib/test/test_mimetypes.py
+++ b/Lib/test/test_mimetypes.py
@@ -113,20 +113,29 @@ def test_filename_with_url_delimiters(self):
eq(self.db.guess_type(r" \"\`;b&b&c |.tar.gz"), gzip_expected)
def test_guess_all_types(self):
- eq = self.assertEqual
- unless = self.assertTrue
# First try strict. Use a set here for testing the results because if
# test_urllib2 is run before test_mimetypes, global state is modified
# such that the 'all' set will have more items in it.
- all = set(self.db.guess_all_extensions('text/plain', strict=True))
- unless(all >= set(['.bat', '.c', '.h', '.ksh', '.pl', '.txt']))
+ all = self.db.guess_all_extensions('text/plain', strict=True)
+ self.assertTrue(set(all) >= {'.bat', '.c', '.h', '.ksh', '.pl', '.txt'})
+ self.assertEqual(len(set(all)), len(all)) # no duplicates
# And now non-strict
all = self.db.guess_all_extensions('image/jpg', strict=False)
- all.sort()
- eq(all, ['.jpg'])
+ self.assertEqual(all, ['.jpg'])
# And now for no hits
all = self.db.guess_all_extensions('image/jpg', strict=True)
- eq(all, [])
+ self.assertEqual(all, [])
+ # And now for type existing in both strict and non-strict mappings.
+ self.db.add_type('test-type', '.strict-ext')
+ self.db.add_type('test-type', '.non-strict-ext', strict=False)
+ all = self.db.guess_all_extensions('test-type', strict=False)
+ self.assertEqual(all, ['.strict-ext', '.non-strict-ext'])
+ all = self.db.guess_all_extensions('test-type')
+ self.assertEqual(all, ['.strict-ext'])
+ # Test that changing the result list does not affect the global state
+ all.append('.no-such-ext')
+ all = self.db.guess_all_extensions('test-type')
+ self.assertNotIn('.no-such-ext', all)
def test_encoding(self):
getpreferredencoding = locale.getpreferredencoding
diff --git a/Misc/NEWS.d/next/Library/2021-09-11-10-45-12.bpo-35474.tEY3SD.rst b/Misc/NEWS.d/next/Library/2021-09-11-10-45-12.bpo-35474.tEY3SD.rst
new file mode 100644
index 0000000000000..f4dd3b947a493
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-09-11-10-45-12.bpo-35474.tEY3SD.rst
@@ -0,0 +1,3 @@
+Calling :func:`mimetypes.guess_all_extensions` with ``strict=False`` no
+longer affects the result of the following call with ``strict=True``.
+Also, mutating the returned list no longer affects the global state.
More information about the Python-checkins
mailing list