changeset 18205:8c92b5e7fa4d

improve handling of integer field overflow in printf (bug #36278) * oct-stream.cc (DO_DOUBLE_CONV_1): If value will overflow given format type, switch to G format. (DO_DOUBLE_CONV): Check format modifier and call DO_DOUBLE_CONV_1 to do the real work. (octave_base_stream::do_print): Style fix.
author John W. Eaton <jwe@octave.org>
date Fri, 03 Jan 2014 15:12:30 -0500
parents b29beed0e98d
children bea06b5d4423
files libinterp/corefcn/oct-stream.cc
diffstat 1 files changed, 27 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc	Fri Jan 03 11:58:21 2014 -0800
+++ b/libinterp/corefcn/oct-stream.cc	Fri Jan 03 15:12:30 2014 -0500
@@ -2358,15 +2358,15 @@
   return retval;
 }
 
-#define DO_DOUBLE_CONV(TQUAL) \
+#define DO_DOUBLE_CONV_1(TYPE) \
   do \
     { \
-      if (val > std::numeric_limits<TQUAL long>::max () \
-          || val < std::numeric_limits<TQUAL long>::min ()) \
+      if (val > std::numeric_limits<TYPE>::max () \
+          || val < std::numeric_limits<TYPE>::min ()) \
         { \
           std::string tfmt = fmt; \
  \
-          tfmt.replace (tfmt.rfind (elt->type), 1, ".f"); \
+          tfmt.replace (tfmt.rfind (elt->type), 1, ".g"); \
  \
           if (elt->modifier == 'l') \
             tfmt.replace (tfmt.rfind (elt->modifier), 1, ""); \
@@ -2376,7 +2376,17 @@
         } \
       else \
         retval += do_printf_conv (os, fmt, nsa, sa_1, sa_2, \
-                                  static_cast<TQUAL long> (val), who); \
+                                  static_cast<TYPE> (val), who); \
+    } \
+  while (0)
+
+#define DO_DOUBLE_CONV(TQUAL) \
+  do \
+    { \
+       if (elt->modifier == 'l') \
+         DO_DOUBLE_CONV_1 (TQUAL long); \
+       else \
+         DO_DOUBLE_CONV_1 (TQUAL int); \
     } \
   while (0)
 
@@ -2479,15 +2489,19 @@
 
                           const char *tval;
                           if (xisinf (val))
-                            if (elt->flags.find ('+') != std::string::npos)
-                              tval = (val < 0 ? "-Inf" : "+Inf");
-                            else
-                              tval = (val < 0 ? "-Inf" : "Inf");
+                            {
+                              if (elt->flags.find ('+') != std::string::npos)
+                                tval = (val < 0 ? "-Inf" : "+Inf");
+                              else
+                                tval = (val < 0 ? "-Inf" : "Inf");
+                            }
                           else
-                            if (elt->flags.find ('+') != std::string::npos)
-                              tval = (lo_ieee_is_NA (val) ? "+NA" : "+NaN");
-                            else
-                              tval = (lo_ieee_is_NA (val) ? "NA" : "NaN");
+                            {
+                              if (elt->flags.find ('+') != std::string::npos)
+                                tval = (lo_ieee_is_NA (val) ? "+NA" : "+NaN");
+                              else
+                                tval = (lo_ieee_is_NA (val) ? "NA" : "NaN");
+                            }
 
                           retval += do_printf_conv (os, tfmt.c_str (),
                                                     nsa, sa_1, sa_2,