8000 bpo-35474: Fix mimetypes.guess_all_extensions() potentially mutating … · python/cpython@06c26f4 · GitHub
[go: up one dir, main page]

Skip to content

Commit 06c26f4

Browse files
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 97ea18e) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parent 2f1d9bc commit 06c26f4

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

Lib/mimetypes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def guess_all_extensions(self, type, strict=True):
175175
but non-standard types.
176176
"""
177177
type = type.lower()
178-
extensions = self.types_map_inv[True].get(type, [])
178+
extensions = list(self.types_map_inv[True].get(type, []))
179179
if not strict:
180180
for ext in self.types_map_inv[False].get(type, []):
181181
if ext not in extensions:

Lib/test/test_mimetypes.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,29 @@ def test_filename_with_url_delimiters(self):
113113
eq(self.db.guess_type(r" \"\`;b&b&c |.tar.gz"), gzip_expected)
114114

115115
def test_guess_all_types(self):
116-
eq = self.assertEqual
117-
unless = self.assertTrue
118116
# First try strict. Use a set here for testing the results because if
119117
# test_urllib2 is run before test_mimetypes, global state is modified
120118
# such that the 'all' set will have more items in it.
121-
all = set(self.db.guess_all_extensions('text/plain', strict=True))
122-
unless(all >= set(['.bat', '.c', '.h', '.ksh', '.pl', '.txt']))
119+
all = self.db.guess_all_extensions('text/plain', strict=True)
120+
self.assertTrue(set(all) >= {'.bat', '.c', '.h', '.ksh', '.pl', '.txt'})
121+
self.assertEqual(len(set(all)), len(all)) # no duplicates
123122
# And now non-strict
124123
all = self.db.guess_all_extensions('image/jpg', strict=False)
125-
all.sort()
126-
eq(all, ['.jpg'])
124+
self.assertEqual(all, ['.jpg'])
127125
# And now for no hits
128126
all = self.db.guess_all_extensions('image/jpg', strict=True)
129-
eq(all, [])
127+
self.assertEqual(all, [])
128+
# And now for type existing in both strict and non-strict mappings.
129+
self.db.add_type('test-type', '.strict-ext')
130+
self.db.add_type('test-type', '.non-strict-ext', strict=False)
131+
all = self.db.guess_all_extensions('test-type', strict=False)
132+
self.assertEqual(all, ['.strict-ext', '.non-strict-ext'])
133+
all = self.db.guess_all_extensions('test-type')
134+
self.assertEqual(all, ['.strict-ext'])
135+
# Test that changing the result list does not affect the global state
136+
all.append('.no-such-ext')
137+
all = self.db.guess_all_extensions('test-type')
138+
self.assertNotIn('.no-such-ext', all)
130139

131140
def test_encoding(self):
132141
getpreferredencoding = locale.getpreferredencoding
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Calling :func:`mimetypes.guess_all_extensions` with ``strict=False`` no
2+
longer affects the result of the following call with ``strict=True``.
3+
Also, mutating the returned list no longer affects the global state.

0 commit comments

Comments
 (0)
0