
Here's this, which IIRC I never wrote tests for, which is what needs to be done to specify the correct behavior: ```python def pathjoin(*args, **kwargs): """ Arguments: args (list): *args list of paths if len(args) == 1, args[0] is not a string, and args[0] is iterable, set args to args[0]. Basically:: joined_path = u'/'.join( [args[0].rstrip('/')] + [a.strip('/') for a in args[1:-1]] + [args[-1].lstrip('/')]) """ log.debug('pathjoin: %r' % list(args)) def _pathjoin(*args, **kwargs): len_ = len(args) - 1 if len_ < 0: raise Exception('no args specified') elif len_ == 0: if not isinstance(args, basestring): if hasattr(args, '__iter__'): _args = args _args args = args[0] for i, arg in enumerate(args): if not i: yield arg.rstrip('/') elif i == len_: yield arg.lstrip('/') else: yield arg.strip('/') joined_path = u'/'.join(_pathjoin(*args)) return sanitize_path(joined_path) def sanitize_path(path): # XXX TODO FIXME if '/../' in path: raise Exception() return path ``` https://github.com/westurner/pgs/blob/master/pgs/app.py#L60-L95 On Mon, Jun 28, 2021, 04:09 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> wrote:
On Sun, Jun 27, 2021 at 09:55:34PM -0400, Wes Turner wrote:
"[Python-ideas] Sanitize filename (path part) 2nd try"
https://mail.python.org/archives/list/python-ideas@python.org/thread/LRIKMG3...
"[Python-ideas] Sanitize filename (path part)"
https://mail.python.org/archives/list/python-ideas@python.org/thread/SQH4LPE...
```quote What does sanitizepart do with a leading slash?
assert os.path.join("a", "/b") == "/b"
A new safejoin() or joinsafe() or join(safe='True') could call sanitizepart() such that:
assert joinsafe("a\n", "/b") == "a\n/b" ```
Thanks for the links. "sanitizepart()" seems to be about *constructing* a safe filename. It's a different problem and there's a thousand ways to do it.
I think the idea with joinsafe() is similar to my idea... But I think the req to disallow '..' is crucial. If we set the requirements as:
1. the resulting path must not be above the lhs arg 2. the operation must be done without actually accessing the fs
right now I see the proposed operation that rejects '..' as the best approach.
Zbyszek