vi crash on page forward with long lines

Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

vi crash on page forward with long lines

Anthony J. Bentley-4
Hi,

I have a vi test case that reliably crashes.

It consists of two files. To crash in a 80x24 terminal, the files should
be as follows:

foo.txt should be 27 lines long. The fifth line should consist of 81
characters, and the others 80 or below.

bar.txt should be 5 lines or more, each line of less than 80 characters.

Example foo.txt:
a
b
c
d
123456789012345678901234567890123456789012345678901234567890123456789012345678901
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
A

Example bar.txt:
1
2
3
4
5
6

Start with "vi foo.txt bar.txt".
In foo, hit ^F once, then :n to switch files.
In bar, line 6 is not visible (bug). Hitting ^F here will crash vi.

This might be related to the fact that after the first ^F, foo's long
line is split, with only the second half shown on screen. The crash
occurs when trying to return the logical column of the cursor:

#0  0x00000733ac5cbda6 in vs_column (sp=0x73623e317b0, colp=0x73623e31850)
    at /usr/src/usr.bin/vi/build/../vi/vs_relative.c:40
#1  0x00000733ac5c5c15 in vi (spp=0x7f7ffffbfdc0)
    at /usr/src/usr.bin/vi/build/../vi/vi.c:110
#2  0x00000733ac5ae0b4 in editor (gp=0x7363966e5f0, argc=<optimized out>,
    argv=<optimized out>) at /usr/src/usr.bin/vi/build/../common/main.c:427
#3  0x00000733ac58e6ce in main (argc=3, argv=0x7f7ffffc0008)
    at /usr/src/usr.bin/vi/build/../cl/cl_main.c:93

--
Anthony J. Bentley

Reply | Threaded
Open this post in threaded view
|

Re: vi crash on page forward with long lines

Otto Moerbeek
On Thu, Jan 10, 2019 at 02:18:50AM -0700, Anthony J. Bentley wrote:

> Hi,
>
> I have a vi test case that reliably crashes.
>
> It consists of two files. To crash in a 80x24 terminal, the files should
> be as follows:
>
> foo.txt should be 27 lines long. The fifth line should consist of 81
> characters, and the others 80 or below.
>
> bar.txt should be 5 lines or more, each line of less than 80 characters.
>
> Example foo.txt:
> a
> b
> c
> d
> 123456789012345678901234567890123456789012345678901234567890123456789012345678901
> f
> g
> h
> i
> j
> k
> l
> m
> n
> o
> p
> q
> r
> s
> t
> u
> v
> w
> x
> y
> z
> A
>
> Example bar.txt:
> 1
> 2
> 3
> 4
> 5
> 6
>
> Start with "vi foo.txt bar.txt".
> In foo, hit ^F once, then :n to switch files.
> In bar, line 6 is not visible (bug). Hitting ^F here will crash vi.
>
> This might be related to the fact that after the first ^F, foo's long
> line is split, with only the second half shown on screen. The crash
> occurs when trying to return the logical column of the cursor:
>
> #0  0x00000733ac5cbda6 in vs_column (sp=0x73623e317b0, colp=0x73623e31850)
>     at /usr/src/usr.bin/vi/build/../vi/vs_relative.c:40
> #1  0x00000733ac5c5c15 in vi (spp=0x7f7ffffbfdc0)
>     at /usr/src/usr.bin/vi/build/../vi/vi.c:110
> #2  0x00000733ac5ae0b4 in editor (gp=0x7363966e5f0, argc=<optimized out>,
>     argv=<optimized out>) at /usr/src/usr.bin/vi/build/../common/main.c:427
> #3  0x00000733ac58e6ce in main (argc=3, argv=0x7f7ffffc0008)
>     at /usr/src/usr.bin/vi/build/../cl/cl_main.c:93
>
> --
> Anthony J. Bentley
>

If you enable DEBUG, the abort in vs_refresh.c:695 gets triggered.
Note that not only line 6 is not drawn, also the ~ lines are missing.
Not hitting ^F but walking to the end or going to the last line with G
in bar works...

No further clue yet.

        -Otto

Reply | Threaded
Open this post in threaded view
|

Re: vi crash on page forward with long lines

