Fixed potentially incorrect dereference in autorecode dialog
authorJohn Darrington <john@darrington.wattle.id.au>
Sat, 5 Oct 2013 17:18:12 +0000 (19:18 +0200)
committerJohn Darrington <john@darrington.wattle.id.au>
Sun, 6 Oct 2013 14:32:45 +0000 (16:32 +0200)
src/ui/gui/autorecode-dialog.c
src/ui/gui/psppire-var-view.c
src/ui/gui/psppire-var-view.h

index fb060f0a4061c940277670a18481247f222d5c59..7b027d9badae5380e8505a007e188ede868318bd 100644 (file)
@@ -91,7 +91,7 @@ on_change_clicked (GObject *obj, gpointer data)
   struct autorecode *rd = data;
   struct variable *var = NULL;
   struct nlp *nlp;
-  GtkTreeModel *model = GTK_TREE_MODEL (PSPPIRE_VAR_VIEW (rd->var_view)->list);
+  GtkTreeModel *model = psppire_var_view_get_current_model (PSPPIRE_VAR_VIEW (rd->var_view));
   GtkTreeIter iter;
   GtkTreeSelection *selection =
     gtk_tree_view_get_selection (GTK_TREE_VIEW (rd->var_view));
@@ -184,7 +184,6 @@ on_entry_change (struct autorecode *rd)
              valid = FALSE;
              break;
            }
-
        }
     }
 
@@ -200,7 +199,8 @@ static void
 on_selection_change (GtkTreeSelection *selection, gpointer data)
 {
   struct autorecode *rd = data;
-  GtkTreeModel *model = GTK_TREE_MODEL (PSPPIRE_VAR_VIEW (rd->var_view)->list);
+  GtkTreeModel *model = psppire_var_view_get_current_model (PSPPIRE_VAR_VIEW (rd->var_view));
+
   GList *rows = gtk_tree_selection_get_selected_rows (selection, &model);
 
   if ( rows && !rows->next)
index c71a5e66103e2821814972461c12b46e1de0aa5a..8f701a4dc742e4ac96a85f4cb49201c931af7081 100644 (file)
@@ -105,14 +105,14 @@ void
 psppire_var_view_clear (PsppireVarView *vv)
 {
   gint i;
-  for (i = 0; i < vv->n_lists; ++i)
-    g_object_unref (vv->list[i]);
+  for (i = 0; i < vv->state->n_lists; ++i)
+    g_object_unref (vv->state->list[i]);
 
-  g_free (vv->list);
+  g_free (vv->state->list);
 
-  vv->n_lists = 0;
-  vv->l_idx = -1;
-  vv->list = NULL;
+  vv->state->n_lists = 0;
+  vv->state->l_idx = -1;
+  vv->state->list = NULL;
 
   psppire_var_view_push_model (vv);
 }
@@ -124,11 +124,12 @@ psppire_var_view_finalize (GObject *object)
   gint i;
   PsppireVarView *var_view = PSPPIRE_VAR_VIEW (object);
   g_free (var_view->nums);
-  for (i = 0; i < var_view->n_lists; ++i)
-    g_object_unref (var_view->list[i]);
+  for (i = 0; i < var_view->state->n_lists; ++i)
+    g_object_unref (var_view->state->list[i]);
 
-  g_free (var_view->list);
+  g_free (var_view->state->list);
   g_free (var_view->cols);
+  g_free (var_view->state);
 }
 
 
@@ -226,23 +227,40 @@ set_renderers (PsppireVarView *var_view)
 void
 psppire_var_view_push_model (PsppireVarView *vv)
 {
-  vv->n_lists++;
-  vv->l_idx++;
-  vv->list = xrealloc (vv->list, sizeof (*vv->list) * vv->n_lists);
-  vv->list[vv->l_idx] = gtk_list_store_newv  (vv->n_cols, vv->cols);
-  g_object_ref (vv->list[vv->l_idx]);
-  gtk_tree_view_set_model (GTK_TREE_VIEW (vv), GTK_TREE_MODEL (vv->list[vv->l_idx]));
+  vv->state->n_lists++;
+  vv->state->l_idx++;
+  vv->state->list = xrealloc (vv->state->list, sizeof (*vv->state->list) * vv->state->n_lists);
+  vv->state->list[vv->state->l_idx] = gtk_list_store_newv  (vv->n_cols, vv->cols);
+  g_object_ref (vv->state->list[vv->state->l_idx]);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (vv), GTK_TREE_MODEL (vv->state->list[vv->state->l_idx]));
 }
 
