Subject: Re: bug#67926: 29.1; fail to extract ZIP subfile named with [...]

From: [email-masked]
Date: Wed, 27 Dec 2023 23:36:32 +0900

Eli Zaretskii <[email-masked]> writes:

>> I think that avoiding the use of unzip.exe/zip.exe solves problems about
>> directory names, archive names, subfile names.
>> Replacing #'archive-zip-extract with the form below,
>> ZIP subfiles can be extracted without unzip.exe.
>> 
>> (defun archive-zip-extract (archive name)
>>   (let* ((desc archive-subfile-mode)
>>          (buf (current-buffer))
>>          (bufname (buffer-file-name)))
>>     (set-buffer archive-superior-buffer)
>>     (save-restriction
>>       (widen)
>>       (let* ((file-beg archive-proper-file-start)
>>              (p0 (+ file-beg (archive--file-desc-pos desc)))
>>              (p  (+ file-beg (archive-l-e (+ p0 42) 4)))
>>              (bitflags (archive-l-e (+ p  6) 2))
>>              (method   (archive-l-e (+ p  8) 2))
>>              (compsize (archive-l-e (+ p0 20) 4))
>>              (fn-len   (archive-l-e (+ p 26) 2))
>>              (ex-len   (archive-l-e (+ p 28) 2))
>>              (data-beg (+ p 30 fn-len ex-len))
>>              (data-end (+ data-beg compsize))
>>              (coding-system-for-read  'no-conversion)
>>              (coding-system-for-write 'no-conversion)
>>              (default-directory temporary-file-directory))
>>         (cond ((/= 0 (logand bitflags 1))
>>                (message "Subfile is encrypted"))
>>               ((= method 0)
>>                (with-current-buffer buf
>>                  (insert-buffer-substring archive-superior-buffer
>>                                           data-beg data-end)))
>>               ((eq method 8)
>>                (let ((crc-32    (buffer-substring (+ p0 16) (+ p0 20)))
>>                      (orig-size (buffer-substring (+ p0 24) (+ p0 28)))
>>                      (proc (start-process "gzip" buf "gzip" "-cd"))
>>                      (header "\x1f\x8b\x08\0\0\0\0\0\0\0"))
>>                  (set-process-sentinel proc #'ignore)
>>                  (process-send-string proc header)
>>                  (process-send-region proc data-beg data-end)
>>                  (process-send-string proc crc-32)
>>                  (process-send-string proc orig-size)
>>                  (process-send-eof proc)
>>                  (accept-process-output proc nil nil t)
>>                  (delete-process proc)))
>>               ((eq method 12)
>>                (call-process-region data-beg data-end
>>                                     "bzip2" nil buf nil "-cd"))
>>               (t (message "Unknown compression method")))))
>>     (set-buffer buf)))
>
> Thanks, but I don't think it's a good idea.  There are more
> compression methods than just those 3, and some of them aren't
> documented.  unzip.exe itself supports 17 methods.  So I'd rather stay
> with unzip.exe than invent our own wheel.

If unzip.exe(or an alternative external program) is necessary,
I want emacs not to load contents of archive files into archive-mode
buffer. It is waste of time and memory.
I never opened large ZIP archives of Giga Byte size.
But I would be glad to open such files with archive-mode
in a short time and with a small memory.