From 448f64f80ad7e081c686c79bcc006b1657315491 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 20 May 2024 15:29:39 +0300 Subject: [PATCH] Fix visiting zip archives inside tar archives * lisp/tar-mode.el (tar-archive-from-tar): New local variable. (tar-extract): Set it non-nil for an extracted member that happens to be arc-mode archive. * lisp/arc-mode.el (tar-archive-from-tar): Defvar it. (archive-unique-fname): Make sure FNAME can be created in DIR, even if FNAME is provided as an absolute file name (this happens if the archive is a member of a Tar archive, for example). (archive-extract): Set 'archive-remote' for archives that were extracted from Tar archives. (Bug#70987) (cherry picked from commit 45916eadaed1b7f3a02df62a25bc851a838b6309) --- lisp/arc-mode.el | 11 ++++++++++- lisp/tar-mode.el | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index 9a8dd6679e3..bf9def681c3 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el @@ -563,6 +563,8 @@ Its value is an `archive--file-desc'.") (defvar-local archive-files nil "Vector of `archive--file-desc' objects.") +(defvar tar-archive-from-tar nil) + ;; ------------------------------------------------------------------------- ;;; Section: Support functions. @@ -754,7 +756,8 @@ archive. ;; on local filesystem. Treat such archives as remote. (or archive-remote (setq archive-remote - (or (string-match archive-remote-regexp (buffer-file-name)) + (or tar-archive-from-tar ; was included in a tar archive + (string-match archive-remote-regexp (buffer-file-name)) (string-match file-name-invalid-regexp (buffer-file-name))))) @@ -920,6 +923,9 @@ If FNAME can be uniquely created in DIR, it is returned unaltered. If FNAME is something our underlying filesystem can't grok, or if another file by that name already exists in DIR, a unique new name is generated using `make-temp-file', and the generated name is returned." + (if (file-name-absolute-p fname) + ;; We need a file name relative to the filesystem root. + (setq fname (substring fname (1+ (string-search "/" fname))))) (let ((fullname (expand-file-name fname dir)) (alien (string-match file-name-invalid-regexp fname)) (tmpfile @@ -1179,6 +1185,9 @@ NEW-NAME." (buffer (get-buffer bufname)) (just-created nil) (file-name-coding archive-file-name-coding-system)) + (or archive-remote + (and (local-variable-p 'tar-archive-from-tar) + (setq archive-remote tar-archive-from-tar))) (if (and buffer (string= (buffer-file-name buffer) arcfilename)) nil diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el index 375191a8167..7278bee48d4 100644 --- a/lisp/tar-mode.el +++ b/lisp/tar-mode.el @@ -135,6 +135,10 @@ This information is useful, but it takes screen space away from file names." (put 'tar-superior-buffer 'permanent-local t) (put 'tar-superior-descriptor 'permanent-local t) +(defvar tar-archive-from-tar nil + "Non-nil if an arc-mode archive file is a member of a tar archive.") +(put tar-archive-from-tar 'permanent-local t) + ;; The Tar data is made up of bytes and better manipulated as bytes ;; and can be very large, so insert/delete can be costly. The summary we ;; want to display may contain non-ascii chars, of course, so we'd like it @@ -1124,6 +1128,8 @@ return nil. Otherwise point is returned." default-directory)) (set-buffer-modified-p nil) (normal-mode) ; pick a mode. + (when (derived-mode-p 'archive-mode) + (setq-local tar-archive-from-tar t)) (setq-local tar-superior-buffer tar-buffer) (setq-local tar-superior-descriptor descriptor) (setq buffer-read-only read-only-p) -- 2.39.5