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):