Subject: Re: bug#22181: endless loop in grep 2.22

From: Paul Eggert <[email-masked]>
Date: Fri, 8 Jan 2016 18:53:46 -0800

Jim Meyering wrote:
> It was trivial: printf does not necessarily support \xHH hexadecimal
> escapes.

Thanks for catching that. I looked and found one other problem of that kind. I 
tried running the tests on Solaris and AIX and found a few more porting issues 
in the grep tests, and installed the attached.
>From 2a661493355a53c11ddef2187fc9c6370916747d Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Fri, 8 Jan 2016 18:48:14 -0800
Subject: [PATCH] tests: port to other POSIXish platforms

I tested this on Solaris 10 and AIX 7.1.
* tests/max-count-overread:
* tests/mb-non-UTF8-performance:
Don't assume 'yes' exists, as 'yes' is not in POSIX.
* tests/mb-non-UTF8-performance:
Don't rely on 'head -1000', as that option syntax is not POSIX.
* tests/pcre-count: Don't rely on "printf '\x0'".
* tests/unibyte-binary: Don't assume \200 is an encoding error
in every unibyte locale.
---
 tests/max-count-overread      | 2 +-
 tests/mb-non-UTF8-performance | 4 +++-
 tests/pcre-count              | 2 +-
 tests/unibyte-binary          | 6 +++++-
 4 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/tests/max-count-overread b/tests/max-count-overread
index d7aafd6..ec98ac8 100755
--- a/tests/max-count-overread
+++ b/tests/max-count-overread
@@ -9,7 +9,7 @@ fail=0
 
 echo x > exp || framework_failure_
 
-yes x | timeout 3 grep -m1 x > out || fail=1
+${AWK-awk} 'BEGIN{for (;;) print "x"}' | timeout 3 grep -m1 x > out || fail=1
 compare exp out || fail=1
 
 Exit $fail
diff --git a/tests/mb-non-UTF8-performance b/tests/mb-non-UTF8-performance
index fc371bd..c350dfb 100755
--- a/tests/mb-non-UTF8-performance
+++ b/tests/mb-non-UTF8-performance
@@ -31,7 +31,9 @@ expensive_
 # the unibyte test takes at least 10ms of user time.
 n_lines=100000
 while :; do
-  yes $(printf '%078d' 0) | head -$n_lines > in || framework_failure_
+  ${AWK-awk} -v n_lines=$n_lines \
+      'BEGIN {while (n_lines--) printf "%078d\n", 0}' </dev/null >in ||
+    framework_failure_
   ubyte_ms=$(LC_ALL=C user_time_ 1 grep -i foobar in) || fail=1
   test $ubyte_ms -ge 10 && break
   n_lines=$(expr $n_lines + 200000)
diff --git a/tests/pcre-count b/tests/pcre-count
index 24afa17..4bcb2b3 100755
--- a/tests/pcre-count
+++ b/tests/pcre-count
@@ -13,7 +13,7 @@ require_pcre_
 
 fail=0
 
-printf 'a\n%032768d\nb\x0\n%032768d\na\n' 0 0 > in
+printf 'a\n%032768d\nb\0\n%032768d\na\n' 0 0 > in
 
 LC_ALL=C grep -P 'a' in | wc -l > exp
 
diff --git a/tests/unibyte-binary b/tests/unibyte-binary
index 78735b8..11325ee 100755
--- a/tests/unibyte-binary
+++ b/tests/unibyte-binary
@@ -24,5 +24,9 @@ fail=0
 printf 'a\n\200\nb\n' >in || framework_failure_
 printf 'a\nBinary file in matches\n' >exp || framework_failure_
 grep . in >out || fail=1
-compare exp out || fail=1
+
+# In some unibyte locales, \200 is an encoding error;
+# in others, it is a valid character.  Allow either possibility.
+compare exp out || compare in out || fail=1
+
 Exit $fail
-- 
2.5.0