1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-15 10:30:25 -08:00

* lisp/emacs-lisp/package.el: Fix decoding of downloaded files

This is a different fix for bug#34909, which should also fix bug#35739.

Our downloading code used to automatically decode the result according
to the usual heuristics for files.  This caused problems when we later
needed to save the data in a file that needed to be byte-for-byte
equal to the original in order to pass the signature verification,
especially because we didn't keep track of which coding-system was
used to decode the data.

(package--unless-error): New macro extracted from
package--with-response-buffer-1, so that we can specify edebug and
indent specs.
(package--with-response-buffer-1): Use it.  More importantly, change
code so it runs `body` in a unibyte buffer with undecoded data.
(package--download-one-archive): Don't encode with utf-8 since the data
is not decoded yet.
(describe-package-1): Explicitly decode the readem.txt files here.

* lisp/url/url-handlers.el (url-insert-file-contents): Use it.
(url-insert): Don't decode if buffer is unibyte.

* lisp/url/url-http.el (url-http--insert-file-helper): New function,
extracted from url-insert-file-contents.
This commit is contained in:
Stefan Monnier 2019-05-18 18:32:47 -04:00
parent 2a5705761e
commit 5f9671e57e
3 changed files with 98 additions and 63 deletions

View file

@ -299,7 +299,8 @@ accessible."
(defun url-insert (buffer &optional beg end)
"Insert the body of a URL object.
BUFFER should be a complete URL buffer as returned by `url-retrieve'.
If the headers specify a coding-system, it is applied to the body before it is inserted.
If the headers specify a coding-system (and current buffer is multibyte),
it is applied to the body before it is inserted.
Returns a list of the form (SIZE CHARSET), where SIZE is the size in bytes
of the inserted text and CHARSET is the charset that was specified in the header,
or nil if none was found.
@ -311,12 +312,13 @@ They count bytes from the beginning of the body."
(buffer-substring (+ (point-min) beg)
(if end (+ (point-min) end) (point-max)))
(buffer-string))))
(charset (mail-content-type-get (mm-handle-type handle)
'charset)))
(charset (if enable-multibyte-characters
(mail-content-type-get (mm-handle-type handle)
'charset))))
(mm-destroy-parts handle)
(if charset
(insert (mm-decode-string data (mm-charset-to-coding-system charset)))
(insert data))
(insert (if charset
(mm-decode-string data (mm-charset-to-coding-system charset))
data))
(list (length data) charset)))
(defvar url-http-codes)
@ -349,23 +351,10 @@ if it had been inserted from a file named URL."
(defun url-insert-file-contents (url &optional visit beg end replace)
(let ((buffer (url-retrieve-synchronously url)))
(unless buffer (signal 'file-error (list url "No Data")))
(with-current-buffer buffer
(when (fboundp 'url-http--insert-file-helper)
;; XXX: This is HTTP/S specific and should be moved to url-http
;; instead. See bug#17549.
(when (bound-and-true-p url-http-response-status)
;; Don't signal an error if VISIT is non-nil, because
;; 'insert-file-contents' doesn't. This is required to
;; support, e.g., 'browse-url-emacs', which is a fancy way of
;; visiting the HTML source of a URL: in that case, we want to
;; display a file buffer even if the URL does not exist and
;; 'url-retrieve-synchronously' returns 404 or whatever.
(unless (or visit
(and (>= url-http-response-status 200)
(< url-http-response-status 300)))
(let ((desc (nth 2 (assq url-http-response-status url-http-codes))))
(kill-buffer buffer)
;; Signal file-error per bug#16733.
(signal 'file-error (list url desc))))))
(url-http--insert-file-helper buffer url visit))
(url-insert-buffer-contents buffer url visit beg end replace)))
(put 'insert-file-contents 'url-file-handlers 'url-insert-file-contents)