]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
ptx: fix infinite loop with -G and a narrow output width master
authorAyesha Shafique <ayeshashafique123@gmail.com>
Mon, 27 Jul 2026 07:03:19 +0000 (02:03 -0500)
committerPádraig Brady <P@draigBrady.com>
Tue, 28 Jul 2026 11:05:32 +0000 (12:05 +0100)
With GNU extensions disabled, before_max_width can go negative, and
define_all_fields then loops forever trying to shrink the before field
to a width narrower than empty:

  $ printf 'qux\n' | src/ptx -G -w2
  [hangs]

Commit v6.12-96-g773be9eca added a clamp for this, but placed it in
the GNU-extensions branch only.  Move it after that if/else so that
both branches are covered.

* src/ptx.c (fix_output_parameters): Clamp before_max_width for both
the GNU and non-GNU cases.
* tests/ptx/ptx-overrun.sh: Add a test case.
* NEWS: Mention the bug fix.
Fixes https://bugs.gnu.org/81507

NEWS
src/ptx.c
tests/ptx/ptx-overrun.sh

diff --git a/NEWS b/NEWS
index fd0902cb724a1bd97b4f705878abf604cf696607..28d1da64d923e52b8baebca663ad1ae9f1c13e4f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,11 @@ GNU coreutils NEWS                                    -*- outline -*-
   like when processing large tab stops.
   [This bug was present in "the beginning".]
 
+  'ptx -G' no longer hangs when the output width is smaller than twice the
+  gap size, as with 'ptx -G -w4', or when a long reference leaves that
+  little room, as with 'ptx -G -r'.
+  [This bug was present in "the beginning".]
+
   'shred' no longer blocks when opening a FIFO that has no readers.
   [This bug was present in "the beginning".]
 
index 8c7d1535af0cb8259c1712541a3afd68bb53efdd..6ef19ee15a3d71e185b5710ff987c4fd8bf90bf2 100644 (file)
--- a/src/ptx.c
+++ b/src/ptx.c
@@ -1145,8 +1145,6 @@ fix_output_parameters (void)
          right side, or one on either side.  */
 
       before_max_width -= 2 * truncation_string_length;
-      if (before_max_width < 0)
-        before_max_width = 0;
       keyafter_max_width -= 2 * truncation_string_length;
     }
   else
@@ -1161,6 +1159,9 @@ fix_output_parameters (void)
       keyafter_max_width -= 2 * truncation_string_length + 1;
     }
 
+  if (before_max_width < 0)
+    before_max_width = 0;
+
   /* Compute which characters need special output processing.  Initialize
      by flagging any white space character.  Some systems do not consider
      form feed as a space character, but we do.  */
index ff8b57ad55c3818cf6d6bdb15e033a058c491091..7562779c1cfbe3d3baf90fe572fb38cefbe3bba9 100755 (executable)
@@ -50,4 +50,10 @@ compare /dev/null out || fail=1
 echo a > a
 ptx -w1 -A "$PWD/a" >/dev/null || fail=1
 
+
+# Trigger an infinite loop from coreutils-9.11 and earlier.
+# This would hang with -G whenever (width >> 1) < gap size.
+printf 'qux\n' | timeout 10 ptx -G -w2 || fail=1
+
+
 Exit $fail