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. */