XFree86 3.9x - xterm patch #56 - T.Dickey This patch is based on analysis by Arfst Ludwig , who reported: Setting the following resources xterm (all current versions) receives a segmentation fault on after scrolling: *XTerm*VT100*translations: #override \ ~Shift~Ctrl: insert-selection(PRIMARY, CUT_BUFFER0)\n\ Shift~Ctrl: insert-selection(CLIPBOARD, CUT_BUFFER1)\n\ ~Shift: select-end(PRIMARY, CUT_BUFFER0)\n\ Shift: 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; }