Subject: bug#75877: 30.0.91; dired-omit-expunge embeds unquoted filename in format string

From: Eli Zaretskii <[email-masked]>
Date: Sat, 01 Feb 2025 12:57:03 +0200

> Date: Sun, 26 Jan 2025 10:26:27 -0800
> From:  Derek Upham via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <[email-masked]>
> 
> 
> Looking at “dired-omit-expunge” in dired-x.el, in this block:
> 
>     (setq count  (+ count
>                     (dired-do-kill-lines
>                      nil
>                      (if dired-omit-verbose
>                          (format "Omitted %%d line%%s in %s"
>                                  (abbreviate-file-name
>                                   dired-directory))
>                        "")
>                      init-count)))
> 
> Here that “format” call generates a format template, such that
> “dired-do-kill-lines” can invoke “message” with that text plus 
> count
> information.
> 
> If the directory name contains embedded percentage characters, 
> then the
> template ends up with extra parameter slots.  The call to 
> “message”
> fails with an error and Dired does not present the directory.
> 
>     (error "Not enough arguments for format string")
> 
> (In case someone is curious “Why put percentages in the names at 
> all?”,
> I use it to map those directories 1:1 with URLs/websites.)

Thanks.  Is the below the right fix?

diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 4a05f60..89390a4 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -498,8 +498,10 @@ dired-omit-expunge
                                nil
                                (if dired-omit-verbose
                                    (format "Omitted %%d line%%s in %s"
-                                           (abbreviate-file-name
-                                            dired-directory))
+                                           (replace-regexp-in-string
+                                            "%" "%%"
+                                            (abbreviate-file-name
+                                             dired-directory)))
                                  "")
                                init-count)))
               (force-mode-line-update))))