aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2015-05-27 17:35:11 +0300
committerEli Zaretskii2015-05-27 17:35:11 +0300
commit171981622f072546aed135668e53fdeb7b012631 (patch)
tree7b0e7ab04cf5c9b403e785bf8718c89bc61c58db
parentabf082383aca563ff8615f695c9f2accb6ac222d (diff)
downloademacs-171981622f072546aed135668e53fdeb7b012631.tar.gz
emacs-171981622f072546aed135668e53fdeb7b012631.zip
Support ZIP files that use Zip64 extensions
* lisp/arc-mode.el (archive-zip-summarize): Handle the new ZIP format of central directory offsets used by Zip64 extensions. (Bug#20665)
-rw-r--r--lisp/arc-mode.el31
1 files changed, 29 insertions, 2 deletions
diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el
index 063e4ba9dcb..5f2fc8f3804 100644
--- a/lisp/arc-mode.el
+++ b/lisp/arc-mode.el
@@ -1811,11 +1811,38 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1811(defun archive-zip-summarize () 1811(defun archive-zip-summarize ()
1812 (goto-char (- (point-max) (- 22 18))) 1812 (goto-char (- (point-max) (- 22 18)))
1813 (search-backward-regexp "[P]K\005\006") 1813 (search-backward-regexp "[P]K\005\006")
1814 (let ((p (+ (point-min) (archive-l-e (+ (point) 16) 4))) 1814 (let ((p (archive-l-e (+ (point) 16) 4))
1815 (maxlen 8) 1815 (maxlen 8)
1816 (totalsize 0) 1816 (totalsize 0)
1817 files 1817 files
1818 visual) 1818 visual
1819 emacs-int-has-32bits)
1820 (when (= p -1)
1821 ;; If the offset of end-of-central-directory is -1, this is a
1822 ;; Zip64 extended ZIP file format, and we need to glean the info
1823 ;; from Zip64 records instead.
1824 ;;
1825 ;; First, find the Zip64 end-of-central-directory locator.
1826 (search-backward "PK\006\007")
1827 ;; Pay attention: the offset of Zip64 end-of-central-directory
1828 ;; is a 64-bit field, so it could overflow the Emacs integer
1829 ;; even on a 64-bit host, let alone 32-bit one. But since we've
1830 ;; already read the zip file into a buffer, and this is a byte
1831 ;; offset into the file we've read, it must be short enough, so
1832 ;; such an overflow can never happen, and we can safely read
1833 ;; these 8 bytes into an Emacs integer. Moreover, on host with
1834 ;; 32-bit Emacs integer we can only read 4 bytes, since they are
1835 ;; stored in little-endian byte order.
1836 (setq emacs-int-has-32bits (<= most-positive-fixnum #x1fffffff))
1837 (setq p (+ (point-min)
1838 (archive-l-e (+ (point) 8) (if emacs-int-has-32bits 4 8))))
1839 (goto-char p)
1840 ;; We should be at Zip64 end-of-central-directory record now.
1841 (or (string= "PK\006\006" (buffer-substring p (+ p 4)))
1842 (error "Unrecognized ZIP file format"))
1843 ;; Offset to central directory:
1844 (setq p (+ (point-min)
1845 (archive-l-e (+ p 48) (if emacs-int-has-32bits 4 8)))))
1819 (while (string= "PK\001\002" (buffer-substring p (+ p 4))) 1846 (while (string= "PK\001\002" (buffer-substring p (+ p 4)))
1820 (let* ((creator (byte-after (+ p 5))) 1847 (let* ((creator (byte-after (+ p 5)))
1821 ;; (method (archive-l-e (+ p 10) 2)) 1848 ;; (method (archive-l-e (+ p 10) 2))