mirror of
https://github.com/9001/copyparty.git
synced 2026-03-27 10:33:11 +10:00
unlink files before replacing them
to avoid hardlink-related surprises
This commit is contained in:
@@ -1393,25 +1393,6 @@ class HttpCli(object):
|
||||
|
||||
path = os.path.join(fdir, fn)
|
||||
|
||||
if is_put and not self.args.no_dav:
|
||||
# allow overwrite if...
|
||||
# * volflag 'daw' is set
|
||||
# * and account has delete-access
|
||||
# or...
|
||||
# * file exists and is empty
|
||||
# * and there is no .PARTIAL
|
||||
|
||||
tnam = fn + ".PARTIAL"
|
||||
if self.args.dotpart:
|
||||
tnam = "." + tnam
|
||||
|
||||
if (vfs.flags.get("daw") and self.can_delete) or (
|
||||
not bos.path.exists(os.path.join(fdir, tnam))
|
||||
and bos.path.exists(path)
|
||||
and not bos.path.getsize(path)
|
||||
):
|
||||
params["overwrite"] = "a"
|
||||
|
||||
if xbu:
|
||||
at = time.time() - lifetime
|
||||
if not runhook(
|
||||
@@ -1430,6 +1411,26 @@ class HttpCli(object):
|
||||
self.log(t, 1)
|
||||
raise Pebkac(403, t)
|
||||
|
||||
if is_put and not self.args.no_dav:
|
||||
# allow overwrite if...
|
||||
# * volflag 'daw' is set
|
||||
# * and account has delete-access
|
||||
# or...
|
||||
# * file exists and is empty
|
||||
# * and there is no .PARTIAL
|
||||
|
||||
tnam = fn + ".PARTIAL"
|
||||
if self.args.dotpart:
|
||||
tnam = "." + tnam
|
||||
|
||||
if (vfs.flags.get("daw") and self.can_delete) or (
|
||||
not bos.path.exists(os.path.join(fdir, tnam))
|
||||
and bos.path.exists(path)
|
||||
and not bos.path.getsize(path)
|
||||
):
|
||||
# small toctou, but better than clobbering a hardlink
|
||||
bos.unlink(path)
|
||||
|
||||
with ren_open(fn, *open_a, **params) as zfw:
|
||||
f, fn = zfw["orz"]
|
||||
path = os.path.join(fdir, fn)
|
||||
@@ -2300,7 +2301,7 @@ class HttpCli(object):
|
||||
raise Pebkac(400, "could not read lastmod from request")
|
||||
|
||||
nullwrite = self.args.nw
|
||||
vfs, rem = self.asrv.vfs.get(self.vpath, self.uname, False, True)
|
||||
vfs, rem = self.asrv.vfs.get(self.vpath, self.uname, True, True)
|
||||
self._assert_safe_rem(rem)
|
||||
|
||||
clen = int(self.headers.get("content-length", -1))
|
||||
@@ -2382,6 +2383,9 @@ class HttpCli(object):
|
||||
if p_field != "body":
|
||||
raise Pebkac(400, "expected body, got {}".format(p_field))
|
||||
|
||||
if bos.path.exists(fp):
|
||||
bos.unlink(fp)
|
||||
|
||||
with open(fsenc(fp), "wb", 512 * 1024) as f:
|
||||
sz, sha512, _ = hashcopy(p_data, f, self.args.s_wr_slp)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user