diff --git a/jupyter_server/services/contents/fileio.py b/jupyter_server/services/contents/fileio.py index 5799b57497..6afe6b6524 100644 --- a/jupyter_server/services/contents/fileio.py +++ b/jupyter_server/services/contents/fileio.py @@ -39,6 +39,12 @@ def copy2_safe(src, dst, log=None): like shutil.copy2, but log errors in copystat instead of raising """ + # if src file is not writable, avoid creating a back-up + if not os.access(src, os.W_OK): + if log: + log.debug("Source file, %s, is not writable", src, exc_info=True) + raise PermissionError(errno.EACCES, f"File is not writable: {src}") + shutil.copyfile(src, dst) try: shutil.copystat(src, dst) @@ -52,6 +58,11 @@ async def async_copy2_safe(src, dst, log=None): like shutil.copy2, but log errors in copystat instead of raising """ + if not os.access(src, os.W_OK): + if log: + log.debug("Source file, %s, is not writable", src, exc_info=True) + raise PermissionError(errno.EACCES, f"File is not writable: {src}") + await run_sync(shutil.copyfile, src, dst) try: await run_sync(shutil.copystat, src, dst)