Skip to content

Commit

Permalink
Run locale identifiers through os.path.basename()
Browse files Browse the repository at this point in the history
  • Loading branch information
akx committed Apr 28, 2021
1 parent 5afe2b2 commit 3a700b5
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
2 changes: 2 additions & 0 deletions babel/localedata.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def exists(name):
"""
if not name or not isinstance(name, string_types):
return False
name = os.path.basename(name)
if name in _cache:
return True
file_found = os.path.exists(os.path.join(_dirname, '%s.dat' % name))
Expand Down Expand Up @@ -102,6 +103,7 @@ def load(name, merge_inherited=True):
:raise `IOError`: if no locale data file is found for the given locale
identifer, or one of the locales it inherits from
"""
name = os.path.basename(name)
_cache_lock.acquire()
try:
data = _cache.get(name)
Expand Down
30 changes: 29 additions & 1 deletion tests/test_localedata.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://babel.edgewall.org/log/.

import os
import pickle
import sys
import tempfile
import unittest
import random
from operator import methodcaller

from babel import localedata
import pytest

from babel import localedata, Locale, UnknownLocaleError


class MergeResolveTestCase(unittest.TestCase):
Expand Down Expand Up @@ -131,3 +137,25 @@ def listdir_spy(*args):
localedata.locale_identifiers.cache = None
assert localedata.locale_identifiers()
assert len(listdir_calls) == 2


def test_locale_name_cleanup():
"""
Test that locale identifiers are cleaned up to avoid directory traversal.
"""
no_exist_name = os.path.join(tempfile.gettempdir(), "babel%d.dat" % random.randint(1, 99999))
with open(no_exist_name, "wb") as f:
pickle.dump({}, f)

try:
name = os.path.splitext(os.path.relpath(no_exist_name, localedata._dirname))[0]
except ValueError:
if sys.platform == "win32":
pytest.skip("unable to form relpath")
raise

assert not localedata.exists(name)
with pytest.raises(IOError):
localedata.load(name)
with pytest.raises(UnknownLocaleError):
Locale(name)

0 comments on commit 3a700b5

Please sign in to comment.