Martijn van Duren-8
On 1/10/19 1:00 PM, Otto Moerbeek wrote:

> On Thu, Jan 10, 2019 at 02:18:50AM -0700, Anthony J. Bentley wrote:
>
>> Hi,
>>
>> I have a vi test case that reliably crashes.
>>
>> It consists of two files. To crash in a 80x24 terminal, the files should
>> be as follows:
>>
>> foo.txt should be 27 lines long. The fifth line should consist of 81
>> characters, and the others 80 or below.
>>
>> bar.txt should be 5 lines or more, each line of less than 80 characters.
>>
>> Example foo.txt:
>> a
>> b
>> c
>> d
>> 123456789012345678901234567890123456789012345678901234567890123456789012345678901
>> f
>> g
>> h
>> i
>> j
>> k
>> l
>> m
>> n
>> o
>> p
>> q
>> r
>> s
>> t
>> u
>> v
>> w
>> x
>> y
>> z
>> A
>>
>> Example bar.txt:
>> 1
>> 2
>> 3
>> 4
>> 5
>> 6
>>
>> Start with "vi foo.txt bar.txt".
>> In foo, hit ^F once, then :n to switch files.
>> In bar, line 6 is not visible (bug). Hitting ^F here will crash vi.
>>
>> This might be related to the fact that after the first ^F, foo's long
>> line is split, with only the second half shown on screen. The crash
>> occurs when trying to return the logical column of the cursor:
>>
>> #0  0x00000733ac5cbda6 in vs_column (sp=0x73623e317b0, colp=0x73623e31850)
>>     at /usr/src/usr.bin/vi/build/../vi/vs_relative.c:40
>> #1  0x00000733ac5c5c15 in vi (spp=0x7f7ffffbfdc0)
>>     at /usr/src/usr.bin/vi/build/../vi/vi.c:110
>> #2  0x00000733ac5ae0b4 in editor (gp=0x7363966e5f0, argc=<optimized out>,
>>     argv=<optimized out>) at /usr/src/usr.bin/vi/build/../common/main.c:427
>> #3  0x00000733ac58e6ce in main (argc=3, argv=0x7f7ffffc0008)
>>     at /usr/src/usr.bin/vi/build/../cl/cl_main.c:93
>>
>> --
>> Anthony J. Bentley
>>
>
> If you enable DEBUG, the abort in vs_refresh.c:695 gets triggered.
> Note that not only line 6 is not drawn, also the ~ lines are missing.
> Not hitting ^F but walking to the end or going to the last line with G
> in bar works...
>
> No further clue yet.
>
> -Otto
>
I don't have a solution just yet, but I found the culprit.

When doing the ^F it places the top of the top of the screen at the
overflow of the long line. This position causes HMAP->soff to be set to
2, which isn't reset when loading the new file and causes the soff on
all the lines to increment by 1 compared to the previous line, so line
2 is placed at 2 + 3 = 5, line 3 at 3 + 4 = 7, ...
This isn't a full explanation yet, since I haven't figured out yet why
line 1-5 are printed correctly and I also don't know why scrolling down
causes the file to be reset correctly or even exactly what happens when
we ^F on the incorrectly printed file, but it's a start.

The following (not to be committed) diff proves that the soff is indeed
the culprit, but the math is still to obscure for me to say where the
fix really should be, which could be somewhere entirely different.

martijn@

Index: ex/ex_args.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/ex/ex_args.c,v
retrieving revision 1.12
diff -u -p -r1.12 ex_args.c
--- ex/ex_args.c 6 Jan 2016 22:28:52 -0000 1.12
+++ ex/ex_args.c 10 Jan 2019 17:08:37 -0000
@@ -52,6 +52,7 @@ ex_next(SCR *sp, EXCMD *cmdp)
  msgq(sp, M_ERR, "No more files to edit");
  return (1);
  }
+ HMAP->soff = 1;
 
  if (F_ISSET(cmdp, E_NEWSCREEN)) {
  /* By default, edit the next file in the old argument list. */

Reply | Threaded
Open this post in threaded view
|

Re: vi crash on page forward with long lines

Martijn van Duren-8
On 1/10/19 6:13 PM, Martijn van Duren wrote:

> On 1/10/19 1:00 PM, Otto Moerbeek wrote:
>> On Thu, Jan 10, 2019 at 02:18:50AM -0700, Anthony J. Bentley wrote:
>>
>>> Hi,
>>>
>>> I have a vi test case that reliably crashes.
>>>
>>> It consists of two files. To crash in a 80x24 terminal, the files should
>>> be as follows:
>>>
>>> foo.txt should be 27 lines long. The fifth line should consist of 81
>>> characters, and the others 80 or below.
>>>
>>> bar.txt should be 5 lines or more, each line of less than 80 characters.
>>>
>>> Example foo.txt:
>>> a
>>> b
>>> c
>>> d
>>> 123456789012345678901234567890123456789012345678901234567890123456789012345678901
>>> f
>>> g
>>> h
>>> i
>>> j
>>> k
>>> l
>>> m
>>> n
>>> o
>>> p
>>> q
>>> r
>>> s
>>> t
>>> u
>>> v
>>> w
>>> x
>>> y
>>> z
>>> A
>>>
>>> Example bar.txt:
>>> 1
>>> 2
>>> 3
>>> 4
>>> 5
>>> 6
>>>
>>> Start with "vi foo.txt bar.txt".
>>> In foo, hit ^F once, then :n to switch files.
>>> In bar, line 6 is not visible (bug). Hitting ^F here will crash vi.
>>>
>>> This might be related to the fact that after the first ^F, foo's long
>>> line is split, with only the second half shown on screen. The crash
>>> occurs when trying to return the logical column of the cursor:
>>>
>>> #0  0x00000733ac5cbda6 in vs_column (sp=0x73623e317b0, colp=0x73623e31850)
>>>     at /usr/src/usr.bin/vi/build/../vi/vs_relative.c:40
>>> #1  0x00000733ac5c5c15 in vi (spp=0x7f7ffffbfdc0)
>>>     at /usr/src/usr.bin/vi/build/../vi/vi.c:110
>>> #2  0x00000733ac5ae0b4 in editor (gp=0x7363966e5f0, argc=<optimized out>,
>>>     argv=<optimized out>) at /usr/src/usr.bin/vi/build/../common/main.c:427
>>> #3  0x00000733ac58e6ce in main (argc=3, argv=0x7f7ffffc0008)
>>>     at /usr/src/usr.bin/vi/build/../cl/cl_main.c:93
>>>
>>> --
>>> Anthony J. Bentley
>>>
>>
>> If you enable DEBUG, the abort in vs_refresh.c:695 gets triggered.
>> Note that not only line 6 is not drawn, also the ~ lines are missing.
>> Not hitting ^F but walking to the end or going to the last line with G
>> in bar works...
>>
>> No further clue yet.
>>
>> -Otto
>>
> I don't have a solution just yet, but I found the culprit.
>
> When doing the ^F it places the top of the top of the screen at the
> overflow of the long line. This position causes HMAP->soff to be set to
> 2, which isn't reset when loading the new file and causes the soff on
> all the lines to increment by 1 compared to the previous line, so line
> 2 is placed at 2 + 3 = 5, line 3 at 3 + 4 = 7, ...
> This isn't a full explanation yet, since I haven't figured out yet why
> line 1-5 are printed correctly and I also don't know why scrolling down
> causes the file to be reset correctly or even exactly what happens when
> we ^F on the incorrectly printed file, but it's a start.
>
> The following (not to be committed) diff proves that the soff is indeed
> the culprit, but the math is still to obscure for me to say where the
> fix really should be, which could be somewhere entirely different.
>
> martijn@
>
So this is how far I'm willing to go for today:
When entering vi/vs_refresh.c:326 HMAP->lno says that there's 5 lines,
which get returned. I haven't been able to trace where this value is
set so far, but it's obviously related to how the HMAP->soff is set to
2.

