Paul Eggert <[email protected]> writes: > On 2026-10-07 22:15, Collin Funk wrote: >> Given the preceeding checks in that if statement, I suspect >> Paul meant to write something like this: >> ... >> - && 0 <= lseek (fd, hi_pos, SEEK_CUR)) >> + && 0 <= lseek (fd, hi_pos - current_pos, SEEK_CUR)) > > Yes, I should have written either that, or 'lseek (fd, hi_pos, SEEK_SET)'. > > Looking into nearby code I see another bug. That "end_pos % > (STP_BLKSIZE (&fstatus->st) + 1)" is bogus: why add 1 to the > blocksize? In the unlikely event that end_pos is a multiple of both > page_size and of (STP_BLKSIZE (&fstatus->st) + 1), this will surely do > the wrong thing.
I thought it looked a bit strange as well. But I didn't look into it enough to comment on it. :) > Also, the two separate calls to lseek are awkward. Looks good to me. > I installed the attached patch to fix all this. If someone has the energy to > add a test case that would be nice. I pushed the attached patch adding some tests. Perhaps a bit overkill, but mistyping a SEEK_* macro seems a bit too easy to do. Hopefully, it will catch any similar issues in the future. Closing this report now. Thank you both. Collin
>From 77e7674add55be35d83e175c116425735b2f1f74 Mon Sep 17 00:00:00 2001 Message-ID: <77e7674add55be35d83e175c116425735b2f1f74.1791445486.git.collin.fu...@gmail.com> From: Collin Funk <[email protected]> Date: Thu, 8 Oct 2026 00:39:50 -0700 Subject: [PATCH] tests: wc: add a test for the fix in the previous commit * tests/wc/page-size.sh: New file. * tests/local.mk (all_tests): Add the new test. --- tests/local.mk | 1 + tests/wc/page-size.sh | 54 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100755 tests/wc/page-size.sh diff --git a/tests/local.mk b/tests/local.mk index c513c0756..06d8f934d 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -312,6 +312,7 @@ all_tests = \ tests/cut/bounded-memory.sh \ tests/cut/cut-huge-range.sh \ tests/wc/mb-non-utf8.sh \ + tests/wc/page-size.sh \ tests/wc/wc.pl \ tests/wc/wc-cpu.sh \ tests/wc/wc-files0-from.pl \ diff --git a/tests/wc/page-size.sh b/tests/wc/page-size.sh new file mode 100755 index 000000000..562690970 --- /dev/null +++ b/tests/wc/page-size.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# Test 'wc' on files with a size that is a multiple of the system's page size. + +# Copyright (C) 2026 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ wc + +# Get the systems actual page size if possible. Otherwise 4096 is good enough. +page_size=$(getconf PAGESIZE || echo 4096) + +for multiple in $(seq 3); do + head -c $page_size /dev/zero >> file || framework_failure_ + # Count the entire file as a sanity check. + wc -c < file > out 2> err || fail=1 + file_size=$(($multiple * $page_size)) + cat <<EOF > exp || framework_failure_ +$file_size +EOF + compare exp out || fail=1 + compare /dev/null err || fail=1 + # Test 'wc -c' when standard input has a nonzero offset. + # This would give an incorrect result from coreutils-8.24 + # to coreutils-9.12. + skip=$(($multiple * 100)) + (head -c $skip; wc -c > out 2> err) < file || fail=1 + cat <<EOF > exp || framework_failure_ +$(($file_size - $skip)) +EOF + compare exp out || fail=1 + compare /dev/null err || fail=1 + # Likewise. + (head -c $page_size; wc -c > out 2> err) < file || fail=1 + cat <<EOF > exp || framework_failure_ +$(($file_size - $page_size)) +EOF + compare exp out || fail=1 + compare /dev/null err || fail=1 +done + +Exit $fail -- 2.56.0
