X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/53b64418c20b6288e0e3a589b61db47861a575b6..2bfa3d3e1fb347ba76bddf77f3e288049635821d:/src/decompress.c diff --git a/src/decompress.c b/src/decompress.c index b7cd8a6c40..9dfec8818b 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -1,5 +1,5 @@ /* Interface to zlib. - Copyright (C) 2013 Free Software Foundation, Inc. + Copyright (C) 2013-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -85,7 +85,7 @@ init_zlib_functions (void) struct decompress_unwind_data { - ptrdiff_t old_point, start; + ptrdiff_t old_point, start, nbytes; z_stream *stream; }; @@ -95,12 +95,14 @@ unwind_decompress (void *ddata) struct decompress_unwind_data *data = ddata; fn_inflateEnd (data->stream); - /* Delete any uncompressed data already inserted and restore point. */ + /* Delete any uncompressed data already inserted on error. */ if (data->start) - { - del_range (data->start, PT); - SET_PT (data->old_point); - } + del_range (data->start, data->start + data->nbytes); + + /* Put point where it was, or if the buffer has shrunk because the + compressed data is bigger than the uncompressed, at + point-max. */ + SET_PT (min (data->old_point, ZV)); } DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0, @@ -114,7 +116,8 @@ DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0, else { Lisp_Object status; - status = init_zlib_functions () ? Qt : Qnil; + zlib_initialized = init_zlib_functions (); + status = zlib_initialized ? Qt : Qnil; Vlibrary_cache = Fcons (Fcons (Qzlib_dll, status), Vlibrary_cache); return status; } @@ -136,7 +139,7 @@ This function can be called only in unibyte buffers. */) z_stream stream; int inflate_status; struct decompress_unwind_data unwind_data; - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); validate_region (&start, &end); @@ -146,6 +149,10 @@ This function can be called only in unibyte buffers. */) #ifdef WINDOWSNT if (!zlib_initialized) zlib_initialized = init_zlib_functions (); + if (!zlib_initialized) { + dynwind_end (); + return Qnil; + } #endif /* This is a unibyte buffer, so character positions and bytes are @@ -160,15 +167,17 @@ This function can be called only in unibyte buffers. */) stream.avail_in = 0; stream.next_in = Z_NULL; - /* The magic number 32 apparently means "autodect both the gzip and + /* The magic number 32 apparently means "autodetect both the gzip and zlib formats" according to zlib.h. */ - if (fn_inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK) + if (fn_inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK) { + dynwind_end (); return Qnil; + } unwind_data.start = iend; unwind_data.stream = &stream; unwind_data.old_point = PT; - + unwind_data.nbytes = 0; record_unwind_protect_ptr (unwind_decompress, &unwind_data); /* Insert the decompressed data at the end of the compressed data. */ @@ -181,12 +190,10 @@ This function can be called only in unibyte buffers. */) { /* Maximum number of bytes that one 'inflate' call should read and write. Do not make avail_out too large, as that might unduly delay C-g. - In any case zlib requires that these values not exceed UINT_MAX. */ + zlib requires that avail_in and avail_out not exceed UINT_MAX. */ ptrdiff_t avail_in = min (iend - pos_byte, UINT_MAX); - enum { avail_out = 1 << 14 }; - verify (avail_out <= UINT_MAX); - - ptrdiff_t decompressed; + int avail_out = 16 * 1024; + int decompressed; if (GAP_SIZE < avail_out) make_gap (avail_out - GAP_SIZE); @@ -198,19 +205,24 @@ This function can be called only in unibyte buffers. */) pos_byte += avail_in - stream.avail_in; decompressed = avail_out - stream.avail_out; insert_from_gap (decompressed, decompressed, 0); + unwind_data.nbytes += decompressed; QUIT; } while (inflate_status == Z_OK); - if (inflate_status != Z_STREAM_END) - return unbind_to (count, Qnil); + if (inflate_status != Z_STREAM_END){ + + dynwind_end (); + return Qnil; + } unwind_data.start = 0; /* Delete the compressed data. */ del_range (istart, iend); - return unbind_to (count, Qt); + dynwind_end (); + return Qt; } @@ -220,9 +232,9 @@ This function can be called only in unibyte buffers. */) void syms_of_decompress (void) { +#include "decompress.x" + DEFSYM (Qzlib_dll, "zlib"); - defsubr (&Szlib_decompress_region); - defsubr (&Szlib_available_p); } #endif /* HAVE_ZLIB */