Considering the different ways vi may switch files I found that that
vi only test for this on vi/vi.c:396. So the diff below resets the
HMAP state there. Only HMAP should be reset, because the other SMAP
fields are derived from that one (see vs_sm_{next,prev}. This is
also backed by vi/vi.c:965, which only initializes HMAP, and not all
the other maps.

I also tested the diff with a small number of args and opening
files in split screen and I didn't notice any issues.

I'm somewhat confident that this is the correct solution, but I'm
not 100% certain, considering Rapunzel probably has an easier time
untangling her hair.

thoughts?

martijn@

Index: vi/vi.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/vi/vi.c,v
retrieving revision 1.21
diff -u -p -r1.21 vi.c
--- vi/vi.c 18 Apr 2017 01:45:35 -0000 1.21
+++ vi/vi.c 11 Jan 2019 07:18:39 -0000
@@ -396,6 +396,10 @@ intr: CLR_INTERRUPT(sp);
  if (F_ISSET(sp, SC_FSWITCH)) {
  F_CLR(sp, SC_FSWITCH);
  (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
+ /* If we switch files, we must draw a fresh screen. */
+ HMAP->lno = sp->lno;
+ HMAP->coff = 0;
+ HMAP->soff = 1;
  }
 
  /* If leaving vi, return to the main editor loop. */

Reply | Threaded
Open this post in threaded view
|

Re: vi crash on page forward with long lines

Otto Moerbeek
On Fri, Jan 11, 2019 at 08:23:36AM +0100, Martijn van Duren wrote:

> On 1/10/19 6:13 PM, Martijn van Duren wrote:
> > On 1/10/19 1:00 PM, Otto Moerbeek wrote:
> >> On Thu, Jan 10, 2019 at 02:18:50AM -0700, Anthony J. Bentley wrote:
> >>
> >>> Hi,
> >>>
> >>> I have a vi test case that reliably crashes.
> >>>
> >>> It consists of two files. To crash in a 80x24 terminal, the files should
> >>> be as follows:
> >>>
> >>> foo.txt should be 27 lines long. The fifth line should consist of 81
> >>> characters, and the others 80 or below.
> >>>
> >>> bar.txt should be 5 lines or more, each line of less than 80 characters.
> >>>
> >>> Example foo.txt:
> >>> a
> >>> b
> >>> c
> >>> d
> >>> 123456789012345678901234567890123456789012345678901234567890123456789012345678901
> >>> f
> >>> g
> >>> h
> >>> i
> >>> j
> >>> k
> >>> l
> >>> m
> >>> n
> >>> o
> >>> p
> >>> q
> >>> r
> >>> s
> >>> t
> >>> u
> >>> v
> >>> w
> >>> x
> >>> y
> >>> z
> >>> A
> >>>
> >>> Example bar.txt:
> >>> 1
> >>> 2
> >>> 3
> >>> 4
> >>> 5
> >>> 6
> >>>
> >>> Start with "vi foo.txt bar.txt".
> >>> In foo, hit ^F once, then :n to switch files.
> >>> In bar, line 6 is not visible (bug). Hitting ^F here will crash vi.
> >>>
> >>> This might be related to the fact that after the first ^F, foo's long
> >>> line is split, with only the second half shown on screen. The crash
> >>> occurs when trying to return the logical column of the cursor:
> >>>
> >>> #0  0x00000733ac5cbda6 in vs_column (sp=0x73623e317b0, colp=0x73623e31850)
> >>>     at /usr/src/usr.bin/vi/build/../vi/vs_relative.c:40
> >>> #1  0x00000733ac5c5c15 in vi (spp=0x7f7ffffbfdc0)
> >>>     at /usr/src/usr.bin/vi/build/../vi/vi.c:110
> >>> #2  0x00000733ac5ae0b4 in editor (gp=0x7363966e5f0, argc=<optimized out>,
> >>>     argv=<optimized out>) at /usr/src/usr.bin/vi/build/../common/main.c:427
> >>> #3  0x00000733ac58e6ce in main (argc=3, argv=0x7f7ffffc0008)
> >>>     at /usr/src/usr.bin/vi/build/../cl/cl_main.c:93
> >>>
> >>> --
> >>> Anthony J. Bentley
> >>>
> >>
> >> If you enable DEBUG, the abort in vs_refresh.c:695 gets triggered.
> >> Note that not only line 6 is not drawn, also the ~ lines are missing.
> >> Not hitting ^F but walking to the end or going to the last line with G
> >> in bar works...
> >>
> >> No further clue yet.
> >>
> >> -Otto
> >>
> > I don't have a solution just yet, but I found the culprit.
> >
> > When doing the ^F it places the top of the top of the screen at the
> > overflow of the long line. This position causes HMAP->soff to be set to
> > 2, which isn't reset when loading the new file and causes the soff on
> > all the lines to increment by 1 compared to the previous line, so line
> > 2 is placed at 2 + 3 = 5, line 3 at 3 + 4 = 7, ...
> > This isn't a full explanation yet, since I haven't figured out yet why
> > line 1-5 are printed correctly and I also don't know why scrolling down
> > causes the file to be reset correctly or even exactly what happens when
> > we ^F on the incorrectly printed file, but it's a start.
> >
> > The following (not to be committed) diff proves that the soff is indeed
> > the culprit, but the math is still to obscure for me to say where the
> > fix really should be, which could be somewhere entirely different.
> >
> > martijn@
> >
> So this is how far I'm willing to go for today:
> When entering vi/vs_refresh.c:326 HMAP->lno says that there's 5 lines,
> which get returned. I haven't been able to trace where this value is
> set so far, but it's obviously related to how the HMAP->soff is set to
> 2.
>
> Considering the different ways vi may switch files I found that that
> vi only test for this on vi/vi.c:396. So the diff below resets the
> HMAP state there. Only HMAP should be reset, because the other SMAP
> fields are derived from that one (see vs_sm_{next,prev}. This is
> also backed by vi/vi.c:965, which only initializes HMAP, and not all
> the other maps.
>
> I also tested the diff with a small number of args and opening
> files in split screen and I didn't notice any issues.
>
> I'm somewhat confident that this is the correct solution, but I'm
> not 100% certain, considering Rapunzel probably has an easier time
> untangling her hair.
>
> thoughts?

This works indeed in my tests as well.

        -Otto

>
> martijn@
>
> Index: vi/vi.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/vi/vi/vi.c,v
> retrieving revision 1.21
> diff -u -p -r1.21 vi.c
> --- vi/vi.c 18 Apr 2017 01:45:35 -0000 1.21
> +++ vi/vi.c 11 Jan 2019 07:18:39 -0000
> @@ -396,6 +396,10 @@ intr: CLR_INTERRUPT(sp);
>   if (F_ISSET(sp, SC_FSWITCH)) {
>   F_CLR(sp, SC_FSWITCH);
>   (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
> + /* If we switch files, we must draw a fresh screen. */
> + HMAP->lno = sp->lno;
> + HMAP->coff = 0;
> + HMAP->soff = 1;
>   }
>  
>   /* If leaving vi, return to the main editor loop. */
>

Reply | Threaded
Open this post in threaded view
|

Re: vi crash on page forward with long lines

Todd C. Miller-3
In reply to this post by Martijn van Duren-8
On Fri, 11 Jan 2019 08:23:36 +0100, Martijn van Duren wrote:

> I'm somewhat confident that this is the correct solution, but I'm
> not 100% certain, considering Rapunzel probably has an easier time
> untangling her hair.

I think all we really need to do is set SC_SCR_TOP so that the HMAP
settings get refreshed while painting the screen.

 - todd

Index: usr.bin/vi/vi/vi.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/vi/vi.c,v
retrieving revision 1.21
diff -u -p -u -r1.21 vi.c
--- usr.bin/vi/vi/vi.c 18 Apr 2017 01:45:35 -0000 1.21
+++ usr.bin/vi/vi/vi.c 14 Jan 2019 15:59:15 -0000
@@ -395,6 +395,7 @@ intr: CLR_INTERRUPT(sp);
  /* If the last command switched files, change focus. */
  if (F_ISSET(sp, SC_FSWITCH)) {
  F_CLR(sp, SC_FSWITCH);
+ F_SET(sp, SC_SCR_TOP);
  (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
  }
 

Reply | Threaded
Open this post in threaded view
|

Re: vi crash on page forward with long lines

Otto Moerbeek
On Mon, Jan 14, 2019 at 09:02:44AM -0700, Todd C. Miller wrote:

> On Fri, 11 Jan 2019 08:23:36 +0100, Martijn van Duren wrote:
>
> > I'm somewhat confident that this is the correct solution, but I'm
> > not 100% certain, considering Rapunzel probably has an easier time
> > untangling her hair.
>
> I think all we really need to do is set SC_SCR_TOP so that the HMAP
> settings get refreshed while painting the screen.
>
>  - todd
>
> Index: usr.bin/vi/vi/vi.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/vi/vi/vi.c,v
> retrieving revision 1.21
> diff -u -p -u -r1.21 vi.c
> --- usr.bin/vi/vi/vi.c 18 Apr 2017 01:45:35 -0000 1.21
> +++ usr.bin/vi/vi/vi.c 14 Jan 2019 15:59:15 -0000
> @@ -395,6 +395,7 @@ intr: CLR_INTERRUPT(sp);
>   /* If the last command switched files, change focus. */
>   if (F_ISSET(sp, SC_FSWITCH)) {
>   F_CLR(sp, SC_FSWITCH);
> + F_SET(sp, SC_SCR_TOP);
>   (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
>   }
>  
>

A problem with this diff is that is changes the part of the screen
shown while switching back and forth between files with Ctrl-^

Normally, vi remembers both the cursor position in the files and the
part of the file shown (it does recenter in some cases). With this
diff, it the cursor remains at the correct line, but that part of the
file shown changes in a differnent way than before.

        -Otto


Reply | Threaded
Open this post in threaded view
|

Re: vi crash on page forward with long lines

Todd C. Miller-3
On Mon, 14 Jan 2019 21:15:54 +0100, Otto Moerbeek wrote:

> A problem with this diff is that is changes the part of the screen
> shown while switching back and forth between files with Ctrl-^
>
> Normally, vi remembers both the cursor position in the files and the
> part of the file shown (it does recenter in some cases). With this
> diff, it the cursor remains at the correct line, but that part of the
> file shown changes in a differnent way than before.

Good catch.  What we really want to set is SC_SCR_CENTER, like
v_init() does.  This will still start at the top of a new file.

 - todd

Index: usr.bin/vi/vi/vi.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/vi/vi.c,v
retrieving revision 1.21
diff -u -p -u -r1.21 vi.c
--- usr.bin/vi/vi/vi.c 18 Apr 2017 01:45:35 -0000 1.21
+++ usr.bin/vi/vi/vi.c 14 Jan 2019 20:50:03 -0000
@@ -395,6 +395,8 @@ intr: CLR_INTERRUPT(sp);
  /* If the last command switched files, change focus. */
  if (F_ISSET(sp, SC_FSWITCH)) {
  F_CLR(sp, SC_FSWITCH);
+ F_CLR(sp, SC_SCR_TOP);
+ F_SET(sp, SC_SCR_CENTER);
  (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
  }
 

Reply | Threaded
Open this post in threaded view
|

Re: vi crash on page forward with long lines

Otto Moerbeek
On Mon, Jan 14, 2019 at 01:55:42PM -0700, Todd C. Miller wrote:

> On Mon, 14 Jan 2019 21:15:54 +0100, Otto Moerbeek wrote:
>
> > A problem with this diff is that is changes the part of the screen
> > shown while switching back and forth between files with Ctrl-^
> >
> > Normally, vi remembers both the cursor position in the files and the
> > part of the file shown (it does recenter in some cases). With this
> > diff, it the cursor remains at the correct line, but that part of the
> > file shown changes in a differnent way than before.
>
> Good catch.  What we really want to set is SC_SCR_CENTER, like
> v_init() does.  This will still start at the top of a new file.

great, ok from me,

        -Otto

>
>  - todd
>
> Index: usr.bin/vi/vi/vi.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/vi/vi/vi.c,v
> retrieving revision 1.21
> diff -u -p -u -r1.21 vi.c
> --- usr.bin/vi/vi/vi.c 18 Apr 2017 01:45:35 -0000 1.21
> +++ usr.bin/vi/vi/vi.c 14 Jan 2019 20:50:03 -0000
> @@ -395,6 +395,8 @@ intr: CLR_INTERRUPT(sp);
>   /* If the last command switched files, change focus. */
>   if (F_ISSET(sp, SC_FSWITCH)) {
>   F_CLR(sp, SC_FSWITCH);
> + F_CLR(sp, SC_SCR_TOP);
> + F_SET(sp, SC_SCR_CENTER);
>   (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
>   }
>