Subject: bug#56393: Actually fix the long lines display bug

From: Eli Zaretskii <[email-masked]>
Date: Sat, 09 Jul 2022 13:54:24 +0300

> Date: Sat, 09 Jul 2022 08:56:16 +0000
> From: Gregory Heytings <[email-masked]>
> cc: [email-masked], [email-masked], [email-masked]
> 
> > . I'm not sure the "restriction" should be computed relative to point: 
> > that might be OK for redisplaying a window, but for commands that use 
> > the display code the position with which we call init_iterator and 
> > start_display might be a better/safer alternative, because that position 
> > could be very far from point. In any case, get_narrowed_begv receives a 
> > pointer to a window, so I think it should use the window-point, not PT, 
> > which is the value of point in the current buffer.
> 
> Okay, I'll do that.

Here's one problem caused by using PT in get_narrowed_begv:

  emacs -Q
  C-x C-f src/xdisp.c RET
  C-x 2
  M->

Now move the mouse pointer over the "other" window, the one which
still shows xdisp.c at BOB, and turn the mouse wheel to scroll the
window towards the end of the buffer.  This segfaults:

  Thread 1 received signal SIGSEGV, Segmentation fault.
  0x01054f5c in get_visually_first_element (it=0x82d960) at xdisp.c:8667
  8667                   && (FETCH_BYTE (it->bidi_it.bytepos - 1) == '\n'
  (gdb) bt
  #0  0x01054f5c in get_visually_first_element (it=0x82d960) at xdisp.c:8667
  #1  0x010562b8 in next_element_from_buffer (it=0x82d960) at xdisp.c:9125
  #2  0x01052b35 in get_next_display_element (it=0x82d960) at xdisp.c:7762
  #3  0x0105704a in move_it_in_display_line_to (it=0x82d960, to_charpos=-1,
      to_x=0, op=MOVE_TO_X) at xdisp.c:9550
  #4  0x01059bcb in move_it_to (it=0x82d960, to_charpos=-1, to_x=0, to_y=119,
      to_vpos=-1, op=3) at xdisp.c:10221
  #5  0x01010aac in buffer_posn_from_coords (w=0x7c4ade8, x=0x82e90c,
      y=0x82e908, pos=0x82e920, object=0x82e938, dx=0x82e91c, dy=0x82e918,
      width=0x82e914, height=0x82e910) at dispnew.c:5539
  #6  0x0117d5a6 in make_lispy_position (f=0x75fd018, x=make_fixnum(492),
      y=make_fixnum(427), t=1403593421) at keyboard.c:5532
  #7  0x0117fae8 in make_lispy_event (event=0x1841100 <kbd_buffer+4096>)
      at keyboard.c:6157
  #8  0x01179e8d in kbd_buffer_get_event (kbp=0x82ee74,
      used_mouse_menu=0x82f43f, end_time=0x0) at keyboard.c:4241
  #9  0x011721b4 in read_event_from_main_queue (end_time=0x0,
      local_getcjmp=0x82f190, used_mouse_menu=0x82f43f) at keyboard.c:2238
  #10 0x011726d3 in read_decoded_event_from_main_queue (end_time=0x0,
      local_getcjmp=0x82f190, prev_event=XIL(0), used_mouse_menu=0x82f43f)
      at keyboard.c:2302
  #11 0x01174d50 in read_char (commandflag=1, map=XIL(0xc000000007c46380),
      prev_event=XIL(0), used_mouse_menu=0x82f43f, end_time=0x0)
      at keyboard.c:2932
  #12 0x0118d435 in read_key_sequence (keybuf=0x82f728, prompt=XIL(0),
      dont_downcase_last=false, can_return_switch_frame=true,
      fix_current_buffer=true, prevent_redisplay=false) at keyboard.c:9947
  #13 0x0116eeaf in command_loop_1 () at keyboard.c:1391
  #14 0x01270266 in internal_condition_case (bfun=0x116e774 <command_loop_1>,
      handlers=XIL(0x90), hfun=0x116d742 <cmd_error>) at eval.c:1485
  #15 0x0116e1e1 in command_loop_2 (handlers=XIL(0x90)) at keyboard.c:1132
  #16 0x0126f0ed in internal_catch (tag=XIL(0xfe70),
      func=0x116e1aa <command_loop_2>, arg=XIL(0x90)) at eval.c:1208
  #17 0x0116e14c in command_loop () at keyboard.c:1110
  #18 0x0116d1a2 in recursive_edit_1 () at keyboard.c:719
  #19 0x0116d440 in Frecursive_edit () at keyboard.c:802
  #20 0x011683aa in main (argc=2, argv=0xa42a10) at emacs.c:2517
  (gdb) p it.bidi_it.bytepos
  $1 = 1
  (gdb) p it.bidi_it.charpos
  $2 = 1
  (gdb) p bob
  $3 = 1160000
  (gdb) p it.narrowed_begv
  $4 = 1160000

The problem is that narrowed_begv was computed using PT, which doesn't
correspond to the window's point, and so the logic in
get_visually_first_element backfires.