xterm-56.patch.txt

XFree86 3.9x - xterm patch #56 - T.Dickey <dickey@clark.net>
 
This patch is based on analysis by Arfst Ludwig <arfst@luxor.IN-Berlin.DE>,
who reported:
 
        Setting the following resources xterm (all current versions) receives a
        segmentation fault on <Btn2Up> after scrolling:
 
        *XTerm*VT100*translations:    #override \
            ~Shift~Ctrl<Btn2Up>:        insert-selection(PRIMARY, CUT_BUFFER0)\n\
            Shift~Ctrl<Btn2Up>:         insert-selection(CLIPBOARD, CUT_BUFFER1)\n\
            ~Shift<BtnUp>:              select-end(PRIMARY, CUT_BUFFER0)\n\
            Shift<BtnUp>:               select-end(CLIPBOARD, CUT_BUFFER1)
 
        (The above resources intention is to be able to paste the latest
        selection even if the xterm was cleared.)
 
        And here is how it works (and a fix!):  The widget given to the action
        handler as first argument is not guranteed to be a XtermWidget (it can
        be the ScrollbarWidget).  Instead of accessing the widget's member
        directly XtDisplay gives the required pointer in a safe way.
 
I noticed that this was not the only instance (by reading the code, and testing
with his example), and extended the solution to check the widget-class to
ensure that it is indeed xterm's widget class before attempting to use it in
the context of translations.
 
--------------------------------------------------------------------------------
 Tekproc.c   |    2 -
 button.c    |   77 ++++++++++++++++++++++++++++++++++++++++++----------------
 main.c      |    3 --
 os2main.c   |    3 --
 ptyx.h      |    4 +++
 scrollbar.c |   16 ++++++------
 6 files changed, 68 insertions, 37 deletions
--------------------------------------------------------------------------------
Index: Tekproc.c
--- xterm-55+/Tekproc.c Fri Sep 19 13:58:52 1997
+++ xterm-56/Tekproc.c  Fri Nov 28 13:47:02 1997
@@ -123,8 +123,6 @@
 
 #include "xterm.h"
 
-#define TekColormap DefaultColormap( screen->display, \
-                                   DefaultScreen(screen->display) )
 #define DefaultGCID XGContextFromGC(DefaultGC(screen->display, DefaultScreen(screen->display)))
 
 /* Tek defines */
Index: button.c
--- xterm-55+/button.c  Tue Oct 14 21:40:58 1997
+++ xterm-56/button.c   Fri Nov 28 15:35:20 1997
@@ -73,9 +73,8 @@
 #define SHIFTS 8               /* three keys, so eight combinations */
 #define        Coordinate(r,c)         ((r) * (term->screen.max_col+1) + (c))
 
-extern char *xterm_name;
-
 
+extern char *xterm_name;
 extern XtermWidget term;
 
 /* Selection/extension variables */
