changeset 14443:fa909c29c50e

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>
author Paul Eggert <eggert@cs.ucla.edu>
date Sun, 20 Mar 2011 23:59:29 -0700
parents 099915a3d0a0
children 4d990235f694
files ChangeLog lib/strftime.c
diffstat 2 files changed, 14 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -172,15 +172,15 @@
 #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                                                            \