Skip to content

Commit

Permalink
Fix safe_join to handle trailing slash with intermediate paths (#341)
Browse files Browse the repository at this point in the history
Regression introduced in 895a068

Partially reverts 39a2a7a
  • Loading branch information
jdufresne authored and jschneier committed Jun 22, 2017
1 parent 39f9b80 commit 112ae43
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
django-storages change log
==========================

1.6.2 (UNRELEASED)
******************

* Fix regression in ``safe_join()`` to handle a trailing slash in an
intermediate path.

1.6.1 (2017-06-22)
******************

Expand Down
15 changes: 10 additions & 5 deletions storages/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,16 @@ def safe_join(base, *paths):
"""
base_path = force_text(base)
base_path = base_path.rstrip('/')
paths = [base_path + '/'] + [force_text(p) for p in paths if p]

final_path = posixpath.normpath(posixpath.join(*paths))
# posixpath.normpath() strips the trailing /. Add it back.
if paths[-1].endswith('/'):
paths = [force_text(p) for p in paths]

final_path = base_path + '/'
for path in paths:
_final_path = posixpath.normpath(posixpath.join(final_path, path))
# posixpath.normpath() strips the trailing /. Add it back.
if path.endswith('/') or _final_path + '/' == final_path:
_final_path += '/'
final_path = _final_path
if final_path == base_path:
final_path += '/'

# Ensure final_path starts with base_path and that the next character after
Expand Down
20 changes: 20 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ def test_with_dot(self):
".", "to/./somewhere")
self.assertEqual(path, "path/to/somewhere")

def test_with_only_dot(self):
path = utils.safe_join("", ".")
self.assertEqual(path, "")

def test_base_url(self):
path = utils.safe_join("base_url", "path/to/somewhere")
self.assertEqual(path, "base_url/path/to/somewhere")
Expand Down Expand Up @@ -95,3 +99,19 @@ def test_datetime_isoformat(self):
def test_join_empty_string(self):
path = utils.safe_join('base_url', '')
self.assertEqual(path, 'base_url/')

def test_with_base_url_and_dot(self):
path = utils.safe_join('base_url', '.')
self.assertEqual(path, 'base_url/')

def test_with_base_url_and_dot_and_path_and_slash(self):
path = utils.safe_join('base_url', '.', 'path/to/', '.')
self.assertEqual(path, 'base_url/path/to/')

def test_join_nothing(self):
path = utils.safe_join('')
self.assertEqual(path, '')

def test_with_base_url_join_nothing(self):
path = utils.safe_join('base_url')
self.assertEqual(path, 'base_url/')

0 comments on commit 112ae43

Please sign in to comment.