Commit b36913d8 authored by Noam Postavsky's avatar Noam Postavsky

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.
parent 2bd3e484
Pipeline #1142 failed with stage
in 43 minutes and 34 seconds
......@@ -4513,14 +4513,17 @@ This function returns non-@code{nil} if built-in zlib decompression is
available.
@end defun
@defun zlib-decompress-region start end
@defun zlib-decompress-region start end &optional allow-partial
This function decompresses the region between @var{start} and
@var{end}, using built-in zlib decompression. The region should
contain data that were compressed with gzip or zlib. On success, the
function replaces the contents of the region with the decompressed
data. On failure, the function leaves the region unchanged and
returns @code{nil}. This function can be called only in unibyte
buffers.
data. If @var{allow-partial} is @code{nil} or omitted, then on
failure, the function leaves the region unchanged and returns
@code{nil}. Otherwise, it returns the number of bytes that were not
decompressed and replaces the region text by whatever data was
successfully decompressed. This function can be called only in
unibyte buffers.
@end defun
......
......@@ -1672,6 +1672,12 @@ are implemented in C using the Jansson library.
and 'flatten' it such that the result is a list of all the terminal
nodes.
+++
** 'zlib-decompress-region' can partially decompress corrupted data.
If the new optional ALLOW-PARTIAL argument is passed, then the data
that was decompressed successfully before failing will be inserted
into the buffer.
** Mailcap
---
......
......@@ -939,7 +939,8 @@ should be shown to the user."
(goto-char (point-min))
success))
(declare-function zlib-decompress-region "decompress.c" (start end))
(declare-function zlib-decompress-region "decompress.c"
(start end &optional allow-partial))
(defun url-handle-content-transfer-encoding ()
(let ((encoding (mail-fetch-field "content-encoding")))
......@@ -951,7 +952,7 @@ should be shown to the user."
(widen)
(goto-char (point-min))
(when (search-forward "\n\n")
(zlib-decompress-region (point) (point-max)))))))
(zlib-decompress-region (point) (point-max) t))))))
;; Miscellaneous
(defun url-http-activate-callback ()
......
......@@ -120,12 +120,18 @@ DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0,
DEFUN ("zlib-decompress-region", Fzlib_decompress_region,
Szlib_decompress_region,
2, 2, 0,
2, 3, 0,
doc: /* Decompress a gzip- or zlib-compressed region.
Replace the text in the region by the decompressed data.
On failure, return nil and leave the data in place.
If optional parameter ALLOW-PARTIAL is nil or omitted, then on
failure, return nil and leave the data in place. Otherwise, return
the number of bytes that were not decompressed and replace the region
text by whatever data was successfully decompressed (similar to gzip).
If decompression is completely successful return t.
This function can be called only in unibyte buffers. */)
(Lisp_Object start, Lisp_Object end)
(Lisp_Object start, Lisp_Object end, Lisp_Object allow_partial)
{
ptrdiff_t istart, iend, pos_byte;
z_stream stream;
......@@ -206,8 +212,14 @@ This function can be called only in unibyte buffers. */)
}
while (inflate_status == Z_OK);
Lisp_Object ret = Qt;
if (inflate_status != Z_STREAM_END)
return unbind_to (count, Qnil);
{
if (!NILP (allow_partial))
ret = make_int (iend - pos_byte);
else
return unbind_to (count, Qnil);
}
unwind_data.start = 0;
......@@ -218,7 +230,7 @@ This function can be called only in unibyte buffers. */)
signal_after_change (istart, iend - istart, unwind_data.nbytes);
update_compositions (istart, istart, CHECK_HEAD);
return unbind_to (count, Qt);
return unbind_to (count, ret);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment