app/django/utils/_os.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
     1 from os.path import join, normcase, abspath, sep
     1 from os.path import join, normcase, abspath, sep
       
     2 from django.utils.encoding import force_unicode
     2 
     3 
     3 def safe_join(base, *paths):
     4 def safe_join(base, *paths):
     4     """
     5     """
     5     Joins one or more path components to the base path component intelligently.
     6     Joins one or more path components to the base path component intelligently.
     6     Returns a normalized, absolute version of the final path.
     7     Returns a normalized, absolute version of the final path.
     8     The final path must be located inside of the base path component (otherwise
     9     The final path must be located inside of the base path component (otherwise
     9     a ValueError is raised).
    10     a ValueError is raised).
    10     """
    11     """
    11     # We need to use normcase to ensure we don't false-negative on case
    12     # We need to use normcase to ensure we don't false-negative on case
    12     # insensitive operating systems (like Windows).
    13     # insensitive operating systems (like Windows).
       
    14     base = force_unicode(base)
       
    15     paths = [force_unicode(p) for p in paths]
    13     final_path = normcase(abspath(join(base, *paths)))
    16     final_path = normcase(abspath(join(base, *paths)))
    14     base_path = normcase(abspath(base))
    17     base_path = normcase(abspath(base))
    15     base_path_len = len(base_path)
    18     base_path_len = len(base_path)
    16     # Ensure final_path starts with base_path and that the next character after
    19     # Ensure final_path starts with base_path and that the next character after
    17     # the final path is os.sep (or nothing, in which case final_path must be
    20     # the final path is os.sep (or nothing, in which case final_path must be