XFree86 3.9x - xterm patch #55 - 1997/11/25 - T.Dickey This fixes the segmentation violation noted by Rogier Wolff about a month ago. He'd set xterm to 400 (rows) by 150 columns, which broke because there were limited buffers (200 rows) used for juggling data when adding or deleting lines and for switching between alternate and normal screens. I replaced this by an allocated buffer. The bug is simple to test if you set titeInhibit false. -------------------------------------------------------------------------------- charproc.c | 10 +++------ error.h | 1 ptyx.h | 5 +--- screen.c | 62 ++++++++++++++++++++++++++++++++++++++--------------------- util.c | 29 +++++++++++++++------------ xterm.h | 5 ++-- 6 files changed, 66 insertions, 46 deletions -------------------------------------------------------------------------------- Index: charproc.c --- xterm-54+/charproc.c Sun Oct 26 16:05:57 1997 +++ xterm-55/charproc.c Sun Nov 23 19:07:33 1997 @@ -3324,13 +3324,11 @@ SwitchBufPtrs(screen) register TScreen *screen; { - register int rows = screen->max_row + 1; - char *save [4 /* MAX_PTRS */ * MAX_ROWS]; - Size_t len = MAX_PTRS * sizeof(char *) * rows; + Size_t len = ScrnPointers(screen, screen->max_row + 1); - memcpy ( (char *)save, (char *)screen->buf, len); - memcpy ( (char *)screen->buf, (char *)screen->altbuf, len); - memcpy ( (char *)screen->altbuf, (char *)save, len); + memcpy ( (char *)screen->save_ptr, (char *)screen->buf, len); + memcpy ( (char *)screen->buf, (char *)screen->altbuf, len); + memcpy ( (char *)screen->altbuf, (char *)screen->save_ptr, len); } void Index: error.h --- xterm-54+/error.h Thu Feb 25 17:21:29 1993 +++ xterm-55/error.h Sun Nov 23 20:30:07 1997 @@ -98,6 +98,7 @@ #define ERROR_RESIZROW2 99 /* ScreenResize: realloc() failed on alt attr */ #define ERROR_RESIZROW3 100 /* ScreenResize: realloc() failed on attr */ #define ERROR_RESIZROW4 101 /* ScreenResize: realloc() failed on attr */ +#define ERROR_SAVE_PTR 102 /* ScrnPointers: malloc/realloc() failed */ /* scrollbar.c */ #define ERROR_SBRALLOC 110 /* ScrollBarOn: realloc() failed on base */ #define ERROR_SBRALLOC2 111 /* ScrollBarOn: realloc() failed on rows */ Index: ptyx.h --- xterm-54+/ptyx.h Sun Oct 26 16:05:57 1997 +++ xterm-55/ptyx.h Sun Nov 23 19:10:15 1997 @@ -56,9 +56,6 @@ (((detail)&(Button1Mask|Button2Mask)) == 0)) \ ) -#define MAX_COLS 200 -#define MAX_ROWS 128 - /* ** System V definitions */ @@ -620,6 +617,8 @@ Char *sbuf_address; /* main screen memory address */ ScrnBuf altbuf; /* alternate screen buffer */ Char *abuf_address; /* alternate screen memory address */ + Char **save_ptr; /* workspace for save-pointers */ + size_t save_len; /* ...and its length */ Boolean alternate; /* true if using alternate buf */ unsigned short do_wrap; /* true if cursor in last column and character just output */ Index: screen.c --- xterm-54+/screen.c Sat Nov 1 16:03:40 1997 +++ xterm-55/screen.c Sun Nov 23 20:30:56 1997 @@ -100,7 +100,7 @@ #endif static int Reallocate PROTO((ScrnBuf *sbuf, Char **sbufaddr, int nrow, int ncol, int oldrow, int oldcol)); -static void ScrnClearLines PROTO((char **save, ScrnBuf sb, int where, int n, int size)); +static void ScrnClearLines PROTO((TScreen *screen, ScrnBuf sb, int where, int n, int size)); ScrnBuf Allocate (nrow, ncol, addr) @@ -282,52 +282,72 @@ } static void -ScrnClearLines (save, sb, where, n, size) +ScrnClearLines (screen, sb, where, n, size) /* * Saves pointers to the n lines beginning at sb + where, and clears the lines */ -char **save; +TScreen *screen; ScrnBuf sb; int where, n, size; { register int i; + size_t len = ScrnPointers(screen, n); /* save n lines at where */ - memcpy ( (char *)save, + memcpy ( (char *) screen->save_ptr, (char *) &sb[MAX_PTRS * where], - MAX_PTRS * sizeof(char *) * n); + len); /* clear contents of old rows */ if (TERM_COLOR_FLAGS) { int last = (n * MAX_PTRS); int flags = TERM_COLOR_FLAGS; for (i = 0; i < last; i += MAX_PTRS) { - bzero(save[i+0], size); - memset(save[i+1], flags, size); - memset(save[i+2], xtermColorPair(), size); + bzero(screen->save_ptr[i+0], size); + memset(screen->save_ptr[i+1], flags, size); + memset(screen->save_ptr[i+2], xtermColorPair(), size); } } else { for (i = MAX_PTRS * n - 1 ; i >= 0 ; i--) - bzero (save[i], size); + bzero (screen->save_ptr[i], size); + } +} + +size_t +ScrnPointers (screen, len) +TScreen *screen; +size_t len; +{ + len *= (MAX_PTRS * sizeof(Char *)); + + if (len > screen->save_len) { + if (screen->save_len) + screen->save_ptr = realloc(screen->save_ptr, len); + else + screen->save_ptr = malloc(len); + screen->save_len = len; + if (screen->save_ptr == 0) + SysError (ERROR_SAVE_PTR); } + return len; } void -ScrnInsertLine (sb, last, where, n, size) +ScrnInsertLine (screen, sb, last, where, n, size) /* Inserts n blank lines at sb + where, treating last as a bottom margin. Size is the size of each entry in sb. Requires: 0 <= where < where + n <= last - n <= MAX_ROWS */ +TScreen *screen; register ScrnBuf sb; int last; register int where, n, size; { - char *save [4 /* MAX_PTRS */ * MAX_ROWS]; + size_t len = ScrnPointers(screen, n); /* save n lines at bottom */ - ScrnClearLines(save, sb, (last -= n - 1), n, size); + ScrnClearLines(screen, sb, (last -= n - 1), n, size); /* * WARNING, overlapping copy operation. Move down lines (pointers). @@ -340,29 +360,27 @@ */ memmove( (char *) &sb [MAX_PTRS * (where + n)], (char *) &sb [MAX_PTRS * where], - MAX_PTRS * sizeof (char *) * (last - where)); + MAX_PTRS * sizeof (char *) * (last - where)); /* reuse storage for new lines at where */ memcpy ( (char *) &sb[MAX_PTRS * where], - (char *)save, - MAX_PTRS * sizeof(char *) * n); + (char *) screen->save_ptr, + len); } void -ScrnDeleteLine (sb, last, where, n, size) +ScrnDeleteLine (screen, sb, last, where, n, size) /* Deletes n lines at sb + where, treating last as a bottom margin. Size is the size of each entry in sb. Requires 0 <= where < where + n < = last - n <= MAX_ROWS */ +TScreen *screen; register ScrnBuf sb; register int n, last, size; int where; { - char *save [4 /* MAX_PTRS */ * MAX_ROWS]; - - ScrnClearLines(save, sb, where, n, size); + ScrnClearLines(screen, sb, where, n, size); /* move up lines */ memmove( (char *) &sb[MAX_PTRS * where], @@ -371,7 +389,7 @@ /* reuse storage for new bottom lines */ memcpy ( (char *) &sb[MAX_PTRS * last], - (char *)save, + (char *)screen->save_ptr, MAX_PTRS * sizeof(char *) * n); } Index: util.c --- xterm-54+/util.c Tue Oct 14 21:40:58 1997 +++ xterm-55/util.c Sun Nov 23 19:15:02 1997 @@ -261,11 +261,13 @@ } } if(screen->scrollWidget && !screen->alternate && screen->top_marg == 0) - ScrnDeleteLine(screen->allbuf, screen->bot_marg + - screen->savelines, 0, amount, screen->max_col + 1); + ScrnDeleteLine(screen, screen->allbuf, + screen->bot_marg + screen->savelines, 0, + amount, screen->max_col + 1); else - ScrnDeleteLine(screen->buf, screen->bot_marg, screen->top_marg, - amount, screen->max_col + 1); + ScrnDeleteLine(screen, screen->buf, + screen->bot_marg, screen->top_marg, + amount, screen->max_col + 1); if(refreshheight > 0) ScrnRefresh(screen, refreshtop, 0, refreshheight, screen->max_col + 1, False); @@ -336,8 +338,8 @@ (unsigned) Width(screen)); } } - ScrnInsertLine (screen->buf, screen->bot_marg, screen->top_marg, - amount, screen->max_col + 1); + ScrnInsertLine(screen, screen->buf, screen->bot_marg, screen->top_marg, + amount, screen->max_col + 1); } /* @@ -396,9 +398,8 @@ (unsigned) Width(screen)); } } - /* adjust screen->buf */ - ScrnInsertLine(screen->buf, screen->bot_marg, screen->cur_row, n, - screen->max_col + 1); + ScrnInsertLine(screen, screen->buf, screen->bot_marg, screen->cur_row, n, + screen->max_col + 1); } /* @@ -474,11 +475,13 @@ } /* adjust screen->buf */ if(screen->scrollWidget && !screen->alternate && screen->cur_row == 0) - ScrnDeleteLine(screen->allbuf, screen->bot_marg + - screen->savelines, 0, n, screen->max_col + 1); + ScrnDeleteLine(screen, screen->allbuf, + screen->bot_marg + screen->savelines, 0, + n, screen->max_col + 1); else - ScrnDeleteLine(screen->buf, screen->bot_marg, screen->cur_row, - n, screen->max_col + 1); + ScrnDeleteLine(screen, screen->buf, + screen->bot_marg, screen->cur_row, + n, screen->max_col + 1); } /* Index: xterm.h --- xterm-54+/xterm.h Sun Oct 26 16:05:57 1997 +++ xterm-55/xterm.h Sun Nov 23 19:15:11 1997 @@ -172,12 +172,13 @@ extern ScrnBuf Allocate PROTO((int nrow, int ncol, Char **addr)); extern int ScreenResize PROTO((TScreen *screen, int width, int height, unsigned *flags)); extern int ScrnGetAttributes PROTO((TScreen *screen, int row, int col, Char *str, int length)); +extern size_t ScrnPointers PROTO((TScreen *screen, size_t len)); extern void ClearBufRows PROTO((TScreen *screen, int first, int last)); extern void ScreenWrite PROTO((TScreen *screen, Char *str, unsigned flags, unsigned cur_fg_bg, int length)); extern void ScrnDeleteChar PROTO((TScreen *screen, int n, int size)); -extern void ScrnDeleteLine PROTO((ScrnBuf sb, int n, int last, int size, int where)); +extern void ScrnDeleteLine PROTO((TScreen *screen, ScrnBuf sb, int n, int last, int size, int where)); extern void ScrnInsertChar PROTO((TScreen *screen, int n, int size)); -extern void ScrnInsertLine PROTO((ScrnBuf sb, int last, int where, int n, int size)); +extern void ScrnInsertLine PROTO((TScreen *screen, ScrnBuf sb, int last, int where, int n, int size)); extern void ScrnRefresh PROTO((TScreen *screen, int toprow, int leftcol, int nrows, int ncols, int force)); extern void ScrnSetAttributes PROTO((TScreen *screen, int row, int col, unsigned mask, unsigned value, int length));