I found a bug that can cause the status bar to crash when the
window-list fills up. It only manifests when status-left is empty.

The cause was a one-off in status.c. During calculation of how much
space will be available to the window-list, an extra space is counted
for llen when status-left has content, but isn't when status-left is empty.

Meanwhile, after the "draw:" label, when calculating the offset for
where to start copying the window-list, that offset is _always_ set to
at least 1 (this is the bit that the patch fixes). Since we weren't
counting this character in the earlier calculations, this now ensures
that the final line drawn to the status bar is one cell longer than we
actually have space for. When screen_write_putc() is called for the
final cell, it wraps the line, and results in the status bar being
one-character long (this effect is visible for me, before the eventual
crash).

Bad memory accesses occurs when we get to the call to grid_compare()
after the "out:" label. Inside grid_compare(), the inner loop assumes
that both grids use their entire horizontal space on each line.
Normally, this assumption is valid, since grid_compare() is only ever
used on status lines, and the status-drawing functions always ensure all
the real estate is used (barring the bug described above). But with the
bug in effect, the status line is one-character long, and we get into
reading all sorts of cells that aren't actually there.

I think a pretty good case could be made that grid_compare() should
either not make such an assumption, or should be renamed and moved to
status.c, to indicate it's only intended for use with status screens.
Anyway, I haven't addressed that part of the problem in my patch, which
simply fixes it by ensuring the full-line assumption is once again valid.

-- 
Micah J. Cowan
http://micah.cowan.name/
Index: status.c
===================================================================
--- status.c.orig
+++ status.c
@@ -302,18 +302,20 @@
 	}
 
 	/* Figure out the offset for the window list. */
-	wloffset = 1;
+	if (llen != 0)
+		wloffset = llen + 1;
+	else
+		wloffset = 0;
 	if (wlwidth < wlavailable) {
 		switch (options_get_number(&s->options, "status-justify")) {
 		case 1:	/* centered */
-			wloffset = 1 + (wlavailable - wlwidth) / 2;
+			wloffset += (wlavailable - wlwidth) / 2;
 			break;
 		case 2:	/* right */
-			wloffset = 1 + (wlavailable - wlwidth);
+			wloffset += (wlavailable - wlwidth);
 			break;
 		}
 	}
-	wloffset += llen;
 	if (larrow != 0)
 		wloffset++;
 
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to