From ad8deb1d854c66016f9c4e45b20c8ea0ba69ab07 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Sat, 5 Oct 2013 19:18:12 +0200 Subject: [PATCH] Fixed potentially incorrect dereference in autorecode dialog --- src/ui/gui/autorecode-dialog.c | 6 +-- src/ui/gui/psppire-var-view.c | 71 +++++++++++++++++++++------------- src/ui/gui/psppire-var-view.h | 20 +++++++--- 3 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/ui/gui/autorecode-dialog.c b/src/ui/gui/autorecode-dialog.c index fb060f0a40..7b027d9bad 100644 --- a/src/ui/gui/autorecode-dialog.c +++ b/src/ui/gui/autorecode-dialog.c @@ -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) diff --git a/src/ui/gui/psppire-var-view.c b/src/ui/gui/psppire-var-view.c index c71a5e6610..8f701a4dc7 100644 --- a/src/ui/gui/psppire-var-view.c +++ b/src/ui/gui/psppire-var-view.c @@ -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); diff --git a/src/ui/gui/psppire-var-view.h b/src/ui/gui/psppire-var-view.h index a8fb0565ca..bd1dca2df3 100644 --- a/src/ui/gui/psppire-var-view.h +++ b/src/ui/gui/psppire-var-view.h @@ -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__ */ -- 2.30.2