* src/fold.c (adjust_column): Ensure BS goes back
1 column after a TAB.
* tests/fold/fold-characters.sh: Add test cases.
* NEWS: Mention the bug fix.
---
 NEWS                          |  5 +++--
 src/fold.c                    |  6 +++++-
 tests/fold/fold-characters.sh | 18 ++++++++++++++++++
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index a5e6ba57a..2460c14e6 100644
--- a/NEWS
+++ b/NEWS
@@ -9,8 +9,9 @@ GNU coreutils NEWS                                    -*- 
outline -*-
   [bug introduced in coreutils-9.11]
 
   'fold' no longer prematurely wraps lines with a wide character towards
-  the start of a line, followed by multiple backspaces.
-  [bug introduced in coreutils-9.8]
+  the start of a line, followed by multiple backspaces.  Also backspaces
+  after a tab character are accounted for correctly.
+  [bugs introduced in coreutils-9.8]
 
   'realpath' without -s, or 'readlink' with -e,-f,-m no longer
   loop infinitely when resolving a symbolic link which
diff --git a/src/fold.c b/src/fold.c
index 2d725c3d5..170cdb752 100644
--- a/src/fold.c
+++ b/src/fold.c
@@ -121,7 +121,11 @@ adjust_column (size_t column, mcel_t g)
       else if (g.ch == '\r')
         column = 0;
       else if (g.ch == '\t')
-        column += TAB_WIDTH - column % TAB_WIDTH;
+        {
+          /* A backspace after a tab moves back one column.  */
+          last_character_width = 1;
+          column += TAB_WIDTH - column % TAB_WIDTH;
+        }
       else
         {
           if (counting_mode == COUNT_CHARACTERS)
diff --git a/tests/fold/fold-characters.sh b/tests/fold/fold-characters.sh
index cfdee2b3e..a6a083c53 100755
--- a/tests/fold/fold-characters.sh
+++ b/tests/fold/fold-characters.sh
@@ -97,4 +97,22 @@ test $(env printf '\xC3' | fold | wc -c) = 1 || fail=1
 # causing premature line wrapping.
 test $(env printf 'A\uB250\b\bB\n' | fold -w80 | wc -l) = 1 || fail=1
 
+# A backspace after an initial tab must move back one column.
+env printf '\t\bX\n' > exp5 || framework_failure_
+fold -w8 exp5 > out5 || fail=1
+compare exp5 out5 || fail=1
+fold --characters -w8 exp5 > out5 || fail=1
+compare exp5 out5 || fail=1
+
+# A tab must reset the saved width after a wide character.
+env printf '\uB250\t\bXX\n' > input6 || framework_failure_
+env printf '\uB250\t\bX\nX\n' > exp6 || framework_failure_
+fold -w8 input6 > out6 || fail=1
+compare exp6 out6 || fail=1
+
+# Likewise after a zero width combining character.
+env printf 'a\u0301\t\bX\n' > exp7 || framework_failure_
+fold -w8 exp7 > out7 || fail=1
+compare exp7 out7 || fail=1
+
 Exit $fail
-- 
2.55.0


Reply via email to