diff --git a/copyparty/broker_util.py b/copyparty/broker_util.py index 3406dc91..527ecc7b 100644 --- a/copyparty/broker_util.py +++ b/copyparty/broker_util.py @@ -4,7 +4,6 @@ from __future__ import print_function, unicode_literals import traceback -from .__init__ import PY2 from .util import Pebkac, Queue diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index ae443063..0de326c3 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -420,9 +420,11 @@ class HttpCli(object): vfs, rem = self.conn.auth.vfs.get(self.vpath, self.uname, False, True) self._assert_safe_rem(rem) + sanitized = sanitize_fn(new_dir) + if not nullwrite: fdir = os.path.join(vfs.realpath, rem) - fn = os.path.join(fdir, sanitize_fn(new_dir)) + fn = os.path.join(fdir, sanitized) if not os.path.isdir(fsenc(fdir)): raise Pebkac(500, "parent folder does not exist") @@ -435,7 +437,7 @@ class HttpCli(object): except: raise Pebkac(500, "mkdir failed, check the logs") - vpath = "{}/{}".format(self.vpath, new_dir).lstrip("/") + vpath = "{}/{}".format(self.vpath, sanitized).lstrip("/") html = self.conn.tpl_msg.render( h2='go to /{}'.format( quotep(vpath), html_escape(vpath, quote=False) @@ -457,9 +459,11 @@ class HttpCli(object): if not new_file.endswith(".md"): new_file += ".md" + sanitized = sanitize_fn(new_file) + if not nullwrite: fdir = os.path.join(vfs.realpath, rem) - fn = os.path.join(fdir, sanitize_fn(new_file)) + fn = os.path.join(fdir, sanitized) if os.path.exists(fsenc(fn)): raise Pebkac(500, "that file exists already") @@ -467,7 +471,7 @@ class HttpCli(object): with open(fsenc(fn), "wb") as f: f.write(b"`GRUNNUR`\n") - vpath = "{}/{}".format(self.vpath, new_file).lstrip("/") + vpath = "{}/{}".format(self.vpath, sanitized).lstrip("/") html = self.conn.tpl_msg.render( h2='go to /{}?edit'.format( quotep(vpath), html_escape(vpath, quote=False) diff --git a/copyparty/tcpsrv.py b/copyparty/tcpsrv.py index 035559fd..5c6c0e69 100644 --- a/copyparty/tcpsrv.py +++ b/copyparty/tcpsrv.py @@ -24,7 +24,7 @@ class TcpSrv(object): ip = "127.0.0.1" eps = {ip: "local only"} if self.args.i != ip: - eps = self.detect_interfaces(self.args.i) or eps + eps = self.detect_interfaces(self.args.i) or {self.args.i: "external"} for ip, desc in sorted(eps.items(), key=lambda x: x[1]): self.log( diff --git a/copyparty/up2k.py b/copyparty/up2k.py index 4c8ac4fe..b3dc1271 100644 --- a/copyparty/up2k.py +++ b/copyparty/up2k.py @@ -13,7 +13,7 @@ import threading from copy import deepcopy from .__init__ import WINDOWS -from .util import Pebkac, Queue, fsenc +from .util import Pebkac, Queue, fsenc, sanitize_fn class Up2k(object): @@ -48,6 +48,7 @@ class Up2k(object): self.r_hash = re.compile("^[0-9a-zA-Z_-]{43}$") def handle_json(self, cj): + cj["name"] = sanitize_fn(cj["name"]) wark = self._get_wark(cj) now = time.time() with self.mutex: diff --git a/copyparty/util.py b/copyparty/util.py index 54ad6a21..854f5b8e 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -356,7 +356,30 @@ def undot(path): def sanitize_fn(fn): - return fn.replace("\\", "/").split("/")[-1].strip() + fn = fn.replace("\\", "/").split("/")[-1] + + if WINDOWS: + for bad, good in [ + ["<", "<"], + [">", ">"], + [":", ":"], + ['"', """], + ["/", "/"], + ["\\", "\"], + ["|", "|"], + ["?", "?"], + ["*", "*"], + ]: + fn = fn.replace(bad, good) + + bad = ["con", "prn", "aux", "nul"] + for n in range(1, 10): + bad += "com{0} lpt{0}".format(n).split(" ") + + if fn.lower() in bad: + fn = "_" + fn + + return fn.strip() def exclude_dotfiles(filepaths):