changeset 10304:2ceae0b40515

fix builtin_type for permutation matrices, avoid segfaults with invalid values in get_dispatch_type
author Jaroslav Hajek <highegg@gmail.com>
date Wed, 10 Feb 2010 22:12:36 +0100
parents e4899d6320b6
children d6cdf08d0424
files src/ChangeLog src/ov-perm.h src/symtab.cc
diffstat 3 files changed, 26 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Feb 10 16:12:13 2010 -0500
+++ b/src/ChangeLog	Wed Feb 10 22:12:36 2010 +0100
@@ -1,3 +1,10 @@
+2010-02-10  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov-perm.h (octave_perm_matrix::builtin_type): New function.
+	* symtab.cc (build_sup_table): Build the matrix with extra column
+	and row to avoid segfault when undefined value leaks in.
+	(get_dispatch_type): Update. Gripe if invalid result is detected.
+
 2010-02-10  John W. Eaton  <jwe@octave.org>
 
 	* data.cc: Ensure that CLOCKS_PER_SEC is defined instead of HZ.
--- a/src/ov-perm.h	Wed Feb 10 16:12:13 2010 -0500
+++ b/src/ov-perm.h	Wed Feb 10 22:12:36 2010 +0100
@@ -100,6 +100,8 @@
   sortmode is_sorted_rows (sortmode mode = UNSORTED) const
     { return to_dense ().is_sorted_rows (mode); }
 
+  builtin_type_t builtin_type (void) const { return btyp_double; }
+
   bool is_perm_matrix (void) const { return true; }
 
   bool is_matrix_type (void) const { return true; }
--- a/src/symtab.cc	Wed Feb 10 16:12:13 2010 -0500
+++ b/src/symtab.cc	Wed Feb 10 22:12:36 2010 +0100
@@ -452,9 +452,10 @@
 // to btyp_num_types (static constant). Only the leftmost dimension can be
 // variable in C/C++. Typedefs are boring.
 
-static builtin_type_t (*build_sup_table (void))[btyp_num_types]
+// For safety, we include btyp_unknown in the table
+static builtin_type_t (*build_sup_table (void))[btyp_num_types + 1]
 {
-  static builtin_type_t sup_table[btyp_num_types][btyp_num_types];
+  static builtin_type_t sup_table[btyp_num_types + 1][btyp_num_types + 1];
   for (int i = 0; i < btyp_num_types; i++)
     for (int j = 0; j < btyp_num_types; j++)
       {
@@ -472,6 +473,12 @@
         sup_table[i][j] = use_j ? jtyp : ityp;
       }
 
+  for (int i = 0; i <= btyp_num_types; i++)
+    {
+      sup_table[btyp_unknown][i] = btyp_unknown;
+      sup_table[i][btyp_unknown] = btyp_unknown;
+    }
+
   return sup_table;
 }
 
@@ -479,7 +486,7 @@
 get_dispatch_type (const octave_value_list& args, 
                    bool& builtin_class)
 {
-  static builtin_type_t (*sup_table)[btyp_num_types] = build_sup_table ();
+  static builtin_type_t (*sup_table)[btyp_num_types+1] = build_sup_table ();
   std::string dispatch_type;
 
   int n = args.length ();
@@ -530,7 +537,13 @@
           if (btyp != btyp_unknown)
             dispatch_type = btyp_class_name[btyp];
           else
-            builtin_class = false;
+            {
+              // Basically, this should never happen if all values are defined.
+              // If not, that's an internal inconsistency.
+              builtin_class = false;
+              error ("internal error: undefined or invalid value in argument list");
+            }
+
         }
     }