+
+GtkTreeModel *
+psppire_var_view_get_current_model (PsppireVarView *vv)
+{
+  if (vv->state == NULL) 
+    return NULL;
+
+  if (vv->state->list == NULL) 
+    return NULL;
+
+  if (vv->state->l_idx <= 0) 
+    return NULL;
+
+  return GTK_TREE_MODEL (vv->state->list[vv->state->l_idx]);
+}
+
+
 gboolean
 psppire_var_view_set_current_model (PsppireVarView *vv, gint n)
 {
-  if (n < 0 || n >= vv->n_lists)
+  if (n < 0 || n >= vv->state->n_lists)
     return FALSE;
 
-  vv->l_idx = n;
+  vv->state->l_idx = n;
 
-  gtk_tree_view_set_model (GTK_TREE_VIEW (vv), GTK_TREE_MODEL (vv->list[vv->l_idx]));
+  gtk_tree_view_set_model (GTK_TREE_VIEW (vv), GTK_TREE_MODEL (vv->state->list[vv->state->l_idx]));
 
   return TRUE;
 }
@@ -326,9 +344,10 @@ static void
 psppire_var_view_init (PsppireVarView *vv)
 {
   vv->cols = 0;
-  vv->n_lists = 0;
-  vv->l_idx = -1;
-  vv->list = NULL;
+  vv->state = g_malloc (sizeof *vv->state);
+  vv->state->n_lists = 0;
+  vv->state->l_idx = -1;
+  vv->state->list = NULL;
 }
 
 
@@ -343,19 +362,19 @@ gboolean
 psppire_var_view_get_iter_first (PsppireVarView *vv, GtkTreeIter *iter)
 {
   GtkTreeIter dummy;
-  if ( vv->l_idx < 0)
+  if ( vv->state->l_idx < 0)
     return FALSE;
 
-  return gtk_tree_model_get_iter_first (GTK_TREE_MODEL (vv->list[vv->l_idx]), iter ? iter : &dummy);
+  return gtk_tree_model_get_iter_first (GTK_TREE_MODEL (vv->state->list[vv->state->l_idx]), iter ? iter : &dummy);
 }
 
 gboolean
 psppire_var_view_get_iter_next (PsppireVarView *vv, GtkTreeIter *iter)
 {
-  if ( vv->l_idx < 0)
+  if ( vv->state->l_idx < 0)
     return FALSE;
 
-  return gtk_tree_model_iter_next (GTK_TREE_MODEL (vv->list[vv->l_idx]), iter);
+  return gtk_tree_model_iter_next (GTK_TREE_MODEL (vv->state->list[vv->state->l_idx]), iter);
 }
 
 const struct variable *
@@ -363,7 +382,7 @@ psppire_var_view_get_variable (PsppireVarView *vv, gint column, GtkTreeIter *ite
 {
   const struct variable *var = NULL;
   GValue value = {0};
-  gtk_tree_model_get_value (GTK_TREE_MODEL (vv->list[vv->l_idx]), iter, column, &value);
+  gtk_tree_model_get_value (GTK_TREE_MODEL (vv->state->list[vv->state->l_idx]), iter, column, &value);
 
   if ( G_VALUE_TYPE (&value) == PSPPIRE_VAR_PTR_TYPE)
     var = g_value_get_boxed (&value);
index a8fb0565cab64fbcb2bfd1f0f902621451f99d70..bd1dca2df311535f182bd5e60b1fefb65b3bb7fa 100644 (file)
@@ -40,19 +40,28 @@ typedef struct _PsppireVarViewClass  PsppireVarViewClass;
 
 struct variable;
 
+struct vvstate
+{
+  /* An array of GtkListStores */
+  GtkListStore **list;
+
+  /* The size of the above array */
+  gint n_lists;
+
+  /* The currently selected item in the array */
+  gint l_idx;
+};
+
 struct _PsppireVarView
 {
   GtkTreeView parent;
 
   /* Private */
-  GtkListStore **list;
+  struct vvstate *state;
   
   GType *cols;
   gint *nums;
   gint n_cols;
-
-  gint n_lists;
-  gint l_idx;
 };
 
 struct _PsppireVarViewClass
@@ -76,13 +85,12 @@ const struct variable * psppire_var_view_get_variable (PsppireVarView *vv, gint
 void     psppire_var_view_push_model (PsppireVarView *vv);
 
 gboolean psppire_var_view_set_current_model (PsppireVarView *vv, gint n);
+GtkTreeModel *psppire_var_view_get_current_model (PsppireVarView *vv);
 
 void psppire_var_view_clear (PsppireVarView *vv);
 
 GtkWidget* psppire_var_view_new (void);
 
-
-
 G_END_DECLS
 
 #endif /* __PSPPIRE_VAR_VIEW_H__ */