From: Pádraig Brady Date: Wed, 28 Dec 2022 14:04:19 +0000 (+0000) Subject: wc: fix regression determining file size X-Git-Tag: v9.2~101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=266b7cbc846f91e5f48085c7de68682f5841e2a0;p=thirdparty%2Fcoreutils.git wc: fix regression determining file size * src/wc.c (wc): Use off_t rather than size_t when calculating where to seek to, so that we don't seek to a too low offset on systems where size_t < off_t, which would result in many read() calls to determine the file size. * tests/misc/wc-proc.sh: Add a test case sufficient for 32 bit systems at least. * NEWS: Mention the bug fix. Reported at https://bugs.debian.org/1027101 --- diff --git a/NEWS b/NEWS index b6b5201e7c..7fb8c5363f 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,11 @@ GNU coreutils NEWS -*- outline -*- and the system supported set of valid speeds. [This bug was present in "the beginning".] + `wc -c` will again efficiently determine the size of large files + on all systems. It no longer redundantly reads data from certain + sized files larger than SIZE_MAX. + [bug introduced in coreutils-8.24] + ** Changes in behavior 'cp --reflink=always A B' no longer leaves behind a newly created diff --git a/src/wc.c b/src/wc.c index bc52a8c0ea..df9770396a 100644 --- a/src/wc.c +++ b/src/wc.c @@ -431,7 +431,7 @@ wc (int fd, char const *file_x, struct fstatus *fstatus, off_t current_pos) if (! fstatus->failed && usable_st_size (&fstatus->st) && 0 <= fstatus->st.st_size) { - size_t end_pos = fstatus->st.st_size; + off_t end_pos = fstatus->st.st_size; if (current_pos < 0) current_pos = lseek (fd, 0, SEEK_CUR); diff --git a/tests/misc/wc-proc.sh b/tests/misc/wc-proc.sh index 581890ddd1..030872a91b 100755 --- a/tests/misc/wc-proc.sh +++ b/tests/misc/wc-proc.sh @@ -42,4 +42,11 @@ cat <<\EOF > exp EOF compare exp out || fail=1 +# Ensure we don't read too much when reading, +# as was the case on 32 bit systems +# from coreutils-8.24 to coreutils-9.1 +if timeout 10 truncate -s1T do_read; then + timeout 10 wc -c do_read || fail=1 +fi + Exit $fail