aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoam Postavsky2018-10-27 17:45:00 -0400
committerNoam Postavsky2019-04-02 22:02:32 -0400
commitb36913d803ee22a314f2e0a27523fbadeb60dd2c (patch)
treeb5f8fa4e531198d1c049c42b1b0853a5dd87d72d
parent2bd3e484041b2b7ea47c236b86f59610d971b609 (diff)
downloademacs-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.texi11
-rw-r--r--etc/NEWS6
-rw-r--r--lisp/url/url-http.el5
-rw-r--r--src/decompress.c22
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
4513available. 4513available.
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
4517This function decompresses the region between @var{start} and 4517This 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
4519contain data that were compressed with gzip or zlib. On success, the 4519contain data that were compressed with gzip or zlib. On success, the
4520function replaces the contents of the region with the decompressed 4520function replaces the contents of the region with the decompressed
4521data. On failure, the function leaves the region unchanged and 4521data. If @var{allow-partial} is @code{nil} or omitted, then on
4522returns @code{nil}. This function can be called only in unibyte 4522failure, the function leaves the region unchanged and returns
4523buffers. 4523@code{nil}. Otherwise, it returns the number of bytes that were not
4524decompressed and replaces the region text by whatever data was
4525successfully decompressed. This function can be called only in
4526unibyte buffers.
4524@end defun 4527@end defun
4525 4528
4526 4529
diff --git a/etc/NEWS b/etc/NEWS
index 7f6aeab73f0..2bf2b4972a5 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1672,6 +1672,12 @@ are implemented in C using the Jansson library.
1672and 'flatten' it such that the result is a list of all the terminal 1672and 'flatten' it such that the result is a list of all the terminal
1673nodes. 1673nodes.
1674 1674
1675+++
1676** 'zlib-decompress-region' can partially decompress corrupted data.
1677If the new optional ALLOW-PARTIAL argument is passed, then the data
1678that was decompressed successfully before failing will be inserted
1679into 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
121DEFUN ("zlib-decompress-region", Fzlib_decompress_region, 121DEFUN ("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.
125Replace the text in the region by the decompressed data. 125Replace the text in the region by the decompressed data.
126On failure, return nil and leave the data in place. 126
127If optional parameter ALLOW-PARTIAL is nil or omitted, then on
128failure, return nil and leave the data in place. Otherwise, return
129the number of bytes that were not decompressed and replace the region
130text by whatever data was successfully decompressed (similar to gzip).
131If decompression is completely successful return t.
132
127This function can be called only in unibyte buffers. */) 133This 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