From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.bugs Subject: bug#36431: Crash in marker.c:337 Date: Tue, 02 Jul 2019 12:29:34 -0400 Message-ID: References: <831rzch9nd.fsf@gnu.org> <83zhm0fuqg.fsf@gnu.org> <20190630.092626.1377512789964814286.wl@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="204827"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: 36431@debbugs.gnu.org To: Werner LEMBERG Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Jul 02 19:51:01 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1hiMvl-000qOm-41 for geb-bug-gnu-emacs@m.gmane.org; Tue, 02 Jul 2019 19:51:01 +0200 Original-Received: from localhost ([::1]:55768 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hiMio-0004MR-Ms for geb-bug-gnu-emacs@m.gmane.org; Tue, 02 Jul 2019 13:37:38 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:48906) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hiLfQ-0006dV-FN for bug-gnu-emacs@gnu.org; Tue, 02 Jul 2019 12:30:06 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hiLfO-0000FB-QD for bug-gnu-emacs@gnu.org; Tue, 02 Jul 2019 12:30:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:38955) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hiLfO-0000Ev-ML for bug-gnu-emacs@gnu.org; Tue, 02 Jul 2019 12:30:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1hiLfO-0003QT-F6 for bug-gnu-emacs@gnu.org; Tue, 02 Jul 2019 12:30:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 02 Jul 2019 16:30:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36431 X-GNU-PR-Package: emacs Original-Received: via spool by 36431-submit@debbugs.gnu.org id=B36431.156208498713126 (code B ref 36431); Tue, 02 Jul 2019 16:30:02 +0000 Original-Received: (at 36431) by debbugs.gnu.org; 2 Jul 2019 16:29:47 +0000 Original-Received: from localhost ([127.0.0.1]:47776 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hiLf8-0003Pd-MJ for submit@debbugs.gnu.org; Tue, 02 Jul 2019 12:29:47 -0400 Original-Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:16966) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hiLf6-0003PO-4T for 36431@debbugs.gnu.org; Tue, 02 Jul 2019 12:29:44 -0400 Original-Received: from pmg3.iro.umontreal.ca (localhost [127.0.0.1]) by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id DC61744445C; Tue, 2 Jul 2019 12:29:37 -0400 (EDT) Original-Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id E191344445A; Tue, 2 Jul 2019 12:29:35 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1562084975; bh=MALSdmTD8IuF81nVMjWxkQjt9qlXNJIyqIuxw0vYfXA=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=PwHwdqxZrB0FDsoMLYGKudLvxr7YSfJCxtq4ZRpsR0vXguGg3HieEggzhaQD4SuHA pYvdGVOL+HeFsnCbJat8HXVyRgLUOkYa6xfS2eUNCwBE7a4zjK0oaoSYBjf2+zyQiZ 8bQ5cUQuziS55C3NRYg+3H+YVjKv4JuwjKdMgwiYFAKnc08O3Bu25YTHmO12IaJamX c7zIx1C6V3P8GhX2Umk/2BqA7H1ReNSqqI3mXY5R1I6pOz6fwuEl+DmTz6JaKiqLnC +IM0S921FMMO7oxmw7wTkfQtOkOZyebqDcT6wzQZEGJtxQncGo0AO/dSo0f8qrkAkv f28Qt09Z3LljA== Original-Received: from pastel (76-10-151-214.dsl.teksavvy.com [76.10.151.214]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 6FC4E120BC2; Tue, 2 Jul 2019 12:29:35 -0400 (EDT) In-Reply-To: (Stefan Monnier's message of "Sun, 30 Jun 2019 09:14:51 -0400") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:161967 Archived-At: Stefan Monnier writes: >> No, it doesn't fix the problem, unfortunately =E2=80=93 mew doesn't star= t at >> all with this patch; the error message shows a string that is >> definitely cropped. > > Yes, I also saw other problems with the patch. > I'll send an updated patch later. Can you try the patch below? Stefan =20=20=20=20=20=20=20=20 diff --git a/src/fileio.c b/src/fileio.c index ed1d2aedf3..1fea93fa8e 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3741,6 +3741,7 @@ by calling `format-decode', which see. */) CHECK_CODING_SYSTEM (Vcoding_system_for_read); Fset (Qbuffer_file_coding_system, Vcoding_system_for_read); } + eassert (inserted =3D=3D 0); goto notfound; } =20 @@ -3767,7 +3768,10 @@ by calling `format-decode', which see. */) not_regular =3D 1; =20 if (! NILP (visit)) - goto notfound; + { + eassert (inserted =3D=3D 0); + goto notfound; + } =20 if (! NILP (replace) || ! NILP (beg) || ! NILP (end)) xsignal2 (Qfile_error, @@ -4435,19 +4439,6 @@ by calling `format-decode', which see. */) if (how_much < 0) report_file_error ("Read error", orig_filename); =20 - /* Make the text read part of the buffer. */ - GAP_SIZE -=3D inserted; - GPT +=3D inserted; - GPT_BYTE +=3D inserted; - ZV +=3D inserted; - ZV_BYTE +=3D inserted; - Z +=3D inserted; - Z_BYTE +=3D inserted; - - if (GAP_SIZE > 0) - /* Put an anchor to ensure multi-byte form ends at gap. */ - *GPT_ADDR =3D 0; - notfound: =20 if (NILP (coding_system)) @@ -4457,6 +4448,7 @@ by calling `format-decode', which see. */) =20 Note that we can get here only if the buffer was empty before the insertion. */ + eassert (Z =3D=3D BEG); =20 if (!NILP (Vcoding_system_for_read)) coding_system =3D Vcoding_system_for_read; @@ -4477,6 +4469,10 @@ by calling `format-decode', which see. */) bset_undo_list (current_buffer, Qt); record_unwind_protect (decide_coding_unwind, unwind_data); =20 + /* Make the text read part of the buffer. */ + eassert (NILP (BVAR (current_buffer, enable_multibyte_characters= ))); + insert_from_gap_1 (inserted, inserted, false); + if (inserted > 0 && ! NILP (Vset_auto_coding_function)) { coding_system =3D call2 (Vset_auto_coding_function, @@ -4493,8 +4489,22 @@ by calling `format-decode', which see. */) if (CONSP (coding_system)) coding_system =3D XCAR (coding_system); } - unbind_to (count1, Qnil); + + /* Move the text back to the beginning of 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); + /* In general this may have to move all the bytes, but here + this can't move more bytes than were moved during the executi= on + of Vset_auto_coding_function, which is normally 0 (because it + normally doesn't modify the buffer). */ + move_gap_both (Z, Z_BYTE); inserted =3D Z_BYTE - BEG_BYTE; + GAP_SIZE +=3D inserted; + ZV =3D Z =3D GPT =3D BEG; + ZV_BYTE =3D Z_BYTE =3D GPT_BYTE =3D BEG_BYTE; + + unbind_to (count1, Qnil); } =20 if (NILP (coding_system)) @@ -4528,22 +4538,29 @@ by calling `format-decode', which see. */) } } =20 - coding.dst_multibyte =3D ! NILP (BVAR (current_buffer, enable_multibyte_= characters)); + eassert (PT =3D=3D GPT); + + coding.dst_multibyte + =3D ! 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 +=3D inserted; - ZV_BYTE -=3D inserted; - Z_BYTE -=3D inserted; - ZV -=3D inserted; - Z -=3D inserted; + /* Now we have all the new bytes at the beginning of the gap, + but `decode_coding_gap` needs them at the end of the gap, so + we need to move them. + FIXME: We should arrange for the bytes to be already at the right + place so we don't need to memmove them in the common case! */ + memmove (GAP_END_ADDR - inserted, GPT_ADDR, inserted); decode_coding_gap (&coding, inserted, inserted); inserted =3D coding.produced_char; coding_system =3D 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))); + insert_from_gap_1 (inserted, inserted, false); + invalidate_buffer_caches (current_buffer, PT, PT + inserted); adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, inserted); diff --git a/src/insdel.c b/src/insdel.c index 85fffd8fd1..51371ee13c 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -115,7 +115,7 @@ gap_left (ptrdiff_t charpos, ptrdiff_t bytepos, bool ne= wgap) i =3D GPT_BYTE; to =3D GAP_END_ADDR; from =3D GPT_ADDR; - new_s1 =3D GPT_BYTE; + new_s1 =3D GPT_BYTE; /* May point in the middle of multibyte sequences. = */ =20 /* Now copy the characters. To move the gap down, copy characters up. */ @@ -133,6 +133,7 @@ gap_left (ptrdiff_t charpos, ptrdiff_t bytepos, bool ne= wgap) make_gap_smaller set inhibit-quit. */ if (QUITP) { + /* FIXME: This can point in the middle of a multibyte character.= */ bytepos =3D new_s1; charpos =3D BYTE_TO_CHAR (bytepos); break; @@ -164,7 +165,7 @@ gap_right (ptrdiff_t charpos, ptrdiff_t bytepos) { register unsigned char *to, *from; register ptrdiff_t i; - ptrdiff_t new_s1; + ptrdiff_t new_s1; /* May point in the middle of multibyte sequences. */ =20 BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT); =20 @@ -189,6 +190,7 @@ gap_right (ptrdiff_t charpos, ptrdiff_t bytepos) make_gap_smaller set inhibit-quit. */ if (QUITP) { + /* FIXME: This can point in the middle of a multibyte character.= */ bytepos =3D new_s1; charpos =3D BYTE_TO_CHAR (bytepos); break; @@ -1072,6 +1074,31 @@ insert_from_string_1 (Lisp_Object string, ptrdiff_t = pos, ptrdiff_t pos_byte, /* Insert a sequence of NCHARS chars which occupy NBYTES bytes starting at GAP_END_ADDR - NBYTES (if text_at_gap_tail) and at + GPT_ADDR (if not text_at_gap_tail). + Contrary to insert_from_gap, this does not invalidate any cache, + nor update any markers, nor record any buffer modification information + of any sort. */ +void +insert_from_gap_1 (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_ta= il) +{ + GAP_SIZE -=3D nbytes; + if (! text_at_gap_tail) + { + GPT +=3D nchars; + GPT_BYTE +=3D nbytes; + } + ZV +=3D nchars; + Z +=3D nchars; + ZV_BYTE +=3D nbytes; + Z_BYTE +=3D nbytes; + + /* Put an anchor to ensure multi-byte form ends at gap. */ + if (GAP_SIZE > 0) *(GPT_ADDR) =3D 0; + eassert (GPT <=3D GPT_BYTE); +} + +/* Insert a sequence of NCHARS chars which occupy NBYTES bytes + starting at GAP_END_ADDR - NBYTES (if text_at_gap_tail) and at GPT_ADDR (if not text_at_gap_tail). */ =20 void @@ -1090,19 +1117,7 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes,= bool text_at_gap_tail) record_insert (GPT, nchars); modiff_incr (&MODIFF); =20 - GAP_SIZE -=3D nbytes; - if (! text_at_gap_tail) - { - GPT +=3D nchars; - GPT_BYTE +=3D nbytes; - } - ZV +=3D nchars; - Z +=3D nchars; - ZV_BYTE +=3D nbytes; - Z_BYTE +=3D nbytes; - if (GAP_SIZE > 0) *(GPT_ADDR) =3D 0; /* Put an anchor. */ - - eassert (GPT <=3D GPT_BYTE); + insert_from_gap_1 (nchars, nbytes, text_at_gap_tail); =20 adjust_overlays_for_insert (ins_charpos, nchars); adjust_markers_for_insert (ins_charpos, ins_bytepos, diff --git a/src/lisp.h b/src/lisp.h index a0619e64f2..1a1d8ee7e4 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3667,6 +3667,7 @@ extern void insert (const char *, ptrdiff_t); extern void insert_and_inherit (const char *, ptrdiff_t); extern void insert_1_both (const char *, ptrdiff_t, ptrdiff_t, bool, bool, bool); +extern void insert_from_gap_1 (ptrdiff_t, ptrdiff_t, bool text_at_gap_tail= ); extern void insert_from_gap (ptrdiff_t, ptrdiff_t, bool text_at_gap_tail); extern void insert_from_string (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool);