changeset 20653:c16947991354

avoid fixed-size buffers in index exception code * lo-array-gripes.h, lo-array-gripes.cc (index_exception::expression): Use std::ostringstream instead of fixed size buffer. (gripe_invalid_index): Likewise. (out_of_range::details): Likewise. (index_exception::index_exception): Set default dim value to -1. * ov-complex.h, ov-complex.cc (gripe_complex_index): Now static. Pass arg by const reference instead of value. Use std::ostringstream instead of fixed size buffer. (octave_complex::index_vector): Move definition out of header file.
author John W. Eaton <jwe@octave.org>
date Thu, 22 Oct 2015 12:48:49 -0400
parents 7a8096f8df5d
children b4ceb06009e0
files libinterp/octave-value/ov-complex.cc libinterp/octave-value/ov-complex.h liboctave/util/lo-array-gripes.cc liboctave/util/lo-array-gripes.h
diffstat 4 files changed, 109 insertions(+), 135 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-complex.cc	Wed Oct 21 23:43:46 2015 -0400
+++ b/libinterp/octave-value/ov-complex.cc	Thu Oct 22 12:48:49 2015 -0400
@@ -25,6 +25,7 @@
 #endif
 
 #include <iostream>
+#include <sstream>
 
 #include "lo-ieee.h"
 #include "lo-specfun.h"
@@ -55,6 +56,39 @@
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex,
                                      "complex scalar", "double");
 
+// Complain if a complex value is used as a subscript.
+
+class complex_index_exception : public index_exception
+{
+public:
+
+  complex_index_exception (const std::string& value)
+    : index_exception (value) { }
+
+  ~complex_index_exception (void) { }
+
+  std::string details (void) const
+  {
+    return "subscripts must be real (forgot to initialize i or j?)";
+  }
+
+  // ID of error to throw.
+  const char *err_id (void) const
+  {
+    return error_id_invalid_index;
+  }
+};
+
+static void
+gripe_complex_index (const Complex& idx)
+{
+  std::ostringstream buf;
+  buf << std::real (idx) << std::showpos << std::imag (idx) << "i";
+  complex_index_exception e (buf.str ());
+
+  throw e;
+}
+
 static octave_base_value *
 default_numeric_demotion_function (const octave_base_value& a)
 {
@@ -102,6 +136,14 @@
   return tmp.do_index_op (idx, resize_ok);
 }
 
+idx_vector
+octave_complex::index_vector (bool) const
+{
+  gripe_complex_index (scalar);
+
+  return idx_vector ();
+}
+
 double
 octave_complex::double_value (bool force_conversion) const
 {
@@ -481,40 +523,3 @@
       return octave_base_value::map (umap);
     }
 }
-
-class complex_index_exception : public index_exception
-{
-public:
-
-  complex_index_exception (const std::string& value)
-    : index_exception (value) { }
-
-  ~complex_index_exception (void) { }
-
-  std::string details (void) const
-  {
-    return "subscripts must be real (forgot to initialize i or j?)";
-  }
-
-  // ID of error to throw.
-  const char *err_id (void) const
-  {
-    return error_id_invalid_index;
-  }
-};
-
-// Complain if a complex value is used as a subscript
-
-void
-gripe_complex_index (Complex idx)
-{
-  // FIXME: don't use a fixed size buffer!
-
-  char buf [100];
-
-  sprintf (buf, "%g%+gi", std::real(idx), std::imag(idx));
-
-  complex_index_exception e (buf);
-
-  throw e;
-}
--- a/libinterp/octave-value/ov-complex.h	Wed Oct 21 23:43:46 2015 -0400
+++ b/libinterp/octave-value/ov-complex.h	Thu Oct 22 12:48:49 2015 -0400
@@ -43,9 +43,6 @@
 
 class tree_walker;
 
-extern void OCTAVE_API
-gripe_complex_index (Complex idx);
-
 // Complex scalar values.
 
 class
@@ -81,12 +78,8 @@
   octave_value do_index_op (const octave_value_list& idx,
                             bool resize_ok = false);
 
-  // Use this to give a more specific error message
-  idx_vector index_vector (bool /* require_integers */ = false) const
-  {
-    gripe_complex_index (scalar);
-    return idx_vector ();
-  }
+  // Use this to give a more specific error message.
+  idx_vector index_vector (bool /* require_integers */ = false) const;
 
   octave_value any (int = 0) const
   {
--- a/liboctave/util/lo-array-gripes.cc	Wed Oct 21 23:43:46 2015 -0400
+++ b/liboctave/util/lo-array-gripes.cc	Thu Oct 22 12:48:49 2015 -0400
@@ -25,7 +25,7 @@
 #include <config.h>
 #endif
 
-#include <cstring>
+#include <sstream>
 
 #include "lo-array-gripes.h"
 #include "lo-error.h"
@@ -122,71 +122,45 @@
 std::string
 index_exception::expression (void) const
 {
-  // FIXME: don't use a fixed size buffer!
-  const int buf_len = 300;
-
-  char output [buf_len];
-  char pre [buf_len];
-  char post [buf_len];
+  std::ostringstream buf;
 
-  // dim == 0 if position not yet given, or
-  // <static_cast unsigned int>(-1) if explicitly shown to be unknown
-  // both are caught by this condition
+  if (var.empty () || var == "<unknown>")
+    buf << "index ";
+  else
+    buf << var;
 
-  if (static_cast <unsigned int> (dim-1) > 100000)
-    {
-      // No parentheses are given if the dimension is not known.
-      pre[0] = post[0] = '\0';
-    }
-  else
+  bool show_parens = dim > 0;
+
+  if (show_parens)
     {
       if (dim < 5)
         {
-          pre[0] = '(';
-          octave_idx_type i;
+          buf << "(";
 
-          for (i = 1; i < dim; i++)
-            {
-              pre[2*i-1] = '_';
-              pre[2*i]   = ',';
-            }
-
-          pre[2*i-1] = '\0';    // i == min (1, dim)
+          for (octave_idx_type i = 1; i < dim; i++)
+            buf << "_,";
         }
       else
-        {
-          sprintf (pre, "(...[x%d]...", dim-1);
-        }
+        buf << "(...[x" << dim - 1 << "]...";
+    }
 
-      if (static_cast <unsigned int> (nd-dim) < 5)
+  buf << idx ();
+
+  if (show_parens)
+    {
+      if (nd - dim < 5)
         {
-          for (octave_idx_type i = 0; i < nd-dim; i++)
-            {
-              post[2*i]   = ',';
-              post[2*i+1] = '_';
-            }
+          for (octave_idx_type i = 0; i < nd - dim; i++)
+            buf << ",_";
 
           if (nd >= dim)
-            {
-              post[2*(nd-dim)] = ')';
-              post[2*(nd-dim)+1] = '\0';
-            }
+            buf << ")";
         }
       else
-        sprintf (post, "...[x%d]...)", nd-dim);
+        buf << "...[x" << nd - dim << "]...)";
     }
 
-  const char *v;
-
-  if (var[0] == '\0' || var == "<unknown>")
-    v = "index ";
-  else
-    v = var.c_str ();
-
-  std::string tmp_idx = idx ();
-  snprintf (output, buf_len, "%s%s%s%s", v, pre, tmp_idx.c_str (), post);
-
-  return output;
+  return buf.str ();
 }
 
 class invalid_index : public index_exception
@@ -229,23 +203,18 @@
 gripe_invalid_index (octave_idx_type n, octave_idx_type nd,
                      octave_idx_type dim, const std::string& var)
 {
-  // Note: log10 (2^63) = 19 digits.
-  char buf[64];
-
-  sprintf (buf, "%d", n+1);
-
-  gripe_invalid_index (buf, nd, dim, var);
+  std::ostringstream buf;
+  buf << n + 1;
+  gripe_invalid_index (buf.str (), nd, dim, var);
 }
 
 void
 gripe_invalid_index (double n, octave_idx_type nd, octave_idx_type dim,
                      const std::string& var)
 {
-  char buf[64];
-
-  sprintf (buf, "%g", n+1);
-
-  gripe_invalid_index (buf, nd, dim, var);
+  std::ostringstream buf;
+  buf << n + 1;
+  gripe_invalid_index (buf.str (), nd, dim, var);
 }
 
 
@@ -275,9 +244,9 @@
       }
     else
       {
-        char buf[64];
-        sprintf (buf, "%d", extent);
-        expl = "out of bound " + std::string (buf);
+        std::ostringstream buf;
+        buf << extent;
+        expl = "out of bound " + buf.str ();
       }
 
     return expl;
@@ -295,9 +264,11 @@
 
 private:
 
-  dim_vector size;          // dimension of object being accessed
+  // Dimension of object being accessed.
+  dim_vector size;
 
-  octave_idx_type extent;   // length of dimension being accessed
+  // Length of dimension being accessed.
+  octave_idx_type extent;
 };
 
 // Complain of an index that is out of range, but we don't know matrix size
@@ -305,14 +276,15 @@
 gripe_index_out_of_range (int nd, int dim, octave_idx_type idx,
                           octave_idx_type ext)
 {
-    char buf[64];
-    sprintf (buf, "%d", idx);
-    out_of_range e (buf, nd, dim);
+  std::ostringstream buf;
+  buf << idx;
+  out_of_range e (buf.str (), nd, dim);
 
-    e.set_extent (ext);
-    dim_vector d (1,1,1,1,1,1,1);   // make explain give extent not size
-    e.set_size (d);
-    throw e;
+  e.set_extent (ext);
+  // ??? Make details method give extent not size.
+  e.set_size (dim_vector (1, 1, 1, 1, 1, 1,1));
+
+  throw e;
 }
 
 // Complain of an index that is out of range
@@ -320,13 +292,14 @@
 gripe_index_out_of_range (int nd, int dim, octave_idx_type idx,
                           octave_idx_type ext, const dim_vector& d)
 {
-    char buf[64];
-    sprintf (buf, "%d", idx);
-    out_of_range e (buf, nd, dim);
+  std::ostringstream buf;
+  buf << idx;
+  out_of_range e (buf.str (), nd, dim);
 
-    e.set_extent (ext);
-    e.set_size (d);
-    throw e;
+  e.set_extent (ext);
+  e.set_size (d);
+
+  throw e;
 }
 
 void
--- a/liboctave/util/lo-array-gripes.h	Wed Oct 21 23:43:46 2015 -0400
+++ b/liboctave/util/lo-array-gripes.h	Thu Oct 22 12:48:49 2015 -0400
@@ -37,9 +37,9 @@
 {
 public:
 
-  index_exception (const std::string& index_in, octave_idx_type nd_in = 0,
-                   octave_idx_type dim_in = 0, const char *var_in = "")
-    : index (index_in), nd (nd_in), dim (dim_in), var (var_in)
+  index_exception (const std::string& index_arg, octave_idx_type nd_arg = 0,
+                   octave_idx_type dim_arg = -1, const char *var_arg = "")
+    : index (index_arg), nd (nd_arg), dim (dim_arg), var (var_arg)
   { }
 
   ~index_exception (void) { }
@@ -57,23 +57,26 @@
   virtual std::string message (void) const;
 
   // Position of error: dimension in error, and number of dimensions.
-  void set_pos (octave_idx_type nd_in, octave_idx_type dim_in)
+  void set_pos (octave_idx_type nd_arg, octave_idx_type dim_arg)
   {
-    nd = nd_in;
-    dim = dim_in;
+    nd = nd_arg;
+    dim = dim_arg;
   }
 
-  void set_pos_if_unset (octave_idx_type nd_in, octave_idx_type dim_in)
+  void set_pos_if_unset (octave_idx_type nd_arg, octave_idx_type dim_arg)
   {
     if (nd == 0)
       {
-        nd  = nd_in;
-        dim = dim_in;
+        nd  = nd_arg;
+        dim = dim_arg;
       }
   }
 
   // Name of variable being indexed.  eye(2)(1,1) gives "<unknown>".
-  void set_var (const std::string& var_in = std::string ()) { var = var_in; }
+  void set_var (const std::string& var_arg = std::string ())
+  {
+    var = var_arg;
+  }
 
 private: