Subject: bug#36431: Crash in marker.c:337

From: Eli Zaretskii <[email-masked]>
Date: Wed, 03 Jul 2019 07:55:18 +0300

> From: Stefan Monnier <[email-masked]>
> Cc: [email-masked],  [email-masked]
> Date: Wed, 03 Jul 2019 00:21:54 -0400
> 
> -      move_gap_both (PT, PT_BYTE);
> -      GAP_SIZE += inserted;
> -      ZV_BYTE -= inserted;
> -      Z_BYTE -= inserted;
> -      ZV -= inserted;
> -      Z -= inserted;
> +      if (ingap)
> +        { /* Text is at beginning of gap, move it to the end.  */
> +          memmove (GAP_END_ADDR - inserted, GPT_ADDR, inserted);
> +        }
> +      else
> +        { /* Text is inside the buffer; move it to end of the gap.  */
> +          move_gap_both (PT, PT_BYTE);
> +	  eassert (inserted == Z_BYTE - BEG_BYTE);
> +          GAP_SIZE += inserted;
> +          ZV = Z = GPT = BEG;
> +          ZV_BYTE = Z_BYTE = GPT_BYTE = BEG_BYTE;
> +          /* Now we are safe to change the buffer's multibyteness directly.  */
> +          bset_enable_multibyte_characters (current_buffer, multibyte);
> +        }
> +

Why did you prefer to use memmove instead of move_gap_both?  AFAIK the
latter actually does the former under the hood, but why expose that
implementation detail outside of insdel.c?