Subject: bin/28382: vi crashes when auto-completing long filenames
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <Peter.Bex@student.kun.nl>
List: netbsd-bugs
Date: 11/21/2004 21:58:00
>Number: 28382
>Category: bin
>Synopsis: When completing filenames longer than the screen is wide, vi segfaults
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Nov 21 21:58:00 +0000 2004
>Originator: Peter Bex
>Release: NetBSD 2.0_BETA
>Organization:
>Environment:
System: NetBSD byers.nvie.com 2.0_BETA NetBSD 2.0_BETA (BYERS) #7: Thu Sep 2 12:51:54 CEST 2004 sjamaan@byers.nvie.com:/usr/src/sys/arch/macppc/compile/BYERS macppc
Architecture: powerpc
Machine: macppc
>Description:
When you enable filecompletion, when a filename contains more
characters than the screen is wide, vi crashes with a SEGFAULT.
After code inspection, it appears on line 2237 of vi/v_txt.c,
av[0]->bp is passed to msg_print. av is not re-initialised after
the last use of it in the loop which determines `colwidth'.
At this point, av points beyond the last valid argv, which contains
all NULL data.
Looking at the `else' branch of the `if' in which the offending code
is located, it appears the msg_print statement should simply be
moved to the inside of the for loop.
>How-To-Repeat:
- Create a file which has more characters than your screen is wide
or just resize your screen/terminal enough.
- :set filec=^V^V^I
- :e path/to/file/^I
- See vi crash and burn ;)
>Fix:
This is a quick fix I hacked together. Should do the trick.
(I'll send a copy of this message to Keith Bostic as well, so he can
integrate the patch in nvi main distribution)
$NetBSD$
--- v_txt.c.orig 2003-06-06 10:06:47.000000000 +0200
+++ v_txt.c
@@ -2234,8 +2234,8 @@ txt_fc_col(sp, argc, argv)
/* If the largest file name is too large, just print them. */
if (colwidth > sp->cols) {
- p = msg_print(sp, av[0]->bp + prefix, &nf);
for (ac = argc, av = argv; ac > 0; --ac, ++av) {
+ p = msg_print(sp, av[0]->bp + prefix, &nf);
(void)ex_printf(sp, "%s\n", p);
if (F_ISSET(gp, G_INTERRUPTED))
break;
>Unformatted: