mirror of
https://github.com/python/cpython.git
synced 2025-07-24 03:35:53 +00:00
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 97ea18eced
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
2f1d9bca14
commit
06c26f4d29
3 changed files with 20 additions and 8 deletions
|
@ -175,7 +175,7 @@ class MimeTypes:
|
|||
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:
|
||||
|
|
|
@ -113,20 +113,29 @@ class MimeTypesTestCase(unittest.TestCase):
|
|||
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
|
||||
|
|
|
@ -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.
|
Loading…
Add table
Add a link
Reference in a new issue