Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Lib/encodings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from . import aliases

_cache = {}
_MAXCACHE = 500
_unknown = '--unknown--'
_import_tail = ['*']
_aliases = aliases.aliases
Expand Down Expand Up @@ -115,6 +116,8 @@ def search_function(encoding):

if mod is None:
# Cache misses
if len(_cache) >= _MAXCACHE:
_cache.clear()
_cache[encoding] = None
return None

Expand All @@ -136,6 +139,8 @@ def search_function(encoding):
entry = codecs.CodecInfo(*entry)

# Cache the codec registry entry
if len(_cache) >= _MAXCACHE:
_cache.clear()
_cache[encoding] = entry

# Register its aliases (without overwriting previously registered
Expand Down
11 changes: 11 additions & 0 deletions Lib/test/test_codecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3907,5 +3907,16 @@ def test_encodings_normalize_encoding(self):
self.assertEqual(normalize('utf...8'), 'utf...8')


class CodecCacheTest(unittest.TestCase):
def test_cache_bounded(self):
for i in range(encodings._MAXCACHE + 1000):
try:
b'x'.decode(f'nonexist_{i}')
except LookupError:
pass

self.assertLessEqual(len(encodings._cache), encodings._MAXCACHE)


if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Limit the size of :func:`encodings.search_function` cache.
Found by OSS Fuzz in :oss-fuzz:`493449985`.
Loading