Subject: bug#32989: 26.1; Opening PDF attachments in Gnus with doc-view-mode causes error on Windows

From: Jordan Wilson <[email-masked]>
Date: Wed, 10 Oct 2018 11:45:57 +0100

On 2018-10-08 (Mon) at 23:02 (ZZZ), Eli Zaretskii <[email-masked]> wrote:
>> From: Jordan Wilson <[email-masked]>
>> Date: Mon, 08 Oct 2018 15:44:55 +0100
>> 
>>   File error: "Opening output file", "Invalid argument", "c:/Users/Jordan/Emacs/.cache/docview-cache/ *mm*-012345" 
>> 
>> this leaves a buffer showing the file literally. If I rename that buffer
>> to something not containing an asterisk, it displays fine when running
>> "doc-view-mode". Windows apparently can't handle asterisks in
>> directory/file names.
>
> Windows doesn't allow '*' (and a few other characters) in any file
> name, not just in directory name.  Gnus should run the file name
> through convert-standard-filename to get something that is guaranteed
> to work on any filesystem.
Looking, it seems to be on doc-view's side -- if a buffer isn't
associated with a file, it uses the buffer name for the file's cache
directory. Here's a patch to the 26 and trunk branches of doc-view.el to
run the file names through `convert-standard-filename'. It fixes the
problem for me, at least.
--- doc-view-26.el	2018-10-09 16:27:18.890549900 +0100
+++ doc-view-26-2.el	2018-10-09 16:29:04.122599100 +0100
@@ -1772,27 +1772,28 @@
     (doc-view-make-safe-dir doc-view-cache-directory)
     ;; Handle compressed files, remote files, files inside archives
     (setq-local doc-view--buffer-file-name
-                (cond
-                 (jka-compr-really-do-compress
-                  ;; FIXME: there's a risk of name conflicts here.
-                  (expand-file-name
-                   (file-name-nondirectory
-                    (file-name-sans-extension buffer-file-name))
-                   doc-view-cache-directory))
-                 ;; Is the file readable by local processes?
-                 ;; We used to use `file-remote-p' but it's unclear what it's
-                 ;; supposed to return nil for things like local files accessed
-                 ;; via `su' or via file://...
-                 ((let ((file-name-handler-alist nil))
-                    (not (and buffer-file-name
-                              (file-readable-p buffer-file-name))))
-                  ;; FIXME: there's a risk of name conflicts here.
-                  (expand-file-name
-                   (if buffer-file-name
-                       (file-name-nondirectory buffer-file-name)
-                     (buffer-name))
-                   doc-view-cache-directory))
-                 (t buffer-file-name)))
+		(convert-standard-filename
+                 (cond
+                  (jka-compr-really-do-compress
+                   ;; FIXME: there's a risk of name conflicts here.
+                   (expand-file-name
+                    (file-name-nondirectory
+                     (file-name-sans-extension buffer-file-name))
+                    doc-view-cache-directory))
+                  ;; Is the file readable by local processes?
+                  ;; We used to use `file-remote-p' but it's unclear what it's
+                  ;; supposed to return nil for things like local files accessed
+                  ;; via `su' or via file://...
+                  ((let ((file-name-handler-alist nil))
+                     (not (and buffer-file-name
+                               (file-readable-p buffer-file-name))))
+                   ;; FIXME: there's a risk of name conflicts here.
+                   (expand-file-name
+                    (if buffer-file-name
+			(file-name-nondirectory buffer-file-name)
+                      (buffer-name))
+                    doc-view-cache-directory))
+                  (t buffer-file-name))))
     (when (not (string= doc-view--buffer-file-name buffer-file-name))
       (write-region nil nil doc-view--buffer-file-name))
 
--- doc-view-trunk.el	2018-10-09 16:31:48.000000000 +0100
+++ doc-view-trunk-2.el	2018-10-09 16:31:31.502299800 +0100
@@ -1764,27 +1764,28 @@
     (doc-view-make-safe-dir doc-view-cache-directory)
     ;; Handle compressed files, remote files, files inside archives
     (setq-local doc-view--buffer-file-name
-                (cond
-                 (jka-compr-really-do-compress
-                  ;; FIXME: there's a risk of name conflicts here.
-                  (expand-file-name
-                   (file-name-nondirectory
-                    (file-name-sans-extension buffer-file-name))
-                   doc-view-cache-directory))
-                 ;; Is the file readable by local processes?
-                 ;; We used to use `file-remote-p' but it's unclear what it's
-                 ;; supposed to return nil for things like local files accessed
-                 ;; via `su' or via file://...
-                 ((let ((file-name-handler-alist nil))
-                    (not (and buffer-file-name
-                              (file-readable-p buffer-file-name))))
-                  ;; FIXME: there's a risk of name conflicts here.
-                  (expand-file-name
-                   (if buffer-file-name
-                       (file-name-nondirectory buffer-file-name)
-                     (buffer-name))
-                   doc-view-cache-directory))
-                 (t buffer-file-name)))
+                (convert-standard-filename
+                 (cond
+                  (jka-compr-really-do-compress
+                   ;; FIXME: there's a risk of name conflicts here.
+                   (expand-file-name
+                    (file-name-nondirectory
+                     (file-name-sans-extension buffer-file-name))
+                    doc-view-cache-directory))
+                  ;; Is the file readable by local processes?
+                  ;; We used to use `file-remote-p' but it's unclear what it's
+                  ;; supposed to return nil for things like local files accessed
+                  ;; via `su' or via file://...
+                  ((let ((file-name-handler-alist nil))
+                     (not (and buffer-file-name
+                               (file-readable-p buffer-file-name))))
+                   ;; FIXME: there's a risk of name conflicts here.
+                   (expand-file-name
+                    (if buffer-file-name
+                        (file-name-nondirectory buffer-file-name)
+                      (buffer-name))
+                    doc-view-cache-directory))
+                  (t buffer-file-name))))
     (when (not (string= doc-view--buffer-file-name buffer-file-name))
       (write-region nil nil doc-view--buffer-file-name))
 
-- 
Jordan Wilson
    Sent from Gnus v5.13, GNU Emacs 26.1