> Delivered-To: [email protected]
> Received: by 10.100.125.2 with SMTP id x2cs7548anc;
> Wed, 8 Dec 2010 00:00:53 -0800 (PST)
> Received: by 10.231.32.197 with SMTP id e5mr738073ibd.188.1291795252925;
> Wed, 08 Dec 2010 00:00:52 -0800 (PST)
> Return-Path: <[email protected]>
> Received: from shear.ucar.edu (lists.openbsd.org [192.43.244.163])
> by mx.google.com with ESMTP id
> gy42si1064435ibb.88.2010.12.08.00.00.52;
> Wed, 08 Dec 2010 00:00:52 -0800 (PST)
> Received-SPF: pass (google.com: manual fallback record for domain of
> [email protected] designates 192.43.244.163 as permitted sender)
> client-ip=192.43.244.163;
> Authentication-Results: mx.google.com; spf=pass (google.com: manual fallback
> record for domain of [email protected] designates 192.43.244.163
> as permitted sender) [email protected]
> Received: from openbsd.org (localhost.ucar.edu [127.0.0.1])
> by shear.ucar.edu (8.14.3/8.14.3) with ESMTP id oB87xxwI017467;
> Wed, 8 Dec 2010 00:59:59 -0700 (MST)
> Received: from mail.boxsoft.com (dsl092-062-211.lax1.dsl.speakeasy.net
> [66.92.62.211])
> by shear.ucar.edu (8.14.3/8.14.3) with ESMTP id oB87we7E023081
> (version=TLSv1/SSLv3 cipher=DHE-DSS-AES256-SHA bits=256 verify=NO)
> for <[email protected]>; Wed, 8 Dec 2010 00:58:42 -0700 (MST)
> Received: from mail.boxsoft.com (sidster@localhost [127.0.0.1])
> by mail.boxsoft.com (8.14.3/8.14.3) with ESMTP id oB87weGu028472
> for <[email protected]>; Tue, 7 Dec 2010 23:58:40 -0800 (PST)
> Received: (from sidster@localhost)
> by mail.boxsoft.com (8.14.3/8.14.3/Submit) id oB87wdB5002430
> for [email protected]; Tue, 7 Dec 2010 23:58:40 -0800 (PST)
> X-Authentication-Warning: roppongi.boxsoft.com: sidster set sender to
> [email protected] using -f
> Date: Tue, 7 Dec 2010 23:58:39 -0800
> From: patrick keshishian <[email protected]>
> To: [email protected]
> Subject: nvi diff fixing a display glitch leading to crash
> Message-ID: <[email protected]>
> Mime-Version: 1.0
> Content-Type: text/plain; charset=us-ascii
> User-Agent: Mutt/1.4.2.3i
> List-Help: <mailto:[email protected]?body=help>
> List-Owner: <mailto:[email protected]>
> List-Post: <mailto:[email protected]>
> List-Subscribe: <mailto:[email protected]?body=sub%20tech>
> List-Unsubscribe: <mailto:[email protected]?body=unsub%20tech>
> X-Loop: [email protected]
> Precedence: list
> Sender: [email protected]
>
> Hello,
>
> I work with a lot of sources that have strange formatting
> (as do you no doubt). I noticed that sometimes changing the
> tabstop value in search of a reasonable display vi would
> crash.
>
> Took me a bit to figure out the reproducible steps to be
> able to come up with a fix.
>
> Steps to reproduce the crash. Reproducible on i386, amd64,
> and macppc:
>
> 1. Imagine a file edited with a small tabstop value (say 2
> or 3) containing lines long enough so they wrap in default
> tabstop (8), but possibly not in the smaller tabstop values.
>
> 2. While tabstop set to 8, position one of the wrapping lines
> such that the beginning of said line is off screen and the
> tail end of the wrapped portion is the first line on the
> screen with the cursor positioned on same first line.
>
> 3. Change tabstop to 2 (or 3).
> Assuming there were more lines below the line your cursor
> is on, you will notice a drawing glitch where only the
> top line is redrawn and the rest of the screen is blanked
> out.
>
> 4. If at this point you press ^B (page backwards) vi will
> core dump.
>
> A visual of what I experience (series of five screen-shots):
> http://sidster.com/scratch/nvi/
>
>
> The patch below resets the HMAP->soff (screen offset of line)
> to 1 if the number of lines HMAP->lno spans has changed and is
> now less than HMAP->soff. This essentially forces the entire
> line to be redrawn at the top of the screen, avoids the redraw
> glitch and eventual crash.
>
> Comments?
Thanks for the detailed report.
However, your diff is wrong.
> --patrick
>
>
> Index: vi/vs_smap.c
> ===================================================================
> RCS file: /cvs/obsd/src/usr.bin/vi/vi/vs_smap.c,v
> retrieving revision 1.7
> diff -u -p vi/vs_smap.c
> --- vi/vs_smap.c 27 Oct 2009 23:59:49 -0000 1.7
> +++ vi/vs_smap.c 8 Dec 2010 06:22:09 -0000
> @@ -224,6 +224,17 @@ top: HMAP->lno = lno;
> HMAP->coff = 0;
> HMAP->soff = 1;
> }
> + else {
This is not the right place to fix this, since it would affect the
other 6 calls with OOBLNO in a bad way.
> + /*
> + * If number of lines HMAP->lno (top line) spans
> + * changed due to, say reformatting, and now is
> + * fewer than HMAP->soff, reset so the line is
> + * redrawn at the top of the screen.
> + */
This should additionally check if the current line is HMAP->lno
(top line); otherwise you're changing behaviour in a strange way,
the top line will be forced to be on top. (Try it.)
> + cnt = vs_screens(sp, HMAP->lno, NULL);
This could use the cached value (cno), it would be faster for larger
lines.
> + if (cnt < HMAP->soff)
> + HMAP->soff = 1;
This should actually be cnt, not 1--you're forcing the top to be
at the beginning of the line; however this is only good for your
test case (two lines become one). This is bad for longer lines.
> + }
A similar problem applies for the TMAP case, too.
> /* If we fail, just punt. */
> for (p = HMAP, cnt = sp->t_rows; --cnt; ++p)
> if (vs_sm_next(sp, p, p + 1))
Could you verify that the attached diff fixes your problem?
Index: vi/vs_refresh.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/vi/vs_refresh.c,v
retrieving revision 1.16
diff -u -r1.16 vs_refresh.c
--- vi/vs_refresh.c 27 Oct 2009 23:59:49 -0000 1.16
+++ vi/vs_refresh.c 3 Apr 2011 10:13:47 -0000
@@ -199,9 +199,18 @@
else if (F_ISSET(sp, SC_SCR_CENTER)) {
if (vs_sm_fill(sp, LNO, P_MIDDLE))
return (1);
- } else
+ } else {
+ if (LNO == HMAP->lno || LNO == TMAP->lno) {
+ cnt = vs_screens(sp, LNO, &CNO);
+ if (LNO == HMAP->lno && cnt < HMAP->soff)
+ HMAP->soff = cnt;
+ if (LNO == TMAP->lno && cnt > TMAP->soff)
+ TMAP->soff = cnt;
+ }
+
if (vs_sm_fill(sp, OOBLNO, P_TOP))
return (1);
+ }
F_SET(sp, SC_SCR_REDRAW);
}