diff options
| author | Noam Postavsky | 2018-10-27 17:45:00 -0400 |
|---|---|---|
| committer | Noam Postavsky | 2019-04-02 22:02:32 -0400 |
| commit | b36913d803ee22a314f2e0a27523fbadeb60dd2c (patch) | |
| tree | b5f8fa4e531198d1c049c42b1b0853a5dd87d72d | |
| parent | 2bd3e484041b2b7ea47c236b86f59610d971b609 (diff) | |
| download | emacs-b36913d803ee22a314f2e0a27523fbadeb60dd2c.tar.gz emacs-b36913d803ee22a314f2e0a27523fbadeb60dd2c.zip | |
Allow partial decompression (Bug#33133)
* src/decompress.c (Fzlib_decompress_region): Add optional
ALLOW-PARTIAL parameter.
* lisp/url/url-http.el (url-handle-content-transfer-encoding): Use it.
* doc/lispref/text.texi (Decompression): Document it.
* etc/NEWS: Announce it.
| -rw-r--r-- | doc/lispref/text.texi | 11 | ||||
| -rw-r--r-- | etc/NEWS | 6 | ||||
| -rw-r--r-- | lisp/url/url-http.el | 5 | ||||
| -rw-r--r-- | src/decompress.c | 22 |
4 files changed, 33 insertions, 11 deletions
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index b430adf5976..86f9fa0e5f5 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi | |||
| @@ -4513,14 +4513,17 @@ This function returns non-@code{nil} if built-in zlib decompression is | |||
| 4513 | available. | 4513 | available. |
| 4514 | @end defun | 4514 | @end defun |
| 4515 | 4515 | ||
| 4516 | @defun zlib-decompress-region start end | 4516 | @defun zlib-decompress-region start end &optional allow-partial |
| 4517 | This function decompresses the region between @var{start} and | 4517 | This function decompresses the region between @var{start} and |
| 4518 | @var{end}, using built-in zlib decompression. The region should | 4518 | @var{end}, using built-in zlib decompression. The region should |
| 4519 | contain data that were compressed with gzip or zlib. On success, the | 4519 | contain data that were compressed with gzip or zlib. On success, the |
| 4520 | function replaces the contents of the region with the decompressed | 4520 | function replaces the contents of the region with the decompressed |
| 4521 | data. On failure, the function leaves the region unchanged and | 4521 | data. If @var{allow-partial} is @code{nil} or omitted, then on |
| 4522 | returns @code{nil}. This function can be called only in unibyte | 4522 | failure, the function leaves the region unchanged and returns |
| 4523 | buffers. | 4523 | @code{nil}. Otherwise, it returns the number of bytes that were not |
| 4524 | decompressed and replaces the region text by whatever data was | ||
| 4525 | successfully decompressed. This function can be called only in | ||
| 4526 | unibyte buffers. | ||
| 4524 | @end defun | 4527 | @end defun |
| 4525 | 4528 | ||
| 4526 | 4529 | ||
| @@ -1672,6 +1672,12 @@ are implemented in C using the Jansson library. | |||
| 1672 | and 'flatten' it such that the result is a list of all the terminal | 1672 | and 'flatten' it such that the result is a list of all the terminal |
| 1673 | nodes. | 1673 | nodes. |
| 1674 | 1674 | ||
| 1675 | +++ | ||
| 1676 | ** 'zlib-decompress-region' can partially decompress corrupted data. | ||
| 1677 | If the new optional ALLOW-PARTIAL argument is passed, then the data | ||
| 1678 | that was decompressed successfully before failing will be inserted | ||
| 1679 | into the buffer. | ||
| 1680 | |||
| 1675 | ** Mailcap | 1681 | ** Mailcap |
| 1676 | 1682 | ||
| 1677 | --- | 1683 | --- |
diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el index 1fbc0870737..cf1952066a5 100644 --- a/lisp/url/url-http.el +++ b/lisp/url/url-http.el | |||
| @@ -939,7 +939,8 @@ should be shown to the user." | |||
| 939 | (goto-char (point-min)) | 939 | (goto-char (point-min)) |
| 940 | success)) | 940 | success)) |
| 941 | 941 | ||
| 942 | (declare-function zlib-decompress-region "decompress.c" (start end)) | 942 | (declare-function zlib-decompress-region "decompress.c" |
| 943 | (start end &optional allow-partial)) | ||
| 943 | 944 | ||
| 944 | (defun url-handle-content-transfer-encoding () | 945 | (defun url-handle-content-transfer-encoding () |
| 945 | (let ((encoding (mail-fetch-field "content-encoding"))) | 946 | (let ((encoding (mail-fetch-field "content-encoding"))) |
| @@ -951,7 +952,7 @@ should be shown to the user." | |||
| 951 | (widen) | 952 | (widen) |
| 952 | (goto-char (point-min)) | 953 | (goto-char (point-min)) |
| 953 | (when (search-forward "\n\n") | 954 | (when (search-forward "\n\n") |
| 954 | (zlib-decompress-region (point) (point-max))))))) | 955 | (zlib-decompress-region (point) (point-max) t)))))) |
| 955 | 956 | ||
| 956 | ;; Miscellaneous | 957 | ;; Miscellaneous |
| 957 | (defun url-http-activate-callback () | 958 | (defun url-http-activate-callback () |
diff --git a/src/decompress.c b/src/decompress.c index e66e4798b18..4ca6a50b2a2 100644 --- a/src/decompress.c +++ b/src/decompress.c | |||
| @@ -120,12 +120,18 @@ DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0, | |||
| 120 | 120 | ||
| 121 | DEFUN ("zlib-decompress-region", Fzlib_decompress_region, | 121 | DEFUN ("zlib-decompress-region", Fzlib_decompress_region, |
| 122 | Szlib_decompress_region, | 122 | Szlib_decompress_region, |
| 123 | 2, 2, 0, | 123 | 2, 3, 0, |
| 124 | doc: /* Decompress a gzip- or zlib-compressed region. | 124 | doc: /* Decompress a gzip- or zlib-compressed region. |
| 125 | Replace the text in the region by the decompressed data. | 125 | Replace the text in the region by the decompressed data. |
| 126 | On failure, return nil and leave the data in place. | 126 | |
| 127 | If optional parameter ALLOW-PARTIAL is nil or omitted, then on | ||
| 128 | failure, return nil and leave the data in place. Otherwise, return | ||
| 129 | the number of bytes that were not decompressed and replace the region | ||
| 130 | text by whatever data was successfully decompressed (similar to gzip). | ||
| 131 | If decompression is completely successful return t. | ||
| 132 | |||
| 127 | This function can be called only in unibyte buffers. */) | 133 | This function can be called only in unibyte buffers. */) |
| 128 | (Lisp_Object start, Lisp_Object end) | 134 | (Lisp_Object start, Lisp_Object end, Lisp_Object allow_partial) |
| 129 | { | 135 | { |
| 130 | ptrdiff_t istart, iend, pos_byte; | 136 | ptrdiff_t istart, iend, pos_byte; |
| 131 | z_stream stream; | 137 | z_stream stream; |
| @@ -206,8 +212,14 @@ This function can be called only in unibyte buffers. */) | |||
| 206 | } | 212 | } |
| 207 | while (inflate_status == Z_OK); | 213 | while (inflate_status == Z_OK); |
| 208 | 214 | ||
| 215 | Lisp_Object ret = Qt; | ||
| 209 | if (inflate_status != Z_STREAM_END) | 216 | if (inflate_status != Z_STREAM_END) |
| 210 | return unbind_to (count, Qnil); | 217 | { |
| 218 | if (!NILP (allow_partial)) | ||
| 219 | ret = make_int (iend - pos_byte); | ||
| 220 | else | ||
| 221 | return unbind_to (count, Qnil); | ||
| 222 | } | ||
| 211 | 223 | ||
| 212 | unwind_data.start = 0; | 224 | unwind_data.start = 0; |
| 213 | 225 | ||
| @@ -218,7 +230,7 @@ This function can be called only in unibyte buffers. */) | |||
| 218 | signal_after_change (istart, iend - istart, unwind_data.nbytes); | 230 | signal_after_change (istart, iend - istart, unwind_data.nbytes); |
| 219 | update_compositions (istart, istart, CHECK_HEAD); | 231 | update_compositions (istart, istart, CHECK_HEAD); |
| 220 | 232 | ||
| 221 | return unbind_to (count, Qt); | 233 | return unbind_to (count, ret); |
| 222 | } | 234 | } |
| 223 | 235 | ||
| 224 | 236 | ||