From 124a4763e07cf79768307db8dfda786a40353e20 Mon Sep 17 00:00:00 2001 From: huuan26 Date: Tue, 3 Nov 2026 13:45:04 +0700 Subject: [PATCH] unexpand: resume tab conversion when backspaces move before last tab stop (#16120) --- src/uu/unexpand/src/unexpand.rs | 5 +++-- tests/by-util/test_unexpand.rs | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/uu/unexpand/src/unexpand.rs b/src/uu/unexpand/src/unexpand.rs index 93c13f634ea..a119c179ef0 100644 --- a/src/uu/unexpand/src/unexpand.rs +++ b/src/uu/unexpand/src/unexpand.rs @@ -579,8 +579,9 @@ fn unexpand_buf( } while byte < buf.len() { - // when we have a finite number of columns, never convert past the last column - if lastcol > 0 && print_state.col >= lastcol { + // when we have a finite number of columns, never convert past the last column, + // but only fast forward if there are no backspaces that could move col back + if lastcol > 0 && print_state.col >= lastcol && !buf[byte..].contains(&b'\x08') { write_tabs(output, tab_config, print_state, true)?; output.write_all(&buf[byte..])?; print_state.scol = print_state.col; diff --git a/tests/by-util/test_unexpand.rs b/tests/by-util/test_unexpand.rs index 25a3279217c..771957b3a6c 100644 --- a/tests/by-util/test_unexpand.rs +++ b/tests/by-util/test_unexpand.rs @@ -498,3 +498,13 @@ fn test_buffered_read_edgecase_behaviour() { .stdout_only(String::from_utf8(expected).unwrap()); } } + +#[test] +fn test_backspaces_before_last_tab_stop_resume_conversion() { + // issue #16120: backspaces moving column back below the last tab stop allow conversion + new_ucmd!() + .args(&["-t", "3,5"]) + .pipe_in("abcde\x08\x08 X\n") + .succeeds() + .stdout_is("abcde\x08\x08\tX\n"); +}