Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
6 changes: 5 additions & 1 deletion Lib/encodings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from . import aliases

_cache = {}
_MAXCACHE = 500
_unknown = '--unknown--'
_import_tail = ['*']
_aliases = aliases.aliases
Expand Down Expand Up @@ -110,7 +111,8 @@ def search_function(encoding):
mod = None

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

Expand All @@ -132,6 +134,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 @@ -3908,5 +3908,16 @@ def test_encodings_normalize_encoding(self):
self.assertEqual(normalize('utf\xE9\u20AC\U0010ffff-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