]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix decoding non-ASCII file names in zip archives on MS-Windows
authorEli Zaretskii <eliz@gnu.org>
Sat, 11 Mar 2023 11:30:37 +0000 (13:30 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sat, 11 Mar 2023 11:30:37 +0000 (13:30 +0200)
* lisp/arc-mode.el (archive-zip-summarize): On MS-Windows,
override archive-file-name-coding-system for files compressed
on MS-Windows, and use the local console encoding instead.

lisp/arc-mode.el

index dcf7c17a878f27c99733d79dab33137e152e576e..41b239fbef9ae55fffe0adc4500cfb1841dea939 100644 (file)
@@ -1960,6 +1960,16 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
   (goto-char (- (point-max) (- 22 18)))
   (search-backward-regexp "[P]K\005\006")
   (let ((p (archive-l-e (+ (point) 16) 4))
+        (w32-fname-encoding
+         ;; On MS-Windows, both InfoZip's Zip and the system's
+         ;; built-in File Explorer use the console codepage for
+         ;; encoding file names.  Problem: the codepage of the system
+         ;; where the zip file was created cannot be known; we assume
+         ;; it is the same as the one of the current system.  Also,
+         ;; the zip file doesn't tell us the OS where the file was
+         ;; created, it only tells the filesystem.
+         (if (eq system-type 'windows-nt)
+             (intern (format "cp%d" (w32-get-console-codepage)))))
         files)
     (when (or (= p #xffffffff) (= p -1))
       ;; If the offset of end-of-central-directory is 0xFFFFFFFF, this
@@ -1989,7 +1999,15 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
              ;; (lheader (archive-l-e (+ p 42) 4))
              (efnname (let ((str (buffer-substring (+ p 46) (+ p 46 fnlen))))
                        (decode-coding-string
-                        str archive-file-name-coding-system)))
+                        str
+                         (or (if (and w32-fname-encoding
+                                      (memq creator
+                                            ;; This should be just 10 and
+                                            ;; 14, but InfoZip uses 0 and
+                                            ;; File Explorer uses 11(??).
+                                            '(0 10 11 14)))
+                                 w32-fname-encoding)
+                             archive-file-name-coding-system))))
              (ucsize  (if (and (or (= ucsize #xffffffff) (= ucsize -1))
                                (> exlen 0))
                           ;; APPNOTE.TXT, para 4.5.3: the Extra Field