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;
}