From: Aizal Khan Date: Wed, 1 Jul 2026 13:21:41 +0000 (+0530) Subject: col: fix cur_col underflow on backspace over a wide char X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=65627ec56bfeed5fa6fd3edff8e65f3e587fee7e;p=thirdparty%2Futil-linux.git 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 --- 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: