Commit 955db220 authored by Michael Albinus's avatar Michael Albinus

Check directory in Tramp's {copy,rename}-file

* lisp/net/tramp-adb.el (tramp-adb-handle-copy-file)
(tramp-adb-handle-rename-file):
* lisp/net/tramp-gvfs.el (tramp-gvfs-do-copy-or-rename-file):
* lisp/net/tramp-rclone.el (tramp-rclone-do-copy-or-rename-file):
* lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file):
* lisp/net/tramp-smb.el (tramp-smb-handle-copy-file)
(tramp-smb-handle-rename-file):
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-do-copy-or-rename-file):
Check, that NEWNAME is not a directory given as file name.

* test/lisp/net/tramp-tests.el (tramp-test11-copy-file)
(tramp-test12-rename-file): Extend tests.
parent 9f769131
Pipeline #2381 failed with stage
in 90 minutes and 1 second
...@@ -709,15 +709,16 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ...@@ -709,15 +709,16 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(let ((t1 (tramp-tramp-file-p filename)) (let ((t1 (tramp-tramp-file-p filename))
(t2 (tramp-tramp-file-p newname))) (t2 (tramp-tramp-file-p newname)))
(with-parsed-tramp-file-name (if t1 filename newname) nil (with-parsed-tramp-file-name (if t1 filename newname) nil
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname) (not (directory-name-p newname)))
(tramp-error v 'file-error "File is a directory %s" newname))
(with-tramp-progress-reporter (with-tramp-progress-reporter
v 0 (format "Copying %s to %s" filename newname) v 0 (format "Copying %s to %s" filename newname)
(if (and t1 t2 (tramp-equal-remote filename newname)) (if (and t1 t2 (tramp-equal-remote filename newname))
(let ((l1 (tramp-compat-file-local-name filename)) (let ((l1 (tramp-compat-file-local-name filename))
(l2 (tramp-compat-file-local-name newname))) (l2 (tramp-compat-file-local-name newname)))
(when (and (not ok-if-already-exists)
(file-exists-p newname))
(tramp-error v 'file-already-exists newname))
;; We must also flush the cache of the directory, ;; We must also flush the cache of the directory,
;; because `file-attributes' reads the values from ;; because `file-attributes' reads the values from
;; there. ;; there.
...@@ -788,17 +789,18 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ...@@ -788,17 +789,18 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(let ((t1 (tramp-tramp-file-p filename)) (let ((t1 (tramp-tramp-file-p filename))
(t2 (tramp-tramp-file-p newname))) (t2 (tramp-tramp-file-p newname)))
(with-parsed-tramp-file-name (if t1 filename newname) nil (with-parsed-tramp-file-name (if t1 filename newname) nil
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname) (not (directory-name-p newname)))
(tramp-error v 'file-error "File is a directory %s" newname))
(with-tramp-progress-reporter (with-tramp-progress-reporter
v 0 (format "Renaming %s to %s" filename newname) v 0 (format "Renaming %s to %s" filename newname)
(if (and t1 t2 (if (and t1 t2
(tramp-equal-remote filename newname) (tramp-equal-remote filename newname)
(not (file-directory-p filename))) (not (file-directory-p filename)))
(let ((l1 (tramp-compat-file-local-name filename)) (let ((l1 (tramp-compat-file-local-name filename))
(l2 (tramp-compat-file-local-name newname))) (l2 (tramp-compat-file-local-name newname)))
(when (and (not ok-if-already-exists)
(file-exists-p newname))
(tramp-error v 'file-already-exists newname))
;; We must also flush the cache of the directory, because ;; We must also flush the cache of the directory, because
;; `file-attributes' reads the values from there. ;; `file-attributes' reads the values from there.
(tramp-flush-file-properties v (file-name-directory l1)) (tramp-flush-file-properties v (file-name-directory l1))
......
...@@ -765,6 +765,8 @@ file names." ...@@ -765,6 +765,8 @@ file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil (with-parsed-tramp-file-name (if t1 filename newname) nil
(when (and (not ok-if-already-exists) (file-exists-p newname)) (when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname)) (tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname) (not (directory-name-p newname)))
(tramp-error v 'file-error "File is a directory %s" newname))
(if (or (and equal-remote (if (or (and equal-remote
(tramp-get-connection-property v "direct-copy-failed" nil)) (tramp-get-connection-property v "direct-copy-failed" nil))
......
...@@ -215,6 +215,8 @@ file names." ...@@ -215,6 +215,8 @@ file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil (with-parsed-tramp-file-name (if t1 filename newname) nil
(when (and (not ok-if-already-exists) (file-exists-p newname)) (when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname)) (tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname) (not (directory-name-p newname)))
(tramp-error v 'file-error "File is a directory %s" newname))
(if (or (and t1 (not (tramp-rclone-file-name-p filename))) (if (or (and t1 (not (tramp-rclone-file-name-p filename)))
(and t2 (not (tramp-rclone-file-name-p newname)))) (and t2 (not (tramp-rclone-file-name-p newname))))
......
...@@ -1995,6 +1995,8 @@ file names." ...@@ -1995,6 +1995,8 @@ file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil (with-parsed-tramp-file-name (if t1 filename newname) nil
(when (and (not ok-if-already-exists) (file-exists-p newname)) (when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname)) (tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname) (not (directory-name-p newname)))
(tramp-error v 'file-error "File is a directory %s" newname))
(with-tramp-progress-reporter (with-tramp-progress-reporter
v 0 (format "%s %s to %s" v 0 (format "%s %s to %s"
......
...@@ -588,9 +588,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ...@@ -588,9 +588,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(expand-file-name (file-name-nondirectory filename) newname))) (expand-file-name (file-name-nondirectory filename) newname)))
(with-parsed-tramp-file-name newname nil (with-parsed-tramp-file-name newname nil
(when (and (not ok-if-already-exists) (when (and (not ok-if-already-exists) (file-exists-p newname))
(file-exists-p newname))
(tramp-error v 'file-already-exists newname)) (tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
(not (directory-name-p newname)))
(tramp-error v 'file-error "File is a directory %s" newname))
;; We must also flush the cache of the directory, because ;; We must also flush the cache of the directory, because
;; `file-attributes' reads the values from there. ;; `file-attributes' reads the values from there.
...@@ -1335,48 +1337,49 @@ component is used as the target of the symlink." ...@@ -1335,48 +1337,49 @@ component is used as the target of the symlink."
(setq filename (expand-file-name filename) (setq filename (expand-file-name filename)
newname (expand-file-name newname)) newname (expand-file-name newname))
(when (and (not ok-if-already-exists) (with-parsed-tramp-file-name
(file-exists-p newname)) (if (tramp-tramp-file-p filename) filename newname) nil
(tramp-error (when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-dissect-file-name (tramp-error v 'file-already-exists newname))
(if (tramp-tramp-file-p filename) filename newname)) (when (and (file-directory-p newname) (not (directory-name-p newname)))
'file-already-exists newname)) (tramp-error v 'file-error "File is a directory %s" newname))
(with-tramp-progress-reporter (with-tramp-progress-reporter
(tramp-dissect-file-name v 0 (format "Renaming %s to %s" filename newname)
(if (tramp-tramp-file-p filename) filename newname))
0 (format "Renaming %s to %s" filename newname) (if (and (not (file-exists-p newname))
(tramp-equal-remote filename newname)
(if (and (not (file-exists-p newname)) (string-equal
(tramp-equal-remote filename newname) (tramp-smb-get-share (tramp-dissect-file-name filename))
(string-equal (tramp-smb-get-share (tramp-dissect-file-name newname))))
(tramp-smb-get-share (tramp-dissect-file-name filename)) ;; We can rename directly.
(tramp-smb-get-share (tramp-dissect-file-name newname)))) (with-parsed-tramp-file-name filename v1
;; We can rename directly. (with-parsed-tramp-file-name newname v2
(with-parsed-tramp-file-name filename v1
(with-parsed-tramp-file-name newname v2 ;; We must also flush the cache of the directory, because
;; `file-attributes' reads the values from there.
;; We must also flush the cache of the directory, because (tramp-flush-file-properties
;; `file-attributes' reads the values from there. v1 (file-name-directory v1-localname))
(tramp-flush-file-properties v1 (file-name-directory v1-localname)) (tramp-flush-file-properties v1 v1-localname)
(tramp-flush-file-properties v1 v1-localname) (tramp-flush-file-properties
(tramp-flush-file-properties v2 (file-name-directory v2-localname)) v2 (file-name-directory v2-localname))
(tramp-flush-file-properties v2 v2-localname) (tramp-flush-file-properties v2 v2-localname)
(unless (tramp-smb-get-share v2) (unless (tramp-smb-get-share v2)
(tramp-error (tramp-error
v2 'file-error "Target `%s' must contain a share name" newname)) v2 'file-error
(unless (tramp-smb-send-command "Target `%s' must contain a share name" newname))
v2 (format "rename \"%s\" \"%s\"" (unless (tramp-smb-send-command
(tramp-smb-get-localname v1) v2 (format "rename \"%s\" \"%s\""
(tramp-smb-get-localname v2))) (tramp-smb-get-localname v1)
(tramp-error v2 'file-error "Cannot rename `%s'" filename)))) (tramp-smb-get-localname v2)))
(tramp-error v2 'file-error "Cannot rename `%s'" filename))))
;; We must rename via copy.
(copy-file ;; We must rename via copy.
filename newname ok-if-already-exists 'keep-time 'preserve-uid-gid) (copy-file
(if (file-directory-p filename) filename newname ok-if-already-exists 'keep-time 'preserve-uid-gid)
(delete-directory filename 'recursive) (if (file-directory-p filename)
(delete-file filename))))) (delete-directory filename 'recursive)
(delete-file filename))))))
(defun tramp-smb-action-set-acl (proc vec) (defun tramp-smb-action-set-acl (proc vec)
"Set ACL data." "Set ACL data."
......
...@@ -244,6 +244,8 @@ absolute file names." ...@@ -244,6 +244,8 @@ absolute file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil (with-parsed-tramp-file-name (if t1 filename newname) nil
(when (and (not ok-if-already-exists) (file-exists-p newname)) (when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname)) (tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname) (not (directory-name-p newname)))
(tramp-error v 'file-error "File is a directory %s" newname))
(if (or (and (file-remote-p filename) (not t1)) (if (or (and (file-remote-p filename) (not t1))
(and (file-remote-p newname) (not t2))) (and (file-remote-p newname) (not t2)))
......
...@@ -2394,7 +2394,10 @@ This checks also `file-name-as-directory', `file-name-directory', ...@@ -2394,7 +2394,10 @@ This checks also `file-name-as-directory', `file-name-directory',
(when (and (tramp--test-expensive-test) (tramp--test-emacs26-p)) (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p))
(should-error (should-error
(copy-file source target) (copy-file source target)
:type 'file-already-exists)) :type 'file-already-exists)
(should-error
(copy-file source target 'ok)
:type 'file-error))
(copy-file source (file-name-as-directory target)) (copy-file source (file-name-as-directory target))
(should (should
(file-exists-p (file-exists-p
...@@ -2508,7 +2511,10 @@ This checks also `file-name-as-directory', `file-name-directory', ...@@ -2508,7 +2511,10 @@ This checks also `file-name-as-directory', `file-name-directory',
(when (and (tramp--test-expensive-test) (tramp--test-emacs26-p)) (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p))
(should-error (should-error
(rename-file source target) (rename-file source target)
:type 'file-already-exists)) :type 'file-already-exists)
(should-error
(rename-file source target 'ok)
:type 'file-error))
(rename-file source (file-name-as-directory target)) (rename-file source (file-name-as-directory target))
(should-not (file-exists-p source)) (should-not (file-exists-p source))
(should (should
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment