From: Thierry Volpiatto <thierry.volpiatto@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 10489@debbugs.gnu.org, michael.albinus@gmx.de
Subject: bug#10489: 24.0.92; dired-do-copy may create infinite directory hierarchy
Date: Sat, 14 Jan 2012 11:25:16 +0100 [thread overview]
Message-ID: <87mx9q1sz7.fsf@gmail.com> (raw)
In-Reply-To: <83fwfik92e.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 14 Jan 2012 10:00:25 +0200")
[-- Attachment #1.1: Type: text/plain, Size: 2896 bytes --]
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Thierry Volpiatto <thierry.volpiatto@gmail.com>
>> Date: Fri, 13 Jan 2012 20:17:43 +0100
>> Cc: 10489@debbugs.gnu.org
>>
>> (defun dired-copy-file-recursive (from to ok-flag &optional
>> preserve-time top recursive)
>> - (let ((attrs (file-attributes from)))
>> + (let* ((case-fold-search t)
>> + (fromname (file-name-as-directory (file-truename from)))
>> + (destname (file-name-as-directory (file-truename to)))
>> + (rem-dirname (and (equal "sudo" (file-remote-p fromname 'method))
>> + (file-remote-p fromname 'localname)))
>> + (rem-newname (and (equal "sudo" (file-remote-p destname 'method))
>> + (file-remote-p destname 'localname)))
>> + (attrs (file-attributes from)))
>> + (when (equal (or rem-dirname fromname)
>> + (or rem-newname destname))
>> + (error "Can't copy directory `%s' on itself" from))
>
> Why is case-fold-search being unconditionally bound to t? I don't
> think this is TRT on case-sensitive filesystems. Am I missing
> something?
Ignore, it have no effect, I have changed that.
The last patch use this instead, which avoid duplication of code and is
more readable.
--8<---------------cut here---------------start------------->8---
(defun files-copyable-p (from to)
"Verify if file FROM is not the same than TO on this system."
(let* ((fromname (file-name-as-directory (file-truename from)))
(destname (file-name-as-directory (file-truename to)))
(rem-fromname (and (equal "sudo" (file-remote-p fromname 'method))
(string-match (system-name)
(file-remote-p fromname 'host))
(file-remote-p fromname 'localname)))
(rem-newname (and (equal "sudo" (file-remote-p destname 'method))
(string-match (system-name) (file-remote-p destname 'host))
(file-remote-p destname 'localname))))
(not (equal (or rem-fromname fromname)
(or rem-newname destname)))))
--8<---------------cut here---------------end--------------->8---
This work in these cases:
- usage on local filesystem.
- Copying from a remote filesystem on local filesystem.
- Copying from local filesystem to remote filesystem.
- Copying on a remote filesystem to same remote filesystem with same
method.
This may not work in these cases:
- copying from a remote filesystem to this same remote filesystem with a
different method. (Why one would do that?)
e.g /ssh:host:/foo => /scpc:host:/foo
- Others - please complete (Windows, other tramp use cases, etc...)
--
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997
[-- Attachment #1.2: patch-r118414 --]
[-- Type: application/octet-stream, Size: 7002 bytes --]
# HG changeset patch
# User Thierry Volpiatto <thierry.volpiatto@gmail.com>
# Date 1326536680 -3600
# Node ID b4330fbf1c358a96445d8780fd9eca7eb195d057
# Parent 2065b5b887c3bb946af6eefdc134759d0459876e
Bugfix bug#10489, dired-do-copy may create infinite directory hierarchy.
* lisp/dired-aux.el
* lisp/files.el
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1264,24 +1264,26 @@
(defun dired-copy-file-recursive (from to ok-flag &optional
preserve-time top recursive)
+ (unless (files-copyable-p from to)
+ (error "Can't copy directory `%s' on itself" from))
(let ((attrs (file-attributes from)))
(if (and recursive
- (eq t (car attrs))
- (or (eq recursive 'always)
- (yes-or-no-p (format "Recursive copies of %s? " from))))
- ;; This is a directory.
- (copy-directory from to preserve-time)
+ (eq t (car attrs))
+ (or (eq recursive 'always)
+ (yes-or-no-p (format "Recursive copies of %s? " from))))
+ ;; This is a directory.
+ (copy-directory from to preserve-time)
;; Not a directory.
(or top (dired-handle-overwrite to))
(condition-case err
- (if (stringp (car attrs))
- ;; It is a symlink
- (make-symbolic-link (car attrs) to ok-flag)
- (copy-file from to ok-flag preserve-time))
- (file-date-error
- (push (dired-make-relative from)
- dired-create-files-failures)
- (dired-log "Can't set date on %s:\n%s\n" from err))))))
+ (if (stringp (car attrs))
+ ;; It is a symlink
+ (make-symbolic-link (car attrs) to ok-flag)
+ (copy-file from to ok-flag preserve-time))
+ (file-date-error
+ (push (dired-make-relative from)
+ dired-create-files-failures)
+ (dired-log "Can't set date on %s:\n%s\n" from err))))))
;;;###autoload
(defun dired-rename-file (file newname ok-if-already-exists)
@@ -1402,7 +1404,7 @@
newfile's entry, or t to use the current marker character if the
old file was marked."
(let (dired-create-files-failures failures
- skipped (success-count 0) (total (length fn-list)))
+ skipped (success-count 0) (total (length fn-list)))
(let (to overwrite-query
overwrite-backup-query) ; for dired-handle-overwrite
(dolist (from fn-list)
@@ -1430,10 +1432,25 @@
(cond ((integerp marker-char) marker-char)
(marker-char (dired-file-marker from)) ; slow
(t nil))))
- (when (and (file-directory-p from)
- (file-directory-p to)
- (eq file-creator 'dired-copy-file))
- (setq to (file-name-directory to)))
+ ;; Handle the `dired-copy-file' file-creator specially
+ ;; When copying a directory to another directory or
+ ;; possibly to itself.
+ ;; (e.g "~/foo" => "~/test" or "~/foo" =>"~/foo")
+ ;; In this case the 'name-constructor' have set the destination
+ ;; 'to' to "~/test/foo" because the old
+ ;; emacs23 behavior of `copy-directory'
+ ;; was no not create the subdir and copy instead the contents only.
+ ;; With it's new behavior (similar to cp shell command) we don't
+ ;; need such a construction, so modify the destination 'to' to
+ ;; "~/test/" instead of "~/test/foo/".
+ ;; If from and to are the same directory do the same,
+ ;; the error will be handled by `dired-copy-file-recursive'.
+ (let ((destname (file-name-directory to)))
+ (when (and (file-directory-p from)
+ (or (not (files-copyable-p from destname))
+ (file-directory-p to))
+ (eq file-creator 'dired-copy-file))
+ (setq to (file-name-directory to))))
(condition-case err
(progn
(funcall file-creator from to dired-overwrite-confirmed)
@@ -1456,21 +1473,21 @@
(setq failures (nconc failures dired-create-files-failures))
(dired-log-summary
(format "%s failed for %d file%s in %d requests"
- operation (length failures)
- (dired-plural-s (length failures))
- total)
+ operation (length failures)
+ (dired-plural-s (length failures))
+ total)
failures))
(failures
(dired-log-summary
(format "%s failed for %d of %d file%s"
- operation (length failures)
- total (dired-plural-s total))
+ operation (length failures)
+ total (dired-plural-s total))
failures))
(skipped
(dired-log-summary
(format "%s: %d of %d file%s skipped"
- operation (length skipped) total
- (dired-plural-s total))
+ operation (length skipped) total
+ (dired-plural-s total))
skipped))
(t
(message "%s: %s file%s"
diff --git a/lisp/files.el b/lisp/files.el
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4902,6 +4902,21 @@
directory 'full directory-files-no-dot-files-regexp)))
(delete-directory-internal directory)))))
+(defun files-copyable-p (from to)
+ "Verify if file FROM is not the same than TO on this system."
+ (let* ((fromname (file-name-as-directory (file-truename from)))
+ (destname (file-name-as-directory (file-truename to)))
+ (rem-fromname (and (equal "sudo" (file-remote-p fromname 'method))
+ (string-match (system-name)
+ (file-remote-p fromname 'host))
+ (file-remote-p fromname 'localname)))
+ (rem-newname (and (equal "sudo" (file-remote-p destname 'method))
+ (string-match (system-name)
+ (file-remote-p destname 'host))
+ (file-remote-p destname 'localname))))
+ (not (equal (or rem-fromname fromname)
+ (or rem-newname destname)))))
+
(defun copy-directory (directory newname &optional keep-time parents copy-contents)
"Copy DIRECTORY to NEWNAME. Both args must be strings.
This function always sets the file modes of the output files to match
@@ -4928,10 +4943,12 @@
(format "Copy directory %s to: " dir)
default-directory default-directory nil nil)
current-prefix-arg t nil)))
+ (unless (files-copyable-p directory newname)
+ (error "Can't copy directory `%s' on itself" directory))
;; If default-directory is a remote directory, make sure we find its
;; copy-directory handler.
(let ((handler (or (find-file-name-handler directory 'copy-directory)
- (find-file-name-handler newname 'copy-directory))))
+ (find-file-name-handler newname 'copy-directory))))
(if handler
(funcall handler 'copy-directory directory newname keep-time parents)
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
next prev parent reply other threads:[~2012-01-14 10:25 UTC|newest]
Thread overview: 174+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-12 19:35 bug#10489: 24.0.92; dired-do-copy may create infinite directory hierarchy Michael Heerdegen
2012-01-12 21:33 ` Thierry Volpiatto
2012-01-13 7:23 ` Eli Zaretskii
2012-01-13 8:38 ` Thierry Volpiatto
2012-01-13 10:31 ` Eli Zaretskii
2012-01-13 11:19 ` Thierry Volpiatto
2012-01-13 12:01 ` Juanma Barranquero
2012-01-13 12:41 ` Eli Zaretskii
2012-01-13 13:01 ` Michael Albinus
2012-01-13 13:11 ` Juanma Barranquero
2012-01-13 13:13 ` Juanma Barranquero
2012-01-13 13:18 ` Juanma Barranquero
2012-01-13 13:32 ` Michael Albinus
2012-01-13 13:27 ` Stefan Monnier
2012-01-13 14:06 ` Thierry Volpiatto
2012-01-13 14:44 ` Michael Albinus
2012-01-13 15:13 ` Stefan Monnier
2012-01-13 15:17 ` Juanma Barranquero
2012-01-13 15:29 ` Michael Albinus
2012-01-13 16:59 ` Drew Adams
2012-01-13 9:38 ` Thierry Volpiatto
2012-01-13 9:49 ` Michael Albinus
2012-01-13 11:00 ` Thierry Volpiatto
2012-01-13 12:48 ` Michael Albinus
2012-01-13 13:55 ` Thierry Volpiatto
2012-01-13 14:14 ` Drew Adams
2012-01-13 15:06 ` Juanma Barranquero
2012-01-13 15:14 ` Michael Albinus
2012-01-13 18:43 ` Thierry Volpiatto
2012-01-13 18:57 ` Drew Adams
2012-01-13 19:11 ` Thierry Volpiatto
2012-01-13 19:21 ` Drew Adams
2012-01-13 19:35 ` Michael Albinus
2012-01-13 20:56 ` Drew Adams
2012-01-13 18:59 ` Thierry Volpiatto
2012-01-13 19:04 ` Michael Albinus
2012-01-13 19:17 ` Thierry Volpiatto
2012-01-14 8:00 ` Eli Zaretskii
2012-01-14 10:25 ` Thierry Volpiatto [this message]
2012-01-15 12:50 ` Michael Albinus
2012-01-15 17:20 ` Thierry Volpiatto
2012-01-15 17:31 ` Thierry Volpiatto
2012-01-15 18:24 ` Michael Albinus
2012-01-15 19:09 ` Thierry Volpiatto
2012-01-15 19:49 ` Michael Albinus
2012-01-15 21:01 ` Thierry Volpiatto
2012-01-16 8:58 ` Thierry Volpiatto
2012-01-16 13:56 ` Stefan Monnier
2012-01-16 14:13 ` Michael Albinus
2012-01-16 15:18 ` Stefan Monnier
2012-01-16 15:27 ` Michael Albinus
2012-01-16 21:40 ` Stefan Monnier
2012-02-21 16:53 ` Thierry Volpiatto
2012-02-21 17:59 ` Stefan Monnier
2012-02-21 19:46 ` Michael Albinus
2012-02-21 20:58 ` Thierry Volpiatto
2012-02-21 22:51 ` Stefan Monnier
2012-02-22 21:37 ` Thierry Volpiatto
2012-02-22 22:00 ` Stefan Monnier
2012-02-23 6:15 ` Thierry Volpiatto
2012-02-23 16:01 ` Thierry Volpiatto
2012-02-23 17:18 ` Stefan Monnier
2012-02-23 22:10 ` Thierry Volpiatto
2012-02-24 5:37 ` Thierry Volpiatto
2012-02-24 7:16 ` Thierry Volpiatto
2012-02-24 9:19 ` Eli Zaretskii
2012-02-24 9:49 ` Thierry Volpiatto
2012-02-24 12:18 ` Thierry Volpiatto
2012-02-24 12:54 ` Michael Albinus
2012-02-24 13:36 ` Thierry Volpiatto
2012-02-24 15:00 ` Michael Albinus
2012-02-24 14:33 ` Eli Zaretskii
2012-02-24 15:19 ` Michael Albinus
2012-02-24 19:42 ` Eli Zaretskii
2012-02-24 20:35 ` Michael Albinus
2012-02-25 6:21 ` Eli Zaretskii
2012-02-27 8:39 ` Michael Albinus
2012-02-27 17:40 ` Eli Zaretskii
2012-02-24 14:45 ` Thierry Volpiatto
2012-02-24 15:23 ` Michael Albinus
2012-02-24 14:39 ` Eli Zaretskii
2012-02-24 14:50 ` Thierry Volpiatto
2012-02-24 15:26 ` Michael Albinus
2012-02-24 15:52 ` Thierry Volpiatto
2012-02-24 16:17 ` Michael Albinus
2012-02-24 16:02 ` Thierry Volpiatto
2012-02-24 16:15 ` Drew Adams
2012-02-24 16:25 ` Michael Albinus
2012-02-24 16:42 ` Drew Adams
2012-02-24 17:04 ` Michael Albinus
2012-02-24 16:21 ` Michael Albinus
2012-02-24 17:23 ` Thierry Volpiatto
2012-02-24 18:43 ` Michael Albinus
2012-02-24 20:06 ` Thierry Volpiatto
2012-02-24 20:04 ` Eli Zaretskii
2012-02-24 20:33 ` Michael Albinus
2012-02-24 21:54 ` Thierry Volpiatto
2012-02-25 8:56 ` Michael Albinus
2012-02-25 9:08 ` Thierry Volpiatto
2012-02-26 9:48 ` Michael Albinus
2012-02-26 19:48 ` Thierry Volpiatto
2012-02-26 21:40 ` Stefan Monnier
2012-02-27 6:45 ` Thierry Volpiatto
2012-02-27 7:45 ` Stefan Monnier
2012-02-27 8:04 ` Thierry Volpiatto
2012-02-27 10:34 ` Stefan Monnier
2012-02-27 11:06 ` Thierry Volpiatto
2012-02-27 11:10 ` Michael Albinus
2012-02-27 11:34 ` Thierry Volpiatto
2012-02-27 13:24 ` Stefan Monnier
2012-02-27 14:59 ` Thierry Volpiatto
2012-02-27 17:38 ` Stefan Monnier
2012-02-27 18:34 ` Thierry Volpiatto
2012-02-27 19:08 ` Michael Albinus
2012-02-27 19:33 ` Thierry Volpiatto
2012-02-27 19:49 ` Michael Albinus
2012-02-27 21:58 ` Stefan Monnier
2012-02-27 22:11 ` Thierry Volpiatto
2012-02-28 6:12 ` Thierry Volpiatto
2012-02-28 7:14 ` Thierry Volpiatto
2012-02-28 7:34 ` Michael Albinus
2012-02-28 8:15 ` Thierry Volpiatto
2012-02-28 8:31 ` Michael Albinus
2012-02-28 9:34 ` Thierry Volpiatto
2012-02-28 10:15 ` Michael Albinus
2012-02-28 19:29 ` Stefan Monnier
2012-02-28 19:53 ` Michael Albinus
2012-02-29 2:01 ` Stefan Monnier
2012-02-29 11:04 ` Michael Albinus
2012-02-29 16:48 ` Stefan Monnier
2012-02-29 17:52 ` Thierry Volpiatto
2012-03-01 2:33 ` Stefan Monnier
2012-03-01 8:37 ` Michael Albinus
2012-02-27 10:40 ` Thierry Volpiatto
2012-02-27 11:03 ` Michael Albinus
2012-02-27 11:29 ` Thierry Volpiatto
2012-02-27 14:19 ` Drew Adams
2012-02-27 13:54 ` Chong Yidong
2012-02-27 15:15 ` Thierry Volpiatto
2012-02-25 7:05 ` Eli Zaretskii
2012-02-25 9:56 ` Stefan Monnier
2012-02-25 13:05 ` Michael Albinus
2012-02-25 15:36 ` Michael Albinus
2012-02-25 15:53 ` Thierry Volpiatto
2012-02-25 22:41 ` Stefan Monnier
2012-02-26 9:21 ` Michael Albinus
2012-02-26 21:38 ` Stefan Monnier
2012-02-27 8:19 ` Michael Albinus
2012-02-27 10:39 ` Stefan Monnier
2012-02-25 13:03 ` Michael Albinus
2012-02-25 14:35 ` Stefan Monnier
2012-02-25 14:56 ` Lennart Borgman
2012-02-21 19:43 ` Michael Albinus
2012-02-21 21:03 ` Thierry Volpiatto
2012-01-16 14:09 ` Andreas Schwab
2012-01-16 19:14 ` Thierry Volpiatto
2012-01-17 6:06 ` Thierry Volpiatto
2012-01-21 13:01 ` Thierry Volpiatto
2012-01-21 16:02 ` Thierry Volpiatto
2012-01-13 19:43 ` Stefan Monnier
2012-01-13 22:51 ` Michael Albinus
2012-01-14 1:55 ` Stefan Monnier
2012-01-14 8:59 ` Eli Zaretskii
2012-01-14 14:19 ` Stefan Monnier
2012-01-14 15:55 ` Eli Zaretskii
2012-01-15 5:59 ` Thierry Volpiatto
2012-01-15 12:40 ` Michael Albinus
2012-01-15 17:28 ` Thierry Volpiatto
2012-01-13 15:31 ` Drew Adams
2012-01-13 15:41 ` Eli Zaretskii
2012-01-13 16:56 ` Drew Adams
2012-01-15 18:42 ` Drew Adams
2012-01-13 10:32 ` Eli Zaretskii
2012-03-22 2:18 ` Michael Heerdegen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87mx9q1sz7.fsf@gmail.com \
--to=thierry.volpiatto@gmail.com \
--cc=10489@debbugs.gnu.org \
--cc=eliz@gnu.org \
--cc=michael.albinus@gmx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.