From 65627ec56bfeed5fa6fd3edff8e65f3e587fee7e Mon Sep 17 00:00:00 2001 From: Aizal Khan Date: Wed, 1 Jul 2026 18:51:41 +0530 Subject: [PATCH] col: fix cur_col underflow on backspace over a wide char The BS handler in handle_not_graphic() subtracts the last stored character's width from lns->cur_col (a size_t) and only guards against cur_col == 0. When the last graphic character is double-width and the column was reset by CR then advanced by a single space, cur_col is 1 and cur_col -= 2 wraps to SIZE_MAX. That feeds l_max_col and the stored c_column, so flush_line() sizes count[] as l_max_col + 1 (== 0) and then memsets sizeof(size_t) * l_max_col bytes and indexes count[SIZE_MAX] -- an out-of-bounds write reachable from stdin under a UTF-8 locale. Clamp the subtraction so the column cannot go below zero. Signed-off-by: Aizal Khan --- text-utils/col.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/text-utils/col.c b/text-utils/col.c index 286a6f833..9c0c9acef 100644 --- a/text-utils/col.c +++ b/text-utils/col.c @@ -396,9 +396,12 @@ static int handle_not_graphic(struct col_ctl *ctl, struct col_lines *lns) case BS: if (lns->cur_col == 0) return 1; /* can't go back further */ - if (lns->c) - lns->cur_col -= lns->c->c_width; - else + if (lns->c) { + if ((size_t) lns->c->c_width <= lns->cur_col) + lns->cur_col -= lns->c->c_width; + else + lns->cur_col = 0; + } else lns->cur_col -= 1; return 1; case CR: -- 2.47.3