Fix Dired check for newlines in file names

Ensure that Dired does not treat the sequence "\\n" within a file
name as a newline (bug#80608).

* lisp/dired.el (dired--filename-with-newline-p): Rewrite using
'directory-files' with match for regexp "\n".

* test/lisp/dired-tests.el
(dired-test--filename-with-backslash-n): New function.
(dired-test-filename-with-backslash-n): New test.
This commit is contained in:
Stephen Berman
2026-03-25 20:45:44 +01:00
parent 2ca648068f
commit f2b9b827c9
2 changed files with 45 additions and 14 deletions

View File

@@ -4011,20 +4011,11 @@ Considers buffers closer to the car of `buffer-list' to be more recent."
(not (memq buffer1 (memq buffer2 (buffer-list))))))
(defun dired--filename-with-newline-p ()
"Check if a file name in this directory has a newline.
Return non-nil if at least one file name in this directory contains
either a literal newline or the string \"\\n\")."
(save-excursion
(goto-char (point-min))
(catch 'found
(while (not (eobp))
(when (dired-move-to-filename)
(let ((fn (buffer-substring-no-properties
(point) (dired-move-to-end-of-filename))))
(when (or (memq 10 (seq-into fn 'list))
(string-search "\\n" fn))
(throw 'found t))))
(forward-line)))))
"Check whether a file name in this directory has a newline.
Return non-nil if at least one file name in this directory contains a
newline character (regardless of whether Dired displays the character as
a literal newline or as \"\\n\")."
(directory-files default-directory nil "\n"))
(defun dired--remove-b-switch ()
"Remove all variants of the `b' switch from `dired-actual-switches'.

View File

@@ -658,5 +658,45 @@ The current directory at call time should not affect the result (Bug#50630)."
(let ((default-directory test-dir-other))
(files-tests--insert-directory-shows-given-free test-dir)))))
(defun dired-test--filename-with-backslash-n ()
"Core of test `dired-test-filename-with-backslash-n'."
(let* ((dir (ert-resource-file
(file-name-as-directory "filename-with-backslash")))
(file (concat dir "C:\\nppdf32log\\debuglog.txt"))
(buf (progn (make-empty-file file t)
(dired-noselect (file-name-directory file))))
(warnbuf (get-buffer "*Warnings*")))
(with-current-buffer buf
(should-not (dired--filename-with-newline-p))
(dired--toggle-b-switch)
(should-not (dired--filename-with-newline-p))
(let ((fn (car (directory-files dir t
directory-files-no-dot-files-regexp))))
(should (equal fn file))))
(if noninteractive
(with-current-buffer "*Messages*"
(goto-char (point-min))
(should-error (search-forward
"Warning (dired): Literal newline in file name.")))
(should-not (get-buffer "*Warnings*")))
(kill-buffer buf)
(kill-buffer warnbuf)
(delete-directory dir t)))
(ert-deftest dired-test-filename-with-backslash-n () ; bug#80608
"Test file name containing literal backslash-n sequence.
Dired should not treat this sequence as a newline character, regardless
of the value of `dired-auto-toggle-b-switch'."
(with-current-buffer "*Messages*"
(let ((inhibit-read-only t))
(erase-buffer)))
(let ((dired-auto-toggle-b-switch nil))
(dired-test--filename-with-backslash-n))
(with-current-buffer "*Messages*"
(let ((inhibit-read-only t))
(erase-buffer)))
(let ((dired-auto-toggle-b-switch nil))
(dired-test--filename-with-backslash-n)))
(provide 'dired-tests)
;;; dired-tests.el ends here