aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2019-07-02 18:02:51 -0400
committerStefan Monnier2019-07-02 18:02:51 -0400
commitfe3676fe18577643d9d247db2e6c32691f3acf80 (patch)
tree638a1ef4ce2f7a82aea4929d81463affc111351d /src
parentc136f93dfad1a55c653e844d3cf25f804744275e (diff)
downloademacs-fe3676fe18577643d9d247db2e6c32691f3acf80.tar.gz
emacs-fe3676fe18577643d9d247db2e6c32691f3acf80.zip
(Finsert_file_contents): Keep buffer consistent in non-local exit
* src/fileio.c (decide_coding_unwind): Delete function. (Finsert_file_contents): Don't let invalid multibyte byte sequences escape when we exit non-locally. * test/src/fileio-tests.el (fileio-tests--insert-file-interrupt): New test.
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c65
1 files changed, 22 insertions, 43 deletions
diff --git a/src/fileio.c b/src/fileio.c
index fc938ebe1fa..2825c1b54c6 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3459,42 +3459,6 @@ otherwise, if FILE2 does not exist, the answer is t. */)
3459 3459
3460enum { READ_BUF_SIZE = MAX_ALLOCA }; 3460enum { READ_BUF_SIZE = MAX_ALLOCA };
3461 3461
3462/* This function is called after Lisp functions to decide a coding
3463 system are called, or when they cause an error. Before they are
3464 called, the current buffer is set unibyte and it contains only a
3465 newly inserted text (thus the buffer was empty before the
3466 insertion).
3467
3468 The functions may set markers, overlays, text properties, or even
3469 alter the buffer contents, change the current buffer.
3470
3471 Here, we reset all those changes by:
3472 o set back the current buffer.
3473 o move all markers and overlays to BEG.
3474 o remove all text properties.
3475 o set back the buffer multibyteness. */
3476
3477static void
3478decide_coding_unwind (Lisp_Object unwind_data)
3479{
3480 Lisp_Object multibyte, undo_list, buffer;
3481
3482 multibyte = XCAR (unwind_data);
3483 unwind_data = XCDR (unwind_data);
3484 undo_list = XCAR (unwind_data);
3485 buffer = XCDR (unwind_data);
3486
3487 set_buffer_internal (XBUFFER (buffer));
3488 adjust_markers_for_delete (BEG, BEG_BYTE, Z, Z_BYTE);
3489 adjust_overlays_for_delete (BEG, Z - BEG);
3490 set_buffer_intervals (current_buffer, NULL);
3491 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3492
3493 /* Now we are safe to change the buffer's multibyteness directly. */
3494 bset_enable_multibyte_characters (current_buffer, multibyte);
3495 bset_undo_list (current_buffer, undo_list);
3496}
3497
3498/* Read from a non-regular file. Return the number of bytes read. */ 3462/* Read from a non-regular file. Return the number of bytes read. */
3499 3463
3500union read_non_regular 3464union read_non_regular
@@ -4457,15 +4421,14 @@ by calling `format-decode', which see. */)
4457 enable-multibyte-characters directly here without taking 4421 enable-multibyte-characters directly here without taking
4458 care of marker adjustment. By this way, we can run Lisp 4422 care of marker adjustment. By this way, we can run Lisp
4459 program safely before decoding the inserted text. */ 4423 program safely before decoding the inserted text. */
4460 Lisp_Object unwind_data; 4424 Lisp_Object multibyte
4425 = BVAR (current_buffer, enable_multibyte_characters);
4426 Lisp_Object undo_list = BVAR (current_buffer, undo_list);
4461 ptrdiff_t count1 = SPECPDL_INDEX (); 4427 ptrdiff_t count1 = SPECPDL_INDEX ();
4462 4428
4463 unwind_data = Fcons (BVAR (current_buffer, enable_multibyte_characters),
4464 Fcons (BVAR (current_buffer, undo_list),
4465 Fcurrent_buffer ()));
4466 bset_enable_multibyte_characters (current_buffer, Qnil); 4429 bset_enable_multibyte_characters (current_buffer, Qnil);
4467 bset_undo_list (current_buffer, Qt); 4430 bset_undo_list (current_buffer, Qt);
4468 record_unwind_protect (decide_coding_unwind, unwind_data); 4431 record_unwind_protect (restore_buffer, Fcurrent_buffer ());
4469 4432
4470 if (inserted > 0 && ! NILP (Vset_auto_coding_function)) 4433 if (inserted > 0 && ! NILP (Vset_auto_coding_function))
4471 { 4434 {
@@ -4484,8 +4447,24 @@ by calling `format-decode', which see. */)
4484 coding_system = XCAR (coding_system); 4447 coding_system = XCAR (coding_system);
4485 } 4448 }
4486 unbind_to (count1, Qnil); 4449 unbind_to (count1, Qnil);
4487 inserted = Z_BYTE - BEG_BYTE; 4450 /* We're about to "delete" the text by moving it back into the gap
4488 } 4451 (right before calling decode_coding_gap).
4452 So move markers that set-auto-coding might have created to BEG,
4453 just in case. */
4454 adjust_markers_for_delete (BEG, BEG_BYTE, Z, Z_BYTE);
4455 adjust_overlays_for_delete (BEG, Z - BEG);
4456 set_buffer_intervals (current_buffer, NULL);
4457 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
4458
4459 /* Change the buffer's multibyteness directly. We used to do this
4460 from within unbind_to, but it was unsafe since the bytes
4461 may contain invalid sequences for a multibyte buffer (which is OK
4462 here since we'll decode them before anyone else gets to see
4463 them, but is dangerous when we're doing a non-local exit). */
4464 bset_enable_multibyte_characters (current_buffer, multibyte);
4465 bset_undo_list (current_buffer, undo_list);
4466 inserted = Z_BYTE - BEG_BYTE;
4467 }
4489 4468
4490 if (NILP (coding_system)) 4469 if (NILP (coding_system))
4491 coding_system = Qundecided; 4470 coding_system = Qundecided;