NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/47490: terminfo if-then-else is buggy, breaking xterm-256color



>Number:         47490
>Category:       lib
>Synopsis:       terminfo if-then-else is buggy, breaking xterm-256color
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jan 22 22:30:00 +0000 2013
>Originator:     Julien Oster
>Release:        NetBSD 6.0.1
>Organization:
        
>Environment:
        
        
System: NetBSD green-jelly.h.ejelly.net 6.0_RC2 NetBSD 6.0_RC2 
(GREEN_JELLY_XEN3_DOM0) #1: Tue Jan 1 21:48:20 CET 2013 
ejelly%green-jelly.h.ejelly.net@localhost:/usr/obj/sys/arch/amd64/compile/GREEN_JELLY_XEN3_DOM0
 amd64
Architecture: x86_64
Machine: amd64
>Description:
terminfo entries may contain conditionals using the %?, %t,
%e and %; commands. In NetBSD's libtermcap, the handling of these
commands is broken.

This is especially noticeable when TERM is set to xterm-256color (as
e.g. the OS X Terminal.app uses as default), which contains
conditionals in its color capabilities. In this case, output by any
program that uses colors (including vim and emacs) is broken.

The cause is two-fold: First, evaluation of the conditional is
reversed, causing the then-path to be wrongly chosen when the
condition evaluates to false and the else-path when it evaluates to
true. Second, in some cases, the 'e' and ';' characters in the
respective '%e' and '%;' commands are not overread and instead output
as part of the terminal sequence, causing it to become garbage.

>How-To-Repeat:
Set TERM to xterm-256color in a compatible terminal (most modern
xterms or Terminal.app qualify) and run a program that does color
output, e.g. vim or emacs. Color change sequences are output as
garbage.

>Fix:
The following patch fixes the problem:

diff -ru libterminfo-original/tparm.c libterminfo/tparm.c
--- libterminfo-original/tparm.c        2013-01-22 22:53:18.000000000 +0100
+++ libterminfo/tparm.c 2013-01-22 22:39:59.000000000 +0100
@@ -453,21 +453,25 @@
                        break;
                case 't': /* then */
                        pop(&val, NULL, &stack);
-                       if (val != 0) {
+                       if (val == 0) {
                                l = 0;
                                for (; *str != '\0'; str++) {
                                        if (*str != '%')
                                                continue;
                                        str++;
-                                       if (*str == '?')
+                                       if (*str == '?') {
+                                               str++;
                                                l++;
-                                       else if (*str == ';') {
+                                       } else if (*str == ';') {
+                                               str++;
                                                if (l > 0)
                                                        l--;
                                                else
                                                        break;
-                                       } else if (*str == 'e' && l == 0)
+                                       } else if (*str == 'e' && l == 0) {
+                                               str++;
                                                break;
+                                       }
                                }
                        }
                        break;
@@ -477,9 +481,11 @@
                                if (*str != '%')
                                        continue;
                                str++;
-                               if (*str == '?')
+                               if (*str == '?') {
+                                       str++;
                                        l++;
-                               else if (*str == ';') {
+                               } else if (*str == ';') {
+                                       str++;
                                        if (l > 0)
                                                l--;
                                        else

>Unformatted:
        
        


Home | Main Index | Thread Index | Old Index