diff --git a/CHANGELOG.md b/CHANGELOG.md index 464f096f..5dbb4e15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,10 +82,13 @@ * DECCRA not clamping or verifying the destination rectangle ([#2352][2352]). * Empty selection clearing the clipboard ([#2327][2327]). +* Passing a very large value as CHT/CBT argument hangs the terminal + ([#2360][2360]). [2353]: https://codeberg.org/dnkl/foot/issues/2353 [2352]: https://codeberg.org/dnkl/foot/issues/2352 [2327]: https://codeberg.org/dnkl/foot/issues/2327 +[2360]: https://codeberg.org/dnkl/foot/issues/2360 ### Security diff --git a/csi.c b/csi.c index 176cc3ac..961a4a76 100644 --- a/csi.c +++ b/csi.c @@ -1171,37 +1171,40 @@ csi_dispatch(struct terminal *term, uint8_t final) case 'I': { /* CHT - Tab Forward (param is number of tab stops to move through) */ - for (int i = 0; i < vt_param_get(term, 0, 1); i++) { - int new_col = term->cols - 1; - tll_foreach(term->tab_stops, it) { - if (it->item > term->grid->cursor.point.col) { - new_col = it->item; + int count = vt_param_get(term, 0, 1); + int new_col = term->grid->cursor.point.col; + tll_foreach(term->tab_stops, it) { + if (it->item > new_col) { + if (--count < 0) { break; } + new_col = it->item; } - xassert(new_col >= term->grid->cursor.point.col); - - bool lcf = term->grid->cursor.lcf; - term_cursor_right(term, new_col - term->grid->cursor.point.col); - term->grid->cursor.lcf = lcf; } + xassert(new_col >= term->grid->cursor.point.col); + + bool lcf = term->grid->cursor.lcf; + term_cursor_right(term, new_col - term->grid->cursor.point.col); + term->grid->cursor.lcf = lcf; break; } - case 'Z': + case 'Z': { /* CBT - Back tab (param is number of tab stops to move back through) */ - for (int i = 0; i < vt_param_get(term, 0, 1); i++) { - int new_col = 0; - tll_rforeach(term->tab_stops, it) { - if (it->item < term->grid->cursor.point.col) { - new_col = it->item; + int count = vt_param_get(term, 0, 1); + int new_col = term->grid->cursor.point.col; + tll_rforeach(term->tab_stops, it) { + if (it->item < new_col) { + if (--count < 0) { break; } + new_col = it->item; } - xassert(term->grid->cursor.point.col >= new_col); - term_cursor_left(term, term->grid->cursor.point.col - new_col); } + xassert(term->grid->cursor.point.col >= new_col); + term_cursor_left(term, term->grid->cursor.point.col - new_col); break; + } case 'h': case 'l': {