coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[coreutils] Re: [PATCH] du: don't print junk when diagnosing out-of-rang


From: Jim Meyering
Subject: [coreutils] Re: [PATCH] du: don't print junk when diagnosing out-of-range time stamps
Date: Sat, 23 Oct 2010 23:26:00 +0200

Paul Eggert wrote:
> While looking into the inttostr issues circulated recently on
> bug-gnulib, I was experimenting with an inttostr variant that I hope
> will be nicer.  In the process, I discovered a bug in du, where du
> uses uninitialized storage.  Here's a patch.

Good catch!

> The tabs in the new file tests/du/bigtime should not be replaced by
> spaces: hope that's OK.

It's ok, but you can avoid them and save two lines:

printf "0\t$bignum\tfuture\n" > exp || framework_failure_

The framework_failure_ isn't absolutely essential, but good
practice, just in case the printf prints nothing and fails
and the following du prints nothing and succeeds.
Without the framework_failure_ use, the test would
mistakenly pass.

> There are a lot of file systems that do reeeeally flaky things
> with time stamps.  For example, NetApp silently replaces out-of-range
> time stamps with the nearest representable time stamp: it uses
> 32-bit unsigned time stamps so the year range is from 1970 to 2106.
> tests/du/bigtime attempts to detect any such shortcomings, and to
> apply the test to du only on hosts where file systems work correctly
> on big time stamps, but localtime does not.
>
> Conversely, it's conceivable that the file system and localtime
> both support big timestamps, in which case du should not report
> an error when converting.  The test also tries to detect hosts where
> that is true, and to skip the test if so.  I don't know of any such
> hosts, so I haven't tested that part of the script.
>
> I haven't pushed this patch, because I don't know whether it's
> safe to get back into the water after the recent coreutils release.

Thanks for asking.
You've guessed right that I want to make a new release ASAP
with an adjusted stat command.  However, this is obviously
a bug fix, so it belongs, too.

> Subject: [PATCH] du: don't print junk when diagnosing out-of-range time stamps
>
> * src/du.c (show_date): Fix call to fputs with a buffer that
> contains some uninitialized data.  While we're at it, print
> the nanosecond part of the time stamp, too, if the file system
> supports that.
> * tests/Makefile.am (TESTS): Add du/big-timestamp.
> * tests/du/bigtime: New file, which checks for the bug.
> ---
>  src/du.c          |   27 ++++++++++++++++++++++++---
>  tests/Makefile.am |    1 +
>  tests/du/bigtime  |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 73 insertions(+), 3 deletions(-)
>  create mode 100755 tests/du/bigtime
>
> diff --git a/src/du.c b/src/du.c
> index 3d92579..33f2656 100644
> --- a/src/du.c
> +++ b/src/du.c
> @@ -350,9 +350,30 @@ show_date (const char *format, struct timespec when)
>    struct tm *tm = localtime (&when.tv_sec);
>    if (! tm)
>      {
> -      char buf[INT_BUFSIZE_BOUND (intmax_t)];
> -      error (0, 0, _("time %s is out of range"), timetostr (when.tv_sec, 
> buf));
> -      fputs (buf, stdout);
> +      char buf[INT_BUFSIZE_BOUND (intmax_t) + 10];
> +      char *when_str = timetostr (when.tv_sec, buf);
> +      int nsec = when.tv_nsec;
> +
> +      /* Display the fraction, omitting trailing zeros.  */

Why is it useful to display the fractional part here?

> +      if (nsec)
> +        {
> +          char *p = when_str + strlen (when_str);
> +          int power_of_ten = 100000000;
> +          *p++ = '.';
> +
> +          do
> +            {
> +              *p++ = '0' + nsec / power_of_ten;
> +              nsec %= power_of_ten;
> +              power_of_ten /= 10;
> +            }
> +          while (nsec);
> +
> +          *p = '\0';
> +        }
> +
> +      error (0, 0, _("time %s is out of range"), when_str);
> +      fputs (when_str, stdout);
>        return;
>      }
>
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 41e0cbc..84db367 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -346,6 +346,7 @@ TESTS =                                           \
>    du/2g                                              \
>    du/8gb                                     \
>    du/basic                                   \
> +  du/bigtime                                 \
>    du/deref                                   \
>    du/deref-args                                      \
>    du/exclude                                 \
> diff --git a/tests/du/bigtime b/tests/du/bigtime
> new file mode 100755
> index 0000000..1a78d52
> --- /dev/null
> +++ b/tests/du/bigtime
> @@ -0,0 +1,48 @@
> +#!/bin/sh
> +# Exercise du on a file with a big time stamp.
> +
> +# Copyright (C) 2010 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 <http://www.gnu.org/licenses/>.
> +
> +. "${srcdir=.}/init.sh"; path_prepend_ ../src
> +
> +export LC_ALL=C
> +export TZ=UTC0
> +
> +# 2**63 - 1
> +bignum=9223372036854775807
> +
> +touch -d @$bignum future 2>/dev/null &&
> +future_time=$(ls -l future) &&
> +case "$future_time" in
> +*" $bignum "*)
> +  : ;;
> +*' Dec  4  300627798676 '*)
> +  skip_ "file system and localtime both handle big timestamps" ;;
> +*)
> +  skip_ "file system or localtime mishandles big time stamps: $future_time" 
> ;;
> +esac || skip_ "file system cannot represent big time stamps"
> +
> +cat >exp <<EOF
> +0    $bignum future
> +EOF
> +cat >err_ok <<EOF
> +du: time $bignum is out of range
> +EOF
> +du --time future >out 2>err || fail=1
> +compare out exp || fail=1
> +compare err err_ok || fail=1
> +
> +Exit $fail



reply via email to

[Prev in Thread] Current Thread [Next in Thread]