Subject: bug#77924: 31.0.50; [Feature branch] Change marker implementation

From: Gerd Möllmann <[email-masked]>
Date: Sun, 27 Apr 2025 04:30:59 +0200

Stefan Monnier <[email-masked]> writes:

>> -  /* Don't scan forward if CHARPOS is exactly on the previous known
>> -     position because the index bytepos can be in the middle of a
>> -     character, which is found by scanning backwards.  */
>> -  ptrdiff_t bytepos
>> -    = (charpos == prev.charpos ? bytepos_of_head (b, prev.bytepos)
>> -       : (charpos - prev.charpos < next.charpos - charpos
>> -	  ? bytepos_forward_to_charpos (b, prev, charpos)
>> -	  : bytepos_backward_to_charpos (b, next, charpos)));
>> +  /* Scan forward if the distance to the previous known position is
>> +     smaller than the distance to the next known position.  */
>> +  const ptrdiff_t bytepos
>> +    = (charpos - prev.charpos < next.charpos - charpos
>> +       ? bytepos_forward_to_charpos (b, prev, charpos)
>> +       : bytepos_backward_to_charpos (b, next, charpos));
>
> I don't understand: `prev` can point into the middle of a char, so if
> `charpos == prev.charpos`, `bytepos_forward_to_charpos` may return an
> incorrect `bytepos` (it'll return `prev.bytepos` which can be in the
> middle of that char).
>
>
>         Stefan

Oh, shit, I forgot that I didn't make the forward/backward case
symmetrical. Add this to the mix.

1 file changed, 1 insertion(+), 1 deletion(-)
src/text-index.c | 2 +-

modified   src/text-index.c
@@ -457,7 +457,7 @@ bytepos_forward_to_charpos (struct buffer *b, const struct text_pos from,
 			    ptrdiff_t to_charpos)
 {
   eassert (from.charpos < to_charpos);
-  ptrdiff_t bytepos = from.bytepos;
+  ptrdiff_t bytepos = char_start_bytepos (b, from.bytepos);
   ptrdiff_t charpos = from.charpos;
   while (charpos < to_charpos)
     {