diff options
author | btimby <btimby@67cdc799-7952-0410-af00-57a81ceafa0f> | 2012-04-20 19:17:32 +0000 |
---|---|---|
committer | btimby <btimby@67cdc799-7952-0410-af00-57a81ceafa0f> | 2012-04-20 19:17:32 +0000 |
commit | 083d6f32ca749a68541e54c86d95582a3ed46377 (patch) | |
tree | 47a414710dbdf1a07144f4f025a5b234acb574fb | |
parent | d04d263597a8f2c19e3ab7dcc7374704ed1d2ac4 (diff) | |
download | pyfilesystem-083d6f32ca749a68541e54c86d95582a3ed46377.tar.gz |
Use explicit exception to detect invalid path (BackReferenceError), see comments on r773
git-svn-id: http://pyfilesystem.googlecode.com/svn/trunk@775 67cdc799-7952-0410-af00-57a81ceafa0f
-rw-r--r-- | fs/errors.py | 5 | ||||
-rw-r--r-- | fs/expose/sftp.py | 6 | ||||
-rw-r--r-- | fs/path.py | 20 |
3 files changed, 19 insertions, 12 deletions
diff --git a/fs/errors.py b/fs/errors.py index 38cb4b7..93f8905 100644 --- a/fs/errors.py +++ b/fs/errors.py @@ -188,6 +188,11 @@ class NoMMapError(ResourceError): default_message = "Can't get mmap for %(path)s" +class BackReferenceError(FSError, ValueError): + """Exception raised when too many backrefs exist in a path (ex: '/..', '/docs/../..').""" + default_message = "Too many backrefs in '%(path)s'" + + def convert_fs_errors(func): """Function wrapper to convert FSError instances into OSError.""" @wraps(func) diff --git a/fs/expose/sftp.py b/fs/expose/sftp.py index a5bf9f9..7abd359 100644 --- a/fs/expose/sftp.py +++ b/fs/expose/sftp.py @@ -185,12 +185,10 @@ class SFTPServerInterface(paramiko.SFTPServerInterface): def canonicalize(self, path): try: return abspath(normpath(path)).encode(self.encoding) - except ValueError, e: + except BackReferenceError: # If the client tries to use backrefs to escape root, gently # nudge them back to /. - if 'too many backrefs' in e.args[0]: - return '/' - raise + return '/' @report_sftp_errors def chattr(self, path, attr): @@ -33,31 +33,34 @@ def normpath(path): >>> normpath("foo/../../bar") Traceback (most recent call last) ... - ValueError: too many backrefs in path 'foo/../../bar' + BackReferenceError: Too many backrefs in 'foo/../../bar' """ - + if path in ('', '/'): return path - + path = path.replace('\\', '/') - + # An early out if there is no need to normalize this path if not _requires_normalization(path): return path.rstrip('/') - + components = [] append = components.append special = ('..', '.', '').__contains__ try: for component in path.split('/'): if special(component): - if component == '..': + if component == '..': components.pop() else: append(component) except IndexError: - raise ValueError("too many backrefs in path '%s'" % path) + # Imported here because errors imports this module (path), + # causing a circular import. + from fs.errors import BackReferenceError + BackReferenceError(details={ 'path': path }) if path[0] == '/': return '/%s' % '/'.join(components) return '/'.join(components) @@ -77,7 +80,8 @@ def iteratepath(path, numsplits=None): return path.split('/') else: return path.split('/', numsplits) - + + def recursepath(path, reverse=False): """Returns intermediate paths from the root to the given path |