I suspect testing this takes too much time for even expensive tests:

    $ truncate -s 2G f; time pr -2 f > /dev/null
    Segmentation fault         (core dumped) pr -2 f > /dev/null
    
    real        0m28.021s
    user        0m20.729s
    sys 0m4.321s

It is even slower with ASAN, of course. Also, some other things in
that file are probably worth changing to idx_t.

-- 8< --

* src/pr.c (buff_current): Define as an idx_t instead of an int.
(line_vector): Define as an array of idx_t elements instead of int.
(store_colum): Define a variable used to set buff_current as an idx_t.
* NEWS: Mention the bug fix.

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-C1YW9FO0.
---
 NEWS     | 4 ++++
 src/pr.c | 6 +++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index d4345477a..6b4d6855e 100644
--- a/NEWS
+++ b/NEWS
@@ -96,6 +96,10 @@ GNU coreutils NEWS                                    -*- 
outline -*-
   od now exits gracefully when offsets overflow integer limits.
   [This bug was present in "the beginning".]
 
+  'pr' no longer reads past its internal buffer and crashes when it reads more
+  than INT_MAX bytes of column data for a single page.
+  [This bug was present in "the beginning".]
+
   'realpath' without -s, or 'readlink' with -e,-f,-m no longer
   loop infinitely when resolving a symbolic link which
   resolves to a path beginning with the symbolic link itself.
diff --git a/src/pr.c b/src/pr.c
index 29321e58e..e0140e567 100644
--- a/src/pr.c
+++ b/src/pr.c
@@ -456,7 +456,7 @@ static char *buff;
 
 /* Index of the position in buff where the next character
    will be stored. */
-static unsigned int buff_current;
+static idx_t buff_current;
 
 /* The number of characters in buff.
    Used for allocation of buff and to detect overflow of buff. */
@@ -466,7 +466,7 @@ static idx_t buff_allocated;
    Each entry is an index of the first character of a line.
    This is used when storing lines to facilitate shuffling when
    we do column balancing on the last page. */
-static int *line_vector;
+static idx_t *line_vector;
 
 /* Array of horizontal positions.
    For each line in line_vector, end_vector[line] is the horizontal
@@ -1955,7 +1955,7 @@ store_columns (void)
 {
   int i, j;
   unsigned int line = 0;
-  unsigned int buff_start;
+  idx_t buff_start;
   int last_col;                /* The rightmost column which will be saved in 
buff */
   COLUMN *p;
 
-- 
2.56.0


Reply via email to