aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mackenzie2018-01-12 16:31:35 +0000
committerAlan Mackenzie2018-01-12 16:31:35 +0000
commit0aec5b8a5607505c1b492c10b67214f52f33972a (patch)
treec6b40d403503086612a7548c061a85754177b531 /src
parent30e6e312d950400feac858e46f098f360a90d575 (diff)
downloademacs-0aec5b8a5607505c1b492c10b67214f52f33972a.tar.gz
emacs-0aec5b8a5607505c1b492c10b67214f52f33972a.zip
Make Fzlib_decompress_region always call the change hooks in a balanced way.
This means there will be exactly one call of each of before- and after-change-functions, regardless of whether or not the decompression succeeds, and these calls will refer to corresponding buffer regions. src/decompress.c (struct decompress_unwind_data): add a new field, orig. (unwind_decompress): Use del_range_2 and update_compositions in place of del_range, to avoid unwanted change hook calls. Call signal_after_change for the failed case. (Fzlib_decompress_region): Call modify_txt for a before-change-functions. Set the new field orig of unwind_data to the region's start. Use del_range_2 and update_compositions in place of del_range to avoid unwanted change hook calls. Call signal_after_change for the successful case.
Diffstat (limited to 'src')
-rw-r--r--src/decompress.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/src/decompress.c b/src/decompress.c
index 41de6da1dd2..6f75f821c40 100644
--- a/src/decompress.c
+++ b/src/decompress.c
@@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
24 24
25#include "lisp.h" 25#include "lisp.h"
26#include "buffer.h" 26#include "buffer.h"
27#include "composite.h"
27 28
28#include <verify.h> 29#include <verify.h>
29 30
@@ -66,7 +67,7 @@ init_zlib_functions (void)
66 67
67struct decompress_unwind_data 68struct decompress_unwind_data
68{ 69{
69 ptrdiff_t old_point, start, nbytes; 70 ptrdiff_t old_point, orig, start, nbytes;
70 z_stream *stream; 71 z_stream *stream;
71}; 72};
72 73
@@ -76,10 +77,19 @@ unwind_decompress (void *ddata)
76 struct decompress_unwind_data *data = ddata; 77 struct decompress_unwind_data *data = ddata;
77 inflateEnd (data->stream); 78 inflateEnd (data->stream);
78 79
79 /* Delete any uncompressed data already inserted on error. */ 80 /* Delete any uncompressed data already inserted on error, but
81 without calling the change hooks. */
80 if (data->start) 82 if (data->start)
81 del_range (data->start, data->start + data->nbytes); 83 {
82 84 del_range_2 (data->start, data->start, /* byte, char offsets the same */
85 data->start + data->nbytes, data->start + data->nbytes,
86 0);
87 update_compositions (data->start, data->start, CHECK_HEAD);
88 /* "Balance" the before-change-functions call, which would
89 otherwise be left "hanging". */
90 signal_after_change (data->orig, data->start - data->orig,
91 data->start - data->orig);
92 }
83 /* Put point where it was, or if the buffer has shrunk because the 93 /* Put point where it was, or if the buffer has shrunk because the
84 compressed data is bigger than the uncompressed, at 94 compressed data is bigger than the uncompressed, at
85 point-max. */ 95 point-max. */
@@ -141,6 +151,10 @@ This function can be called only in unibyte buffers. */)
141 the same. */ 151 the same. */
142 istart = XINT (start); 152 istart = XINT (start);
143 iend = XINT (end); 153 iend = XINT (end);
154
155 /* Do the following before manipulating the gap. */
156 modify_text (istart, iend);
157
144 move_gap_both (iend, iend); 158 move_gap_both (iend, iend);
145 159
146 stream.zalloc = Z_NULL; 160 stream.zalloc = Z_NULL;
@@ -154,6 +168,7 @@ This function can be called only in unibyte buffers. */)
154 if (inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK) 168 if (inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK)
155 return Qnil; 169 return Qnil;
156 170
171 unwind_data.orig = istart;
157 unwind_data.start = iend; 172 unwind_data.start = iend;
158 unwind_data.stream = &stream; 173 unwind_data.stream = &stream;
159 unwind_data.old_point = PT; 174 unwind_data.old_point = PT;
@@ -196,7 +211,11 @@ This function can be called only in unibyte buffers. */)
196 unwind_data.start = 0; 211 unwind_data.start = 0;
197 212
198 /* Delete the compressed data. */ 213 /* Delete the compressed data. */
199 del_range (istart, iend); 214 del_range_2 (istart, istart, /* byte and char offsets are the same. */
215 iend, iend, 0);
216
217 signal_after_change (istart, iend - istart, unwind_data.nbytes);
218 update_compositions (istart, istart, CHECK_HEAD);
200 219
201 return unbind_to (count, Qt); 220 return unbind_to (count, Qt);
202} 221}