bug#81567: 31.0.90; overlay freeze
Romain Ouabdelkader <[email protected]> Fri, 7 Aug 2026 12:51:45 +0200
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <CAJ8YToZo-cng+bibnuE8mmei4X_3pq135aUMWgjs5cd-JCPwnA@mail.gmail.com> |
Hello Eli, > Quite crazy, IMNSHO. I forgot to include that in my first email, disclaimer: I used LLM to quickly generate test cases to find a simple reproducer of the issue. I tried the patch, and I confirm that it fixed the issue. I don't see any regression right now, I will use it for a few days to see if I notice anything. Thank you! On Thu, 6 Aug 2026 at 18:29, Eli Zaretskii <[email protected]> wrote: > > From: Romain Ouabdelkader <[email protected]> > > Date: Thu, 6 Aug 2026 17:51:24 +0200 > > > > The minimal reproducer I could get: > > - two line overlays with empty 'display > > - an overlay with 'before-string & 'display with multiple lines > > Quite crazy, IMNSHO. > > > When you scroll up to the beginning of the buffer, Emacs hangs. C-g does > > nothing, neither does kill -SIGUSR2. > > > > Attached is a minimal reproducer: > > > > 1. emacs -Q -l overlay-scroll-freeze.el -f overlay-scroll-freeze > > 2. hold C-p to move point to the start of the buffer > > 3. Emacs hangs when reaching the beginning of the buffer > > Thanks. > > (Actually, you must make sure you type C-p twice in quick succession > at BOB, otherwise there's no hang.) > > Please try the patch below and see if it solves the problem without > introducing regressions elsewhere. > > > I am pretty sure that the issue started on emacs31; although I didn't > > reinstall emacs30 to verify the reproducer. > > Emacs 30.2 indeed doesn't hang, but it produces garbled display in > this case. > > diff --git a/src/xdisp.c b/src/xdisp.c > index 5377d5e..b3227ce 100644 > --- a/src/xdisp.c > +++ b/src/xdisp.c > @@ -11298,10 +11298,18 @@ move_it_vertically_backward (struct it *it, int > dy) > y-distance. */ > SAVE_IT (it2, *it, it2data); > it2.max_ascent = it2.max_descent = 0; > + ptrdiff_t to_pos = start_pos; > do > { > + /* Avoid inflooping of there's a large display string with several > + embedded newlines, which makes move_it_to stop after START_POS > + but still inside a display or overlay string. */ > + if (IT_CHARPOS (it2) >= start_pos) > + to_pos = -1; > move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1, > - MOVE_TO_POS | MOVE_TO_VPOS); > + (to_pos > 0 > + ? (MOVE_TO_POS | MOVE_TO_VPOS) > + : MOVE_TO_VPOS)); > } > while (!(IT_POS_VALID_AFTER_MOVE_P (&it2) > /* If we are in a display string which starts at START_POS, >