diff options
| author | Eli Zaretskii | 2015-05-27 17:35:11 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-05-27 17:35:11 +0300 |
| commit | 171981622f072546aed135668e53fdeb7b012631 (patch) | |
| tree | 7b0e7ab04cf5c9b403e785bf8718c89bc61c58db | |
| parent | abf082383aca563ff8615f695c9f2accb6ac222d (diff) | |
| download | emacs-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.el | 31 |
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)) |