Blob Blame History Raw
diff --git a/babel/localedata.py b/babel/localedata.py
index 9308b5e..688af79 100644
--- a/babel/localedata.py
+++ b/babel/localedata.py
@@ -18,6 +18,9 @@
 """
 
 import os
+import re
+import sys
+
 import pickle
 try:
     import threading
@@ -31,7 +34,23 @@ __docformat__ = 'restructuredtext en'
 _cache = {}
 _cache_lock = threading.RLock()
 _dirname = os.path.join(os.path.dirname(__file__), 'localedata')
+_windows_reserved_name_re = re.compile("^(con|prn|aux|nul|com[0-9]|lpt[0-9])$", re.I)
+
+
+def resolve_locale_filename(name):
+    """
+    Resolve a locale identifier to a `.dat` path on disk.
+    """
+
+    # Clean up any possible relative paths.
+    name = os.path.basename(name)
+
+    # Ensure we're not left with one of the Windows reserved names.
+    if sys.platform == "win32" and _windows_reserved_name_re.match(os.path.splitext(name)[0]):
+        raise ValueError("Name %s is invalid on Windows" % name)
 
+    # Build the path.
+    return os.path.join(_dirname, '%s.dat' % name)
 
 def exists(name):
     """Check whether locale data is available for the given locale.
@@ -42,7 +61,7 @@ def exists(name):
     """
     if name in _cache:
         return True
-    return os.path.exists(os.path.join(_dirname, '%s.dat' % name))
+    return os.path.exists(resolve_locale_filename(name))
 
 
 def list():
@@ -85,6 +104,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)
@@ -99,7 +119,7 @@ def load(name, merge_inherited=True):
                 else:
                     parent = '_'.join(parts[:-1])
                 data = load(parent).copy()
-            filename = os.path.join(_dirname, '%s.dat' % name)
+            filename = resolve_locale_filename(name)
             fileobj = open(filename, 'rb')
             try:
                 if name != 'root' and merge_inherited: