findutils-patches
[Top][All Lists]
Advanced

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

[Findutils-patches] [PATCH] Fix savannah bug #23070 (integer overflow wh


From: James Youngman
Subject: [Findutils-patches] [PATCH] Fix savannah bug #23070 (integer overflow when parsing "-used 3")
Date: Sat, 23 Aug 2008 21:48:56 +0100

2008-08-23  James Youngman  <address@hidden>

        * find/parser.c (get_relative_timestamp): Check for overflow after
        the fact by comparing the relatove sizes of the result and the
        operands.  This prevents an incorrect diagnosis of overflow when
        the resulting tv_sec is correctly negative (as is normally the
        case for -used).
---
 find/parser.c |   30 +++++++++++++++++-------------
 1 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/find/parser.c b/find/parser.c
index 623b741..17db633 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -3233,9 +3233,9 @@ get_relative_timestamp (const char *str,
                        double sec_per_unit,
                        const char *overflowmessage)
 {
-  uintmax_t checkval;
   double offset, seconds, nanosec;
-  
+  static const long nanosec_per_sec = 1000000000;
+
   if (get_comp_type(&str, &result->kind))
     {
       /* Invert the sense of the comparison */
@@ -3255,23 +3255,27 @@ get_relative_timestamp (const char *str,
           */
          nanosec = modf(offset * sec_per_unit, &seconds);
          nanosec *= 1.0e9;     /* convert from fractional seconds to ns. */
-         
+         assert (nanosec < nanosec_per_sec);
+
+         /* Perform the subtraction, and then check for overflow. 
+          * On systems where signed aritmetic overflow does not 
+          * wrap, this check may be unreliable.   The C standard 
+          * does not require this approach to work, but I am aware 
+          * of no platforms where it fails.
+          */
          result->ts.tv_sec  = origin.tv_sec - seconds;
+         if ((origin.tv_sec < result->ts.tv_sec) != (seconds < 0))
+           {
+             /* an overflow has occurred. */
+             error (1, 0, overflowmessage, str);
+           }
+
          result->ts.tv_nsec = origin.tv_nsec - nanosec;
-         checkval = (uintmax_t)origin.tv_sec - seconds;
-         
          if (origin.tv_nsec < nanosec) 
            {
              /* Perform a carry operation */
-             result->ts.tv_nsec += 1000000000;
+             result->ts.tv_nsec += nanosec_per_sec;
              result->ts.tv_sec  -= 1;
-             checkval -= 1;
-           }
-         /* Check for overflow. */
-         if (checkval != result->ts.tv_sec)
-           {
-             /* an overflow has occurred. */
-             error (1, 0, overflowmessage, str);
            }
          return true;
        }
-- 
1.5.6.3





reply via email to

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