diff options
author | Jim Meyering <meyering@fb.com> | 2013-12-14 09:34:08 -0800 |
---|---|---|
committer | Jim Meyering <meyering@fb.com> | 2013-12-18 10:33:49 -0800 |
commit | 9316d536321af0c44f75a1e62d910f6444f02318 (patch) | |
tree | b0f51255f32b7d5b1b8942865ee7d1db44b92f10 /tests | |
parent | 84b18cc1aecd61149fc8b686d8665e7c59f784a5 (diff) | |
download | grep-9316d536321af0c44f75a1e62d910f6444f02318.tar.gz |
grep: handle lines longer than INT_MAX on more systems
When trying to exercize some long-line-handling code, I ran these
commands:
$ dd bs=1 seek=2G of=big < /dev/null; grep -l x big; echo $?
grep: big: Invalid argument
2
grep should not have issued that diagnostic, and it should
have exited with status 1, not 2. What happened?
grep read the 2GiB of NULs, doubled its buffer size,
copied the 2GiB into the new 4GiB buffer, and proceeded
to call "read" with a byte-count argument of 2^32.
On at least Darwin 12.5.0, that makes read fail with EINVAL.
The solution is to use gnulib's safe_read wrapper.
* src/main.c: Include "safe-read.h"
(fillbuf): Use safe_read, rather than bare read. The latter
cannot handle a read size of 2^32 on some systems.
* bootstrap.conf (gnulib_modules): Add safe-read.
* tests/long-line-vs-2GiB-read: New file.
* tests/Makefile.am (TESTS): Add it.
* NEWS (Bug fixes): Mention it.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rwxr-xr-x | tests/long-line-vs-2GiB-read | 22 |
2 files changed, 23 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 76b8c52b..72af1556 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -71,6 +71,7 @@ TESTS = \ inconsistent-range \ invalid-multibyte-infloop \ khadafy \ + long-line-vs-2GiB-read \ max-count-vs-context \ multibyte-white-space \ empty-line-mb \ diff --git a/tests/long-line-vs-2GiB-read b/tests/long-line-vs-2GiB-read new file mode 100755 index 00000000..773c542d --- /dev/null +++ b/tests/long-line-vs-2GiB-read @@ -0,0 +1,22 @@ +#!/bin/sh +# Ensure that grep can handle lines 2GiB long. +# Before grep-2.16, a line of length 2^31 or greater would provoke +# an "Invalid argument" (EINVAL) failure from the read syscall on +# systems like OS/X 10.8.5. + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +# Searching 2GiB takes a while. +expensive_ + +echo big > exp || framework_failure_ + +MiB=1048576 +dd bs=$MiB seek=2048 of=big < /dev/null || framework_failure_ +echo x >> big || framework_failure_ +grep -l x big > out 2> err || fail=1 + +compare exp out || fail=1 +compare /dev/null err || fail=1 + +Exit $fail |