From 815a357ad9a13772a8dcaaf0f8a26c358f559359 Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Mon, 8 Sep 2014 21:27:33 +0200 Subject: [PATCH] do not crash when the scrollback mempool is OOM --- src/bin/termpty.c | 57 +++++++++++++++++++++++++++++++++----------- src/bin/termptyops.c | 2 ++ 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/bin/termpty.c b/src/bin/termpty.c index 186cde89..c16f6f9a 100644 --- a/src/bin/termpty.c +++ b/src/bin/termpty.c @@ -613,7 +613,7 @@ termpty_line_length(const Termcell *cells, ssize_t nb_cells) } static int -termpty_line_find_top(Termpty *ty, int y_end) +termpty_line_find_top(Termpty *ty, int y_end, int *top) { int y_start = y_end; Termsave *ts; @@ -623,25 +623,34 @@ termpty_line_find_top(Termpty *ty, int y_end) if (TERMPTY_SCREEN(ty, ty->w - 1, y_start - 1).att.autowrapped) y_start--; else - return y_start; + { + *top = y_start; + return 0; + } } while (-y_start < ty->backscroll_num) { ts = termpty_save_extract(ty->back[(y_start + ty->backpos - 1 + ty->backmax) % ty->backmax]); + if (!ts) + return -1; ty->back[(y_start + ty->backpos - 1 + ty->backmax) % ty->backmax] = ts; if (ts->cell[ts->w - 1].att.autowrapped) y_start--; else - return y_start; + { + *top = y_start; + return 0; + } } - return y_start; + *top = y_start; + return 0; } static int termpty_line_rewrap(Termpty *ty, int y_start, int y_end, Termcell *screen2, Termsave **back2, - int w2, int y2_end) + int w2, int y2_end, int *new_y_start) { int x, x2, y, y2, y2_start; int len, len_last, len_remaining, copy_width, ts2_width; @@ -656,6 +665,8 @@ termpty_line_rewrap(Termpty *ty, int y_start, int y_end, { ts = termpty_save_extract(ty->back[(y_end + ty->backpos + ty->backmax) % ty->backmax]); + if (!ts) + return -1; ty->back[(y_end + ty->backpos + ty->backmax) % ty->backmax] = ts; len_last = ts->w; } @@ -668,7 +679,11 @@ termpty_line_rewrap(Termpty *ty, int y_start, int y_end, else { if (y2_start < 0) - back2[y2_start + ty->backmax] = termpty_save_new(0); + { + back2[y2_start + ty->backmax] = termpty_save_new(0); + if (!back2[y2_start + ty->backmax]) + return -1; + } return y2_start; } if (-y2_start > ty->backmax) @@ -696,6 +711,8 @@ termpty_line_rewrap(Termpty *ty, int y_start, int y_end, { ts = termpty_save_extract(ty->back[(y + ty->backpos + ty->backmax) % ty->backmax]); + if (!ts) + return -1; ty->back[(y + ty->backpos + ty->backmax) % ty->backmax] = ts; line = ts->cell; } @@ -717,6 +734,8 @@ termpty_line_rewrap(Termpty *ty, int y_start, int y_end, { ts2_width = MIN(len_remaining, w2); ts2 = termpty_save_new(ts2_width); + if (!ts2) + return -1; line2 = ts2->cell; back2[y2 + ty->backmax] = ts2; } @@ -738,15 +757,16 @@ termpty_line_rewrap(Termpty *ty, int y_start, int y_end, x = 0; y++; } - return y2_start; + *new_y_start = y2_start; + return 0; } void termpty_resize(Termpty *ty, int new_w, int new_h) { - Termcell *new_screen; - Termsave **new_back; + Termcell *new_screen = NULL; + Termsave **new_back = NULL; int y_start, y_end, new_y_start = 0, new_y_end; int i, altbuf = 0; @@ -773,8 +793,7 @@ termpty_resize(Termpty *ty, int new_w, int new_h) if (!ty->screen2) { ERR("memerr"); - free(new_screen); - return; + goto bad; } new_back = calloc(sizeof(Termsave *), ty->backmax); @@ -782,9 +801,14 @@ termpty_resize(Termpty *ty, int new_w, int new_h) new_y_end = new_h - 1; while ((y_end >= -ty->backscroll_num) && (new_y_end >= -ty->backmax)) { - y_start = termpty_line_find_top(ty, y_end); - new_y_start = termpty_line_rewrap(ty, y_start, y_end, new_screen, - new_back, new_w, new_y_end); + if (termpty_line_find_top(ty, y_end, &y_start) < 0) + goto bad; + if (termpty_line_rewrap(ty, y_start, y_end, new_screen, + new_back, new_w, new_y_end, + &new_y_start) < 0) + { + goto bad; + } y_end = y_start - 1; new_y_end = new_y_start - 1; } @@ -815,6 +839,11 @@ termpty_resize(Termpty *ty, int new_w, int new_h) _pty_size(ty); termpty_save_thaw(); + return; + +bad: + free(new_screen); + free(new_back); } void diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c index c901212a..bd594607 100644 --- a/src/bin/termptyops.c +++ b/src/bin/termptyops.c @@ -42,6 +42,8 @@ termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max) termpty_save_freeze(); w = termpty_line_length(cells, w_max); ts = termpty_save_new(w); + if (!ts) + return; termpty_cell_copy(ty, cells, ts->cell, w); if (!ty->back) ty->back = calloc(1, sizeof(Termsave *) * ty->backmax); if (ty->back[ty->backpos])