Subject: bug#13530: head: memory exhausted when printing all from stdin but last P/E bytes

From: Jim Meyering <[email-masked]>
Date: Tue, 28 May 2013 02:54:28 +0200

Paul Eggert wrote:

> On 05/27/2013 05:07 PM, Jim Meyering wrote:
>
>> +max_BUFSIZ=$(expr 256 '*' 1024)
>> +lim=$(expr $SIZE_MAX - $max_BUFSIZ)
>
> Can't this code fail, due to overflow, on non-GMP hosts?  See:
>
> http://lists.gnu.org/archive/html/coreutils/2013-05/msg00060.html
>
> and look for "$SIZE_MAX".

Thanks for mentioning that.
I propose to move your subtract_one variable into init.cfg
and then use it like this:

diff --git a/tests/misc/head-c.sh b/tests/misc/head-c.sh
index 70a6ccc..41ea52b 100755
--- a/tests/misc/head-c.sh
+++ b/tests/misc/head-c.sh
@@ -34,7 +34,15 @@ esac
 # to the selected value of N without exceeding SIZE_MAX.
 # Since we've seen BUFSIZ up to 128K, use 256K to be safe.
 max_BUFSIZ=$(expr 256 '*' 1024)
-lim=$(expr $SIZE_MAX - $max_BUFSIZ)
+
+# Normally we would just write this,
+#  lim=$(expr $SIZE_MAX - $max_BUFSIZ)
+# But that fails for non-GMP expr.  See this:
+# https://lists.gnu.org/archive/html/coreutils/2013-05/msg00060.html
+# Instead, use that same approach to obtain SIZE_MAX-1, and *then*
+# subtract $max_BUFSIZ.
+lim=$(echo $SIZE_MAX | sed "$subtract_one")
+lim=$(expr $lim - $max_BUFSIZ)

 # Only allocate memory as needed.
 # Coreutils <= 8.21 would allocate memory up front