Subject: Re: bug#5131: Subject: 23.1; interaction of transpose-regions with markers and multibyte chars
From: Eli Zaretskii <[email-masked]>
To: [email-masked]
Cc: [email-masked], [email-masked], [email-masked]
Date: Tue, 19 Jul 2016 19:05:09 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

> From: [email-masked]
> Date: Sun, 17 Jul 2016 00:46:34 -0400
> Cc: [email-masked], [email-masked]
> 
> Andrew Hyatt <[email-masked]> writes:
> 
> > Sorry for the late reply.  I can reproduce the problem of unexpected
> > characters when transposing using markers in Emacs 25.
> >
> > [email-masked] writes:
> >
> >> ;-*- mode: lisp-interaction; coding: utf-8-unix -*-
> >>
> >> ; case 1: abcd      was: abcd
> >> ; case 2: ÷bcd      was: ÷bcd
> >> ; case 3: ÷ab"äé    was: ÷ab"äé
> >>
> >> (progn (defvar start nil) (defvar len nil)) ;do \C-j here
> >>
> >> ; Using markers to move multi-byte characters may cause problems
> >>
> >> (progn (setq begm (make-marker)) (setq endm (make-marker))) ;do \C-j here
> >>
> >> (defun reverse-all ()
> >> (set-marker begm start)
> >> (set-marker endm (+ start (1- len)))
> >>  (while (> endm begm)
> >> (progn (transpose-regions begm (1+ begm) endm (1+ endm) t)
> >>  (set-marker begm (1+ begm))
> >>  (set-marker endm (1- endm))))) ;do \C-j here
> >>
> >> ;case1
> >> (progn (setq start 64) (setq len 4) (reverse-all)) ;do \C-j here
> >>
> >> ;case2
> >> (progn (setq start 94) (setq len 4) (reverse-all)) ;do \C-j here
> >>
> >> ;case3
> >> (progn (setq start 124) (setq len 6) (reverse-all)) ;do \C-j here
> 
> With the latest emacs-25 branch after evaluating up to case3 here, I get
> an abort, here is the backtrace:
> 
> (gdb) bt
> #0  0x00007ffff1218d59 in raise () from /usr/lib/libpthread.so.0
> #1  0x00000000005738c4 in terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at emacs.c:381
> #2  0x0000000000600d84 in die (msg=0x6f4140 "IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))", file=0x6f1ff0 "xdisp.c", 
>     line=7442) at alloc.c:7223
> #3  0x0000000000452c1c in set_iterator_to_next (it=0x7fffffff90f0, reseat_p=true) at xdisp.c:7442

That's because your build is with --enable-checking, while Andrew's
probably isn't.  This recipe causes some markers to have invalid
bytepos values, so any code that calls CHAR_TO_BYTE is likely to crash
or cause assertion violations.

It feels strange to fix bugs that were introduced 18 years ago; I
guess almost no one invokes transpose-regions with last argument
non-nil.

Fixed on the master branch.  I'm closing the bug; feel free to reopen
if there are some left-overs.

Thanks.