strftime: don't assume a byte count fits in 'int'
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 21 Mar 2011 06:59:29 +0000 (23:59 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 21 Mar 2011 07:00:28 +0000 (00:00 -0700)
* lib/strftime.c (add): Don't assume first arg fits in 'int'.  I
found this problem by static analysis, using gcc -Wstrict-overflow
(GCC 4.5.2, x86-64).  This reported an optimization that depended
on an integer overflow having undefined behavior, but it turns out
that the argument is a size, which might not fit in 'int' anyway,

2011-03-20  Paul Eggert  <eggert@cs.ucla.edu>

ChangeLog
lib/strftime.c

index 168a6e9a9c26a76105faafe849847df56b64f894..3b24b8b2ec79ead8359afd172cd32060674658f0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-03-20  Paul Eggert  <eggert@cs.ucla.edu>
+
+       strftime: don't assume a byte count fits in 'int'
+       * lib/strftime.c (add): Don't assume first arg fits in 'int'.  I
+       found this problem by static analysis, using gcc -Wstrict-overflow
+       (GCC 4.5.2, x86-64).  This reported an optimization that depended
+       on an integer overflow having undefined behavior, but it turns out
+       that the argument is a size, which might not fit in 'int' anyway,
+
 2011-03-20  Paul Eggert  <eggert@cs.ucla.edu>
 
        stdio: don't require ignore_value around fwrite
index 0a02b50774450ab234e3c3c3d0bc77aa28bad5a3..95d5beeb84482761d3fc1045ff2edeec241264b1 100644 (file)
@@ -172,15 +172,15 @@ extern char *tzname[];
 #define add(n, f)                                                             \
   do                                                                          \
     {                                                                         \
-      int _n = (n);                                                           \
-      int _delta = width - _n;                                                \
-      int _incr = _n + (_delta > 0 ? _delta : 0);                             \
-      if ((size_t) _incr >= maxsize - i)                                      \
+      size_t _n = (n);                                                        \
+      size_t _incr = _n < width ? width : _n;                                 \
+      if (_incr >= maxsize - i)                                               \
         return 0;                                                             \
       if (p)                                                                  \
         {                                                                     \
-          if (digits == 0 && _delta > 0)                                      \
+          if (digits == 0 && _n < width)                                      \
             {                                                                 \
+              size_t _delta = width - _n;                                     \
               if (pad == L_('0'))                                             \
                 memset_zero (p, _delta);                                      \
               else                                                            \