@@ -139,7 +138,12 @@
 Widget w;
 XEvent* event;
 {
-    register TScreen *screen = &((XtermWidget)w)->screen;
+    register TScreen *screen;
+
+    if (!IsXtermWidget(w))
+       return False;
+
+    screen = &((XtermWidget)w)->screen;
     
     if (screen->send_mouse_pos == 0) return False;
 
@@ -254,9 +258,13 @@
 String *params GCC_UNUSED;
 Cardinal *num_params GCC_UNUSED;
 {
-       register TScreen *screen = &((XtermWidget)w)->screen;
+       register TScreen *screen;
        int row, col;
 
+       if (!IsXtermWidget(w))
+               return;
+
+       screen = &((XtermWidget)w)->screen;
        screen->selection_time = event->xmotion.time;
        switch (eventMode) {
                case LEFTEXTENSION :
@@ -278,6 +286,9 @@
 Cardinal *num_params;
 Bool use_cursor_loc;
 {
+       if (!IsXtermWidget(w))
+               return;
+
        ((XtermWidget)w)->screen.selection_time = event->xbutton.time;
        switch (eventMode) {
                case NORMAL :
@@ -342,12 +353,11 @@
       default:        cutbuffer = -1;
     }
     if (cutbuffer >= 0) {
-       register TScreen *screen = &((XtermWidget)w)->screen;
        int inbytes;
        unsigned long nbytes;
        int fmt8 = 8;
        Atom type = XA_STRING;
-       char *line = XFetchBuffer(screen->display, &inbytes, cutbuffer);
+       char *line = XFetchBuffer(XtDisplay(w), &inbytes, cutbuffer);
        nbytes = (unsigned long) inbytes;
        if (nbytes > 0)
            SelectionReceived(w, NULL, &selection, &type, (XtPointer)line,
@@ -379,10 +389,14 @@
 unsigned long *length;
 int *format GCC_UNUSED;
 {
-    int pty = ((XtermWidget)w)->screen.respond;        /* file descriptor of pty */
+    int pty;
     register char *lag, *cp, *end;
     char *line = (char*)value;
-                                 
+
+    if (!IsXtermWidget(w))
+       return;
+
+    pty = ((XtermWidget)w)->screen.respond;    /* file descriptor of pty */
     if (*type == 0 /*XT_CONVERT_FAIL*/ || *length == 0 || value == NULL) {
        /* could not get this selection, so see if there are more to try */
        struct _SelectionList* list = (struct _SelectionList*)client_data;
@@ -468,9 +482,13 @@
 String *params GCC_UNUSED;
 Cardinal *num_params GCC_UNUSED;
 {
-       register TScreen *screen = &((XtermWidget)w)->screen;
+       register TScreen *screen;
        int startrow, startcol;
 
+       if (!IsXtermWidget(w))
+               return;
+
+       screen = &((XtermWidget)w)->screen;
        firstValidRow = 0;
        lastValidRow  = screen->max_row;
        PointToRowCol(event->xbutton.y, event->xbutton.x, &startrow, &startcol);
@@ -486,8 +504,12 @@
 String *params GCC_UNUSED;
 Cardinal *num_params GCC_UNUSED;
 {
-       register TScreen *screen = &((XtermWidget)w)->screen;
+       register TScreen *screen;
+
+       if (!IsXtermWidget(w))
+               return;
 
+       screen = &((XtermWidget)w)->screen;
        do_select_start (w, event, screen->cursor_row, screen->cursor_col);
 }
 
@@ -657,9 +679,13 @@
 Cardinal *num_params GCC_UNUSED;
 Bool use_cursor_loc;
 {
-       TScreen *screen = &((XtermWidget)w)->screen;
+       TScreen *screen;
        int row, col, coord;
 
+       if (!IsXtermWidget(w))
+               return;
+
+       screen = &((XtermWidget)w)->screen;
        if (SendMousePosition(w, event)) return;
        firstValidRow = 0;
        lastValidRow  = screen->max_row;
@@ -1193,16 +1219,20 @@
 int *format;
 {
     Display* d = XtDisplay(w);
-    XtermWidget xterm = (XtermWidget)w;
+    TScreen *screen;
 
-    if (xterm->screen.selection == NULL) return False; /* can this happen? */
+    if (!IsXtermWidget(w))
+       return False;
+
+    screen = &((XtermWidget)w)->screen;
+    if (screen->selection == NULL) return False; /* can this happen? */
 
     if (*target == XA_TARGETS(d)) {
        Atom* targetP;
        Atom* std_targets;
        unsigned long std_length;
        XmuConvertStandardSelection(
-                   w, xterm->screen.selection_time, selection,
+                   w, screen->selection_time, selection,
                    target, type, (caddr_t*)&std_targets, &std_length, format
                   );
        *length = std_length + 5;
@@ -1226,7 +1256,7 @@
        if (*target == XA_COMPOUND_TEXT(d)) {
            XTextProperty textprop;
 
-           *value = (XtPointer) xterm->screen.selection;
+           *value = (XtPointer) screen->selection;
            if (XmbTextListToTextProperty (d, (char**)value, 1,
                                           XCompoundTextStyle, &textprop)
                        < Success) return False;
@@ -1235,8 +1265,8 @@
            *type = *target;
        } else {
            *type = XA_STRING;
-           *value = xterm->screen.selection;
-           *length = xterm->screen.selection_length;
+           *value = screen->selection;
+           *length = screen->selection_length;
        }
        *format = 8;
        return True;
@@ -1257,9 +1287,9 @@
     if (*target == XA_LENGTH(d)) {
        *value = XtMalloc(4);
        if (sizeof(long) == 4)
-           *(long*)*value = xterm->screen.selection_length;
+           *(long*)*value = screen->selection_length;
        else {
-           long temp = xterm->screen.selection_length;
+           long temp = screen->selection_length;
            memcpy ( (char*)*value, ((char*)&temp)+sizeof(long)-4, 4);
        }
        *type = XA_INTEGER;
@@ -1267,7 +1297,7 @@
        *format = 32;
        return True;
     }
-    if (XmuConvertStandardSelection(w, xterm->screen.selection_time, selection,
+    if (XmuConvertStandardSelection(w, screen->selection_time, selection,
                                    target, type,
                                    (caddr_t *)value, length, format))
        return True;
@@ -1282,9 +1312,14 @@
   Widget w;
   Atom *selection;
 {
-    register TScreen* screen = &((XtermWidget)w)->screen;
+    register TScreen* screen;
     register Atom* atomP;
     Cardinal i;
+
+    if (!IsXtermWidget(w))
+       return;
+
+    screen = &((XtermWidget)w)->screen;
     for (i = 0, atomP = screen->selection_atoms;
         i < screen->selection_count; i++, atomP++)
     {
Index: main.c
--- xterm-55+/main.c    Sat Nov  1 16:03:40 1997
+++ xterm-56/main.c     Fri Nov 28 15:44:52 1997
@@ -1026,9 +1026,6 @@
 }
 #endif /* TIOCCONS */
 
-
-extern WidgetClass xtermWidgetClass;
-
 Arg ourTopLevelShellArgs[] = {
        { XtNallowShellResize, (XtArgVal) TRUE },       
        { XtNinput, (XtArgVal) TRUE },
Index: os2main.c
--- xterm-55+/os2main.c Tue Oct 14 21:40:58 1997
+++ xterm-56/os2main.c  Fri Nov 28 15:44:58 1997
@@ -553,9 +553,6 @@
     return False;
 }
 
-
-extern WidgetClass xtermWidgetClass;
-
 Arg ourTopLevelShellArgs[] = {
        { XtNallowShellResize, (XtArgVal) TRUE },       
        { XtNinput, (XtArgVal) TRUE },
Index: ptyx.h
--- xterm-55+/ptyx.h    Sun Nov 23 19:10:15 1997
+++ xterm-56/ptyx.h     Fri Nov 28 15:20:42 1997
@@ -792,6 +792,10 @@
     XtermClassPart xterm_class;
 } XtermClassRec;
 
+extern WidgetClass xtermWidgetClass;
+
+#define IsXtermWidget(w) (XtClass(w) == xtermWidgetClass)
+
 typedef struct _TekClassRec {
     CoreClassPart core_class;
     TekClassPart tek_class;
Index: scrollbar.c
--- xterm-55+/scrollbar.c       Sun Oct 26 16:05:57 1997
+++ xterm-56/scrollbar.c        Fri Nov 28 15:27:15 1997
@@ -548,11 +548,11 @@
     String *params;
     Cardinal *nparams;
 {
-    XtermWidget w = (XtermWidget) gw;
-    register TScreen *screen = &w->screen;
-
-    ScrollTextUpDownBy (gw, (XtPointer) NULL,
+    if (IsXtermWidget(gw)) {
+       register TScreen *screen = &((XtermWidget)gw)->screen;
+       ScrollTextUpDownBy (gw, (XtPointer) 0,
                        (XtPointer)(params_to_pixels (screen, params, *nparams)));
+    }
     return;
 }
 
@@ -564,10 +564,10 @@
     String *params;
     Cardinal *nparams;
 {
-    XtermWidget w = (XtermWidget) gw;
-    register TScreen *screen = &w->screen;
-
-    ScrollTextUpDownBy (gw, (XtPointer) NULL,
+    if (IsXtermWidget(gw)) {
+       register TScreen *screen = &((XtermWidget)gw)->screen;
+       ScrollTextUpDownBy (gw, (XtPointer) 0,
                        (XtPointer)(-params_to_pixels (screen, params, *nparams)));
+    }
     return;
 }