Package: emacs;
Reported by: Werner LEMBERG <wl <at> gnu.org>
Date: Sat, 29 Jun 2019 11:19:01 UTC
Severity: normal
Done: Stefan Monnier <monnier <at> iro.umontreal.ca>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Stefan Monnier <monnier <at> iro.umontreal.ca> To: Eli Zaretskii <eliz <at> gnu.org> Cc: wl <at> gnu.org, 36431 <at> debbugs.gnu.org Subject: bug#36431: Crash in marker.c:337 Date: Sat, 29 Jun 2019 18:56:53 -0400
>> > while sending an e-mail with `mew', I get the attached crash. This is >> > something new, which I haven't experienced before. I can reliably >> > repeat it. Hmm... indeed insert-file-contents takes some shortcuts when inserting the new text into the buffer which can break the expected invariants. I don't really know how to reproduce your bug, but I think I have an idea of what might be going on. Can you try the patch below, to see if it fixes your problem? Stefan diff --git a/src/fileio.c b/src/fileio.c index ed1d2aedf3..a7be05ef5c 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3741,6 +3741,7 @@ because (1) it preserves some marker positions and (2) it puts less data CHECK_CODING_SYSTEM (Vcoding_system_for_read); Fset (Qbuffer_file_coding_system, Vcoding_system_for_read); } + eassert (inserted == 0); goto notfound; } @@ -3767,7 +3768,10 @@ because (1) it preserves some marker positions and (2) it puts less data not_regular = 1; if (! NILP (visit)) - goto notfound; + { + eassert (inserted == 0); + goto notfound; + } if (! NILP (replace) || ! NILP (beg) || ! NILP (end)) xsignal2 (Qfile_error, @@ -4435,19 +4439,6 @@ because (1) it preserves some marker positions and (2) it puts less data if (how_much < 0) report_file_error ("Read error", orig_filename); - /* Make the text read part of the buffer. */ - GAP_SIZE -= inserted; - GPT += inserted; - GPT_BYTE += inserted; - ZV += inserted; - ZV_BYTE += inserted; - Z += inserted; - Z_BYTE += inserted; - - if (GAP_SIZE > 0) - /* Put an anchor to ensure multi-byte form ends at gap. */ - *GPT_ADDR = 0; - notfound: if (NILP (coding_system)) @@ -4457,6 +4448,7 @@ because (1) it preserves some marker positions and (2) it puts less data Note that we can get here only if the buffer was empty before the insertion. */ + eassert (Z == BEG); if (!NILP (Vcoding_system_for_read)) coding_system = Vcoding_system_for_read; @@ -4477,6 +4469,16 @@ because (1) it preserves some marker positions and (2) it puts less data bset_undo_list (current_buffer, Qt); record_unwind_protect (decide_coding_unwind, unwind_data); + /* Make the text read part of the buffer. */ + eassert (NILP (BVAR (current_buffer, enable_multibyte_characters))); + GAP_SIZE -= inserted; + GPT += inserted; + GPT_BYTE += inserted; + ZV += inserted; + ZV_BYTE += inserted; + Z += inserted; + Z_BYTE += inserted; + if (inserted > 0 && ! NILP (Vset_auto_coding_function)) { coding_system = call2 (Vset_auto_coding_function, @@ -4493,8 +4495,18 @@ because (1) it preserves some marker positions and (2) it puts less data if (CONSP (coding_system)) coding_system = XCAR (coding_system); } - unbind_to (count1, Qnil); + + /* Move the text back into the gap. Do it now, before we set the + buffer back to multibyte, since the bytes may very well not be + valid for a multibyte buffer. */ + set_point_both (BEG, BEG_BYTE); + move_gap_both (BEG, BEG_BYTE); inserted = Z_BYTE - BEG_BYTE; + GAP_SIZE += inserted; + ZV = Z = BEG; + ZV_BYTE = Z_BYTE = BEG_BYTE; + + unbind_to (count1, Qnil); } if (NILP (coding_system)) @@ -4528,22 +4540,28 @@ because (1) it preserves some marker positions and (2) it puts less data } } + eassert (PT == GPT); + coding.dst_multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); if (CODING_MAY_REQUIRE_DECODING (&coding) && (inserted > 0 || CODING_REQUIRE_FLUSHING (&coding))) { - move_gap_both (PT, PT_BYTE); - GAP_SIZE += inserted; - ZV_BYTE -= inserted; - Z_BYTE -= inserted; - ZV -= inserted; - Z -= inserted; decode_coding_gap (&coding, inserted, inserted); inserted = coding.produced_char; coding_system = CODING_ID_NAME (coding.id); } else if (inserted > 0) { + /* Make the text read part of the buffer. */ + eassert (NILP (BVAR (current_buffer, enable_multibyte_characters))); + GAP_SIZE -= inserted; + GPT += inserted; + GPT_BYTE += inserted; + ZV += inserted; + ZV_BYTE += inserted; + Z += inserted; + Z_BYTE += inserted; + invalidate_buffer_caches (current_buffer, PT, PT + inserted); adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, inserted);
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.