Skip to content

Commit 9d7621b

Browse files
gh-146054: Limit the growth of encodings.search_function cache (GH-146055)
1 parent 99e2c5e commit 9d7621b

File tree

3 files changed

+18
-0
lines changed

3 files changed

+18
-0
lines changed

Lib/encodings/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from . import aliases
3535

3636
_cache = {}
37+
_MAXCACHE = 500
3738
_unknown = '--unknown--'
3839
_import_tail = ['*']
3940
_aliases = aliases.aliases
@@ -111,6 +112,8 @@ def search_function(encoding):
111112

112113
if mod is None:
113114
# Cache misses
115+
if len(_cache) >= _MAXCACHE:
116+
_cache.clear()
114117
_cache[encoding] = None
115118
return None
116119

@@ -132,6 +135,8 @@ def search_function(encoding):
132135
entry = codecs.CodecInfo(*entry)
133136

134137
# Cache the codec registry entry
138+
if len(_cache) >= _MAXCACHE:
139+
_cache.clear()
135140
_cache[encoding] = entry
136141

137142
# Register its aliases (without overwriting previously registered

Lib/test/test_codecs.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3908,5 +3908,16 @@ def test_encodings_normalize_encoding(self):
39083908
self.assertEqual(normalize('utf\xE9\u20AC\U0010ffff-8'), 'utf_8')
39093909

39103910

3911+
class CodecCacheTest(unittest.TestCase):
3912+
def test_cache_bounded(self):
3913+
for i in range(encodings._MAXCACHE + 1000):
3914+
try:
3915+
b'x'.decode(f'nonexist_{i}')
3916+
except LookupError:
3917+
pass
3918+
3919+
self.assertLessEqual(len(encodings._cache), encodings._MAXCACHE)
3920+
3921+
39113922
if __name__ == "__main__":
39123923
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Limit the size of :func:`encodings.search_function` cache.
2+
Found by OSS Fuzz in :oss-fuzz:`493449985`.

0 commit comments

Comments
 (0)