Subject: bug#18621: [BUG] wc -c incorrectly counts bytes in /sys

From: Pádraig Brady <[email-masked]>
Date: Wed, 08 Oct 2014 12:51:28 +0100

On 10/08/2014 02:12 AM, Jim Meyering wrote:
> On Tue, Oct 7, 2014 at 5:36 PM, Pádraig Brady <[email-masked]> wrote:
>> On 10/08/2014 12:51 AM, Paul Eggert wrote:
>>> Paul Eggert wrote:
>>>
>>>> The attached patch still needs a changelog entry and test cases.
>>>
>>> I wrote those up and pushed the attached patch; this should fix the bug so I'm closing the bug report.
>>
>> I was just going through the patch as it happens, and I found no issues.
>> I see the tac changes should also avoid erroneous errors if a file was truncated while reading for example.
>> I pushed a follow up to avoid some new syntax check errors.
>>
>> thanks!
>> Pádraig.
> 
> I pushed a patch to avoid a new failiure of the
> split/b-chunk.sh test on non-Linux.

The attached is needed to avoid a new warning on 32 bit.

thanks,
Pádraig.

>From 16c7267d7425fe59b6919e77fa572d104d72c2bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email-masked]>
Date: Wed, 8 Oct 2014 12:35:36 +0100
Subject: [PATCH] maint: avoid new signed overflow warning on 32 bit

Prompted by http://hydra.nixos.org/build/15682577
with GCC 4.8.3 on i686

  src/tac.c:557:6: error: assuming signed overflow does not occur
  when simplifying conditional to constant [-Werror=strict-overflow]
     if (bytes_copied < 0)

This happens because copy_to_temp() is inlined in tac_nonseekable(),
thus reducing the comparison to the bytes_copied variable in
copy_to_temp.  Now this can't overflow on either 32 or 64 bit
due to the protection of the preceding fwrite().  We could use a
guard like "if (bytes_copied <= OFF_T_MAX - bytes_read)" to avoid
the warning, but rather than a runtime branch, just use an unsigned
type to avoid apparent signed overflow on systems where the accumulation
is not promoted to unsigned (32 bit size_t, 64 bit off_t).

* src/tac.c (copy_to_temp): Increment an unsigned type to
avoid the subsequent signed overflow warning.
---
 src/tac.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/src/tac.c b/src/tac.c
index 248afa9..777ec91 100644
--- a/src/tac.c
+++ b/src/tac.c
@@ -506,7 +506,7 @@ copy_to_temp (FILE **g_tmp, char **g_tempfile, int input_fd, char const *file)
 {
   FILE *fp;
   char *file_name;
-  off_t bytes_copied = 0;
+  uintmax_t bytes_copied = 0;
   if (!temp_stream (&fp, &file_name))
     return -1;
 
@@ -527,6 +527,9 @@ copy_to_temp (FILE **g_tmp, char **g_tempfile, int input_fd, char const *file)
           goto Fail;
         }
 
+      /* Implicitly <= OFF_T_MAX due to preceding fwrite(),
+         but unsigned type used to avoid compiler warnings
+         not aware of this fact.  */
       bytes_copied += bytes_read;
     }
 
-- 
1.7.7.6