From f2b9b827c977dee0031e44901cbf3e1111e1cc09 Mon Sep 17 00:00:00 2001 From: Stephen Berman Date: Wed, 25 Mar 2026 20:45:44 +0100 Subject: [PATCH] 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. --- lisp/dired.el | 19 +++++-------------- test/lisp/dired-tests.el | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/lisp/dired.el b/lisp/dired.el index 4c0d34344c3..4782c691411 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -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'. diff --git a/test/lisp/dired-tests.el b/test/lisp/dired-tests.el index 7d0ea1692ff..559e113a24c 100644 --- a/test/lisp/dired-tests.el +++ b/test/lisp/dired-tests.el @@ -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