mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 17:12:13 -06:00
unlink files before replacing them
to avoid hardlink-related surprises
This commit is contained in:
parent
1088e8c6a5
commit
8b62aa7cc7
|
@ -1393,25 +1393,6 @@ class HttpCli(object):
|
||||||
|
|
||||||
path = os.path.join(fdir, fn)
|
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:
|
if xbu:
|
||||||
at = time.time() - lifetime
|
at = time.time() - lifetime
|
||||||
if not runhook(
|
if not runhook(
|
||||||
|
@ -1430,6 +1411,26 @@ class HttpCli(object):
|
||||||
self.log(t, 1)
|
self.log(t, 1)
|
||||||
raise Pebkac(403, t)
|
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:
|
with ren_open(fn, *open_a, **params) as zfw:
|
||||||
f, fn = zfw["orz"]
|
f, fn = zfw["orz"]
|
||||||
path = os.path.join(fdir, fn)
|
path = os.path.join(fdir, fn)
|
||||||
|
@ -2300,7 +2301,7 @@ class HttpCli(object):
|
||||||
raise Pebkac(400, "could not read lastmod from request")
|
raise Pebkac(400, "could not read lastmod from request")
|
||||||
|
|
||||||
nullwrite = self.args.nw
|
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)
|
self._assert_safe_rem(rem)
|
||||||
|
|
||||||
clen = int(self.headers.get("content-length", -1))
|
clen = int(self.headers.get("content-length", -1))
|
||||||
|
@ -2382,6 +2383,9 @@ class HttpCli(object):
|
||||||
if p_field != "body":
|
if p_field != "body":
|
||||||
raise Pebkac(400, "expected body, got {}".format(p_field))
|
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:
|
with open(fsenc(fp), "wb", 512 * 1024) as f:
|
||||||
sz, sha512, _ = hashcopy(p_data, f, self.args.s_wr_slp)
|
sz, sha512, _ = hashcopy(p_data, f, self.args.s_wr_slp)
|
||||||
|
|
||||||
|
|
|
@ -1153,20 +1153,12 @@ def ren_open(
|
||||||
fun = kwargs.pop("fun", open)
|
fun = kwargs.pop("fun", open)
|
||||||
fdir = kwargs.pop("fdir", None)
|
fdir = kwargs.pop("fdir", None)
|
||||||
suffix = kwargs.pop("suffix", None)
|
suffix = kwargs.pop("suffix", None)
|
||||||
overwrite = kwargs.pop("overwrite", None)
|
|
||||||
|
|
||||||
if fname == os.devnull:
|
if fname == os.devnull:
|
||||||
with fun(fname, *args, **kwargs) as f:
|
with fun(fname, *args, **kwargs) as f:
|
||||||
yield {"orz": (f, fname)}
|
yield {"orz": (f, fname)}
|
||||||
return
|
return
|
||||||
|
|
||||||
if overwrite:
|
|
||||||
assert fdir
|
|
||||||
fpath = os.path.join(fdir, fname)
|
|
||||||
with fun(fsenc(fpath), *args, **kwargs) as f:
|
|
||||||
yield {"orz": (f, fname)}
|
|
||||||
return
|
|
||||||
|
|
||||||
if suffix:
|
if suffix:
|
||||||
ext = fname.split(".")[-1]
|
ext = fname.split(".")[-1]
|
||||||
if len(ext) < 7:
|
if len(ext) < 7:
|
||||||
|
|
Loading…
Reference in a new issue